@gez/date-time-kit 1.1.4 → 2.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/assets/arrow-down.svg +1 -0
  2. package/dist/assets/arrow-left-double.svg +1 -0
  3. package/dist/assets/arrow-left.svg +1 -0
  4. package/dist/assets/arrow-right-double.svg +1 -0
  5. package/dist/assets/arrow-right.svg +1 -0
  6. package/dist/assets/back-arrow.svg +1 -0
  7. package/dist/assets/time.svg +1 -0
  8. package/dist/components/calendar/index.css +108 -0
  9. package/dist/components/calendar/index.d.ts +84 -0
  10. package/dist/components/calendar/index.mjs +238 -0
  11. package/dist/components/hhmmss-ms-list-grp/index.css +60 -0
  12. package/dist/components/hhmmss-ms-list-grp/index.d.ts +54 -0
  13. package/dist/components/hhmmss-ms-list-grp/index.mjs +226 -0
  14. package/dist/components/i18n/index.d.ts +13 -0
  15. package/dist/components/i18n/index.mjs +42 -0
  16. package/dist/components/num-list/index.css +35 -0
  17. package/dist/components/num-list/index.d.ts +68 -0
  18. package/dist/components/num-list/index.mjs +259 -0
  19. package/dist/components/period-selector/date-nav.css +92 -0
  20. package/dist/components/period-selector/date-nav.d.ts +64 -0
  21. package/dist/components/period-selector/date-nav.mjs +161 -0
  22. package/dist/components/period-selector/index.css +152 -0
  23. package/dist/components/period-selector/index.d.ts +68 -0
  24. package/dist/components/period-selector/index.mjs +312 -0
  25. package/dist/components/popover/index.d.ts +34 -0
  26. package/dist/components/popover/index.mjs +104 -0
  27. package/dist/components/quick-selector/index.css +167 -0
  28. package/dist/components/quick-selector/index.d.ts +74 -0
  29. package/dist/components/quick-selector/index.mjs +347 -0
  30. package/dist/components/web-component-base/index.css +9 -0
  31. package/dist/components/web-component-base/index.d.ts +46 -0
  32. package/dist/components/web-component-base/index.mjs +118 -0
  33. package/dist/components/web-component-base/scrollbar.css +25 -0
  34. package/dist/components/yyyymmdd-list-grp/index.css +32 -0
  35. package/dist/components/yyyymmdd-list-grp/index.d.ts +52 -0
  36. package/dist/components/yyyymmdd-list-grp/index.mjs +181 -0
  37. package/dist/i18n.d.ts +36 -0
  38. package/dist/i18n.mjs +368 -0
  39. package/dist/index.d.ts +7 -0
  40. package/dist/index.mjs +15 -0
  41. package/dist/utils.d.ts +12 -0
  42. package/dist/utils.mjs +21 -0
  43. package/package.json +37 -63
  44. package/src/assets/arrow-down.svg +1 -0
  45. package/src/assets/arrow-left-double.svg +1 -0
  46. package/src/assets/arrow-left.svg +1 -0
  47. package/src/assets/arrow-right-double.svg +1 -0
  48. package/src/assets/arrow-right.svg +1 -0
  49. package/src/assets/back-arrow.svg +1 -0
  50. package/src/assets/time.svg +1 -0
  51. package/src/components/calendar/index.scss +128 -0
  52. package/src/components/calendar/index.ts +453 -0
  53. package/src/components/hhmmss-ms-list-grp/index.scss +61 -0
  54. package/src/components/hhmmss-ms-list-grp/index.ts +387 -0
  55. package/src/components/i18n/index.ts +48 -0
  56. package/src/components/num-list/index.scss +38 -0
  57. package/src/components/num-list/index.ts +357 -0
  58. package/src/components/period-selector/date-nav.scss +108 -0
  59. package/src/components/period-selector/date-nav.ts +322 -0
  60. package/src/components/period-selector/index.scss +160 -0
  61. package/src/components/period-selector/index.ts +552 -0
  62. package/src/components/popover/index.ts +127 -0
  63. package/src/components/quick-selector/index.scss +183 -0
  64. package/src/components/quick-selector/index.ts +611 -0
  65. package/src/components/web-component-base/index.scss +11 -0
  66. package/src/components/web-component-base/index.ts +235 -0
  67. package/src/components/web-component-base/scrollbar.scss +30 -0
  68. package/src/components/yyyymmdd-list-grp/index.scss +33 -0
  69. package/src/components/yyyymmdd-list-grp/index.ts +257 -0
  70. package/src/i18n.ts +415 -0
  71. package/src/index.ts +12 -0
  72. package/src/utils.ts +36 -0
  73. package/README.md +0 -152
  74. package/dist/index.css +0 -1
  75. package/dist/index.html +0 -85
  76. package/dist/index.js +0 -145
  77. package/type.d.ts +0 -164
