@lobehub/ui 5.64.1 → 5.64.3

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 (56) hide show
  1. package/README.md +3 -3
  2. package/es/EmojiPicker/EmojiPicker.mjs +2 -2
  3. package/es/Form/Form.mjs +6 -2
  4. package/es/Form/Form.mjs.map +1 -1
  5. package/es/Form/style.mjs +3 -2
  6. package/es/Form/style.mjs.map +1 -1
  7. package/es/Form/type.d.mts +10 -0
  8. package/es/base-ui/DatePicker/DatePicker.d.mts +5 -3
  9. package/es/base-ui/DatePicker/DatePicker.mjs +7 -5
  10. package/es/base-ui/DatePicker/DatePicker.mjs.map +1 -1
  11. package/es/base-ui/DatePicker/DateRangePicker.d.mts +1 -1
  12. package/es/base-ui/DatePicker/DayjsDatePicker.d.mts +12 -0
  13. package/es/base-ui/DatePicker/DayjsDatePicker.mjs +19 -0
  14. package/es/base-ui/DatePicker/DayjsDatePicker.mjs.map +1 -0
  15. package/es/base-ui/DatePicker/DayjsDateRangePicker.d.mts +7 -0
  16. package/es/base-ui/DatePicker/DayjsDateRangePicker.mjs +8 -0
  17. package/es/base-ui/DatePicker/DayjsDateRangePicker.mjs.map +1 -0
  18. package/es/base-ui/DatePicker/RangePicker.mjs +7 -1
  19. package/es/base-ui/DatePicker/RangePicker.mjs.map +1 -1
  20. package/es/base-ui/DatePicker/SinglePicker.mjs +3 -1
  21. package/es/base-ui/DatePicker/SinglePicker.mjs.map +1 -1
  22. package/es/base-ui/DatePicker/dateGenerateConfig.mjs +52 -0
  23. package/es/base-ui/DatePicker/dateGenerateConfig.mjs.map +1 -0
  24. package/es/base-ui/DatePicker/index.d.mts +4 -2
  25. package/es/base-ui/DatePicker/legacyDate.mjs +58 -0
  26. package/es/base-ui/DatePicker/legacyDate.mjs.map +1 -0
  27. package/es/base-ui/DatePicker/type.d.mts +65 -39
  28. package/es/base-ui/DatePicker/usePresetActive.mjs +1 -0
  29. package/es/base-ui/DatePicker/usePresetActive.mjs.map +1 -1
  30. package/es/base-ui/Form/Form.mjs +6 -2
  31. package/es/base-ui/Form/Form.mjs.map +1 -1
  32. package/es/base-ui/Form/style.mjs +3 -2
  33. package/es/base-ui/Form/style.mjs.map +1 -1
  34. package/es/base-ui/Form/type.d.mts +7 -0
  35. package/es/base-ui/Input/style.d.mts +1 -1
  36. package/es/base-ui/ProTable/FieldControl.mjs +32 -15
  37. package/es/base-ui/ProTable/FieldControl.mjs.map +1 -1
  38. package/es/base-ui/ProTable/style.mjs +14 -1
  39. package/es/base-ui/ProTable/style.mjs.map +1 -1
  40. package/es/base-ui/ProTable/type.d.mts +5 -2
  41. package/es/base-ui/ProTable/useFetchData.mjs +1 -1
  42. package/es/base-ui/ProTable/useFetchData.mjs.map +1 -1
  43. package/es/base-ui/Switch/Switch.mjs +7 -1
  44. package/es/base-ui/Switch/Switch.mjs.map +1 -1
  45. package/es/base-ui/Switch/atoms.mjs +17 -2
  46. package/es/base-ui/Switch/atoms.mjs.map +1 -1
  47. package/es/base-ui/Switch/style.d.mts +4 -0
  48. package/es/base-ui/Switch/style.mjs +47 -2
  49. package/es/base-ui/Switch/style.mjs.map +1 -1
  50. package/es/base-ui/Table/FixedFrost.mjs +15 -2
  51. package/es/base-ui/Table/FixedFrost.mjs.map +1 -1
  52. package/es/base-ui/Table/Table.mjs +13 -3
  53. package/es/base-ui/Table/Table.mjs.map +1 -1
  54. package/es/base-ui/index.d.mts +4 -2
  55. package/es/base-ui/index.mjs +3 -1
  56. package/package.json +1 -1
@@ -45,11 +45,11 @@ type PickerLocaleInput = Omit<Partial<PickerLocale>, 'lang' | 'timePickerLocale'
45
45
  timePickerLocale?: TimePickerLocale;
46
46
  };
47
47
  /** A `presets` entry: `value` may be a function, evaluated when the preset is hovered or picked. */
48
- type PresetDate<T = Dayjs> = ValueDate<T>;
48
+ type PresetDate<T = Date> = ValueDate<T>;
49
49
  /** `components`: replace a panel (`date` / `week` / … / `time`), the `input` or the OK `button`. */
50
- type PickerComponents = Components<Dayjs>;
50
+ type PickerComponents = Components<Date>;
51
51
  /** Props a custom panel in `components` receives (`value`, `onSelect`, `onHover`, …). */
52
- type PickerPanelProps = SharedPanelProps<Dayjs>;
52
+ type PickerPanelProps<DateType extends object = Date> = SharedPanelProps<DateType>;
53
53
  /** `middle` is kept as an alias of `medium`. */
54
54
  type PickerSize = 'large' | 'medium' | 'small' | 'middle';
55
55
  type PickerVariant = 'outlined' | 'borderless' | 'filled' | 'underlined';
@@ -108,7 +108,7 @@ interface LobePickerProps {
108
108
  variant?: PickerVariant;
109
109
  }
110
110
  /** Props `tagRender` receives for each picked date in `multiple` mode. */
