zkit-ui 2.0.0 → 2.0.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/DatePicker/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAuB/B,OAAO,KAAK,EAKV,eAAe,EAEhB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,uBAAuB,EACvB,gBAAgB,EAChB,6BAA6B,EAC7B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,GAChB,MAAM,SAAS,CAAC;AAmDjB,eAAO,MAAM,UAAU,0GAkMrB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/DatePicker/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAyB/B,OAAO,KAAK,EAKV,eAAe,EAEhB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,uBAAuB,EACvB,gBAAgB,EAChB,6BAA6B,EAC7B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,GAChB,MAAM,SAAS,CAAC;AAmDjB,eAAO,MAAM,UAAU,0GAmNrB,CAAC"}
@@ -86,13 +86,16 @@ exports.DatePicker = React.forwardRef(function DatePicker({ value: valueProp, de
86
86
  const [innerValue, setInnerValue] = React.useState(defaultValue);
87
87
  const committedValue = isValueControlled ? valueProp : innerValue;
88
88
  const bounds = React.useMemo(() => (0, utils_1.resolveDatePickerBounds)(min, max), [max, min]);
89
- const options = React.useMemo(() => (0, utils_1.buildDatePickerOptions)({ bounds, precision, isDateDisabled }), [bounds, isDateDisabled, precision]);
89
+ const optionConfig = React.useMemo(() => ({ bounds, precision, isDateDisabled }), [bounds, isDateDisabled, precision]);
90
+ const options = React.useMemo(() => (0, utils_1.buildDatePickerOptions)(optionConfig), [optionConfig]);
91
+ const getDateOptionChildren = React.useMemo(() => (0, utils_1.createDatePickerOptionChildrenResolver)(optionConfig), [optionConfig]);
92
+ const isDateOptionDisabled = React.useMemo(() => (0, utils_1.createDatePickerOptionDisabledResolver)(optionConfig, getDateOptionChildren), [getDateOptionChildren, optionConfig]);
90
93
  const committedDate = React.useMemo(() => (0, utils_1.resolveCommittedDate)(committedValue, bounds, precision), [bounds, committedValue, precision]);
91
94
  const pickerDate = React.useMemo(() => (0, utils_1.resolvePickerDate)(committedDate, defaultPickerValue, bounds, precision), [bounds, committedDate, defaultPickerValue, precision]);
92
95
  const pickerValue = React.useMemo(() => (0, utils_1.pathFromDate)(pickerDate, precision), [pickerDate, precision]);
93
96
  const committedSelection = React.useMemo(() => committedDate
94
- ? (0, utils_1.createDatePickerSelectionFromDate)(committedDate, precision, options, labelFormat)
95
- : null, [committedDate, labelFormat, options, precision]);
97
+ ? (0, utils_1.createDatePickerSelectionFromDate)(committedDate, precision, options, labelFormat, getDateOptionChildren)
98
+ : null, [committedDate, getDateOptionChildren, labelFormat, options, precision]);
96
99
  const resolveSelection = React.useCallback((selection) => (0, utils_1.createDatePickerSelection)(selection, precision, labelFormat, selection.label), [labelFormat, precision]);
97
100
  const handlePickerChange = React.useCallback((_next, selection) => {
98
101
  const nextSelection = resolveSelection(selection);
@@ -153,5 +156,5 @@ exports.DatePicker = React.forwardRef(function DatePicker({ value: valueProp, de
153
156
  return children;
154
157
  return (pickerContext) => children(createRenderContext(committedSelection, precision, pickerContext, placeholderText));
155
158
  }, [children, committedSelection, placeholderText, precision]);
156
- return ((0, jsx_runtime_1.jsx)(Picker_1.Picker, { ref: ref, options: options, value: pickerValue, onChange: handlePickerChange, valueMode: "path", open: open, defaultOpen: defaultOpen, onOpenChange: onOpenChange, onDismissComplete: onDismissComplete, title: title !== null && title !== void 0 ? title : t('datePicker.title'), placeholder: placeholderText, cancelText: cancelText, confirmText: confirmText, emptyText: emptyText, formatLabel: formatPickerLabel, renderColumnHeader: handleRenderColumnHeader, maxColumns: (0, utils_1.getColumnCount)(precision), lazyContent: lazyContent, sheetHeight: sheetHeight, disabled: disabled, onCancel: onCancel, onConfirm: handlePickerConfirm, onDraftChange: handlePickerDraftChange, children: pickerChildren }));
159
+ return ((0, jsx_runtime_1.jsx)(Picker_1.Picker, { ref: ref, options: options, value: pickerValue, onChange: handlePickerChange, valueMode: "path", open: open, defaultOpen: defaultOpen, onOpenChange: onOpenChange, onDismissComplete: onDismissComplete, title: title !== null && title !== void 0 ? title : t('datePicker.title'), placeholder: placeholderText, cancelText: cancelText, confirmText: confirmText, emptyText: emptyText, formatLabel: formatPickerLabel, renderColumnHeader: handleRenderColumnHeader, getOptionChildren: getDateOptionChildren, isOptionDisabled: isDateOptionDisabled, maxColumns: (0, utils_1.getColumnCount)(precision), lazyContent: lazyContent, sheetHeight: sheetHeight, disabled: disabled, onCancel: onCancel, onConfirm: handlePickerConfirm, onDraftChange: handlePickerDraftChange, children: pickerChildren }));
157
160
  });
@@ -15,6 +15,8 @@ type BuildOptionsConfig = {
15
15
  precision: DatePickerPrecision;
16
16
  isDateDisabled?: DatePickerProps['isDateDisabled'];
17
17
  };
18
+ export type DatePickerOptionChildrenResolver = (option: DatePickerOption, index: number, path: DatePickerOption[]) => readonly DatePickerOption[] | undefined;
19
+ export type DatePickerOptionDisabledResolver = (option: DatePickerOption, index: number, path: DatePickerOption[]) => boolean;
18
20
  export declare function normalizePrecision(input: DatePickerPrecision | undefined): DatePickerPrecision;
19
21
  export declare function getColumnCount(precision: DatePickerPrecision): number;
20
22
  export declare function formatDatePickerValue(date: Dayjs, precision: DatePickerPrecision): DatePickerValue;
@@ -25,8 +27,10 @@ export declare function resolveDatePickerBounds(min: DatePickerInput | null | un
25
27
  export declare function resolveCommittedDate(value: DatePickerValue | null | undefined, bounds: DateBounds, precision: DatePickerPrecision): dayjs.Dayjs | null;
26
28
  export declare function resolvePickerDate(committedDate: Dayjs | null, defaultPickerValue: DatePickerInput | null | undefined, bounds: DateBounds, precision: DatePickerPrecision): dayjs.Dayjs;
27
29
  export declare function buildDatePickerOptions(config: BuildOptionsConfig): DatePickerOption[];
30
+ export declare function createDatePickerOptionChildrenResolver(config: BuildOptionsConfig): DatePickerOptionChildrenResolver;
31
+ export declare function createDatePickerOptionDisabledResolver(config: BuildOptionsConfig, getOptionChildren: DatePickerOptionChildrenResolver): DatePickerOptionDisabledResolver;
28
32
  export declare function createDatePickerSelection(pickerSelection: PickerSelection<DatePickerOption>, precision: DatePickerPrecision, labelFormat?: DatePickerLabelFormat, labelOverride?: string): DatePickerSelection | null;
29
- export declare function createDatePickerSelectionFromDate(date: Dayjs, precision: DatePickerPrecision, options: DatePickerOption[], labelFormat?: DatePickerLabelFormat): DatePickerSelection;
33
+ export declare function createDatePickerSelectionFromDate(date: Dayjs, precision: DatePickerPrecision, options: DatePickerOption[], labelFormat?: DatePickerLabelFormat, getOptionChildren?: DatePickerOptionChildrenResolver): DatePickerSelection;
30
34
  export declare function dateFromOption(option: DatePickerOption | undefined, precision: DatePickerPrecision): dayjs.Dayjs | undefined;
31
35
  export {};
32
36
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ui/DatePicker/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAEV,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,eAAe,EAChB,MAAM,SAAS,CAAC;AAIjB,eAAO,MAAM,mBAAmB,mCAA0E,CAAC;AAoB3G,KAAK,UAAU,GAAG;IAChB,GAAG,EAAE,KAAK,CAAC;IACX,GAAG,EAAE,KAAK,CAAC;CACZ,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,KAAK,CAAC;IACZ,cAAc,EAAE,mBAAmB,CAAC;CACrC,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,cAAc,CAAC,EAAE,eAAe,CAAC,gBAAgB,CAAC,CAAC;CACpD,CAAC;AAUF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,GAAG,mBAAmB,CAE9F;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,mBAAmB,UAE5D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,mBAAmB,GAAG,eAAe,CAElG;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,mBAAmB,GAAG,eAAe,CAI9F;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAKlF;AAoCD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EACzC,SAAS,EAAE,MAAM,GAChB,UAAU,GAAG,SAAS,CAUxB;AAeD,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EACvC,GAAG,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GACtC,UAAU,CAWZ;AAQD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EACzC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,mBAAmB,sBAK/B;AAED,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,KAAK,GAAG,IAAI,EAC3B,kBAAkB,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EACtD,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,mBAAmB,eAO/B;AAmFD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB,sBAuBhE;AAuBD,wBAAgB,yBAAyB,CACvC,eAAe,EAAE,eAAe,CAAC,gBAAgB,CAAC,EAClD,SAAS,EAAE,mBAAmB,EAC9B,WAAW,CAAC,EAAE,qBAAqB,EACnC,aAAa,CAAC,EAAE,MAAM,GACrB,mBAAmB,GAAG,IAAI,CAuB5B;AAwBD,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,KAAK,EACX,SAAS,EAAE,mBAAmB,EAC9B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,WAAW,CAAC,EAAE,qBAAqB,GAClC,mBAAmB,CAsBrB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,SAAS,EAAE,SAAS,EAAE,mBAAmB,2BAGlG"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ui/DatePicker/utils.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,8 @@ exports.resolveDatePickerBounds = resolveDatePickerBounds;
14
14
  exports.resolveCommittedDate = resolveCommittedDate;
15
15
  exports.resolvePickerDate = resolvePickerDate;
16
16
  exports.buildDatePickerOptions = buildDatePickerOptions;
17
+ exports.createDatePickerOptionChildrenResolver = createDatePickerOptionChildrenResolver;
18
+ exports.createDatePickerOptionDisabledResolver = createDatePickerOptionDisabledResolver;
17
19
  exports.createDatePickerSelection = createDatePickerSelection;
18
20
  exports.createDatePickerSelectionFromDate = createDatePickerSelectionFromDate;
19
21
  exports.dateFromOption = dateFromOption;
@@ -200,10 +202,6 @@ function buildMonths(year, config) {
200
202
  const option = createOption('month', parts, precision === 'month'
201
203
  ? resolveDisabled(optionDate(parts), parts, 'month', precision, isDateDisabled)
202
204
  : false);
203
- if (precision === 'day') {
204
- option.children = buildDays(year, month, config);
205
- option.disabled = option.children.length > 0 && option.children.every((child) => child.disabled);
206
- }
207
205
  months.push(option);
208
206
  }
209
207
  return months;
@@ -216,14 +214,62 @@ function buildDatePickerOptions(config) {
216
214
  const option = createOption('year', parts, precision === 'year'
217
215
  ? resolveDisabled(optionDate(parts), parts, 'year', precision, isDateDisabled)
218
216
  : false);
219
- if (precision !== 'year') {
220
- option.children = buildMonths(year, config);
221
- option.disabled = option.children.length > 0 && option.children.every((child) => child.disabled);
222
- }
223
217
  years.push(option);
224
218
  }
225
219
  return years;
226
220
  }
221
+ function createDatePickerOptionChildrenResolver(config) {
222
+ const cache = new Map();
223
+ return (option) => {
224
+ if (option.column === 'year' && config.precision !== 'year') {
225
+ const key = `months:${option.year}`;
226
+ const cached = cache.get(key);
227
+ if (cached)
228
+ return cached;
229
+ const months = buildMonths(option.year, config);
230
+ cache.set(key, months);
231
+ return months;
232
+ }
233
+ if (option.column === 'month' && config.precision === 'day' && option.month != null) {
234
+ const key = `days:${option.year}-${option.month}`;
235
+ const cached = cache.get(key);
236
+ if (cached)
237
+ return cached;
238
+ const days = buildDays(option.year, option.month, config);
239
+ cache.set(key, days);
240
+ return days;
241
+ }
242
+ return [];
243
+ };
244
+ }
245
+ function getOptionPathKey(option) {
246
+ var _a, _b;
247
+ return `${option.column}:${option.year}-${(_a = option.month) !== null && _a !== void 0 ? _a : 0}-${(_b = option.day) !== null && _b !== void 0 ? _b : 0}`;
248
+ }
249
+ function createDatePickerOptionDisabledResolver(config, getOptionChildren) {
250
+ const cache = new Map();
251
+ const resolveOption = (option, index, path) => {
252
+ var _a, _b;
253
+ const key = getOptionPathKey(option);
254
+ const cached = cache.get(key);
255
+ if (cached != null)
256
+ return cached;
257
+ let disabled = false;
258
+ if (option.column === config.precision) {
259
+ disabled =
260
+ (_a = option.disabled) !== null && _a !== void 0 ? _a : resolveDisabled(optionDate(option), option, option.column, config.precision, config.isDateDisabled);
261
+ }
262
+ else if (config.isDateDisabled) {
263
+ const children = (_b = getOptionChildren(option, index, path)) !== null && _b !== void 0 ? _b : [];
264
+ disabled =
265
+ children.length > 0 &&
266
+ children.every((child, childIndex) => resolveOption(child, childIndex, [...path, child]));
267
+ }
268
+ cache.set(key, disabled);
269
+ return disabled;
270
+ };
271
+ return resolveOption;
272
+ }
227
273
  function numberValues(values) {
228
274
  return values.map((value) => Number(value)).filter((value) => Number.isFinite(value));
229
275
  }
@@ -268,11 +314,13 @@ function createDatePickerSelection(pickerSelection, precision, labelFormat, labe
268
314
  label: labelOverride !== null && labelOverride !== void 0 ? labelOverride : resolveSelectionLabel(base, labelFormat),
269
315
  };
270
316
  }
271
- function findOptionPath(options, values) {
317
+ function findOptionPath(options, values, getOptionChildren) {
318
+ var _a, _b;
272
319
  const items = [];
273
320
  const columns = [];
274
321
  const indices = [];
275
322
  let current = options;
323
+ let path = [];
276
324
  for (const value of values) {
277
325
  columns.push(current);
278
326
  const index = current.findIndex((option) => option.value === value);
@@ -283,13 +331,15 @@ function findOptionPath(options, values) {
283
331
  break;
284
332
  items.push(item);
285
333
  indices.push(index);
286
- current = Array.isArray(item.children) ? item.children : [];
334
+ const nextPath = [...path, item];
335
+ current = [...((_b = (_a = getOptionChildren === null || getOptionChildren === void 0 ? void 0 : getOptionChildren(item, index, nextPath)) !== null && _a !== void 0 ? _a : item.children) !== null && _b !== void 0 ? _b : [])];
336
+ path = nextPath;
287
337
  }
288
338
  return { items, columns, indices };
289
339
  }
290
- function createDatePickerSelectionFromDate(date, precision, options, labelFormat) {
340
+ function createDatePickerSelectionFromDate(date, precision, options, labelFormat, getOptionChildren) {
291
341
  const values = pathFromDate(date, precision);
292
- const { items, columns, indices } = findOptionPath(options, values);
342
+ const { items, columns, indices } = findOptionPath(options, values, getOptionChildren);
293
343
  const labels = values.map((value, index) => (index === 0 ? String(value) : pad2(value)));
294
344
  const base = {
295
345
  value: formatDatePickerValue(date, precision),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zkit-ui",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,6 +10,8 @@ import {
10
10
  import { useI18n } from '../../i18n/useI18n';
11
11
  import {
12
12
  buildDatePickerOptions,
13
+ createDatePickerOptionChildrenResolver,
14
+ createDatePickerOptionDisabledResolver,
13
15
  createDatePickerSelection,
14
16
  createDatePickerSelectionFromDate,
15
17
  DATE_PICKER_COLUMNS,
@@ -138,10 +140,19 @@ export const DatePicker = React.forwardRef<DatePickerHandle, DatePickerProps>(fu
138
140
  const committedValue = isValueControlled ? valueProp : innerValue;
139
141
 
140
142
  const bounds = React.useMemo(() => resolveDatePickerBounds(min, max), [max, min]);
141
- const options = React.useMemo(
142
- () => buildDatePickerOptions({ bounds, precision, isDateDisabled }),
143
+ const optionConfig = React.useMemo(
144
+ () => ({ bounds, precision, isDateDisabled }),
143
145
  [bounds, isDateDisabled, precision]
144
146
  );
147
+ const options = React.useMemo(() => buildDatePickerOptions(optionConfig), [optionConfig]);
148
+ const getDateOptionChildren = React.useMemo(
149
+ () => createDatePickerOptionChildrenResolver(optionConfig),
150
+ [optionConfig]
151
+ );
152
+ const isDateOptionDisabled = React.useMemo(
153
+ () => createDatePickerOptionDisabledResolver(optionConfig, getDateOptionChildren),
154
+ [getDateOptionChildren, optionConfig]
155
+ );
145
156
  const committedDate = React.useMemo(
146
157
  () => resolveCommittedDate(committedValue, bounds, precision),
147
158
  [bounds, committedValue, precision]
@@ -154,9 +165,15 @@ export const DatePicker = React.forwardRef<DatePickerHandle, DatePickerProps>(fu
154
165
  const committedSelection = React.useMemo(
155
166
  () =>
156
167
  committedDate
157
- ? createDatePickerSelectionFromDate(committedDate, precision, options, labelFormat)
168
+ ? createDatePickerSelectionFromDate(
169
+ committedDate,
170
+ precision,
171
+ options,
172
+ labelFormat,
173
+ getDateOptionChildren
174
+ )
158
175
  : null,
159
- [committedDate, labelFormat, options, precision]
176
+ [committedDate, getDateOptionChildren, labelFormat, options, precision]
160
177
  );
161
178
 
162
179
  const resolveSelection = React.useCallback(
@@ -281,6 +298,8 @@ export const DatePicker = React.forwardRef<DatePickerHandle, DatePickerProps>(fu
281
298
  emptyText={emptyText}
282
299
  formatLabel={formatPickerLabel}
283
300
  renderColumnHeader={handleRenderColumnHeader}
301
+ getOptionChildren={getDateOptionChildren}
302
+ isOptionDisabled={isDateOptionDisabled}
284
303
  maxColumns={getColumnCount(precision)}
285
304
  lazyContent={lazyContent}
286
305
  sheetHeight={sheetHeight}
@@ -51,6 +51,18 @@ type BuildOptionsConfig = {
51
51
  isDateDisabled?: DatePickerProps['isDateDisabled'];
52
52
  };
53
53
 
54
+ export type DatePickerOptionChildrenResolver = (
55
+ option: DatePickerOption,
56
+ index: number,
57
+ path: DatePickerOption[]
58
+ ) => readonly DatePickerOption[] | undefined;
59
+
60
+ export type DatePickerOptionDisabledResolver = (
61
+ option: DatePickerOption,
62
+ index: number,
63
+ path: DatePickerOption[]
64
+ ) => boolean;
65
+
54
66
  function pad2(n: number) {
55
67
  return String(n).padStart(2, '0');
56
68
  }
@@ -261,11 +273,6 @@ function buildMonths(year: number, config: BuildOptionsConfig) {
261
273
  : false
262
274
  );
263
275
 
264
- if (precision === 'day') {
265
- option.children = buildDays(year, month, config);
266
- option.disabled = option.children.length > 0 && option.children.every((child) => child.disabled);
267
- }
268
-
269
276
  months.push(option);
270
277
  }
271
278
 
@@ -286,17 +293,81 @@ export function buildDatePickerOptions(config: BuildOptionsConfig) {
286
293
  : false
287
294
  );
288
295
 
289
- if (precision !== 'year') {
290
- option.children = buildMonths(year, config);
291
- option.disabled = option.children.length > 0 && option.children.every((child) => child.disabled);
292
- }
293
-
294
296
  years.push(option);
295
297
  }
296
298
 
297
299
  return years;
298
300
  }
299
301
 
302
+ export function createDatePickerOptionChildrenResolver(
303
+ config: BuildOptionsConfig
304
+ ): DatePickerOptionChildrenResolver {
305
+ const cache = new Map<string, DatePickerOption[]>();
306
+
307
+ return (option) => {
308
+ if (option.column === 'year' && config.precision !== 'year') {
309
+ const key = `months:${option.year}`;
310
+ const cached = cache.get(key);
311
+ if (cached) return cached;
312
+
313
+ const months = buildMonths(option.year, config);
314
+ cache.set(key, months);
315
+ return months;
316
+ }
317
+
318
+ if (option.column === 'month' && config.precision === 'day' && option.month != null) {
319
+ const key = `days:${option.year}-${option.month}`;
320
+ const cached = cache.get(key);
321
+ if (cached) return cached;
322
+
323
+ const days = buildDays(option.year, option.month, config);
324
+ cache.set(key, days);
325
+ return days;
326
+ }
327
+
328
+ return [];
329
+ };
330
+ }
331
+
332
+ function getOptionPathKey(option: DatePickerOption) {
333
+ return `${option.column}:${option.year}-${option.month ?? 0}-${option.day ?? 0}`;
334
+ }
335
+
336
+ export function createDatePickerOptionDisabledResolver(
337
+ config: BuildOptionsConfig,
338
+ getOptionChildren: DatePickerOptionChildrenResolver
339
+ ): DatePickerOptionDisabledResolver {
340
+ const cache = new Map<string, boolean>();
341
+
342
+ const resolveOption = (
343
+ option: DatePickerOption,
344
+ index: number,
345
+ path: DatePickerOption[]
346
+ ): boolean => {
347
+ const key = getOptionPathKey(option);
348
+ const cached = cache.get(key);
349
+ if (cached != null) return cached;
350
+
351
+ let disabled = false;
352
+
353
+ if (option.column === config.precision) {
354
+ disabled =
355
+ option.disabled ??
356
+ resolveDisabled(optionDate(option), option, option.column, config.precision, config.isDateDisabled);
357
+ } else if (config.isDateDisabled) {
358
+ const children = getOptionChildren(option, index, path) ?? [];
359
+ disabled =
360
+ children.length > 0 &&
361
+ children.every((child, childIndex) => resolveOption(child, childIndex, [...path, child]));
362
+ }
363
+
364
+ cache.set(key, disabled);
365
+ return disabled;
366
+ };
367
+
368
+ return resolveOption;
369
+ }
370
+
300
371
  function numberValues(values: PickerSelection<DatePickerOption>['values']) {
301
372
  return values.map((value) => Number(value)).filter((value) => Number.isFinite(value));
302
373
  }
@@ -348,11 +419,16 @@ export function createDatePickerSelection(
348
419
  };
349
420
  }
350
421
 
351
- function findOptionPath(options: DatePickerOption[], values: number[]) {
422
+ function findOptionPath(
423
+ options: DatePickerOption[],
424
+ values: number[],
425
+ getOptionChildren?: DatePickerOptionChildrenResolver
426
+ ) {
352
427
  const items: DatePickerOption[] = [];
353
428
  const columns: DatePickerOption[][] = [];
354
429
  const indices: number[] = [];
355
430
  let current = options;
431
+ let path: DatePickerOption[] = [];
356
432
 
357
433
  for (const value of values) {
358
434
  columns.push(current);
@@ -364,7 +440,9 @@ function findOptionPath(options: DatePickerOption[], values: number[]) {
364
440
 
365
441
  items.push(item);
366
442
  indices.push(index);
367
- current = Array.isArray(item.children) ? item.children : [];
443
+ const nextPath = [...path, item];
444
+ current = [...(getOptionChildren?.(item, index, nextPath) ?? item.children ?? [])];
445
+ path = nextPath;
368
446
  }
369
447
 
370
448
  return { items, columns, indices };
@@ -374,10 +452,11 @@ export function createDatePickerSelectionFromDate(
374
452
  date: Dayjs,
375
453
  precision: DatePickerPrecision,
376
454
  options: DatePickerOption[],
377
- labelFormat?: DatePickerLabelFormat
455
+ labelFormat?: DatePickerLabelFormat,
456
+ getOptionChildren?: DatePickerOptionChildrenResolver
378
457
  ): DatePickerSelection {
379
458
  const values = pathFromDate(date, precision);
380
- const { items, columns, indices } = findOptionPath(options, values);
459
+ const { items, columns, indices } = findOptionPath(options, values, getOptionChildren);
381
460
  const labels = values.map((value, index) => (index === 0 ? String(value) : pad2(value)));
382
461
  const base: DatePickerSelection = {
383
462
  value: formatDatePickerValue(date, precision),