@@ -0,0 +1,235 @@
1
+ import type { Lang } from '../../i18n';
2
+ import { css } from '../../utils';
3
+ // import styleStr from './index.scss?inline';
4
+ const styleStr = css`
5
+ /* firefox only: */
6
+ @-moz-document url-prefix() {
7
+ :host, * {
8
+ scrollbar-width: thin;
9
+ scrollbar-color: var(--scrollbar-thumb-color, #4444) transparent;
10
+ }
11
+ :host:hover, *:hover {
12
+ scrollbar-color: var(--scrollbar-thumb-color-hover, var(--scrollbar-thumb-color, #8888)) transparent;
13
+ }
14
+ }
15
+ `;
16
+ // import scrollbarStyleStr from './scrollbar.scss?inline';
17
+ const scrollbarStyleStr = css`
18
+ [dt]::-webkit-scrollbar, :host *::-webkit-scrollbar {
19
+ width: 6px;
20
+ height: 6px;
21
+ }
22
+ [dt]::-webkit-scrollbar-button, :host *::-webkit-scrollbar-button {
23
+ display: none;
24
+ }
25
+ [dt]::-webkit-scrollbar-corner, :host *::-webkit-scrollbar-corner {
26
+ display: none;
27
+ }
28
+ [dt]::-webkit-scrollbar-thumb, :host *::-webkit-scrollbar-thumb {
29
+ background-color: var(--scrollbar-thumb-color, #4444);
30
+ border-radius: 4px;
31
+ cursor: grab;
32
+ }
33
+ [dt]::-webkit-scrollbar-thumb:hover, :host *::-webkit-scrollbar-thumb:hover {
34
+ background-color: var(--scrollbar-thumb-color-hover, var(--scrollbar-thumb-color, #8888));
35
+ }
36
+ [dt]::-webkit-scrollbar-thumb:active, :host *::-webkit-scrollbar-thumb:active {
37
+ background-color: var(--scrollbar-thumb-color-active, var(--scrollbar-thumb-color, #2222));
38
+ cursor: grabbing;
39
+ }
40
+ [dt]::-webkit-scrollbar-track, :host *::-webkit-scrollbar-track {
41
+ background: transparent;
42
+ }
43
+ `;
44
+
45
+ type EmitType = Record<string, any>;
46
+ export type Emit2EventMap<Emit extends EmitType> = {
47
+ [K in keyof Emit]: CustomEvent<Emit[K]>;
48
+ };
49
+
50
+ export type ListenerFn<
51
+ Emit extends EmitType,
52
+ K extends keyof Emit | keyof HTMLElementEventMap
53
+ > = (
54
+ this: HTMLElement,
55
+ ev: K extends keyof Emit
56
+ ? CustomEvent<Emit[K]>
57
+ : HTMLElementEventMap[K & keyof HTMLElementEventMap]
58
+ ) => any;
59
+
60
+ export type EventListenerObj<
61
+ Emit extends EmitType,
62
+ K extends keyof Emit | keyof HTMLElementEventMap
63
+ > = { handleEvent: ListenerFn<Emit, K> };
64
+
65
+ export type EventListenerOrListenerObj<
66
+ Emit extends EmitType,
67
+ K extends keyof Emit | keyof HTMLElementEventMap
68
+ > = ListenerFn<Emit, K> | EventListenerObj<Emit, K>;
69
+
70
+ type getAttrType<Attr, K extends keyof Attr> = Extract<
71
+ Attr[K],
72
+ string
73
+ > extends never
74
+ ? string
75
+ : Extract<Attr[K], string>;
76
+
77
+ // tagName to template element cache
78
+ const templateCache = new Map<string, HTMLTemplateElement>();
79
+
80
+ export interface BaseAttrs {
81
+ /**
82
+ * The language of the component.
83
+ * @type `Lang`
84
+ */
85
+ lang?: Lang;
86
+ }
87
+
88
+ if (typeof document === 'object') {
89
+ // const styleEle = document.createElement('style');
90
+ // styleEle.innerHTML = scrollbarStyleStr;
91
+ // document.head.prepend(styleEle);
92
+ const styleSheet = new CSSStyleSheet();
93
+ styleSheet.replaceSync(scrollbarStyleStr);
94
+ document.adoptedStyleSheets.unshift(styleSheet);
95
+ }
96
+
97
+ const HTMLElementBase = (() => {
98
+ if (typeof HTMLElement === 'function') return HTMLElement;
99
+ return class {} as typeof HTMLElement;
100
+ })();
101
+
102
+ export class UiBase<
103
+ Attr extends BaseAttrs = BaseAttrs,
104
+ Emit extends Record<string, any> = {}
105
+ > extends HTMLElementBase {
106
+ public static readonly tagName: string = '';
107
+ protected static _definePromise: Promise<CustomElementConstructor> | null =
108
+ null;
109
+ public static define() {
110
+ if (this._definePromise) return this._definePromise;
111
+ if (typeof customElements === 'undefined') {
112
+ return;
113
+ }
114
+ const tagName = this.tagName;
115
+ if (!tagName) throw new Error('UiBase.define: tagName is not defined.');
116
+ console.log('Define custom element:', tagName);
117
+ customElements.define(tagName, this);
118
+ return (this._definePromise = customElements.whenDefined(tagName));
119
+ }
120
+
121
+ // TODO: use override keyword in subclasses
122
+ static get observedAttributes(): string[] {
123
+ return ['lang'] satisfies (keyof BaseAttrs)[];
124
+ }
125
+
126
+ protected _template = '';
127
+ protected _style = '';
128
+ protected _initTemplate() {
129
+ const { tagName } = this;
130
+ if (templateCache.has(tagName)) return templateCache.get(tagName)!;
131
+ const templateEle = document.createElement('template');
132
+ templateEle.innerHTML = `<style>${scrollbarStyleStr}${styleStr}${this._style}</style>${this._template}`;
133
+ templateCache.set(tagName, templateEle);
134
+ return templateEle;
135
+ }
136
+ protected _applyTemplate() {
137
+ if (!this.shadowRoot) return;
138
+ this.shadowRoot.innerHTML = '';
139
+ this.shadowRoot.appendChild(
140
+ this._initTemplate().content.cloneNode(true)
141
+ );
142
+ }
143
+
144
+ constructor() {
145
+ super();
146
+ this.attachShadow({ mode: 'open' });
147
+ }
148
+
149
+ protected _getAttr<
150
+ K extends keyof Attr,
151
+ D extends undefined | getAttrType<Attr, K> = undefined
152
+ >(
153
+ qualifiedName: K,
154
+ defaultValue?: D
155
+ ): undefined extends D
156
+ ? getAttrType<Attr, K> | null
157
+ : getAttrType<Attr, K> {
158
+ const attr = this.getAttribute(qualifiedName as string);
159
+ return (
160
+ attr === null && defaultValue !== void 0 ? defaultValue : attr
161
+ ) as getAttrType<Attr, K>;
162
+ }
163
+
164
+ protected _onAttrChanged(_name: string, _oldVal: string, _newVal: string) {}
165
+
166
+ attributeChangedCallback(name: string, oldValue: string, newValue: string) {
167
+ if (oldValue === newValue) return;
168
+ if (name !== 'lang')
169
+ return this._onAttrChanged(name, oldValue, newValue);
170
+ this.shadowRoot?.querySelectorAll('[dt]').forEach((ele) => {
171
+ if (newValue) {
172
+ ele.setAttribute('lang', newValue);
173
+ } else {
174
+ ele.removeAttribute('lang');
175
+ }
176
+ });
177
+ }
178
+ /** return false | void means not continue */
179
+ connectedCallback(): boolean | void {
180
+ this.setAttribute('dt', '');
181
+ return !!this.shadowRoot;
182
+ }
183
+ /** return false | void means not continue */
184
+ disconnectedCallback(): boolean | void {
185
+ return !!this.shadowRoot;
186
+ }
187
+ connectedMoveCallback() {}
188
+ adoptedCallback() {}
189
+
190
+ dispatchEvent<K extends keyof Emit | undefined = undefined>(
191
+ type: K | Event,
192
+ data?: K extends keyof Emit ? Emit[K] : any,
193
+ global = false
194
+ ) {
195
+ return type instanceof Event
196
+ ? super.dispatchEvent(type)
197
+ : super.dispatchEvent(
198
+ new CustomEvent(type as string, {
199
+ ...(global
200
+ ? {
201
+ bubbles: true,
202
+ cancelable: true,
203
+ composed: true
204
+ }
205
+ : {}),
206
+ detail: data
207
+ })
208
+ );
209
+ }
210
+
211
+ public addEventListener<K extends keyof Emit | keyof HTMLElementEventMap>(
212
+ type: K | string,
213
+ listener: EventListenerOrListenerObj<Emit, K>,
214
+ options?: boolean | EventListenerOptions
215
+ ): void {
216
+ super.addEventListener(
217
+ type as string,
218
+ listener as EventListenerOrEventListenerObject,
219
+ options
220
+ );
221
+ }
222
+ public removeEventListener<
223
+ K extends keyof Emit | keyof HTMLElementEventMap
224
+ >(
225
+ type: K | string,
226
+ listener: EventListenerOrListenerObj<Emit, K>,
227
+ options?: boolean | EventListenerOptions
228
+ ): void {
229
+ super.removeEventListener(
230
+ type as string,
231
+ listener as EventListenerOrEventListenerObject,
232
+ options
233
+ );
234
+ }
235
+ }
@@ -0,0 +1,30 @@
1
+
2
+ [dt], :host * {
3
+ &::-webkit-scrollbar {
4
+ width: 6px;
5
+ height: 6px;
6
+ }
7
+ &::-webkit-scrollbar-button {
8
+ display: none;
9
+ }
10
+ &::-webkit-scrollbar-corner {
11
+ display: none;
12
+ }
13
+ &::-webkit-scrollbar-thumb {
14
+ background-color: var(--scrollbar-thumb-color, #4444);
15
+ border-radius: 4px;
16
+ cursor: grab;
17
+
18
+ &:hover {
19
+ background-color: var(--scrollbar-thumb-color-hover, var(--scrollbar-thumb-color, #8888));
20
+ }
21
+
22
+ &:active {
23
+ background-color: var(--scrollbar-thumb-color-active, var(--scrollbar-thumb-color, #2222));
24
+ cursor: grabbing;
25
+ }
26
+ }
27
+ &::-webkit-scrollbar-track {
28
+ background: transparent;
29
+ }
30
+ }
@@ -0,0 +1,33 @@
1
+
2
+ :host {
3
+ display: flex;
4
+ flex-direction: column;
5
+ overflow: hidden;
6
+ gap: 15px;
7
+ }
8
+
9
+ .cols {
10
+ flex: 1;
11
+ display: flex;
12
+ flex-direction: row;
13
+ height: 0;
14
+ justify-content: space-between;
15
+ gap: 2px;
16
+ }
17
+
18
+ .col {
19
+ flex: 1;
20
+ display: flex;
21
+ flex-direction: column;
22
+ gap: 10px;
23
+ }
24
+
25
+ .col > span {
26
+ text-align: center;
27
+ display: inline-block;
28
+ line-height: 27px;
29
+ }
30
+
31
+ dt-num-list {
32
+ flex: 1;
33
+ }
@@ -0,0 +1,257 @@
1
+ import { debounce, html } from '../../utils';
2
+ import { Ele as NumListEle, type EventMap as NumListEvent } from '../num-list';
3
+ NumListEle.define();
4
+ import {
5
+ type BaseAttrs,
6
+ type Emit2EventMap,
7
+ UiBase
8
+ } from '../web-component-base';
9
+ // import styleStr from './index.scss?inline';
10
+ const styleStr = '';
11
+
12
+ export interface Attrs extends BaseAttrs {
13
+ millisecond: number;
14
+ // 'max-millisecond'?: number;
15
+ // 'min-millisecond'?: number;
16
+ /**
17
+ * 选择器的粒度,表示最大可选的时间单位。默认为 year。
18
+ * 例如设置为 'month',则表示最大只能选择到月份,年将被忽略。
19
+ */
20
+ 'max-granularity'?: 'year' | 'month' | 'day';
21
+ /**
22
+ * 选择器的粒度,表示最小可选的时间单位。默认为 second。
23
+ * 例如设置为 'month',则表示只能选择到月份,日会将被忽略。
24
+ */
25
+ 'min-granularity'?: 'year' | 'month' | 'day';
26
+ 'col-order'?: 'ymd' | 'ydm' | 'myd' | 'mdy' | 'dym' | 'dmy';
27
+ }
28
+
29
+ export interface Emits {
30
+ change: {
31
+ oldMs: number;
32
+ newMs: number;
33
+ };
34
+ }
35
+ export type EventMap = Emit2EventMap<Emits>;
36
+
37
+ /**
38
+ * 日期选择器
39
+ */
40
+ export class Ele extends UiBase<Attrs, Emits> {
41
+ public static readonly tagName = 'dt-yyyymmdd-list-grp' as const;
42
+
43
+ static get observedAttributes(): string[] {
44
+ return [
45
+ ...(super.observedAttributes as (keyof BaseAttrs)[]),
46
+ 'millisecond',
47
+ 'max-granularity',
48
+ 'min-granularity',
49
+ 'col-order'
50
+ ] satisfies (keyof Attrs)[];
51
+ }
52
+
53
+ protected _style = styleStr;
54
+ protected _template = html`
55
+ <div class="cols" part="cols">
56
+ <div class="col year" part="col year">
57
+ <span part="col label year">Year</span>
58
+ <dt-num-list part="list year" class="year"></dt-num-list>
59
+ </div>
60
+ <div class="col month" part="col month">
61
+ <span part="col label month">Month</span>
62
+ <dt-num-list part="list month" class="month" min-num="1" max-num="12"></dt-num-list>
63
+ </div>
64
+ <div class="col day" part="col day">
65
+ <span part="col label day">Day</span>
66
+ <dt-num-list part="list day" class="day" min-num="1" max-num="31"></dt-num-list>
67
+ </div>
68
+ </div>
69
+ `;
70
+
71
+ constructor() {
72
+ super();
73
+ this._applyTemplate();
74
+ }
75
+
76
+ private get _listEleYear() {
77
+ return this.shadowRoot?.querySelector('dt-num-list.year') as NumListEle;
78
+ }
79
+ private get _listEleMonth() {
80
+ return this.shadowRoot?.querySelector(
81
+ 'dt-num-list.month'
82
+ ) as NumListEle;
83
+ }
84
+ private get _listEleDay() {
85
+ return this.shadowRoot?.querySelector('dt-num-list.day') as NumListEle;
86
+ }
87
+
88
+ public get millisecond() {
89
+ return Math.floor(+this._getAttr('millisecond', '0'));
90
+ }
91
+ public set millisecond(v: number) {
92
+ if (!Number.isSafeInteger(v)) return;
93
+ this.setAttribute('millisecond', '' + Math.floor(v));
94
+ }
95
+ public get maxGranularity() {
96
+ return this._getAttr('max-granularity', 'year') as
97
+ | 'year'
98
+ | 'month'
99
+ | 'day';
100
+ }
101
+ public set maxGranularity(v: 'year' | 'month' | 'day') {
102
+ if (!['year', 'month', 'day'].includes(v)) return;
103
+ this.setAttribute('max-granularity', v);
104
+ }
105
+ public get minGranularity() {
106
+ return this._getAttr('min-granularity', 'day') as
107
+ | 'year'
108
+ | 'month'
109
+ | 'day';
110
+ }
111
+ public set minGranularity(v: 'year' | 'month' | 'day') {
112
+ if (!['year', 'month', 'day'].includes(v)) return;
113
+ this.setAttribute('min-granularity', v);
114
+ }
115
+ public get colOrder() {
116
+ return this._getAttr('col-order', 'dmy') as
117
+ | 'ymd'
118
+ | 'ydm'
119
+ | 'myd'
120
+ | 'mdy'
121
+ | 'dym'
122
+ | 'dmy';
123
+ }
124
+ public set colOrder(v: 'ymd' | 'ydm' | 'myd' | 'mdy' | 'dym' | 'dmy') {
125
+ if (!['ymd', 'ydm', 'myd', 'mdy', 'dym', 'dmy'].includes(v)) return;
126
+ this.setAttribute('col-order', v);
127
+ }
128
+
129
+ public scrollToCurrentItem() {
130
+ this.shadowRoot?.querySelectorAll('dt-num-list').forEach((ele) => {
131
+ if (ele instanceof NumListEle) ele.scrollToCurrent();
132
+ });
133
+ }
134
+
135
+ public connectedCallback() {
136
+ if (!super.connectedCallback()) return;
137
+ this._listEleYear.formatter = (num) => '' + num;
138
+ this._listEleMonth.formatter = this._listEleDay.formatter = (num) =>
139
+ ('0' + num).slice(-2);
140
+
141
+ this._renderCols();
142
+ this._updateGranularity();
143
+ this._updateColsValue();
144
+
145
+ this._listEleYear.addEventListener('select-num', this._onColsSelect);
146
+ this._listEleMonth.addEventListener('select-num', this._onColsSelect);
147
+ this._listEleDay.addEventListener('select-num', this._onColsSelect);
148
+ }
149
+ public disconnectedCallback() {
150
+ if (!super.disconnectedCallback()) return;
151
+ this._listEleYear.removeEventListener('select-num', this._onColsSelect);
152
+ this._listEleMonth.removeEventListener(
153
+ 'select-num',
154
+ this._onColsSelect
155
+ );
156
+ this._listEleDay.removeEventListener('select-num', this._onColsSelect);
157
+ }
158
+
159
+ protected _onAttrChanged(name: string, oldValue: string, newValue: string) {
160
+ super._onAttrChanged(name, oldValue, newValue);
161
+ if (name === 'col-order') this._renderCols();
162
+ else if (name === 'max-granularity' || name === 'min-granularity')
163
+ this._updateGranularity();
164
+ else if (name === 'millisecond') this._updateColsValue();
165
+ }
166
+
167
+ private _renderCols = debounce(() => {
168
+ if (!this.isConnected) return;
169
+ const { colOrder } = this;
170
+ // columns order
171
+ const orderedCols = ['year', 'month', 'day']
172
+ .sort((a, b) => colOrder.indexOf(a[0]) - colOrder.indexOf(b[0]))
173
+ .map(
174
+ (s) => this.shadowRoot!.querySelector<HTMLElement>(`.col.${s}`)!
175
+ );
176
+ const colsContainer =
177
+ this.shadowRoot!.querySelector<HTMLElement>('.cols')!;
178
+ // return if order not changed
179
+ if (orderedCols.every((el, i) => el === colsContainer.children[i]))
180
+ return;
181
+ colsContainer.append(...orderedCols);
182
+ }, 0);
183
+
184
+ private _updateGranularity = debounce(() => {
185
+ if (!this.isConnected) return;
186
+ const { maxGranularity, minGranularity } = this;
187
+ const colsContainer =
188
+ this.shadowRoot!.querySelector<HTMLElement>('.cols')!;
189
+ const yEle = this.shadowRoot!.querySelector<HTMLElement>('.col.year')!;
190
+ const mEle = this.shadowRoot!.querySelector<HTMLElement>('.col.month')!;
191
+ const dEle = this.shadowRoot!.querySelector<HTMLElement>('.col.day')!;
192
+ const granularityMap = { year: 3, month: 2, day: 1 };
193
+ let maxG = granularityMap[maxGranularity] ?? 1;
194
+ let minG = granularityMap[minGranularity] ?? 3;
195
+ if (maxG < minG) [maxG, minG] = [minG, maxG];
196
+ yEle.style.display = maxG >= 3 && minG <= 3 ? '' : 'none';
197
+ mEle.style.display = maxG >= 2 && minG <= 2 ? '' : 'none';
198
+ dEle.style.display = maxG >= 1 && minG <= 1 ? '' : 'none';
199
+ colsContainer.style.display = [yEle, mEle, dEle].filter(
200
+ (ele) => ele.style.display !== 'none'
201
+ ).length
202
+ ? ''
203
+ : 'none';
204
+ }, 0);
205
+
206
+ private _updateColsValue = debounce(() => {
207
+ if (!this.isConnected) return;
208
+ const { millisecond } = this;
209
+ const date = new Date(millisecond);
210
+ if (Number.isNaN(date.getTime())) return;
211
+ this._listEleYear.currentNum = date.getFullYear();
212
+ this._listEleMonth.currentNum = date.getMonth() + 1;
213
+ this._listEleDay.maxNum = new Date(
214
+ date.getFullYear(),
215
+ date.getMonth() + 1,
216
+ 0
217
+ ).getDate();
218
+ this._listEleDay.currentNum = date.getDate();
219
+ }, 0);
220
+
221
+ private _getMsFromEle() {
222
+ const month = this._listEleMonth.currentNum;
223
+ const date = new Date(
224
+ this._listEleYear.currentNum,
225
+ month - 1,
226
+ this._listEleDay.currentNum
227
+ );
228
+ if (date.getMonth() + 1 !== month) {
229
+ // 日期不符合预期,可能是因为月份天数不够
230
+ // 例如 2021-02-30,Date 对象会自动调整为 2021-03-02
231
+ // 这里需要将日期设置为该月的最后一天
232
+ date.setDate(0);
233
+ }
234
+ return +date;
235
+ }
236
+
237
+ private _onColsSelect = ({
238
+ target,
239
+ detail: { newNum }
240
+ }: NumListEvent['select-num']) => {
241
+ if (!(target instanceof NumListEle)) return;
242
+ target.currentNum = newNum;
243
+ const oldMs = this.millisecond;
244
+ const newMs = this._getMsFromEle();
245
+ this.millisecond = newMs;
246
+ this.dispatchEvent(
247
+ 'change',
248
+ {
249
+ oldMs,
250
+ newMs: this.millisecond
251
+ },
252
+ true
253
+ );
254
+ };
255
+ }
256
+
257
+ Ele.define();