111
- interface PickerTagProps<DateType extends object = Dayjs> {
111
+ interface PickerTagProps<DateType extends object = Date> {
112
112
  closable: boolean;
113
113
  disabled: boolean;
114
114
  /** The date formatted with `format`. */
@@ -119,25 +119,39 @@ interface PickerTagProps<DateType extends object = Dayjs> {
119
119
  }
120
120
  /** `dateString` of a value: a string per date in `multiple` mode. */
121
121
  type PickerDateStrings<ValueType> = ValueType extends readonly unknown[] ? string[] : string | null;
122
+ /**
123
+ * Date inputs the previous lobe DatePicker took (native `Date`), plus date strings and
124
+ * timestamps. On the dayjs pickers they are converted to `Dayjs`; callbacks always get `Dayjs`.
125
+ */
126
+ type LegacyDateInput = Date | string | number;
127
+ /** A date prop value: `Dayjs` or a `LegacyDateInput` on the dayjs pickers, else `DateType`. */
128
+ type PickerDateInput<DateType> = DateType extends Dayjs ? Dayjs | LegacyDateInput : DateType extends Date ? Dayjs | LegacyDateInput : DateType;
129
+ /** Range `onChange` dates: never `null` on the default (native `Date`) picker, as before. */
130
+ type RangeChangeDates<DateType extends object> = DateType extends Date ? DateRangeValue<DateType> : DateRangeValue<DateType> | null;
131
+ type RangeChangeStrings<DateType extends object> = DateType extends Date ? [string, string] : [string, string] | null;
132
+ /** `PickerDateInput` for a single value or each date of a `multiple` array. */
133
+ type PickerValueInput<ValueType> = ValueType extends readonly (infer D)[] ? PickerDateInput<D>[] : PickerDateInput<ValueType>;
122
134
  /**
123
135
  * antd's `PickerPropsWithMultiple`: `InnerPickerProps` with the value props typed by
124
136
  * `ValueType` — `DateType` for one date, `DateType[]` with `multiple`.
125
137
  */
126
138
  type PickerPropsWithMultiple<DateType, InnerPickerProps, ValueType = DateType> = Omit<InnerPickerProps, 'defaultValue' | 'onCalendarChange' | 'onChange' | 'onOk' | 'value'> & {
127
- defaultValue?: ValueType | null;
128
- onCalendarChange?: (date: ValueType | null, dateString: PickerDateStrings<ValueType>, info: BaseInfo) => void;
139
+ /** Also takes a native `Date`, date string or timestamp (converted to `Dayjs`). */
140
+ defaultValue?: PickerValueInput<ValueType> | null;
141
+ onCalendarChange?(date: ValueType | null, dateString: PickerDateStrings<ValueType>, info: BaseInfo): void;
129
142
  /** Cleared: `null` for one date, `[]` with `multiple`. */
130
- onChange?: (date: ValueType | null, dateString: PickerDateStrings<ValueType>) => void;
131
- onOk?: (date?: ValueType | null) => void;
132
- value?: ValueType | null;
143
+ onChange?(date: ValueType | null, dateString: PickerDateStrings<ValueType>): void;
144
+ onOk?(date?: ValueType | null): void;
145
+ /** Also takes a native `Date`, date string or timestamp (converted to `Dayjs`). */
146
+ value?: PickerValueInput<ValueType> | null;
133
147
  };
134
148
  /**
135
149
  * DatePicker props other than the value ones, which `PickerPropsWithMultiple` adds.
136
150
  * `DateType` is the date library's type (`Dayjs`, or another one with `generatePicker`).
137
151
  */
138
- interface DatePickerBaseProps<DateType extends object = Dayjs> extends Omit<PickerProps<DateType>, InternalRcProps | MultipleRcProps | ValueRcProps>, LobePickerProps {
152
+ interface DatePickerBaseProps<DateType extends object = Date> extends Omit<PickerProps<DateType>, InternalRcProps | MultipleRcProps | ValueRcProps>, LobePickerProps {
139
153
  /** Semantic DOM class names: `root` / `prefix` / `input` / `suffix` and `popup.*`. */
140
- classNames?: PickerClassNames<DatePickerProps<any>>;
154
+ classNames?: PickerClassNames<DatePickerBaseProps<DateType>>;
141
155
  /** @deprecated Use `renderExtraFooter` instead. */
142
156
  footer?: ReactNode;
143
157
  /**
@@ -147,14 +161,14 @@ interface DatePickerBaseProps<DateType extends object = Dayjs> extends Omit<Pick
147
161
  */
148
162
  locale?: PickerLocaleInput;
149
163
  /** @deprecated Use `maxDate` instead. */
150
- max?: DateType;
164
+ max?: PickerDateInput<DateType>;
151
165
  /**
152
166
  * `multiple`: at most this many tags; `'responsive'` fits as many as the width allows.
153
167
  * The rest collapse into a `+ N ...` tag.
154
168
  */
155
169
  maxTagCount?: number | 'responsive';
156
170
  /** @deprecated Use `minDate` instead. */
157
- min?: DateType;
171
+ min?: PickerDateInput<DateType>;
158
172
  /**
159
173
  * Pick several dates, shown as tags; clicking a picked cell again removes it. Works on
160
174
  * every `picker` except with `showTime`. Values are `Dayjs[]`, sorted unless
@@ -174,7 +188,7 @@ interface DatePickerBaseProps<DateType extends object = Dayjs> extends Omit<Pick
174
188
  /** `multiple`: the remove icon of each tag. */
175
189
  removeIcon?: ReactNode;
176
190
  /** Semantic DOM styles: `root` / `prefix` / `input` / `suffix` and `popup.*`. */
177
- styles?: PickerStyles<DatePickerProps<any>>;
191
+ styles?: PickerStyles<DatePickerBaseProps<DateType>>;
178
192
  /** `multiple`: render each picked date's tag, e.g. with base-ui `Tag`. */
179
193
  tagRender?: (props: PickerTagProps<DateType>) => ReactNode;
180
194
  }
@@ -182,19 +196,19 @@ interface DatePickerBaseProps<DateType extends object = Dayjs> extends Omit<Pick
182
196
  * `ValueType` is `Dayjs` (default) or `Dayjs[]` with `multiple`; `<DatePicker multiple>`
183
197
  * infers `Dayjs[]` by itself.
184
198
  */
185
- type DatePickerProps<ValueType = Dayjs> = PickerPropsWithMultiple<Dayjs, DatePickerBaseProps, ValueType>;
186
- type DateRangeValue<DateType extends object = Dayjs> = [DateType | null, DateType | null];
199
+ type DatePickerProps<ValueType = Date> = PickerPropsWithMultiple<Date, DatePickerBaseProps, ValueType>;
200
+ type DateRangeValue<DateType extends object = Date> = [DateType | null, DateType | null];
187
201
  /** Which end of a range an event belongs to. */
188
202
  interface RangeInfo {
189
203
  range: 'start' | 'end';
190
204
  }
191
205
  /** `info.from` is the end picked first in the current range selection. */
192
- type RangeDisabledDate<DateType extends object = Dayjs> = (current: DateType, info: {
206
+ type RangeDisabledDate<DateType extends object = Date> = (current: DateType, info: {
193
207
  from?: DateType;
194
208
  type: PanelMode;
195
209
  }) => boolean;
196
210
  type RangeRcProps = 'allowEmpty' | 'disabled' | 'disabledDate' | 'id' | 'onBlur' | 'onFocus' | 'order';
197
- interface DateRangePickerProps<DateType extends object = Dayjs> extends Omit<RangePickerProps<DateType>, InternalRcProps | RangeRcProps | ValueRcProps>, LobePickerProps {
211
+ interface DateRangePickerProps<DateType extends object = Date> extends Omit<RangePickerProps<DateType>, InternalRcProps | RangeRcProps | ValueRcProps>, LobePickerProps {
198
212
  /**
199
213
  * Allow leaving the start / end empty; `true` applies to both ends.
200
214
  * @default [false, false]
@@ -202,7 +216,8 @@ interface DateRangePickerProps<DateType extends object = Dayjs> extends Omit<Ran
202
216
  allowEmpty?: boolean | [boolean, boolean];
203
217
  /** Semantic DOM class names, see `DatePickerProps['classNames']`. */
204
218
  classNames?: PickerClassNames<DateRangePickerProps<DateType>>;
205
- defaultValue?: [DateType | null | undefined, DateType | null | undefined];
219
+ /** Each end also takes a native `Date`, date string or timestamp (converted to `Dayjs`). */
220
+ defaultValue?: [PickerDateInput<DateType> | null | undefined, PickerDateInput<DateType> | null | undefined];
206
221
  /** Disable the whole picker, or each end separately with `[start, end]`. */
207
222
  disabled?: boolean | [boolean, boolean];
208
223
  /** Receives `info.from` once one end is picked, e.g. to limit the range length. */
@@ -217,14 +232,16 @@ interface DateRangePickerProps<DateType extends object = Dayjs> extends Omit<Ran
217
232
  /** antd `PickerLocale`, see `DatePickerProps['locale']`. */
218
233
  locale?: PickerLocaleInput;
219
234
  /** @deprecated Use `maxDate` instead. */
220
- max?: DateType;
235
+ max?: PickerDateInput<DateType>;
221
236
  /** @deprecated Use `minDate` instead. */
222
- min?: DateType;
237
+ min?: PickerDateInput<DateType>;
223
238
  onBlur?: (event: FocusEvent<HTMLElement>, info: RangeInfo) => void;
224
- onCalendarChange?: (dates: DateRangeValue<DateType>, dateStrings: [string, string], info: RangeInfo) => void;
225
- onChange?: (dates: DateRangeValue<DateType> | null, dateStrings: [string, string] | null) => void;
239
+ onCalendarChange?(dates: DateRangeValue<DateType>, dateStrings: [string, string], info: RangeInfo): void;
240
+ /** Cleared: `null` (antd). */
241
+ /** Cleared: `[null, null]` on the default (native `Date`) picker, `null` on the dayjs one (antd). */
242
+ onChange?(dates: RangeChangeDates<DateType>, dateStrings: RangeChangeStrings<DateType>): void;
226
243
  onFocus?: (event: FocusEvent<HTMLElement>, info: RangeInfo) => void;
227
- onOk?: (dates: DateRangeValue<DateType>) => void;
244
+ onOk?(dates: DateRangeValue<DateType>): void;
228
245
  /**
229
246
  * Swap the ends when the end is earlier than the start; `false` keeps them as entered.
230
247
  * @default true
@@ -235,21 +252,22 @@ interface DateRangePickerProps<DateType extends object = Dayjs> extends Omit<Ran
235
252
  ref?: Ref<RangePickerRef>;
236
253
  /** Semantic DOM styles, see `DatePickerProps['styles']`. */
237
254
  styles?: PickerStyles<DateRangePickerProps<DateType>>;
238
- value?: [DateType | null | undefined, DateType | null | undefined] | null;
255
+ /** Each end also takes a native `Date`, date string or timestamp (converted to `Dayjs`). */
256
+ value?: [PickerDateInput<DateType> | null | undefined, PickerDateInput<DateType> | null | undefined] | null;
239
257
  }
240
258
  /** antd `PickerProps<DateType>`: DatePicker props over any date library's type. */
241
- type PickerProps$1<DateType extends object = Dayjs, ValueType = DateType> = PickerPropsWithMultiple<DateType, DatePickerBaseProps<DateType>, ValueType>;
259
+ type PickerProps$1<DateType extends object = Date, ValueType = DateType> = PickerPropsWithMultiple<DateType, DatePickerBaseProps<DateType>, ValueType>;
242
260
  /** Props of `DatePicker.WeekPicker` / `MonthPicker` / … : `picker` is fixed. */
243
- type PresetPickerProps<DateType extends object = Dayjs, ValueType = DateType> = Omit<PickerProps$1<DateType, ValueType>, 'picker'>;
244
- type WeekPickerProps<ValueType = Dayjs> = PresetPickerProps<Dayjs, ValueType>;
245
- type MonthPickerProps<ValueType = Dayjs> = PresetPickerProps<Dayjs, ValueType>;
246
- type YearPickerProps<ValueType = Dayjs> = PresetPickerProps<Dayjs, ValueType>;
247
- type QuarterPickerProps<ValueType = Dayjs> = PresetPickerProps<Dayjs, ValueType>;
261
+ type PresetPickerProps<DateType extends object = Date, ValueType = DateType> = Omit<PickerProps$1<DateType, ValueType>, 'picker'>;
262
+ type WeekPickerProps<ValueType = Date> = PresetPickerProps<Date, ValueType>;
263
+ type MonthPickerProps<ValueType = Date> = PresetPickerProps<Date, ValueType>;
264
+ type YearPickerProps<ValueType = Date> = PresetPickerProps<Date, ValueType>;
265
+ type QuarterPickerProps<ValueType = Date> = PresetPickerProps<Date, ValueType>;
248
266
  /** antd `GenericTimePickerProps`: `DatePicker.TimePicker` has no `picker` / `showTime`. */
249
- type GenericTimePickerProps<DateType extends object = Dayjs, ValueType = DateType> = Omit<PickerProps$1<DateType, ValueType>, 'picker' | 'showTime'>;
250
- type TimePickerProps<ValueType = Dayjs> = GenericTimePickerProps<Dayjs, ValueType>;
267
+ type GenericTimePickerProps<DateType extends object = Date, ValueType = DateType> = Omit<PickerProps$1<DateType, ValueType>, 'picker' | 'showTime'>;
268
+ type TimePickerProps<ValueType = Date> = GenericTimePickerProps<Date, ValueType>;
251
269
  /** antd-style alias of `DateRangePickerProps`. */
252
- type RangePickerProps$1<DateType extends object = Dayjs> = DateRangePickerProps<DateType>;
270
+ type RangePickerProps$1<DateType extends object = Date> = DateRangePickerProps<DateType>;
253
271
  /** antd `DatePickerSemanticType`: the Semantic DOM `classNames` / `styles` shapes. */
254
272
  interface DatePickerSemanticType {
255
273
  classNames?: PickerSemanticClassNames;
@@ -278,14 +296,22 @@ interface GeneratedDatePicker<DateType extends object> extends SinglePickerCompo
278
296
  WeekPicker: SinglePickerComponent<DateType, Omit<DatePickerBaseProps<DateType>, 'picker'>>;
279
297
  YearPicker: SinglePickerComponent<DateType, Omit<DatePickerBaseProps<DateType>, 'picker'>>;
280
298
  }
281
- /** The default `DatePicker` (Dayjs), with antd's pure panels and `generatePicker`. */
282
- interface DatePickerType extends GeneratedDatePicker<Dayjs> {
299
+ /** The default `DatePicker` (native `Date`) or `DayjsDatePicker`, with antd's pure panels and `generatePicker`. */
300
+ interface DatePickerType<D extends object = Date> extends GeneratedDatePicker<D> {
283
301
  /** Debug only: the popup panel rendered inline, always open (antd `render-panel`). */
284
- _InternalPanelDoNotUseOrYouWillBeFired: ComponentType<DatePickerProps<any>>;
302
+ _InternalPanelDoNotUseOrYouWillBeFired: ComponentType<PickerPropsWithMultiple<D, DatePickerBaseProps<D>, any>>;
285
303
  /** Debug only: the RangePicker popup panel rendered inline, always open. */
286
- _InternalRangePanelDoNotUseOrYouWillBeFired: ComponentType<DateRangePickerProps>;
304
+ _InternalRangePanelDoNotUseOrYouWillBeFired: ComponentType<DateRangePickerProps<D>>;
287
305
  generatePicker: <DateType extends object>(generateConfig: GenerateConfig<DateType>) => GeneratedDatePicker<DateType>;
288
306
  }
307
+ /** `DayjsDatePicker`: the antd-aligned DatePicker over `Dayjs`. */
308
+ type DayjsDatePickerType = DatePickerType<Dayjs>;
309
+ /** `DayjsDatePicker` props: values and callbacks use `Dayjs` (`Dayjs[]` with `multiple`). */
310
+ type DayjsDatePickerProps<ValueType = Dayjs> = PickerPropsWithMultiple<Dayjs, DatePickerBaseProps<Dayjs>, ValueType>;
311
+ /** `DayjsDateRangePicker` props. */
312
+ type DayjsDateRangePickerProps = DateRangePickerProps<Dayjs>;
313
+ /** `DayjsDateRangePicker` value: `[Dayjs | null, Dayjs | null]`. */
314
+ type DayjsDateRangeValue = DateRangeValue<Dayjs>;
289
315
  //#endregion
290
- export { CalendarMode, type CellRender, type CellRenderInfo, DatePickerBaseProps, DatePickerProps, DatePickerSemanticType, DatePickerType, DateRangePickerProps, DateRangeValue, GeneratedDatePicker, GenericTimePickerProps, MonthPickerProps, type PanelMode, PickerClassNames, PickerComponents, PickerDateStrings, PickerLocale, PickerLocaleInput, PickerLocaleLang, type PickerMode, PickerPanelProps, PickerPlacement, PickerPopupSemanticName, PickerProps$1 as PickerProps, PickerPropsWithMultiple, type PickerRef, PickerSemanticClassNames, PickerSemanticName, PickerSemanticStyles, PickerSize, PickerStatus, PickerStyles, PickerTagProps, PickerVariant, PresetDate, PresetPickerProps, QuarterPickerProps, RangeDisabledDate, RangeInfo, RangePickerComponent, RangePickerProps$1 as RangePickerProps, type RangePickerRef, SinglePickerComponent, TimePickerLocale, TimePickerProps, WeekPickerProps, YearPickerProps };
316
+ export { CalendarMode, type CellRender, type CellRenderInfo, DatePickerBaseProps, DatePickerProps, DatePickerSemanticType, DatePickerType, DateRangePickerProps, DateRangeValue, DayjsDatePickerProps, DayjsDatePickerType, DayjsDateRangePickerProps, DayjsDateRangeValue, GeneratedDatePicker, GenericTimePickerProps, LegacyDateInput, MonthPickerProps, type PanelMode, PickerClassNames, PickerComponents, PickerDateInput, PickerDateStrings, PickerLocale, PickerLocaleInput, PickerLocaleLang, type PickerMode, PickerPanelProps, PickerPlacement, PickerPopupSemanticName, PickerProps$1 as PickerProps, PickerPropsWithMultiple, type PickerRef, PickerSemanticClassNames, PickerSemanticName, PickerSemanticStyles, PickerSize, PickerStatus, PickerStyles, PickerTagProps, PickerValueInput, PickerVariant, PresetDate, PresetPickerProps, QuarterPickerProps, RangeChangeDates, RangeChangeStrings, RangeDisabledDate, RangeInfo, RangePickerComponent, RangePickerProps$1 as RangePickerProps, type RangePickerRef, SinglePickerComponent, TimePickerLocale, TimePickerProps, WeekPickerProps, YearPickerProps };
291
317
  //# sourceMappingURL=type.d.mts.map
@@ -5,6 +5,7 @@ import { jsx } from "react/jsx-runtime";
5
5
  const sameDay = (a, b) => {
6
6
  if (!a || !b) return !a && !b;
7
7
  if (typeof a.isSame === "function") return a.isSame(b, "day");
8
+ if (a instanceof Date && b instanceof Date) return a.toDateString() === b.toDateString();
8
9
  return a === b;
9
10
  };
10
11
  const sameValue = (a, b) => {
@@ -1 +1 @@
1
- {"version":3,"file":"usePresetActive.mjs","names":[],"sources":["../../../src/base-ui/DatePicker/usePresetActive.tsx"],"sourcesContent":["import { type ReactNode, useCallback, useMemo, useState } from 'react';\n\nimport { PREFIX_CLS } from './style';\n\ninterface Preset {\n label: ReactNode;\n value: unknown;\n}\n\nconst sameDay = (a: any, b: any): boolean => {\n if (!a || !b) return !a && !b;\n if (typeof a.isSame === 'function') return a.isSame(b, 'day');\n return a === b;\n};\n\nconst sameValue = (a: any, b: any): boolean => {\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;\n return a.every((item, i) => sameDay(item, b[i]));\n }\n return sameDay(a, b);\n};\n\nexport const PRESET_ACTIVE_CLS = `${PREFIX_CLS}-preset-active`;\n\n/**\n * rc-picker renders `presets` as the popup sidebar but has no \"current preset\" state.\n * Mirror the picked value (controlled or not) and wrap the matching preset's label so the\n * sidebar can show it as selected (`li:has(> .lobe-picker-preset-active)`).\n */\nexport const usePresetActive = <P extends Preset>(\n presets: P[] | undefined,\n value: unknown,\n defaultValue: unknown,\n) => {\n const [inner, setInner] = useState<unknown>(defaultValue);\n const current = value !== undefined ? value : inner;\n\n const track = useCallback((next: unknown) => setInner(next), []);\n\n const mapped = useMemo(() => {\n if (!presets?.length || !current) return presets;\n return presets.map((preset) => {\n const v =\n typeof preset.value === 'function' ? (preset.value as () => unknown)() : preset.value;\n if (!sameValue(v, current)) return preset;\n return { ...preset, label: <span className={PRESET_ACTIVE_CLS}>{preset.label}</span> };\n });\n }, [presets, current]);\n\n return { presets: mapped, track };\n};\n"],"mappings":";;;;AASA,MAAM,WAAW,GAAQ,MAAoB;CAC3C,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;CAC5B,IAAI,OAAO,EAAE,WAAW,YAAY,OAAO,EAAE,OAAO,GAAG,KAAK;CAC5D,OAAO,MAAM;AACf;AAEA,MAAM,aAAa,GAAQ,MAAoB;CAC7C,IAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;EACxC,IAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,OAAO;EAC5E,OAAO,EAAE,OAAO,MAAM,MAAM,QAAQ,MAAM,EAAE,EAAE,CAAC;CACjD;CACA,OAAO,QAAQ,GAAG,CAAC;AACrB;AAEA,MAAa,oBAAoB,GAAG,WAAW;;;;;;AAO/C,MAAa,mBACX,SACA,OACA,iBACG;CACH,MAAM,CAAC,OAAO,YAAY,SAAkB,YAAY;CACxD,MAAM,UAAU,UAAU,KAAA,IAAY,QAAQ;CAE9C,MAAM,QAAQ,aAAa,SAAkB,SAAS,IAAI,GAAG,CAAC,CAAC;CAY/D,OAAO;EAAE,SAVM,cAAc;GAC3B,IAAI,CAAC,SAAS,UAAU,CAAC,SAAS,OAAO;GACzC,OAAO,QAAQ,KAAK,WAAW;IAC7B,MAAM,IACJ,OAAO,OAAO,UAAU,aAAc,OAAO,MAAwB,IAAI,OAAO;IAClF,IAAI,CAAC,UAAU,GAAG,OAAO,GAAG,OAAO;IACnC,OAAO;KAAE,GAAG;KAAQ,OAAO,oBAAC,QAAD;MAAM,WAAW;MAAoB,UAAA,OAAO;KAAY,CAAA;IAAE;GACvF,CAAC;EACH,GAAG,CAAC,SAAS,OAAO,CAEG;EAAG;CAAM;AAClC"}
1
+ {"version":3,"file":"usePresetActive.mjs","names":[],"sources":["../../../src/base-ui/DatePicker/usePresetActive.tsx"],"sourcesContent":["import { type ReactNode, useCallback, useMemo, useState } from 'react';\n\nimport { PREFIX_CLS } from './style';\n\ninterface Preset {\n label: ReactNode;\n value: unknown;\n}\n\nconst sameDay = (a: any, b: any): boolean => {\n if (!a || !b) return !a && !b;\n if (typeof a.isSame === 'function') return a.isSame(b, 'day');\n if (a instanceof Date && b instanceof Date) return a.toDateString() === b.toDateString();\n return a === b;\n};\n\nconst sameValue = (a: any, b: any): boolean => {\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;\n return a.every((item, i) => sameDay(item, b[i]));\n }\n return sameDay(a, b);\n};\n\nexport const PRESET_ACTIVE_CLS = `${PREFIX_CLS}-preset-active`;\n\n/**\n * rc-picker renders `presets` as the popup sidebar but has no \"current preset\" state.\n * Mirror the picked value (controlled or not) and wrap the matching preset's label so the\n * sidebar can show it as selected (`li:has(> .lobe-picker-preset-active)`).\n */\nexport const usePresetActive = <P extends Preset>(\n presets: P[] | undefined,\n value: unknown,\n defaultValue: unknown,\n) => {\n const [inner, setInner] = useState<unknown>(defaultValue);\n const current = value !== undefined ? value : inner;\n\n const track = useCallback((next: unknown) => setInner(next), []);\n\n const mapped = useMemo(() => {\n if (!presets?.length || !current) return presets;\n return presets.map((preset) => {\n const v =\n typeof preset.value === 'function' ? (preset.value as () => unknown)() : preset.value;\n if (!sameValue(v, current)) return preset;\n return { ...preset, label: <span className={PRESET_ACTIVE_CLS}>{preset.label}</span> };\n });\n }, [presets, current]);\n\n return { presets: mapped, track };\n};\n"],"mappings":";;;;AASA,MAAM,WAAW,GAAQ,MAAoB;CAC3C,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;CAC5B,IAAI,OAAO,EAAE,WAAW,YAAY,OAAO,EAAE,OAAO,GAAG,KAAK;CAC5D,IAAI,aAAa,QAAQ,aAAa,MAAM,OAAO,EAAE,aAAa,MAAM,EAAE,aAAa;CACvF,OAAO,MAAM;AACf;AAEA,MAAM,aAAa,GAAQ,MAAoB;CAC7C,IAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;EACxC,IAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,OAAO;EAC5E,OAAO,EAAE,OAAO,MAAM,MAAM,QAAQ,MAAM,EAAE,EAAE,CAAC;CACjD;CACA,OAAO,QAAQ,GAAG,CAAC;AACrB;AAEA,MAAa,oBAAoB,GAAG,WAAW;;;;;;AAO/C,MAAa,mBACX,SACA,OACA,iBACG;CACH,MAAM,CAAC,OAAO,YAAY,SAAkB,YAAY;CACxD,MAAM,UAAU,UAAU,KAAA,IAAY,QAAQ;CAE9C,MAAM,QAAQ,aAAa,SAAkB,SAAS,IAAI,GAAG,CAAC,CAAC;CAY/D,OAAO;EAAE,SAVM,cAAc;GAC3B,IAAI,CAAC,SAAS,UAAU,CAAC,SAAS,OAAO;GACzC,OAAO,QAAQ,KAAK,WAAW;IAC7B,MAAM,IACJ,OAAO,OAAO,UAAU,aAAc,OAAO,MAAwB,IAAI,OAAO;IAClF,IAAI,CAAC,UAAU,GAAG,OAAO,GAAG,OAAO;IACnC,OAAO;KAAE,GAAG;KAAQ,OAAO,oBAAC,QAAD;MAAM,WAAW;MAAoB,UAAA,OAAO;KAAY,CAAA;IAAE;GACvF,CAAC;EACH,GAAG,CAAC,SAAS,OAAO,CAEG;EAAG;CAAM;AAClC"}
@@ -15,7 +15,9 @@ const serializeForm = (form) => {
15
15
  const entries = [...new FormData(form).entries()].filter(([, value]) => typeof value === "string");
16
16
  return JSON.stringify(entries.sort((a, b) => a[0].localeCompare(b[0])));
17
17
  };
18
- const Form$1 = memo(({ className, itemMinWidth, footer, items = [], children, itemsType = "group", variant = "borderless", classNames, styles: customStyles, gap, style, collapsible, defaultActiveKey, initialValues, activeKey, onCollapse, onFinish, onFormSubmit, layout, ref, ...rest }) => {
18
+ const Form$1 = memo(({ className, itemMinWidth, footer, items = [], children, itemsType = "group", variant = "borderless", classNames, styles: customStyles, gap, style, collapsible, defaultActiveKey, initialValues, activeKey, onCollapse, onFinish, onFormSubmit, layout, ref, compact, itemPadding, ...rest }) => {
19
+ const resolvedGap = gap ?? (compact ? 12 : void 0);
20
+ const resolvedItemPadding = itemPadding ?? (compact ? 10 : void 0);
19
21
  const { mobile } = useResponsive();
20
22
  const formRef = useRef(null);
21
23
  const [submitLoading, setSubmitLoading] = useState(false);
@@ -119,7 +121,9 @@ const Form$1 = memo(({ className, itemMinWidth, footer, items = [], children, it
119
121
  className: cx(rootVariants({ variant }), className),
120
122
  ref: mergedRef,
121
123
  style: {
122
- gap,
124
+ gap: resolvedGap,
125
+ ...resolvedGap === void 0 ? void 0 : { "--lobe-form-gap": typeof resolvedGap === "number" ? `${resolvedGap}px` : resolvedGap },
126
+ ...resolvedItemPadding === void 0 ? void 0 : { "--lobe-form-item-padding-block": typeof resolvedItemPadding === "number" ? `${resolvedItemPadding}px` : resolvedItemPadding },
123
127
  ...style
124
128
  },
125
129
  onFormSubmit: async (values, eventDetails) => {
@@ -1 +1 @@
1
- {"version":3,"file":"Form.mjs","names":["Form","BaseForm"],"sources":["../../../src/base-ui/Form/Form.tsx"],"sourcesContent":["'use client';\n\nimport { Form as BaseForm } from '@base-ui/react/form';\nimport { cx, useResponsive } from 'antd-style';\nimport { isUndefined } from 'es-toolkit/compat';\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport FormField from './components/FormField';\nimport FormFlatGroup from './components/FormFlatGroup';\nimport FormGroup from './components/FormGroup';\nimport { FormContext } from './context';\nimport { rootVariants } from './style';\nimport type { FormFieldProps, FormGroupItemType, FormProps } from './type';\n\nconst serializeForm = (form: HTMLFormElement | null) => {\n if (!form) return '';\n const entries = [...new FormData(form).entries()].filter(\n ([, value]) => typeof value === 'string',\n ) as [string, string][];\n return JSON.stringify(entries.sort((a, b) => a[0].localeCompare(b[0])));\n};\n\nconst Form = memo<FormProps>(\n ({\n className,\n itemMinWidth,\n footer,\n items = [],\n children,\n itemsType = 'group',\n variant = 'borderless',\n classNames,\n styles: customStyles,\n gap,\n style,\n collapsible,\n defaultActiveKey,\n initialValues,\n activeKey,\n onCollapse,\n onFinish,\n onFormSubmit,\n layout,\n ref,\n ...rest\n }) => {\n const { mobile } = useResponsive();\n const formRef = useRef<HTMLFormElement>(null);\n const [submitLoading, setSubmitLoading] = useState(false);\n const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);\n const snapshotRef = useRef('');\n\n const syncUnsaved = useCallback(() => {\n setHasUnsavedChanges(serializeForm(formRef.current) !== snapshotRef.current);\n }, []);\n\n useEffect(() => {\n const form = formRef.current;\n if (!form) return;\n snapshotRef.current = serializeForm(form);\n let resetTimer: ReturnType<typeof setTimeout>;\n const handleMutation = () => syncUnsaved();\n const handleReset = () => {\n resetTimer = setTimeout(() => {\n snapshotRef.current = serializeForm(formRef.current);\n syncUnsaved();\n }, 0);\n };\n form.addEventListener('input', handleMutation);\n form.addEventListener('change', handleMutation);\n form.addEventListener('reset', handleReset);\n return () => {\n clearTimeout(resetTimer);\n form.removeEventListener('input', handleMutation);\n form.removeEventListener('change', handleMutation);\n form.removeEventListener('reset', handleReset);\n };\n }, [syncUnsaved]);\n\n const requestReset = useCallback(() => {\n formRef.current?.reset();\n }, []);\n\n const mergedRef = useCallback(\n (node: HTMLFormElement | null) => {\n formRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref],\n );\n\n const context = useMemo(\n () => ({\n hasUnsavedChanges,\n initialValues,\n itemMinWidth,\n layout: layout || (mobile ? ('vertical' as const) : ('horizontal' as const)),\n requestReset,\n submitLoading,\n variant,\n }),\n [\n hasUnsavedChanges,\n initialValues,\n itemMinWidth,\n layout,\n mobile,\n requestReset,\n submitLoading,\n variant,\n ],\n );\n\n const mapFlat = useCallback(\n (item: FormFieldProps, itemIndex: number) => (\n <FormField\n className={classNames?.item}\n divider={itemIndex !== 0}\n key={itemIndex}\n style={customStyles?.item}\n variant={variant}\n {...item}\n />\n ),\n [variant, classNames, customStyles],\n );\n\n const mapTree = useCallback(\n (group: FormGroupItemType, groupIndex: number) => {\n const key = group?.key || groupIndex;\n return (\n <FormGroup\n active={activeKey && group?.key ? activeKey.includes(key) : undefined}\n className={classNames?.group}\n collapsible={isUndefined(group.collapsible) ? collapsible : group.collapsible}\n desc={group?.desc}\n extra={group?.extra}\n icon={group?.icon}\n key={key}\n style={customStyles?.group}\n title={group.title}\n variant={group?.variant || variant}\n defaultActive={\n defaultActiveKey && group?.key ? defaultActiveKey.includes(key) : group?.defaultActive\n }\n onCollapse={(active) => {\n let keys: (string | number)[] = activeKey || defaultActiveKey || [];\n keys = keys.filter((k) => k !== key);\n onCollapse?.(active ? [...keys, key] : keys);\n }}\n >\n {Array.isArray(group.children)\n ? group.children.filter((item) => !item.hidden).map((item, i) => mapFlat(item, i))\n : group.children}\n </FormGroup>\n );\n },\n [\n activeKey,\n collapsible,\n defaultActiveKey,\n onCollapse,\n variant,\n classNames,\n customStyles,\n mapFlat,\n ],\n );\n\n return (\n <FormContext value={context}>\n <BaseForm\n className={cx(rootVariants({ variant }), className)}\n ref={mergedRef}\n style={{ gap, ...style }}\n onFormSubmit={async (values, eventDetails) => {\n onFormSubmit?.(values, eventDetails);\n if (!onFinish) return;\n setSubmitLoading(true);\n try {\n await onFinish(values, eventDetails);\n snapshotRef.current = serializeForm(formRef.current);\n syncUnsaved();\n } finally {\n setSubmitLoading(false);\n }\n }}\n {...rest}\n >\n {items && items.length > 0 ? (\n itemsType === 'group' ? (\n (items as FormGroupItemType[]).map((item, i) => mapTree(item, i))\n ) : (\n <FormFlatGroup\n className={classNames?.group}\n style={customStyles?.group}\n variant={variant}\n >\n {(items as FormFieldProps[])\n .filter((item) => !item.hidden)\n .map((item, i) => mapFlat(item, i))}\n </FormFlatGroup>\n )\n ) : undefined}\n {children}\n {footer}\n </BaseForm>\n </FormContext>\n );\n },\n);\n\nForm.displayName = 'Form';\n\nexport default Form;\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,iBAAiB,SAAiC;CACtD,IAAI,CAAC,MAAM,OAAO;CAClB,MAAM,UAAU,CAAC,GAAG,IAAI,SAAS,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAC/C,GAAG,WAAW,OAAO,UAAU,QAClC;CACA,OAAO,KAAK,UAAU,QAAQ,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AACxE;AAEA,MAAMA,SAAO,MACV,EACC,WACA,cACA,QACA,QAAQ,CAAC,GACT,UACA,YAAY,SACZ,UAAU,cACV,YACA,QAAQ,cACR,KACA,OACA,aACA,kBACA,eACA,WACA,YACA,UACA,cACA,QACA,KACA,GAAG,WACC;CACJ,MAAM,EAAE,WAAW,cAAc;CACjC,MAAM,UAAU,OAAwB,IAAI;CAC5C,MAAM,CAAC,eAAe,oBAAoB,SAAS,KAAK;CACxD,MAAM,CAAC,mBAAmB,wBAAwB,SAAS,KAAK;CAChE,MAAM,cAAc,OAAO,EAAE;CAE7B,MAAM,cAAc,kBAAkB;EACpC,qBAAqB,cAAc,QAAQ,OAAO,MAAM,YAAY,OAAO;CAC7E,GAAG,CAAC,CAAC;CAEL,gBAAgB;EACd,MAAM,OAAO,QAAQ;EACrB,IAAI,CAAC,MAAM;EACX,YAAY,UAAU,cAAc,IAAI;EACxC,IAAI;EACJ,MAAM,uBAAuB,YAAY;EACzC,MAAM,oBAAoB;GACxB,aAAa,iBAAiB;IAC5B,YAAY,UAAU,cAAc,QAAQ,OAAO;IACnD,YAAY;GACd,GAAG,CAAC;EACN;EACA,KAAK,iBAAiB,SAAS,cAAc;EAC7C,KAAK,iBAAiB,UAAU,cAAc;EAC9C,KAAK,iBAAiB,SAAS,WAAW;EAC1C,aAAa;GACX,aAAa,UAAU;GACvB,KAAK,oBAAoB,SAAS,cAAc;GAChD,KAAK,oBAAoB,UAAU,cAAc;GACjD,KAAK,oBAAoB,SAAS,WAAW;EAC/C;CACF,GAAG,CAAC,WAAW,CAAC;CAEhB,MAAM,eAAe,kBAAkB;EACrC,QAAQ,SAAS,MAAM;CACzB,GAAG,CAAC,CAAC;CAEL,MAAM,YAAY,aACf,SAAiC;EAChC,QAAQ,UAAU;EAClB,IAAI,OAAO,QAAQ,YAAY,IAAI,IAAI;OAClC,IAAI,KAAK,IAAI,UAAU;CAC9B,GACA,CAAC,GAAG,CACN;CAEA,MAAM,UAAU,eACP;EACL;EACA;EACA;EACA,QAAQ,WAAW,SAAU,aAAwB;EACrD;EACA;EACA;CACF,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,MAAM,UAAU,aACb,MAAsB,cACrB,oBAAC,WAAD;EACE,WAAW,YAAY;EACvB,SAAS,cAAc;EAEvB,OAAO,cAAc;EACZ;EACT,GAAI;CACL,GAJM,SAIN,GAEH;EAAC;EAAS;EAAY;CAAY,CACpC;CAEA,MAAM,UAAU,aACb,OAA0B,eAAuB;EAChD,MAAM,MAAM,OAAO,OAAO;EAC1B,OACE,oBAAC,WAAD;GACE,QAAQ,aAAa,OAAO,MAAM,UAAU,SAAS,GAAG,IAAI,KAAA;GAC5D,WAAW,YAAY;GACvB,aAAa,YAAY,MAAM,WAAW,IAAI,cAAc,MAAM;GAClE,MAAM,OAAO;GACb,OAAO,OAAO;GACd,MAAM,OAAO;GAEb,OAAO,cAAc;GACrB,OAAO,MAAM;GACb,SAAS,OAAO,WAAW;GAC3B,eACE,oBAAoB,OAAO,MAAM,iBAAiB,SAAS,GAAG,IAAI,OAAO;GAE3E,aAAa,WAAW;IACtB,IAAI,OAA4B,aAAa,oBAAoB,CAAC;IAClE,OAAO,KAAK,QAAQ,MAAM,MAAM,GAAG;IACnC,aAAa,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,IAAI;GAC7C;GAEC,UAAA,MAAM,QAAQ,MAAM,QAAQ,IACzB,MAAM,SAAS,QAAQ,SAAS,CAAC,KAAK,MAAM,CAAC,CAAC,KAAK,MAAM,MAAM,QAAQ,MAAM,CAAC,CAAC,IAC/E,MAAM;EACD,GAhBJ,GAgBI;CAEf,GACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,OACE,oBAAC,aAAD;EAAa,OAAO;EAClB,UAAA,qBAACC,MAAD;GACE,WAAW,GAAG,aAAa,EAAE,QAAQ,CAAC,GAAG,SAAS;GAClD,KAAK;GACL,OAAO;IAAE;IAAK,GAAG;GAAM;GACvB,cAAc,OAAO,QAAQ,iBAAiB;IAC5C,eAAe,QAAQ,YAAY;IACnC,IAAI,CAAC,UAAU;IACf,iBAAiB,IAAI;IACrB,IAAI;KACF,MAAM,SAAS,QAAQ,YAAY;KACnC,YAAY,UAAU,cAAc,QAAQ,OAAO;KACnD,YAAY;IACd,UAAU;KACR,iBAAiB,KAAK;IACxB;GACF;GACA,GAAI;GAhBN,UAAA;IAkBG,SAAS,MAAM,SAAS,IACvB,cAAc,UACX,MAA8B,KAAK,MAAM,MAAM,QAAQ,MAAM,CAAC,CAAC,IAEhE,oBAAC,eAAD;KACE,WAAW,YAAY;KACvB,OAAO,cAAc;KACZ;KAEP,UAAA,MACC,QAAQ,SAAS,CAAC,KAAK,MAAM,CAAC,CAC9B,KAAK,MAAM,MAAM,QAAQ,MAAM,CAAC,CAAC;IACvB,CAAA,IAEf,KAAA;IACH;IACA;GACO;;CACC,CAAA;AAEjB,CACF;AAEA,OAAK,cAAc"}
1
+ {"version":3,"file":"Form.mjs","names":["Form","BaseForm"],"sources":["../../../src/base-ui/Form/Form.tsx"],"sourcesContent":["'use client';\n\nimport { Form as BaseForm } from '@base-ui/react/form';\nimport { cx, useResponsive } from 'antd-style';\nimport { isUndefined } from 'es-toolkit/compat';\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport FormField from './components/FormField';\nimport FormFlatGroup from './components/FormFlatGroup';\nimport FormGroup from './components/FormGroup';\nimport { FormContext } from './context';\nimport { rootVariants } from './style';\nimport type { FormFieldProps, FormGroupItemType, FormProps } from './type';\n\nconst serializeForm = (form: HTMLFormElement | null) => {\n if (!form) return '';\n const entries = [...new FormData(form).entries()].filter(\n ([, value]) => typeof value === 'string',\n ) as [string, string][];\n return JSON.stringify(entries.sort((a, b) => a[0].localeCompare(b[0])));\n};\n\nconst Form = memo<FormProps>(\n ({\n className,\n itemMinWidth,\n footer,\n items = [],\n children,\n itemsType = 'group',\n variant = 'borderless',\n classNames,\n styles: customStyles,\n gap,\n style,\n collapsible,\n defaultActiveKey,\n initialValues,\n activeKey,\n onCollapse,\n onFinish,\n onFormSubmit,\n layout,\n ref,\n compact,\n itemPadding,\n ...rest\n }) => {\n const resolvedGap = gap ?? (compact ? 12 : undefined);\n const resolvedItemPadding = itemPadding ?? (compact ? 10 : undefined);\n const { mobile } = useResponsive();\n const formRef = useRef<HTMLFormElement>(null);\n const [submitLoading, setSubmitLoading] = useState(false);\n const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);\n const snapshotRef = useRef('');\n\n const syncUnsaved = useCallback(() => {\n setHasUnsavedChanges(serializeForm(formRef.current) !== snapshotRef.current);\n }, []);\n\n useEffect(() => {\n const form = formRef.current;\n if (!form) return;\n snapshotRef.current = serializeForm(form);\n let resetTimer: ReturnType<typeof setTimeout>;\n const handleMutation = () => syncUnsaved();\n const handleReset = () => {\n resetTimer = setTimeout(() => {\n snapshotRef.current = serializeForm(formRef.current);\n syncUnsaved();\n }, 0);\n };\n form.addEventListener('input', handleMutation);\n form.addEventListener('change', handleMutation);\n form.addEventListener('reset', handleReset);\n return () => {\n clearTimeout(resetTimer);\n form.removeEventListener('input', handleMutation);\n form.removeEventListener('change', handleMutation);\n form.removeEventListener('reset', handleReset);\n };\n }, [syncUnsaved]);\n\n const requestReset = useCallback(() => {\n formRef.current?.reset();\n }, []);\n\n const mergedRef = useCallback(\n (node: HTMLFormElement | null) => {\n formRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref],\n );\n\n const context = useMemo(\n () => ({\n hasUnsavedChanges,\n initialValues,\n itemMinWidth,\n layout: layout || (mobile ? ('vertical' as const) : ('horizontal' as const)),\n requestReset,\n submitLoading,\n variant,\n }),\n [\n hasUnsavedChanges,\n initialValues,\n itemMinWidth,\n layout,\n mobile,\n requestReset,\n submitLoading,\n variant,\n ],\n );\n\n const mapFlat = useCallback(\n (item: FormFieldProps, itemIndex: number) => (\n <FormField\n className={classNames?.item}\n divider={itemIndex !== 0}\n key={itemIndex}\n style={customStyles?.item}\n variant={variant}\n {...item}\n />\n ),\n [variant, classNames, customStyles],\n );\n\n const mapTree = useCallback(\n (group: FormGroupItemType, groupIndex: number) => {\n const key = group?.key || groupIndex;\n return (\n <FormGroup\n active={activeKey && group?.key ? activeKey.includes(key) : undefined}\n className={classNames?.group}\n collapsible={isUndefined(group.collapsible) ? collapsible : group.collapsible}\n desc={group?.desc}\n extra={group?.extra}\n icon={group?.icon}\n key={key}\n style={customStyles?.group}\n title={group.title}\n variant={group?.variant || variant}\n defaultActive={\n defaultActiveKey && group?.key ? defaultActiveKey.includes(key) : group?.defaultActive\n }\n onCollapse={(active) => {\n let keys: (string | number)[] = activeKey || defaultActiveKey || [];\n keys = keys.filter((k) => k !== key);\n onCollapse?.(active ? [...keys, key] : keys);\n }}\n >\n {Array.isArray(group.children)\n ? group.children.filter((item) => !item.hidden).map((item, i) => mapFlat(item, i))\n : group.children}\n </FormGroup>\n );\n },\n [\n activeKey,\n collapsible,\n defaultActiveKey,\n onCollapse,\n variant,\n classNames,\n customStyles,\n mapFlat,\n ],\n );\n\n return (\n <FormContext value={context}>\n <BaseForm\n className={cx(rootVariants({ variant }), className)}\n ref={mergedRef}\n style={{\n gap: resolvedGap,\n ...(resolvedGap === undefined\n ? undefined\n : {\n '--lobe-form-gap':\n typeof resolvedGap === 'number' ? `${resolvedGap}px` : resolvedGap,\n }),\n ...(resolvedItemPadding === undefined\n ? undefined\n : {\n '--lobe-form-item-padding-block':\n typeof resolvedItemPadding === 'number'\n ? `${resolvedItemPadding}px`\n : resolvedItemPadding,\n }),\n ...style,\n }}\n onFormSubmit={async (values, eventDetails) => {\n onFormSubmit?.(values, eventDetails);\n if (!onFinish) return;\n setSubmitLoading(true);\n try {\n await onFinish(values, eventDetails);\n snapshotRef.current = serializeForm(formRef.current);\n syncUnsaved();\n } finally {\n setSubmitLoading(false);\n }\n }}\n {...rest}\n >\n {items && items.length > 0 ? (\n itemsType === 'group' ? (\n (items as FormGroupItemType[]).map((item, i) => mapTree(item, i))\n ) : (\n <FormFlatGroup\n className={classNames?.group}\n style={customStyles?.group}\n variant={variant}\n >\n {(items as FormFieldProps[])\n .filter((item) => !item.hidden)\n .map((item, i) => mapFlat(item, i))}\n </FormFlatGroup>\n )\n ) : undefined}\n {children}\n {footer}\n </BaseForm>\n </FormContext>\n );\n },\n);\n\nForm.displayName = 'Form';\n\nexport default Form;\n"],"mappings":"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"}
@@ -17,8 +17,9 @@ const styles = createStaticStyles(({ css }) => ({
17
17
  padding-block: 0;
18
18
  }
19
19
 
20
+ /* Mobile stacks flush, unless the Form sets gap / compact (--lobe-form-gap). */
20
21
  ${responsive.sm} {
21
- gap: 0 !important;
22
+ gap: var(--lobe-form-gap, 0) !important;
22
23
  }
23
24
  `,
24
25
  rootBorderless: css`
@@ -67,7 +68,7 @@ const fieldStyles = createStaticStyles(({ css, cssVar }) => ({
67
68
 
68
69
  box-sizing: border-box;
69
70
  width: 100%;
70
- padding-block: 16px;
71
+ padding-block: var(--lobe-form-item-padding-block, 16px);
71
72
  `,
72
73
  vertical: css`
73
74
  flex-direction: column;
@@ -1 +1 @@
1
- {"version":3,"file":"style.mjs","names":["lobeStaticStylish"],"sources":["../../../src/base-ui/Form/style.ts"],"sourcesContent":["import { createStaticStyles, responsive } from 'antd-style';\nimport { cva } from 'class-variance-authority';\n\nimport { focusRing } from '@/base-ui/focusRing';\nimport { lobeStaticStylish } from '@/styles';\n\nexport const styles = createStaticStyles(({ css }) => ({\n root: css`\n position: relative;\n\n display: flex;\n flex-direction: column;\n gap: 16px;\n\n width: 100%;\n\n [data-form-group-body] {\n padding-block: 0;\n }\n\n ${responsive.sm} {\n gap: 0 !important;\n }\n `,\n rootBorderless: css`\n gap: 48px;\n `,\n}));\n\nexport const rootVariants = cva(styles.root, {\n defaultVariants: {\n variant: 'borderless',\n },\n variants: {\n variant: {\n borderless: styles.rootBorderless,\n filled: null,\n outlined: null,\n },\n },\n});\n\nexport const fieldStyles = createStaticStyles(({ css, cssVar }) => ({\n control: css`\n display: flex;\n flex-direction: column;\n gap: 4px;\n align-items: flex-end;\n\n min-width: var(--form-field-min-width, unset);\n `,\n controlVertical: css`\n align-items: stretch;\n width: 100%;\n `,\n error: css`\n font-size: 12px;\n color: ${cssVar.colorError};\n `,\n horizontal: css`\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n `,\n label: css`\n display: block;\n flex: 1;\n max-width: 100%;\n text-align: start;\n `,\n root: css`\n display: flex;\n gap: 12px;\n\n box-sizing: border-box;\n width: 100%;\n padding-block: 16px;\n `,\n vertical: css`\n flex-direction: column;\n gap: 8px;\n align-items: stretch;\n `,\n}));\n\nexport const fieldVariants = cva(fieldStyles.root, {\n defaultVariants: {\n layout: 'horizontal',\n },\n variants: {\n layout: {\n horizontal: fieldStyles.horizontal,\n vertical: fieldStyles.vertical,\n },\n },\n});\n\nexport const dividerStyles = createStaticStyles(({ css, cssVar }) => ({\n root: css`\n width: 100%;\n height: 1px;\n margin: 0;\n border: none;\n\n background: ${cssVar.colorBorderSecondary};\n `,\n}));\n\nexport const groupStyles = createStaticStyles(({ css, cssVar }) => ({\n body: css`\n display: flex;\n flex-direction: column;\n `,\n bodyBoxed: css`\n padding-block: 16px;\n padding-inline: 16px;\n `,\n chevron: css`\n flex: none;\n color: ${cssVar.colorTextDescription};\n transition: transform 200ms ${cssVar.motionEaseOut};\n\n [data-panel-open] & {\n transform: rotate(180deg);\n }\n `,\n desc: css`\n font-size: 12px;\n font-weight: 400;\n color: ${cssVar.colorTextDescription};\n `,\n header: css`\n display: flex;\n gap: 12px;\n align-items: center;\n justify-content: space-between;\n\n width: 100%;\n `,\n headerBorderless: css`\n padding-block-end: 16px;\n border-block-end: 1px solid ${cssVar.colorBorderSecondary};\n `,\n headerBoxed: css`\n padding: 16px;\n `,\n mobileBody: css`\n padding-block: 0;\n padding-inline: 16px;\n background: ${cssVar.colorBgContainer};\n `,\n mobileHeader: css`\n padding: 16px;\n background: ${cssVar.colorBgLayout};\n `,\n mobileTitle: css`\n font-size: 14px;\n font-weight: 400;\n opacity: 0.5;\n `,\n panel: css`\n overflow: hidden;\n height: var(--collapsible-panel-height);\n transition: height 200ms ${cssVar.motionEaseOut};\n\n &[data-starting-style],\n &[data-ending-style] {\n height: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition-duration: 0s;\n }\n `,\n bodyFilled: css`\n margin-block-end: 3px;\n margin-inline: 3px;\n border-radius: ${cssVar.borderRadius};\n ${lobeStaticStylish.variantOutlinedWithoutHover}\n `,\n bodyFilledLight: lobeStaticStylish.shadow,\n rootFilled: css`\n border-radius: ${cssVar.borderRadiusLG};\n background: ${cssVar.colorFillQuaternary};\n `,\n rootFilledDark: css`\n background: ${cssVar.colorBgLayout};\n `,\n rootOutlined: css`\n border-radius: ${cssVar.borderRadiusLG};\n ${lobeStaticStylish.variantOutlinedWithoutHover}\n `,\n title: css`\n display: flex;\n flex-shrink: 0;\n gap: 8px;\n align-items: center;\n\n font-size: 16px;\n font-weight: bold;\n color: ${cssVar.colorText};\n `,\n titleBorderless: css`\n font-size: 18px;\n `,\n trigger: css`\n cursor: pointer;\n\n display: flex;\n flex: 1;\n gap: 12px;\n align-items: center;\n\n margin: 0;\n padding: 0;\n border: none;\n\n text-align: start;\n\n background: none;\n outline: none;\n\n border-radius: ${cssVar.borderRadius};\n ${focusRing};\n `,\n}));\n\nexport const groupVariants = cva(null, {\n compoundVariants: [\n {\n class: groupStyles.rootFilledDark,\n isDarkMode: true,\n variant: 'filled',\n },\n ],\n defaultVariants: {\n variant: 'borderless',\n },\n variants: {\n variant: {\n borderless: null,\n filled: groupStyles.rootFilled,\n outlined: groupStyles.rootOutlined,\n },\n isDarkMode: {\n false: null,\n true: null,\n },\n },\n});\n\nexport const flatGroupStyles = createStaticStyles(({ cx, css, cssVar }) => ({\n borderless: cx(\n lobeStaticStylish.variantBorderlessWithoutHover,\n css`\n padding-inline: 0;\n `,\n ),\n filled: cx(\n lobeStaticStylish.variantFilledWithoutHover,\n css`\n background: ${cssVar.colorFillQuaternary};\n `,\n ),\n mobile: css`\n padding-block: 0;\n padding-inline: 16px;\n border-radius: 0;\n background: ${cssVar.colorBgContainer};\n `,\n outlined: lobeStaticStylish.variantOutlinedWithoutHover,\n root: css`\n padding-inline: 16px;\n border-radius: ${cssVar.borderRadiusLG};\n `,\n}));\n\nexport const flatGroupVariants = cva(flatGroupStyles.root, {\n defaultVariants: {\n variant: 'borderless',\n },\n variants: {\n variant: {\n borderless: flatGroupStyles.borderless,\n filled: flatGroupStyles.filled,\n outlined: flatGroupStyles.outlined,\n },\n },\n});\n\nexport const footerStyles = createStaticStyles(({ css, cssVar }) => ({\n root: css`\n ${responsive.sm} {\n padding: 16px;\n border-block-start: 1px solid ${cssVar.colorBorderSecondary};\n background: ${cssVar.colorBgContainer};\n }\n `,\n}));\n\nexport const submitFooterStyles = createStaticStyles(({ css, cssVar }) => ({\n floatFooter: css`\n position: fixed;\n z-index: 1000;\n inset-block-end: 24px;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n\n width: max-content;\n padding: 8px;\n border: 1px solid ${cssVar.colorBorderSecondary};\n border-radius: 48px;\n\n background: ${cssVar.colorBgContainer};\n box-shadow: ${cssVar.boxShadowSecondary};\n `,\n footer: css`\n ${responsive.sm} {\n margin-block-start: calc(-1 * ${cssVar.borderRadius});\n padding: 16px;\n border-block-start: 1px solid ${cssVar.colorBorderSecondary};\n background: ${cssVar.colorBgContainer};\n }\n `,\n}));\n\nexport const titleStyles = createStaticStyles(({ css, cssVar }) => ({\n content: css`\n position: relative;\n text-align: start;\n `,\n desc: css`\n display: block;\n\n font-size: 12px;\n font-weight: 400;\n line-height: 1.44;\n color: ${cssVar.colorTextDescription};\n word-wrap: break-word;\n white-space: pre-wrap;\n `,\n title: css`\n font-weight: 500;\n line-height: 1;\n color: ${cssVar.colorText};\n `,\n}));\n"],"mappings":"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"}
1
+ {"version":3,"file":"style.mjs","names":["lobeStaticStylish"],"sources":["../../../src/base-ui/Form/style.ts"],"sourcesContent":["import { createStaticStyles, responsive } from 'antd-style';\nimport { cva } from 'class-variance-authority';\n\nimport { focusRing } from '@/base-ui/focusRing';\nimport { lobeStaticStylish } from '@/styles';\n\nexport const styles = createStaticStyles(({ css }) => ({\n root: css`\n position: relative;\n\n display: flex;\n flex-direction: column;\n gap: 16px;\n\n width: 100%;\n\n [data-form-group-body] {\n padding-block: 0;\n }\n\n /* Mobile stacks flush, unless the Form sets gap / compact (--lobe-form-gap). */\n ${responsive.sm} {\n gap: var(--lobe-form-gap, 0) !important;\n }\n `,\n rootBorderless: css`\n gap: 48px;\n `,\n}));\n\nexport const rootVariants = cva(styles.root, {\n defaultVariants: {\n variant: 'borderless',\n },\n variants: {\n variant: {\n borderless: styles.rootBorderless,\n filled: null,\n outlined: null,\n },\n },\n});\n\nexport const fieldStyles = createStaticStyles(({ css, cssVar }) => ({\n control: css`\n display: flex;\n flex-direction: column;\n gap: 4px;\n align-items: flex-end;\n\n min-width: var(--form-field-min-width, unset);\n `,\n controlVertical: css`\n align-items: stretch;\n width: 100%;\n `,\n error: css`\n font-size: 12px;\n color: ${cssVar.colorError};\n `,\n horizontal: css`\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n `,\n label: css`\n display: block;\n flex: 1;\n max-width: 100%;\n text-align: start;\n `,\n root: css`\n display: flex;\n gap: 12px;\n\n box-sizing: border-box;\n width: 100%;\n padding-block: var(--lobe-form-item-padding-block, 16px);\n `,\n vertical: css`\n flex-direction: column;\n gap: 8px;\n align-items: stretch;\n `,\n}));\n\nexport const fieldVariants = cva(fieldStyles.root, {\n defaultVariants: {\n layout: 'horizontal',\n },\n variants: {\n layout: {\n horizontal: fieldStyles.horizontal,\n vertical: fieldStyles.vertical,\n },\n },\n});\n\nexport const dividerStyles = createStaticStyles(({ css, cssVar }) => ({\n root: css`\n width: 100%;\n height: 1px;\n margin: 0;\n border: none;\n\n background: ${cssVar.colorBorderSecondary};\n `,\n}));\n\nexport const groupStyles = createStaticStyles(({ css, cssVar }) => ({\n body: css`\n display: flex;\n flex-direction: column;\n `,\n bodyBoxed: css`\n padding-block: 16px;\n padding-inline: 16px;\n `,\n chevron: css`\n flex: none;\n color: ${cssVar.colorTextDescription};\n transition: transform 200ms ${cssVar.motionEaseOut};\n\n [data-panel-open] & {\n transform: rotate(180deg);\n }\n `,\n desc: css`\n font-size: 12px;\n font-weight: 400;\n color: ${cssVar.colorTextDescription};\n `,\n header: css`\n display: flex;\n gap: 12px;\n align-items: center;\n justify-content: space-between;\n\n width: 100%;\n `,\n headerBorderless: css`\n padding-block-end: 16px;\n border-block-end: 1px solid ${cssVar.colorBorderSecondary};\n `,\n headerBoxed: css`\n padding: 16px;\n `,\n mobileBody: css`\n padding-block: 0;\n padding-inline: 16px;\n background: ${cssVar.colorBgContainer};\n `,\n mobileHeader: css`\n padding: 16px;\n background: ${cssVar.colorBgLayout};\n `,\n mobileTitle: css`\n font-size: 14px;\n font-weight: 400;\n opacity: 0.5;\n `,\n panel: css`\n overflow: hidden;\n height: var(--collapsible-panel-height);\n transition: height 200ms ${cssVar.motionEaseOut};\n\n &[data-starting-style],\n &[data-ending-style] {\n height: 0;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition-duration: 0s;\n }\n `,\n bodyFilled: css`\n margin-block-end: 3px;\n margin-inline: 3px;\n border-radius: ${cssVar.borderRadius};\n ${lobeStaticStylish.variantOutlinedWithoutHover}\n `,\n bodyFilledLight: lobeStaticStylish.shadow,\n rootFilled: css`\n border-radius: ${cssVar.borderRadiusLG};\n background: ${cssVar.colorFillQuaternary};\n `,\n rootFilledDark: css`\n background: ${cssVar.colorBgLayout};\n `,\n rootOutlined: css`\n border-radius: ${cssVar.borderRadiusLG};\n ${lobeStaticStylish.variantOutlinedWithoutHover}\n `,\n title: css`\n display: flex;\n flex-shrink: 0;\n gap: 8px;\n align-items: center;\n\n font-size: 16px;\n font-weight: bold;\n color: ${cssVar.colorText};\n `,\n titleBorderless: css`\n font-size: 18px;\n `,\n trigger: css`\n cursor: pointer;\n\n display: flex;\n flex: 1;\n gap: 12px;\n align-items: center;\n\n margin: 0;\n padding: 0;\n border: none;\n\n text-align: start;\n\n background: none;\n outline: none;\n\n border-radius: ${cssVar.borderRadius};\n ${focusRing};\n `,\n}));\n\nexport const groupVariants = cva(null, {\n compoundVariants: [\n {\n class: groupStyles.rootFilledDark,\n isDarkMode: true,\n variant: 'filled',\n },\n ],\n defaultVariants: {\n variant: 'borderless',\n },\n variants: {\n variant: {\n borderless: null,\n filled: groupStyles.rootFilled,\n outlined: groupStyles.rootOutlined,\n },\n isDarkMode: {\n false: null,\n true: null,\n },\n },\n});\n\nexport const flatGroupStyles = createStaticStyles(({ cx, css, cssVar }) => ({\n borderless: cx(\n lobeStaticStylish.variantBorderlessWithoutHover,\n css`\n padding-inline: 0;\n `,\n ),\n filled: cx(\n lobeStaticStylish.variantFilledWithoutHover,\n css`\n background: ${cssVar.colorFillQuaternary};\n `,\n ),\n mobile: css`\n padding-block: 0;\n padding-inline: 16px;\n border-radius: 0;\n background: ${cssVar.colorBgContainer};\n `,\n outlined: lobeStaticStylish.variantOutlinedWithoutHover,\n root: css`\n padding-inline: 16px;\n border-radius: ${cssVar.borderRadiusLG};\n `,\n}));\n\nexport const flatGroupVariants = cva(flatGroupStyles.root, {\n defaultVariants: {\n variant: 'borderless',\n },\n variants: {\n variant: {\n borderless: flatGroupStyles.borderless,\n filled: flatGroupStyles.filled,\n outlined: flatGroupStyles.outlined,\n },\n },\n});\n\nexport const footerStyles = createStaticStyles(({ css, cssVar }) => ({\n root: css`\n ${responsive.sm} {\n padding: 16px;\n border-block-start: 1px solid ${cssVar.colorBorderSecondary};\n background: ${cssVar.colorBgContainer};\n }\n `,\n}));\n\nexport const submitFooterStyles = createStaticStyles(({ css, cssVar }) => ({\n floatFooter: css`\n position: fixed;\n z-index: 1000;\n inset-block-end: 24px;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n\n width: max-content;\n padding: 8px;\n border: 1px solid ${cssVar.colorBorderSecondary};\n border-radius: 48px;\n\n background: ${cssVar.colorBgContainer};\n box-shadow: ${cssVar.boxShadowSecondary};\n `,\n footer: css`\n ${responsive.sm} {\n margin-block-start: calc(-1 * ${cssVar.borderRadius});\n padding: 16px;\n border-block-start: 1px solid ${cssVar.colorBorderSecondary};\n background: ${cssVar.colorBgContainer};\n }\n `,\n}));\n\nexport const titleStyles = createStaticStyles(({ css, cssVar }) => ({\n content: css`\n position: relative;\n text-align: start;\n `,\n desc: css`\n display: block;\n\n font-size: 12px;\n font-weight: 400;\n line-height: 1.44;\n color: ${cssVar.colorTextDescription};\n word-wrap: break-word;\n white-space: pre-wrap;\n `,\n title: css`\n font-weight: 500;\n line-height: 1;\n color: ${cssVar.colorText};\n `,\n}));\n"],"mappings":"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"}
@@ -24,6 +24,11 @@ interface FormProps extends BaseFormProps {
24
24
  item?: string;
25
25
  };
26
26
  collapsible?: boolean;
27
+ /**
28
+ * Compact spacing for narrow containers (Drawer / Modal): `gap` 12px and `itemPadding` 10px
29
+ * unless set explicitly. Default `false` (unchanged spacing).
30
+ */
31
+ compact?: boolean;
27
32
  defaultActiveKey?: (string | number)[];
28
33
  footer?: ReactNode;
29
34
  gap?: number | string;
@@ -33,6 +38,8 @@ interface FormProps extends BaseFormProps {
33
38
  */
34
39
  initialValues?: FormValues;
35
40
  itemMinWidth?: FormFieldProps['minWidth'];
41
+ /** Block (top / bottom) padding of every Form.Field. Default `16px`. */
42
+ itemPadding?: number | string;
36
43
  items?: FormGroupItemType[] | FormFieldProps[];
37
44
  itemsType?: ItemsType;
38
45
  layout?: FormLayout;
@@ -30,7 +30,7 @@ declare const styles: {
30
30
  };
31
31
  declare const rootVariants: (props?: ({
32
32
  shadow?: boolean | null | undefined;
33
- size?: "large" | "middle" | "small" | null | undefined;
33
+ size?: "small" | "middle" | "large" | null | undefined;
34
34
  variant?: "filled" | "outlined" | "borderless" | null | undefined;
35
35
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
36
36
  //#endregion
@@ -2,11 +2,12 @@ import Switch from "../Switch/Switch.mjs";
2
2
  import Input_default from "../Input/Input.mjs";
3
3
  import InputNumber_default from "../Input/InputNumber.mjs";
4
4
  import Select from "../Select/Select.mjs";
5
- import DatePicker from "../DatePicker/DatePicker.mjs";
6
- import DateRangePicker from "../DatePicker/DateRangePicker.mjs";
5
+ import DayjsDatePicker from "../DatePicker/DayjsDatePicker.mjs";
6
+ import DayjsDateRangePicker from "../DatePicker/DayjsDateRangePicker.mjs";
7
+ import { styles } from "./style.mjs";
7
8
  import { useColumnRequest } from "./useColumnRequest.mjs";
8
9
  import { resolveValueEnum, resolveValueType, valueEnumToList } from "./utils.mjs";
9
- import { jsx } from "react/jsx-runtime";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
10
11
  import { useThemeMode } from "antd-style";
11
12
  //#region src/base-ui/ProTable/FieldControl.tsx
12
13
  const SELECT_TYPES = /* @__PURE__ */ new Set([
@@ -19,11 +20,16 @@ const FieldControl = ({ column, form, light, onChange, placeholder, value }) =>
19
20
  const valueType = resolveValueType(column) ?? "text";
20
21
  const valueEnum = resolveValueEnum(column);
21
22
  const { fieldProps = {} } = column;
22
- const label = typeof column.title === "string" ? column.title : void 0;
23
23
  const size = light ? "small" : void 0;
24
24
  const { isDarkMode } = useThemeMode();
25
25
  const variant = light ? isDarkMode ? "filled" : "outlined" : void 0;
26
26
  const remote = useColumnRequest(column);
27
+ const lightLabel = light && column.title !== void 0 && column.title !== null && typeof column.title !== "function" ? /* @__PURE__ */ jsx("span", {
28
+ className: styles.lightFilterLabel,
29
+ "data-pro-table-light-label": "",
30
+ children: column.title
31
+ }) : void 0;
32
+ const labelProps = lightLabel ? { prefix: lightLabel } : {};
27
33
  if (column.renderFormItem) return column.renderFormItem(column, {
28
34
  form,
29
35
  isQuery: !light,
@@ -41,8 +47,9 @@ const FieldControl = ({ column, form, light, onChange, placeholder, value }) =>
41
47
  loading: remote.loading,
42
48
  mode: valueType === "checkbox" ? "multiple" : void 0,
43
49
  options,
44
- placeholder: light ? label : placeholder.select,
50
+ placeholder: placeholder.select,
45
51
  size,
52
+ ...labelProps,
46
53
  style: { width: "100%" },
47
54
  value: value ?? (valueType === "checkbox" ? [] : null),
48
55
  variant,
@@ -59,24 +66,32 @@ const FieldControl = ({ column, form, light, onChange, placeholder, value }) =>
59
66
  case "money":
60
67
  case "percent":
61
68
  case "progress": return /* @__PURE__ */ jsx(InputNumber_default, {
62
- placeholder: light ? label : placeholder.input,
69
+ placeholder: placeholder.input,
63
70
  size,
71
+ ...labelProps,
64
72
  style: { width: "100%" },
65
73
  value: value ?? null,
66
74
  variant,
67
75
  ...fieldProps,
68
76
  onChange: (next) => onChange(next ?? void 0)
69
77
  });
70
- case "switch": return /* @__PURE__ */ jsx(Switch, {
71
- checked: !!value,
72
- ...fieldProps,
73
- onChange: (next) => onChange(next)
74
- });
78
+ case "switch": {
79
+ const control = /* @__PURE__ */ jsx(Switch, {
80
+ checked: !!value,
81
+ ...fieldProps,
82
+ onChange: (next) => onChange(next)
83
+ });
84
+ return lightLabel ? /* @__PURE__ */ jsxs("span", {
85
+ className: styles.lightFilterSwitch,
86
+ children: [lightLabel, control]
87
+ }) : control;
88
+ }
75
89
  case "date":
76
- case "dateTime": return /* @__PURE__ */ jsx(DatePicker, {
90
+ case "dateTime": return /* @__PURE__ */ jsx(DayjsDatePicker, {
77
91
  allowClear: true,
78
- placeholder: light ? label : placeholder.select,
92
+ placeholder: placeholder.select,
79
93
  size,
94
+ ...labelProps,
80
95
  style: { width: "100%" },
81
96
  value: value ?? null,
82
97
  variant,
@@ -84,9 +99,10 @@ const FieldControl = ({ column, form, light, onChange, placeholder, value }) =>
84
99
  onChange: (next) => onChange(next ?? void 0)
85
100
  });
86
101
  case "dateRange":
87
- case "dateTimeRange": return /* @__PURE__ */ jsx(DateRangePicker, {
102
+ case "dateTimeRange": return /* @__PURE__ */ jsx(DayjsDateRangePicker, {
88
103
  allowClear: true,
89
104
  size,
105
+ ...labelProps,
90
106
  style: { width: "100%" },
91
107
  value: value ?? [null, null],
92
108
  variant,
@@ -95,8 +111,9 @@ const FieldControl = ({ column, form, light, onChange, placeholder, value }) =>
95
111
  });
96
112
  default: return /* @__PURE__ */ jsx(Input_default, {
97
113
  allowClear: true,
98
- placeholder: light ? label : placeholder.input,
114
+ placeholder: placeholder.input,
99
115
  size,
116
+ ...labelProps,
100
117
  type: valueType === "password" ? "password" : void 0,
101
118
  value: value ?? "",
102
119
  variant,
@@ -1 +1 @@
1
- {"version":3,"file":"FieldControl.mjs","names":["InputNumber","Input"],"sources":["../../../src/base-ui/ProTable/FieldControl.tsx"],"sourcesContent":["import { useThemeMode } from 'antd-style';\nimport { type ReactNode } from 'react';\n\nimport DatePicker from '@/base-ui/DatePicker/DatePicker';\nimport DateRangePicker from '@/base-ui/DatePicker/DateRangePicker';\nimport Input from '@/base-ui/Input/Input';\nimport InputNumber from '@/base-ui/Input/InputNumber';\nimport Select from '@/base-ui/Select';\nimport Switch from '@/base-ui/Switch';\n\nimport type { ProColumnType, ProTableFormInstance, ProTableValueType } from './type';\nimport { useColumnRequest } from './useColumnRequest';\nimport { resolveValueEnum, resolveValueType, valueEnumToList } from './utils';\n\nexport interface FieldControlProps {\n column: ProColumnType<any>;\n form: ProTableFormInstance;\n /** Light filter bar: small controls, outlined in light mode and filled in dark mode. */\n light?: boolean;\n onChange: (value: any) => void;\n placeholder: { input: string; select: string };\n value: any;\n}\n\nconst SELECT_TYPES = new Set<ProTableValueType>(['select', 'radio', 'checkbox']);\n\n/** The search-form control of a column (Pro \"edit\" mode, query flavor). */\nconst FieldControl = ({ column, form, light, onChange, placeholder, value }: FieldControlProps) => {\n const valueType = resolveValueType(column) ?? 'text';\n const valueEnum = resolveValueEnum(column);\n const { fieldProps = {} } = column;\n const label = typeof column.title === 'string' ? column.title : undefined;\n const size = light ? 'small' : undefined;\n const { isDarkMode } = useThemeMode();\n // Light filter: outlined on light backgrounds, filled in dark mode.\n const variant = light ? (isDarkMode ? 'filled' : 'outlined') : undefined;\n const remote = useColumnRequest(column);\n\n if (column.renderFormItem) {\n return column.renderFormItem(\n column,\n { form, isQuery: !light, onChange, value },\n form,\n ) as ReactNode;\n }\n\n if (remote.enabled || valueEnum || SELECT_TYPES.has(valueType)) {\n const options =\n remote.options ??\n fieldProps.options ??\n valueEnumToList(valueEnum).map((item) => ({\n disabled: item.disabled,\n label: item.text,\n value: item.value,\n }));\n return (\n <Select\n allowClear\n loading={remote.loading}\n mode={valueType === 'checkbox' ? 'multiple' : undefined}\n options={options as any}\n placeholder={light ? label : placeholder.select}\n size={size}\n style={{ width: '100%' }}\n value={value ?? (valueType === 'checkbox' ? [] : null)}\n variant={variant}\n {...fieldProps}\n onChange={(next) => onChange(next ?? undefined)}\n onSearch={\n remote.onSearch\n ? (keyWords: string) => {\n remote.onSearch!(keyWords);\n fieldProps.onSearch?.(keyWords);\n }\n : fieldProps.onSearch\n }\n />\n );\n }\n\n switch (valueType) {\n case 'digit':\n case 'money':\n case 'percent':\n case 'progress': {\n return (\n <InputNumber\n placeholder={light ? label : placeholder.input}\n size={size}\n style={{ width: '100%' }}\n value={value ?? null}\n variant={variant}\n {...fieldProps}\n onChange={(next) => onChange(next ?? undefined)}\n />\n );\n }\n case 'switch': {\n return <Switch checked={!!value} {...fieldProps} onChange={(next) => onChange(next)} />;\n }\n case 'date':\n case 'dateTime': {\n return (\n <DatePicker\n allowClear\n placeholder={light ? label : placeholder.select}\n size={size}\n style={{ width: '100%' }}\n value={value ?? null}\n variant={variant}\n {...fieldProps}\n onChange={(next) => onChange(next ?? undefined)}\n />\n );\n }\n case 'dateRange':\n case 'dateTimeRange': {\n return (\n <DateRangePicker\n allowClear\n size={size}\n style={{ width: '100%' }}\n value={value ?? [null, null]}\n variant={variant}\n {...fieldProps}\n onChange={(next) => onChange(next && (next[0] || next[1]) ? next : undefined)}\n />\n );\n }\n default: {\n return (\n <Input\n allowClear\n placeholder={light ? label : placeholder.input}\n size={size}\n type={valueType === 'password' ? 'password' : undefined}\n value={value ?? ''}\n variant={variant}\n {...fieldProps}\n onChange={(event) => onChange(event.target.value === '' ? undefined : event.target.value)}\n onClear={() => {\n onChange(undefined);\n fieldProps.onClear?.();\n }}\n />\n );\n }\n }\n};\n\nexport default FieldControl;\n"],"mappings":";;;;;;;;;;;AAwBA,MAAM,+BAAe,IAAI,IAAuB;CAAC;CAAU;CAAS;AAAU,CAAC;;AAG/E,MAAM,gBAAgB,EAAE,QAAQ,MAAM,OAAO,UAAU,aAAa,YAA+B;CACjG,MAAM,YAAY,iBAAiB,MAAM,KAAK;CAC9C,MAAM,YAAY,iBAAiB,MAAM;CACzC,MAAM,EAAE,aAAa,CAAC,MAAM;CAC5B,MAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ,KAAA;CAChE,MAAM,OAAO,QAAQ,UAAU,KAAA;CAC/B,MAAM,EAAE,eAAe,aAAa;CAEpC,MAAM,UAAU,QAAS,aAAa,WAAW,aAAc,KAAA;CAC/D,MAAM,SAAS,iBAAiB,MAAM;CAEtC,IAAI,OAAO,gBACT,OAAO,OAAO,eACZ,QACA;EAAE;EAAM,SAAS,CAAC;EAAO;EAAU;CAAM,GACzC,IACF;CAGF,IAAI,OAAO,WAAW,aAAa,aAAa,IAAI,SAAS,GAAG;EAC9D,MAAM,UACJ,OAAO,WACP,WAAW,WACX,gBAAgB,SAAS,CAAC,CAAC,KAAK,UAAU;GACxC,UAAU,KAAK;GACf,OAAO,KAAK;GACZ,OAAO,KAAK;EACd,EAAE;EACJ,OACE,oBAAC,QAAD;GACE,YAAA;GACA,SAAS,OAAO;GAChB,MAAM,cAAc,aAAa,aAAa,KAAA;GACrC;GACT,aAAa,QAAQ,QAAQ,YAAY;GACnC;GACN,OAAO,EAAE,OAAO,OAAO;GACvB,OAAO,UAAU,cAAc,aAAa,CAAC,IAAI;GACxC;GACT,GAAI;GACJ,WAAW,SAAS,SAAS,QAAQ,KAAA,CAAS;GAC9C,UACE,OAAO,YACF,aAAqB;IACpB,OAAO,SAAU,QAAQ;IACzB,WAAW,WAAW,QAAQ;GAChC,IACA,WAAW;EAElB,CAAA;CAEL;CAEA,QAAQ,WAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,YACH,OACE,oBAACA,qBAAD;GACE,aAAa,QAAQ,QAAQ,YAAY;GACnC;GACN,OAAO,EAAE,OAAO,OAAO;GACvB,OAAO,SAAS;GACP;GACT,GAAI;GACJ,WAAW,SAAS,SAAS,QAAQ,KAAA,CAAS;EAC/C,CAAA;EAGL,KAAK,UACH,OAAO,oBAAC,QAAD;GAAQ,SAAS,CAAC,CAAC;GAAO,GAAI;GAAY,WAAW,SAAS,SAAS,IAAI;EAAI,CAAA;EAExF,KAAK;EACL,KAAK,YACH,OACE,oBAAC,YAAD;GACE,YAAA;GACA,aAAa,QAAQ,QAAQ,YAAY;GACnC;GACN,OAAO,EAAE,OAAO,OAAO;GACvB,OAAO,SAAS;GACP;GACT,GAAI;GACJ,WAAW,SAAS,SAAS,QAAQ,KAAA,CAAS;EAC/C,CAAA;EAGL,KAAK;EACL,KAAK,iBACH,OACE,oBAAC,iBAAD;GACE,YAAA;GACM;GACN,OAAO,EAAE,OAAO,OAAO;GACvB,OAAO,SAAS,CAAC,MAAM,IAAI;GAClB;GACT,GAAI;GACJ,WAAW,SAAS,SAAS,SAAS,KAAK,MAAM,KAAK,MAAM,OAAO,KAAA,CAAS;EAC7E,CAAA;EAGL,SACE,OACE,oBAACC,eAAD;GACE,YAAA;GACA,aAAa,QAAQ,QAAQ,YAAY;GACnC;GACN,MAAM,cAAc,aAAa,aAAa,KAAA;GAC9C,OAAO,SAAS;GACP;GACT,GAAI;GACJ,WAAW,UAAU,SAAS,MAAM,OAAO,UAAU,KAAK,KAAA,IAAY,MAAM,OAAO,KAAK;GACxF,eAAe;IACb,SAAS,KAAA,CAAS;IAClB,WAAW,UAAU;GACvB;EACD,CAAA;CAGP;AACF"}
1
+ {"version":3,"file":"FieldControl.mjs","names":["InputNumber","DatePicker","DateRangePicker","Input"],"sources":["../../../src/base-ui/ProTable/FieldControl.tsx"],"sourcesContent":["import { useThemeMode } from 'antd-style';\nimport { type ReactNode } from 'react';\n\nimport DatePicker from '@/base-ui/DatePicker/DayjsDatePicker';\nimport DateRangePicker from '@/base-ui/DatePicker/DayjsDateRangePicker';\nimport Input from '@/base-ui/Input/Input';\nimport InputNumber from '@/base-ui/Input/InputNumber';\nimport Select from '@/base-ui/Select';\nimport Switch from '@/base-ui/Switch';\n\nimport { styles } from './style';\nimport type { ProColumnType, ProTableFormInstance, ProTableValueType } from './type';\nimport { useColumnRequest } from './useColumnRequest';\nimport { resolveValueEnum, resolveValueType, valueEnumToList } from './utils';\n\nexport interface FieldControlProps {\n column: ProColumnType<any>;\n form: ProTableFormInstance;\n /** Light filter bar: small controls, outlined in light mode and filled in dark mode. */\n light?: boolean;\n onChange: (value: any) => void;\n placeholder: { input: string; select: string };\n value: any;\n}\n\nconst SELECT_TYPES = new Set<ProTableValueType>(['select', 'radio', 'checkbox']);\n\n/** The search-form control of a column (Pro \"edit\" mode, query flavor). */\nconst FieldControl = ({ column, form, light, onChange, placeholder, value }: FieldControlProps) => {\n const valueType = resolveValueType(column) ?? 'text';\n const valueEnum = resolveValueEnum(column);\n const { fieldProps = {} } = column;\n const size = light ? 'small' : undefined;\n const { isDarkMode } = useThemeMode();\n // Light filter: outlined on light backgrounds, filled in dark mode.\n const variant = light ? (isDarkMode ? 'filled' : 'outlined') : undefined;\n const remote = useColumnRequest(column);\n // Light filter: the field label always stays visible inside the control (Pro `FieldLabel`\n // style, \"Status: All\"), so a placeholder such as \"All\" is never ambiguous.\n const lightLabel =\n light &&\n column.title !== undefined &&\n column.title !== null &&\n typeof column.title !== 'function' ? (\n <span className={styles.lightFilterLabel} data-pro-table-light-label=\"\">\n {column.title as ReactNode}\n </span>\n ) : undefined;\n const labelProps = lightLabel ? { prefix: lightLabel } : {};\n\n if (column.renderFormItem) {\n return column.renderFormItem(\n column,\n { form, isQuery: !light, onChange, value },\n form,\n ) as ReactNode;\n }\n\n if (remote.enabled || valueEnum || SELECT_TYPES.has(valueType)) {\n const options =\n remote.options ??\n fieldProps.options ??\n valueEnumToList(valueEnum).map((item) => ({\n disabled: item.disabled,\n label: item.text,\n value: item.value,\n }));\n return (\n <Select\n allowClear\n loading={remote.loading}\n mode={valueType === 'checkbox' ? 'multiple' : undefined}\n options={options as any}\n placeholder={placeholder.select}\n size={size}\n {...labelProps}\n style={{ width: '100%' }}\n value={value ?? (valueType === 'checkbox' ? [] : null)}\n variant={variant}\n {...fieldProps}\n onChange={(next) => onChange(next ?? undefined)}\n onSearch={\n remote.onSearch\n ? (keyWords: string) => {\n remote.onSearch!(keyWords);\n fieldProps.onSearch?.(keyWords);\n }\n : fieldProps.onSearch\n }\n />\n );\n }\n\n switch (valueType) {\n case 'digit':\n case 'money':\n case 'percent':\n case 'progress': {\n return (\n <InputNumber\n placeholder={placeholder.input}\n size={size}\n {...labelProps}\n style={{ width: '100%' }}\n value={value ?? null}\n variant={variant}\n {...fieldProps}\n onChange={(next) => onChange(next ?? undefined)}\n />\n );\n }\n case 'switch': {\n const control = (\n <Switch checked={!!value} {...fieldProps} onChange={(next) => onChange(next)} />\n );\n return lightLabel ? (\n <span className={styles.lightFilterSwitch}>\n {lightLabel}\n {control}\n </span>\n ) : (\n control\n );\n }\n case 'date':\n case 'dateTime': {\n return (\n <DatePicker\n allowClear\n placeholder={placeholder.select}\n size={size}\n {...labelProps}\n style={{ width: '100%' }}\n value={value ?? null}\n variant={variant}\n {...fieldProps}\n onChange={(next) => onChange(next ?? undefined)}\n />\n );\n }\n case 'dateRange':\n case 'dateTimeRange': {\n return (\n <DateRangePicker\n allowClear\n size={size}\n {...labelProps}\n style={{ width: '100%' }}\n value={value ?? [null, null]}\n variant={variant}\n {...fieldProps}\n onChange={(next) => onChange(next && (next[0] || next[1]) ? next : undefined)}\n />\n );\n }\n default: {\n return (\n <Input\n allowClear\n placeholder={placeholder.input}\n size={size}\n {...labelProps}\n type={valueType === 'password' ? 'password' : undefined}\n value={value ?? ''}\n variant={variant}\n {...fieldProps}\n onChange={(event) => onChange(event.target.value === '' ? undefined : event.target.value)}\n onClear={() => {\n onChange(undefined);\n fieldProps.onClear?.();\n }}\n />\n );\n }\n }\n};\n\nexport default FieldControl;\n"],"mappings":"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"}
@@ -134,16 +134,29 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
134
134
  display: inline-flex;
135
135
  flex: none;
136
136
  align-items: center;
137
- width: 160px;
137
+
138
+ width: auto;
139
+ min-width: 160px;
140
+ max-width: 320px;
138
141
 
139
142
  & > * {
140
143
  width: 100%;
141
144
  }
142
145
  `,
143
146
  lightFilterLabel: css`
147
+ flex: none;
144
148
  font-size: ${cssVar.fontSizeSM};
145
149
  color: ${cssVar.colorTextSecondary};
146
150
  white-space: nowrap;
151
+
152
+ &::after {
153
+ content: ':';
154
+ }
155
+ `,
156
+ lightFilterSwitch: css`
157
+ display: inline-flex;
158
+ gap: 8px;
159
+ align-items: center;
147
160
  `,
148
161
  optionCell: css`
149
162
  display: flex;