@godxjp/ui 33.1.1 → 33.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +5 -5
  2. package/agent/START-HERE.md +7 -7
  3. package/agent/components/Command.json +9 -1
  4. package/agent/components/ResponsiveGrid.json +2 -2
  5. package/agent/components/SearchForm.json +115 -0
  6. package/agent/components/Toolbar.json +6 -3
  7. package/agent/components/TranslatableInput.json +92 -0
  8. package/agent/components/TranslatableTextarea.json +84 -0
  9. package/agent/components-index.json +20 -1
  10. package/agent/components.json +308 -6
  11. package/agent/index.json +8 -8
  12. package/agent/llms.txt +8 -8
  13. package/agent/patterns/condition-builder.json +31 -0
  14. package/agent/patterns/data-table-page.json +1 -1
  15. package/agent/patterns/filter-bar-layouts.json +30 -0
  16. package/agent/patterns/inertia-list-page.json +1 -1
  17. package/agent/patterns/list-filters.json +1 -1
  18. package/agent/patterns/search-form.json +27 -0
  19. package/agent/patterns-index.json +85 -0
  20. package/agent/patterns.json +91 -3
  21. package/agent/rules.json +1 -1
  22. package/agent/tokens.json +12 -0
  23. package/dist/components/data-entry/command.d.ts +22 -1
  24. package/dist/components/data-entry/command.js +14 -1
  25. package/dist/components/data-entry/form-field.js +10 -4
  26. package/dist/components/data-entry/index.d.ts +4 -2
  27. package/dist/components/data-entry/index.js +6 -1
  28. package/dist/components/data-entry/translatable-input.d.ts +29 -0
  29. package/dist/components/data-entry/translatable-input.js +184 -0
  30. package/dist/components/navigation/index.d.ts +2 -0
  31. package/dist/components/navigation/index.js +2 -0
  32. package/dist/components/navigation/search-form.d.ts +31 -0
  33. package/dist/components/navigation/search-form.js +112 -0
  34. package/dist/contracts/measurement.json +1 -1
  35. package/dist/i18n/messages/en.json +13 -0
  36. package/dist/i18n/messages/ja.json +13 -0
  37. package/dist/i18n/messages/vi.json +13 -0
  38. package/dist/lib/field-a11y.d.ts +15 -0
  39. package/dist/lib/field-a11y.js +13 -1
  40. package/dist/lib/intl-cache.d.ts +1 -0
  41. package/dist/lib/intl-cache.js +4 -0
  42. package/dist/props/components/data-entry.prop.d.ts +46 -0
  43. package/dist/props/components/index.d.ts +1 -1
  44. package/dist/props/components/layout.prop.d.ts +3 -1
  45. package/dist/props/components/navigation.prop.d.ts +43 -3
  46. package/dist/props/registry.d.ts +56 -0
  47. package/dist/props/registry.js +91 -0
  48. package/dist/styles/control.css +15 -0
  49. package/dist/styles/data-entry-layout.css +25 -0
  50. package/dist/styles/layers.json +29 -1
  51. package/dist/styles/layout.css +41 -0
  52. package/dist/styles.css +1 -1
  53. package/dist/tokens/components/data-entry.css +4 -0
  54. package/docs/CONSUMER-RULES.md +1 -1
  55. package/package.json +2 -2
  56. package/scripts/ui-audit.mjs +148 -3
@@ -78,7 +78,18 @@ function pickGroupFieldA11y(props) {
78
78
  ...props["data-field"] !== void 0 ? { "data-field": props["data-field"] } : {}
79
79
  };
80
80
  }
