@@ -3,17 +3,44 @@ import { tracked } from '@glimmer/tracking';
33import { action } from ' @ember/object' ;
44import { on } from ' @ember/modifier' ;
55import BasicDropdown from ' ember-basic-dropdown/components/basic-dropdown' ;
6- import PowerCalendar from ' ember-power-calendar/components/power-calendar' ;
6+ import PowerSelect from ' ember-power-select/components/power-select' ;
7+ import PowerCalendar , {
8+ type PowerCalendarDefaultBlock ,
9+ } from ' ember-power-calendar/components/power-calendar' ;
710import {
811 formatDate ,
912 type NormalizeCalendarValue ,
1013 type PowerCalendarDay ,
1114} from ' ember-power-calendar/utils' ;
15+ import { fn } from ' @ember/helper' ;
16+ import type { Dropdown } from ' ember-basic-dropdown/types' ;
17+ import type { Select , Selected } from ' ember-power-select/types' ;
1218
1319export default class extends Component {
1420 @tracked center: Date | undefined = undefined ;
1521 @tracked selected: Date | undefined = undefined ;
1622
23+ dropdownApi: Dropdown | null = null ;
24+
25+ months: string [] = [
26+ ' January' ,
27+ ' February' ,
28+ ' March' ,
29+ ' April' ,
30+ ' May' ,
31+ ' June' ,
32+ ' July' ,
33+ ' August' ,
34+ ' September' ,
35+ ' October' ,
36+ ' November' ,
37+ ' December' ,
38+ ];
39+
40+ years: string [] = Array (... (Array (120 ) as never [])).map (
41+ (_ , i ) => ` ${i + 1940 } ` ,
42+ );
43+
1744 @action
1845 onCenterChange(selected : NormalizeCalendarValue ) {
1946 this .center = selected .date ;
@@ -22,27 +49,94 @@ export default class extends Component {
2249 @action
2350 onSelect(selected : PowerCalendarDay ) {
2451 this .selected = selected .date ;
52+
53+ this .dropdownApi ?.actions .close ();
54+ }
55+
56+ @action
57+ onClose(dropdown : Dropdown , e ? : Event ): boolean {
58+ // Avoid closing date picker when cursor is inside input field
59+ if (
60+ e ?.type === ' click' &&
61+ document .activeElement === e ?.target &&
62+ (e ?.target as HTMLElement ).tagName === ' INPUT' &&
63+ (e ?.target as HTMLElement )?.closest (
64+ ` [data-ebd-id="${dropdown .uniqueId }-trigger"] ` ,
65+ )
66+ ) {
67+ return false ;
68+ }
69+
70+ // Avoid closing date picker when cursor is inside the dropdown
71+ if (
72+ e ?.type === ' click' &&
73+ document .activeElement ?.closest (
74+ ` [id="ember-basic-dropdown-content-${dropdown .uniqueId }"] ` ,
75+ )
76+ ) {
77+ return false ;
78+ }
79+
80+ return true ;
81+ }
82+
83+ @action
84+ async changeCenter(
85+ unit : ' month' | ' year' ,
86+ calendar : PowerCalendarDefaultBlock ,
87+ selectedValue : Selected <string >,
88+ _select : Select <string >,
89+ e ? : Event ,
90+ ) {
91+ const newCenter = new Date (calendar .center );
92+
93+ switch (unit ) {
94+ case ' month' : {
95+ const value = this .months .indexOf (selectedValue ?? ' ' );
96+ newCenter .setMonth (value );
97+ break ;
98+ }
99+
100+ case ' year' :
101+ newCenter .setFullYear (parseInt (selectedValue ?? ' ' ));
102+ break ;
103+ }
104+
105+ if (calendar .actions .changeCenter && e ) {
106+ await calendar .actions .changeCenter (newCenter , calendar , e );
107+ }
108+ }
109+
110+ @action
111+ registerAPI(api : Dropdown | null ) {
112+ this .dropdownApi = api ;
25113 }
26114
27115 <template >
28- <BasicDropdown as | dropdown | >
29- <div >
30- <label for =" datepicker-1" >Date picker</label >
31- </div >
32-
33- <input
34- type =" text"
35- data-ebd-id =" {{dropdown.uniqueId }} -trigger"
36- class =" datepicker-demo-input"
37- value ={{if this . selected ( formatDate this . selected " DD-MM-YYYY" ) }}
38- id =" datepicker-1"
39- readonly
40- {{on " focus" dropdown.actions.toggle }}
41- />
116+ <BasicDropdown
117+ @ onClose ={{this .onClose }}
118+ @ renderInPlace ={{ false }}
119+ @ registerAPI ={{this .registerAPI }}
120+ as | dropdown |
121+ >
122+ <dropdown.Trigger tabindex =" -1" >
123+ <div >
124+ <label for =" datepicker-1" >Date picker</label >
125+ </div >
126+
127+ <input
128+ type =" text"
129+ class =" datepicker-demo-input"
130+ value ={{if this . selected ( formatDate this . selected " DD-MM-YYYY" ) }}
131+ id =" datepicker-1"
132+ readonly
133+ {{on " focus" dropdown.actions.toggle }}
134+ />
135+ </dropdown.Trigger >
42136
43137 <dropdown.Content class =" datepicker-demo-dropdown" >
44138 <PowerCalendar
45- class =" demo-calendar-small"
139+ class =" demo-calendar-small nav-with-power-select-demo "
46140 @ center ={{this .center }}
47141 @ onCenterChange ={{this .onCenterChange }}
48142 @ selected ={{this .selected }}
@@ -51,7 +145,25 @@ export default class extends Component {
51145 @ autofocus ={{ true }}
52146 as | calendar |
53147 >
54- <calendar.Nav />
148+ <calendar.Nav >
149+ <PowerSelect
150+ @ options ={{this .months }}
151+ @ selected ={{formatDate calendar.center " MMMM" }}
152+ @ matchTriggerWidth ={{ false }}
153+ @ onChange ={{fn this . changeCenter " month" calendar }}
154+ as | month |
155+ >
156+ {{month }}
157+ </PowerSelect >
158+ <PowerSelect
159+ @ options ={{this .years }}
160+ @ selected ={{formatDate calendar.center " YYYY" }}
161+ @ onChange ={{fn this . changeCenter " year" calendar }}
162+ as | year |
163+ >
164+ {{year }}
165+ </PowerSelect >
166+ </calendar.Nav >
55167 <calendar.Days />
56168 </PowerCalendar >
57169 </dropdown.Content >
0 commit comments