81
+ const FieldErrorReportContext = React.createContext(null);
82
+ function useReportFieldError(message) {
83
+ const report = React.useContext(FieldErrorReportContext);
84
+ React.useEffect(() => {
85
+ if (!report) return;
86
+ report(message);
87
+ return () => report(void 0);
88
+ }, [report, message]);
89
+ return report !== null;
90
+ }
81
91
  export {
92
+ FieldErrorReportContext,
82
93
  FieldIdentityContext,
83
94
  FieldNameContext,
84
95
  mergeAriaIds,
@@ -88,5 +99,6 @@ export {
88
99
  resolveFieldA11y,
89
100
  useFieldIdentity,
90
101
  useFieldNameFallback,
91
- useMirroredInputAttributes
102
+ useMirroredInputAttributes,
103
+ useReportFieldError
92
104
  };
@@ -30,3 +30,4 @@ export declare function dateTimeFormat(locale: string, options?: Intl.DateTimeFo
30
30
  export declare function numberFormat(locale: string, options?: Intl.NumberFormatOptions): Intl.NumberFormat;
31
31
  export declare function pluralRules(locale: string, options?: Intl.PluralRulesOptions): Intl.PluralRules;
32
32
  export declare function listFormat(locale: string, options?: Intl.ListFormatOptions): Intl.ListFormat;
33
+ export declare function displayNames(locale: string, options: Intl.DisplayNamesOptions): Intl.DisplayNames;
@@ -21,8 +21,12 @@ function pluralRules(locale, options) {
21
21
  function listFormat(locale, options) {
22
22
  return memoise("lf", locale, options, () => new Intl.ListFormat(locale, options));
23
23
  }
24
+ function displayNames(locale, options) {
25
+ return memoise("dn", locale, options, () => new Intl.DisplayNames(locale, options));
26
+ }
24
27
  export {
25
28
  dateTimeFormat,
29
+ displayNames,
26
30
  listFormat,
27
31
  numberFormat,
28
32
  pluralRules
@@ -125,6 +125,14 @@ export type CommandProp = {
125
125
  */
126
126
  split?: boolean;
127
127
  };
128
+ export type CommandSeparatorProp = {
129
+ /**
130
+ * Keep the separator while a search query is typed. Default `true` — the opposite of cmdk, which
131
+ * hides it under a query; a `+ Create "<q>"` group only exists while the user types, so the rule
132
+ * above it must stay. `false` restores cmdk's palette behaviour.
133
+ */
134
+ alwaysRender?: boolean;
135
+ };
128
136
  export type InputProp = Omit<React.InputHTMLAttributes<HTMLInputElement>, "size" | "prefix"> & {
129
137
  onValueChange?: (value: string) => void;
130
138
  /**
@@ -221,6 +229,43 @@ export type TextareaProp = React.TextareaHTMLAttributes<HTMLTextAreaElement> & {
221
229
  /** Character counter — antd `count`. */
222
230
  count?: ControlCountProp;
223
231
  };
232
+ /**
233
+ * One translatable field's per-locale values, keyed by BCP-47 tag: `{ ja: "…", en: "…", vi: "…" }`.
234
+ * A locale with no key (or `""`) is empty. The shape a `*_translations` backend (Astrotomic,
235
+ * Spatie translatable, Rails Mobility) already sends.
236
+ */
237
+ export type TranslatableValue = Partial<Record<string, string>>;
238
+ /** The locale + value contract shared by {@link TranslatableInputProp} and {@link TranslatableTextareaProp}. */
239
+ type TranslatableFieldProp = {
240
+ /** Controlled per-locale values. */
241
+ value?: ValueProp<TranslatableValue>;
242
+ /** Uncontrolled initial per-locale values. */
243
+ defaultValue?: DefaultValueProp<TranslatableValue>;
244
+ /** The WHOLE map after an edit — every other locale's text is carried over untouched. */
245
+ onValueChange?: OnValueChangeProp<TranslatableValue>;
246
+ /**
247
+ * The locales the field edits, in tab order. Default: every locale registered with the app
248
+ * (`getRegisteredLocales()` — the built-in `vi`/`en`/`ja` plus `registerLocale(...)`).
249
+ */
250
+ locales?: readonly string[];
251
+ /** The locale tab selected first. Default: the AppProvider's active locale when it is in `locales`. */
252
+ defaultLocale?: string;
253
+ /**
254
+ * The locale whose text shows as the placeholder of an EMPTY locale. Default: the AppProvider's
255
+ * `fallbackLocale`, or the first of `locales` when that is not one of them.
256
+ */
257
+ fallbackLocale?: string;
258
+ /**
259
+ * Per-locale validation messages. A locale that has one gets an error mark on its tab (a glyph
260
+ * plus screen-reader text, never colour alone); the ACTIVE locale's message sets `aria-invalid`
261
+ * and is shown by the enclosing `FormField` (or under the field when there is none).
262
+ */
263
+ errors?: Partial<Record<string, ErrorProp>>;
264
+ };
265
+ /** @see TranslatableInput — one `Input` holding a value per locale, switched by locale tabs. */
266
+ export type TranslatableInputProp = Omit<InputProp, "value" | "defaultValue" | "onValueChange" | "lang"> & TranslatableFieldProp;
267
+ /** @see TranslatableTextarea — the `Textarea` counterpart of {@link TranslatableInputProp}. */
268
+ export type TranslatableTextareaProp = Omit<TextareaProp, "value" | "defaultValue" | "onValueChange" | "lang"> & TranslatableFieldProp;
224
269
  /**
225
270
  * @see NumberInput — localized numeric spinbutton (composes `Input` + step `Button`s).
226
271
  * `value`/`defaultValue`/`onValueChange` carry a `number | null` (null = empty). `step` drives both
@@ -2469,3 +2514,4 @@ export type EmojiPickerProp = {
2469
2514
  id?: IdProp;
2470
2515
  className?: ClassNameProp;
2471
2516
  };
2517
+ export {};
@@ -1,6 +1,6 @@
1
1
  export type { AppLauncherApp, AppLauncherGroup, AppLauncherLabels, AppLauncherProp, AppShellProp, AuthFooterProp, AuthIdentityProp, OrgSwitcherLabels, OrgSwitcherOrganization, OrgSwitcherProp, DragAxisProp, DragBoundsProp, DraggablePanelLabels, DraggablePanelPlacementProp, DraggablePanelPositionProp, DraggablePanelProp, PageContainerExtraProp, PageContainerProp, PageInsetProp, SidebarItemProp, SidebarProductProp, SidebarProp, SidebarSectionProp, TopbarProp, } from "./layout.prop.js";
2
2
  export type { ButtonProp } from "./general.prop.js";
3
- export type { CommandProp, InputProp, TextareaProp, FormFieldProp, SearchInputProp, CheckboxProp, CheckboxGroupProp, ChoiceOptionProp, RadioProp, RadioGroupProp, SwitchProp, SliderProp, CalendarProp, DatePickerProp, TimePickerProp, ColorPickerProp, ColorPickerPresetProp, UploadProp, UploadFileItemProp, UploadVariantProp, TreeOptionProp, TreeFieldNamesProp, CascaderProp, TreeSelectProp, ShowCheckedStrategyProp, TransferProp, TransferItemProp, } from "./data-entry.prop.js";
3
+ export type { CommandProp, CommandSeparatorProp, InputProp, TextareaProp, FormFieldProp, SearchInputProp, CheckboxProp, CheckboxGroupProp, ChoiceOptionProp, RadioProp, RadioGroupProp, SwitchProp, SliderProp, CalendarProp, DatePickerProp, TimePickerProp, ColorPickerProp, ColorPickerPresetProp, UploadProp, UploadFileItemProp, UploadVariantProp, TreeOptionProp, TreeFieldNamesProp, CascaderProp, TreeSelectProp, ShowCheckedStrategyProp, TransferProp, TransferItemProp, } from "./data-entry.prop.js";
4
4
  export type { AvatarProp, EmptyStateProp, DescriptionsProp, DescriptionsItemProp, BadgeProp, DataTableProp, QrCodeProp, } from "./data-display.prop.js";
5
5
  export type { ChartDatum, ChartSeriesProp, LineChartProp, BarChartProp, AreaChartProp, PieChartProp, } from "./charts.prop.js";
6
6
  export type { AlertQueryErrorProp, AuthExpiryProviderProp, AlertProp, DialogProp, DialogContentProp, AlertTitleProp, AlertContentProp, AlertDescriptionProp, AlertActionsProp, SheetResponsiveProp, SkeletonRowsProp, } from "./feedback.prop.js";
@@ -401,9 +401,11 @@ export type ResponsiveGridPresetProp = "pricing-plans";
401
401
  * Block-axis alignment of the cells in each grid row — antd `Row align`, spelled with Flex's
402
402
  * `FlexAlignProp` values (antd `top` → `start`; `stretch` is the same word). `stretch` gives every
403
403
  * cell the height of the tallest one, so an empty Kanban lane is still a full-height drop zone.
404
+ * `center` is antd `middle`: cells of different heights share one centre line (a condition row's
405
+ * number and +/− buttons beside taller controls).
404
406
  * Omitted, each flow keeps its own alignment: `columns` → `start`, `rows` → the grid's stretch.
405
407
  */
406
- export type ResponsiveGridAlignProp = Extract<FlexAlignProp, "start" | "stretch">;
408
+ export type ResponsiveGridAlignProp = Extract<FlexAlignProp, "start" | "center" | "stretch">;
407
409
  export type MasterDetailRailWidthProp = "narrow" | "compact" | "standard" | "wide";
408
410
  export type MasterDetailRailProp = "master" | "detail";
409
411
  /**
@@ -1,9 +1,9 @@
1
1
  /** Navigation component prop types — @see docs/COMPONENTS.md#navigation */
2
2
  import type * as React from "react";
3
3
  import type { ReactNode } from "react";
4
- import type { AffixProp, AffixTargetProp } from "./layout.prop.js";
5
- import type { ActionsProp, ChildrenProp, ClassNameProp, DisabledProp, ErrorProp, HasActiveFiltersProp, IdProp, LabelProp, OnClearFiltersProp, PendingProp, PlaceholderProp, StickyProp, TextAlignProp } from "../vocabulary/index.js";
6
- import type { SearchSelectOptionProp } from "./data-entry.prop.js";
4
+ import type { AffixProp, AffixTargetProp, ResponsiveGridColumnsProp } from "./layout.prop.js";
5
+ import type { ActionsProp, ChildrenProp, ClassNameProp, DisabledProp, ErrorProp, HasActiveFiltersProp, IdProp, LabelProp, OnClearFiltersProp, OnOpenChangeProp, OpenProp, DefaultOpenProp, PendingProp, PlaceholderProp, StickyProp, TextAlignProp } from "../vocabulary/index.js";
6
+ import type { FormProp, SearchSelectOptionProp } from "./data-entry.prop.js";
7
7
  /**
8
8
  * Renders the canonical SearchInput as the FIRST control of the strip, with a token-owned
9
9
  * consistent width (`--filter-bar-search-width`, full-width below 640px). Controlled by consumer
@@ -123,6 +123,46 @@ export type ToolbarProp = {
123
123
  export type FilterBarViewsPlacementProp = "above" | "inline";
124
124
  /** @see ToolbarProp.clearDisplay */
125
125
  export type FilterBarClearDisplayProp = "label" | "icon";
126
+ /**
127
+ * @see SearchForm — the submit-driven 検索条件フォーム (Ant Design ProComponents `QueryFilter`): a
128
+ * grid of labelled conditions, an explicit Search (検索) + Clear (クリア) pair, the conditions past
129
+ * the first row behind one 詳細条件を開く toggle, and a 検索条件 summary + result count after the
130
+ * search. A live FilterBar applies each change at once; a SearchForm applies them on submit.
131
+ */
132
+ export type SearchFormProp = Omit<FormProp, "role" | "onReset" | "children" | "columns" | "asChild" | "aria-label"> & {
133
+ /** One FormField per condition, in reading order. Each direct child is one grid cell. */
134
+ children: ChildrenProp;
135
+ /** Grid columns per breakpoint. Default `{ base: 1, md: 2, lg: 3 }`: one column on a phone. */
136
+ columns?: ResponsiveGridColumnsProp;
137
+ /**
138
+ * How many conditions stay visible while the detail section is closed (antd
139
+ * `defaultFormItemsNumber`). Defaults to the widest `columns` step: the first row.
140
+ */
141
+ visibleFields?: number;
142
+ /** Whether the conditions past `visibleFields` are shown (controlled). */
143
+ open?: OpenProp;
144
+ /** Initial open state when uncontrolled. Default `false`: collapsed to the first row. */
145
+ defaultOpen?: DefaultOpenProp;
146
+ /** Fires when the 詳細条件を開く / 閉じる toggle is pressed. */
147
+ onOpenChange?: OnOpenChangeProp;
148
+ /** Clear (クリア) handler. The Clear button renders only when this is set. */
149
+ onReset?: () => void;
150
+ /** Overrides the localized Search (検索) button text. */
151
+ searchLabel?: LabelProp;
152
+ /** Overrides the localized Clear (クリア) button text. */
153
+ resetLabel?: LabelProp;
154
+ /**
155
+ * The conditions the CURRENT results were searched with, shown after the localized 検索条件
156
+ * label in a `role="status"` line (e.g. 「国: ベトナム / 状態: 稼働中」).
157
+ */
158
+ summary?: ReactNode;
159
+ /** Localized, pluralized result count shown in the same status line. */
160
+ resultCount?: number;
161
+ /** Puts the Search button in its loading state while the query runs. */
162
+ loading?: PendingProp;
163
+ /** Accessible name of the `search` landmark. Defaults to a localized "Search conditions". */
164
+ label?: string;
165
+ };
126
166
  /** @see ToolbarGroup */
127
167
  export type ToolbarGroupProp = {
128
168
  label: LabelProp;
@@ -1641,11 +1641,62 @@ export declare const COMPONENT_PROP_REGISTRY: {
1641
1641
  readonly reason: "antd List `split` — ruled-list presentation (row dividers, 0 list padding) for option/checkbox lists; the rest of the root API is cmdk's (gh#699).";
1642
1642
  }];
1643
1643
  };
1644
+ readonly CommandSeparatorProp: {
1645
+ readonly group: "data-entry";
1646
+ readonly file: "components/data-entry.prop.ts";
1647
+ readonly vocabulary: readonly [{
1648
+ readonly field: "alwaysRender";
1649
+ readonly local: true;
1650
+ readonly reason: "cmdk's own Command.Separator prop name, kept so the cmdk docs still apply; only its default differs (true) so the rule stays above a `+ Create` group while the user types (gh#1335).";
1651
+ }];
1652
+ };
1644
1653
  readonly TextareaProp: {
1645
1654
  readonly group: "data-entry";
1646
1655
  readonly file: "components/data-entry.prop.ts";
1647
1656
  readonly vocabulary: readonly ["PlaceholderProp", "DisabledProp", "ValueProp", "DefaultValueProp", "OnChangeProp", "IdProp", "ClassNameProp"];
1648
1657
  };
1658
+ readonly TranslatableInputProp: {
1659
+ readonly group: "data-entry";
1660
+ readonly file: "components/data-entry.prop.ts";
1661
+ readonly vocabulary: readonly ["ValueProp", "DefaultValueProp", "OnValueChangeProp", "SizeProp", "PlaceholderProp", "DisabledProp", "IdProp", "ClassNameProp", {
1662
+ readonly field: "locales";
1663
+ readonly local: true;
1664
+ readonly reason: "The BCP-47 tags the field edits, in tab order (gh#1336). Defaults to the app's registered locales; a per-field list, not a value.";
1665
+ }, {
1666
+ readonly field: "defaultLocale";
1667
+ readonly local: true;
1668
+ readonly reason: "The locale tab selected first — the AppProvider's own `defaultLocale` spelling, scoped to one field. Defaults to the active app locale.";
1669
+ }, {
1670
+ readonly field: "fallbackLocale";
1671
+ readonly local: true;
1672
+ readonly reason: "The locale whose text an EMPTY locale shows as its placeholder — the AppProvider's own `fallbackLocale` spelling, scoped to one field.";
1673
+ }, {
1674
+ readonly field: "errors";
1675
+ readonly local: true;
1676
+ readonly reason: "Per-locale validation messages keyed by BCP-47 tag; marks each locale's tab and sends the ACTIVE one through FormField. `error` (one message) cannot say which locale failed.";
1677
+ }];
1678
+ };
1679
+ readonly TranslatableTextareaProp: {
1680
+ readonly group: "data-entry";
1681
+ readonly file: "components/data-entry.prop.ts";
1682
+ readonly vocabulary: readonly ["ValueProp", "DefaultValueProp", "OnValueChangeProp", "SizeProp", "PlaceholderProp", "DisabledProp", "IdProp", "ClassNameProp", {
1683
+ readonly field: "locales";
1684
+ readonly local: true;
1685
+ readonly reason: "The BCP-47 tags the field edits, in tab order (gh#1336). Defaults to the app's registered locales; a per-field list, not a value.";
1686
+ }, {
1687
+ readonly field: "defaultLocale";
1688
+ readonly local: true;
1689
+ readonly reason: "The locale tab selected first — the AppProvider's own `defaultLocale` spelling, scoped to one field. Defaults to the active app locale.";
1690
+ }, {
1691
+ readonly field: "fallbackLocale";
1692
+ readonly local: true;
1693
+ readonly reason: "The locale whose text an EMPTY locale shows as its placeholder — the AppProvider's own `fallbackLocale` spelling, scoped to one field.";
1694
+ }, {
1695
+ readonly field: "errors";
1696
+ readonly local: true;
1697
+ readonly reason: "Per-locale validation messages keyed by BCP-47 tag; marks each locale's tab and sends the ACTIVE one through FormField. `error` (one message) cannot say which locale failed.";
1698
+ }];
1699
+ };
1649
1700
  readonly NumberInputProp: {
1650
1701
  readonly group: "data-entry";
1651
1702
  readonly file: "components/data-entry.prop.ts";
@@ -2641,6 +2692,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
2641
2692
  readonly file: "components/navigation.prop.ts";
2642
2693
  readonly vocabulary: readonly ["OnClearFiltersProp", "HasActiveFiltersProp", "StickyProp", "ActionsProp", "PendingProp", "DisabledProp", "ErrorProp", "ClassNameProp", "ChildrenProp"];
2643
2694
  };
2695
+ readonly SearchFormProp: {
2696
+ readonly group: "navigation";
2697
+ readonly file: "components/navigation.prop.ts";
2698
+ readonly vocabulary: readonly ["OpenProp", "DefaultOpenProp", "OnOpenChangeProp", "LabelProp", "PendingProp", "ChildrenProp"];
2699
+ };
2644
2700
  readonly FilterBarClearDisplayProp: {
2645
2701
  readonly group: "navigation";
2646
2702
  readonly file: "components/navigation.prop.ts";
@@ -1854,6 +1854,17 @@ const COMPONENT_PROP_REGISTRY = {
1854
1854
  }
1855
1855
  ]
1856
1856
  },
1857
+ CommandSeparatorProp: {
1858
+ group: "data-entry",
1859
+ file: "components/data-entry.prop.ts",
1860
+ vocabulary: [
1861
+ {
1862
+ field: "alwaysRender",
1863
+ local: true,
1864
+ reason: "cmdk's own Command.Separator prop name, kept so the cmdk docs still apply; only its default differs (true) so the rule stays above a `+ Create` group while the user types (gh#1335)."
1865
+ }
1866
+ ]
1867
+ },
1857
1868
  TextareaProp: {
1858
1869
  group: "data-entry",
1859
1870
  file: "components/data-entry.prop.ts",
@@ -1867,6 +1878,74 @@ const COMPONENT_PROP_REGISTRY = {
1867
1878
  "ClassNameProp"
1868
1879
  ]
1869
1880
  },
1881
+ TranslatableInputProp: {
1882
+ group: "data-entry",
1883
+ file: "components/data-entry.prop.ts",
1884
+ vocabulary: [
1885
+ "ValueProp",
1886
+ "DefaultValueProp",
1887
+ "OnValueChangeProp",
1888
+ "SizeProp",
1889
+ "PlaceholderProp",
1890
+ "DisabledProp",
1891
+ "IdProp",
1892
+ "ClassNameProp",
1893
+ {
1894
+ field: "locales",
1895
+ local: true,
1896
+ reason: "The BCP-47 tags the field edits, in tab order (gh#1336). Defaults to the app's registered locales; a per-field list, not a value."
1897
+ },
1898
+ {
1899
+ field: "defaultLocale",
1900
+ local: true,
1901
+ reason: "The locale tab selected first \u2014 the AppProvider's own `defaultLocale` spelling, scoped to one field. Defaults to the active app locale."
1902
+ },
1903
+ {
1904
+ field: "fallbackLocale",
1905
+ local: true,
1906
+ reason: "The locale whose text an EMPTY locale shows as its placeholder \u2014 the AppProvider's own `fallbackLocale` spelling, scoped to one field."
1907
+ },
1908
+ {
1909
+ field: "errors",
1910
+ local: true,
1911
+ reason: "Per-locale validation messages keyed by BCP-47 tag; marks each locale's tab and sends the ACTIVE one through FormField. `error` (one message) cannot say which locale failed."
1912
+ }
1913
+ ]
1914
+ },
1915
+ TranslatableTextareaProp: {
1916
+ group: "data-entry",
1917
+ file: "components/data-entry.prop.ts",
1918
+ vocabulary: [
1919
+ "ValueProp",
1920
+ "DefaultValueProp",
1921
+ "OnValueChangeProp",
1922
+ "SizeProp",
1923
+ "PlaceholderProp",
1924
+ "DisabledProp",
1925
+ "IdProp",
1926
+ "ClassNameProp",
1927
+ {
1928
+ field: "locales",
1929
+ local: true,
1930
+ reason: "The BCP-47 tags the field edits, in tab order (gh#1336). Defaults to the app's registered locales; a per-field list, not a value."
1931
+ },
1932
+ {
1933
+ field: "defaultLocale",
1934
+ local: true,
1935
+ reason: "The locale tab selected first \u2014 the AppProvider's own `defaultLocale` spelling, scoped to one field. Defaults to the active app locale."
1936
+ },
1937
+ {
1938
+ field: "fallbackLocale",
1939
+ local: true,
1940
+ reason: "The locale whose text an EMPTY locale shows as its placeholder \u2014 the AppProvider's own `fallbackLocale` spelling, scoped to one field."
1941
+ },
1942
+ {
1943
+ field: "errors",
1944
+ local: true,
1945
+ reason: "Per-locale validation messages keyed by BCP-47 tag; marks each locale's tab and sends the ACTIVE one through FormField. `error` (one message) cannot say which locale failed."
1946
+ }
1947
+ ]
1948
+ },
1870
1949
  NumberInputProp: {
1871
1950
  group: "data-entry",
1872
1951
  file: "components/data-entry.prop.ts",
@@ -3080,6 +3159,18 @@ const COMPONENT_PROP_REGISTRY = {
3080
3159
  "ChildrenProp"
3081
3160
  ]
3082
3161
  },
3162
+ SearchFormProp: {
3163
+ group: "navigation",
3164
+ file: "components/navigation.prop.ts",
3165
+ vocabulary: [
3166
+ "OpenProp",
3167
+ "DefaultOpenProp",
3168
+ "OnOpenChangeProp",
3169
+ "LabelProp",
3170
+ "PendingProp",
3171
+ "ChildrenProp"
3172
+ ]
3173
+ },
3083
3174
  FilterBarClearDisplayProp: {
3084
3175
  group: "navigation",
3085
3176
  file: "components/navigation.prop.ts",
@@ -966,6 +966,17 @@
966
966
  opacity: 0.5;
967
967
  }
968
968
 
969
+ .ui-command-separator {
970
+ height: var(--command-item-divider-width, var(--stroke-hairline));
971
+ margin-block: var(--command-group-padding);
972
+ background: hsl(var(--command-item-divider-color, var(--border)));
973
+ }
974
+
975
+ .ui-command-group[hidden] + .ui-command-separator,
976
+ .ui-command-separator:has(+ .ui-command-group[hidden]) {
977
+ display: none;
978
+ }
979
+
969
980
  .ui-command[data-split] .ui-command-group {
970
981
  padding: var(--command-list-split-padding);
971
982
  }
@@ -990,6 +1001,10 @@
990
1001
  hsl(var(--command-item-divider-color, var(--border)));
991
1002
  }
992
1003
 
1004
+ .ui-command[data-split] .ui-command-separator {
1005
+ display: none;
1006
+ }
1007
+
993
1008
  [data-slot="dialog-content"].ui-command-palette {
994
1009
  top: var(--command-palette-inset-top);
995
1010
  width: min(
@@ -868,3 +868,28 @@
868
868
  border-radius: var(--radius-md);
869
869
  }
870
870
  }
871
+
872
+ @layer components {
873
+
874
+ .ui-translatable-field {
875
+ display: flex;
876
+ flex-direction: column;
877
+ align-items: stretch;
878
+ gap: var(--translatable-field-gap);
879
+ min-inline-size: 0;
880
+ }
881
+ .ui-translatable-field-tabs {
882
+ align-self: flex-start;
883
+ max-inline-size: 100%;
884
+ }
885
+ .ui-translatable-field-panel {
886
+ min-inline-size: 0;
887
+ }
888
+
889
+ .ui-translatable-field-error-mark {
890
+ inline-size: var(--translatable-field-error-icon-size);
891
+ block-size: var(--translatable-field-error-icon-size);
892
+ flex: none;
893
+ color: hsl(var(--text-error));
894
+ }
895
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "33.1.1",
2
+ "version": "33.3.0",
3
3
  "generatedBy": "scripts/gen-style-layers.mjs — do not edit by hand; run `pnpm gen:style-layers`",
4
4
  "base": "base.css",
5
5
  "fonts": "fonts.css",
@@ -853,6 +853,16 @@
853
853
  "data-display-layout.css"
854
854
  ]
855
855
  },
856
+ "SearchForm": {
857
+ "layers": [
858
+ "layout.css",
859
+ "control.css",
860
+ "text-layout.css",
861
+ "dialog-layout.css",
862
+ "alert-layout.css",
863
+ "form-layout.css"
864
+ ]
865
+ },
856
866
  "SearchInput": {
857
867
  "layers": [
858
868
  "control.css"
@@ -1097,6 +1107,24 @@
1097
1107
  "navigation-layout.css"
1098
1108
  ]
1099
1109
  },
1110
+ "TranslatableInput": {
1111
+ "layers": [
1112
+ "control.css",
1113
+ "toggle.css",
1114
+ "dialog-layout.css",
1115
+ "data-entry-layout.css",
1116
+ "navigation-layout.css"
1117
+ ]
1118
+ },
1119
+ "TranslatableTextarea": {
1120
+ "layers": [
1121
+ "control.css",
1122
+ "toggle.css",
1123
+ "dialog-layout.css",
1124
+ "data-entry-layout.css",
1125
+ "navigation-layout.css"
1126
+ ]
1127
+ },
1100
1128
  "Tree": {
1101
1129
  "layers": [
1102
1130
  "layout.css",
@@ -431,6 +431,10 @@
431
431
  align-items: stretch;
432
432
  }
433
433
 
434
+ .ui-responsive-grid[data-align="center"] {
435
+ align-items: center;
436
+ }
437
+
434
438
  .ui-responsive-grid[data-gap="none"] {
435
439
  gap: 0;
436
440
  }
@@ -1580,6 +1584,43 @@
1580
1584
  color: hsl(var(--text-error));
1581
1585
  }
1582
1586
 
1587
+ .ui-search-form-body {
1588
+ display: flex;
1589
+ flex-direction: column;
1590
+ gap: var(--filter-bar-section-gap);
1591
+ }
1592
+
1593
+ .ui-search-form-more {
1594
+ min-inline-size: 0;
1595
+ }
1596
+
1597
+ .ui-search-form-actions {
1598
+ display: flex;
1599
+ flex-wrap: wrap;
1600
+ align-items: center;
1601
+ gap: var(--filter-bar-gap);
1602
+ }
1603
+
1604
+ .ui-search-form-submit {
1605
+ display: flex;
1606
+ flex-wrap: wrap;
1607
+ align-items: center;
1608
+ gap: var(--space-2);
1609
+ margin-inline-start: auto;
1610
+ }
1611
+
1612
+ .ui-search-form-meta {
1613
+ display: flex;
1614
+ flex-wrap: wrap;
1615
+ gap: var(--space-1) var(--space-3);
1616
+ font-size: var(--filter-label-font-size);
1617
+ color: hsl(var(--muted-foreground));
1618
+ }
1619
+
1620
+ .ui-search-form-summary-label {
1621
+ font-weight: var(--font-weight-medium);
1622
+ }
1623
+
1583
1624
  .ui-legal-document-scope {
1584
1625
  container: legal-document / inline-size;
1585
1626
  padding-inline: var(--legal-document-page-padding-inline, var(--space-page-x));