@contractspec/lib.design-system 4.1.0 → 4.2.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 (26) hide show
  1. package/README.md +22 -1
  2. package/dist/browser/components/atoms/Input.js +1 -1
  3. package/dist/browser/components/forms/controls/Autocomplete.js +1 -1
  4. package/dist/browser/components/forms/controls/Select.js +1 -1
  5. package/dist/browser/components/forms/controls/select-options.js +1 -0
  6. package/dist/browser/theme/tailwind-css.js +5 -5
  7. package/dist/components/atoms/Input.js +1 -1
  8. package/dist/components/forms/controls/Autocomplete.d.ts +9 -1
  9. package/dist/components/forms/controls/Autocomplete.js +1 -1
  10. package/dist/components/forms/controls/Autocomplete.native.d.ts +5 -1
  11. package/dist/components/forms/controls/Select.d.ts +7 -5
  12. package/dist/components/forms/controls/Select.js +1 -1
  13. package/dist/components/forms/controls/Select.native.d.ts +7 -5
  14. package/dist/components/forms/controls/index.d.ts +1 -1
  15. package/dist/components/forms/controls/select-options.d.ts +17 -0
  16. package/dist/components/forms/controls/select-options.js +1 -0
  17. package/dist/native/components/atoms/Input.js +1 -1
  18. package/dist/native/components/atoms/Input.native.js +1 -1
  19. package/dist/native/components/forms/controls/Autocomplete.js +1 -1
  20. package/dist/native/components/forms/controls/Autocomplete.native.js +1 -1
  21. package/dist/native/components/forms/controls/Select.js +1 -1
  22. package/dist/native/components/forms/controls/Select.native.js +1 -1
  23. package/dist/native/components/forms/controls/select-options.js +1 -0
  24. package/dist/native/theme/tailwind-css.js +5 -5
  25. package/dist/theme/tailwind-css.js +5 -5
  26. package/package.json +19 -7
package/README.md CHANGED
@@ -154,9 +154,25 @@ import {
154
154
  componentKey="Select"
155
155
  options={[{ labelI18n: "status.draft", value: "draft" }]}
156
156
  />
157
+ <Select
158
+ componentKey="Select"
159
+ groups={[
160
+ {
161
+ labelI18n: "status.lifecycle",
162
+ options: [{ labelI18n: "status.draft", value: "draft" }],
163
+ },
164
+ {
165
+ labelI18n: "status.release",
166
+ options: [{ labelI18n: "status.published", value: "published" }],
167
+ },
168
+ ]}
169
+ />
157
170
  </DesignSystemThemeProvider>;
158
171
  ```
159
172
 
173
+ When both `options` and `groups` are provided to `Select`, grouped options are
174
+ used and the flat `options` list is ignored.
175
+
160
176
  ### Use form controls from the design-system boundary
161
177
 
162
178
  The root barrel exposes themed and translation-aware controls for product
@@ -170,6 +186,11 @@ surfaces: `Button`, `Input`, `Textarea`, `Select`, `NativeSelect`,
170
186
  `FieldSeparator` wrappers so contract-driven forms can preserve accessible
171
187
  legend, description, invalid, and grouped-control structure.
172
188
 
189
+ The `Autocomplete` control renders through the shared combobox primitive on web
190
+ and keeps native rendering aligned for query, selected options, loading, error,
191
+ and empty states. FormSpec renderers pass resolver-backed async state through
192
+ these props without requiring product surfaces to know the underlying transport.
193
+
173
194
  ### Render forms on mobile through the shared renderer
174
195
 
175
196
  Use the focused shared renderer subpath when rendering `FormSpec` contracts in
@@ -285,7 +306,7 @@ hidden-column recovery without widening the primitive table API.
285
306
  ### Renderers and hooks
286
307
 
287
308
  - renderer exports from `./renderers`
288
- - form-contract renderer support, including readonly, password, autocomplete, address, phone, date, time, datetime, semantic FormSpec groups, grid layout hints, mobile-safe FormSpec column helper output, and text/textarea input groups
309
+ - form-contract renderer support, including readonly, email, password, autocomplete, address, phone, date, time, datetime, semantic FormSpec groups, grid layout hints, progressive FormSpec sections/steps, mobile-safe FormSpec column helper output, and text/textarea/email input groups
289
310
  - translation-aware rendering through `DesignSystemTranslationProvider` and `createTranslationResolver`
290
311
  - theme-aware form controls and stack primitives that consume ThemeSpec component variant props
291
312
  - hooks such as `useListUrlState`, including scoped list filters where locked constraints are excluded from user-editable URL state
@@ -1 +1 @@
1
- import{jsx as N}from"react/jsx-runtime";import{Input as j}from"@contractspec/lib.ui-kit-web/ui/input";import{mapKeyboardToWeb as B}from"../../lib/keyboard";import{useThemedTextField as C}from"../primitives/control";export function Input({value:A,defaultValue:D,onChange:E,onSubmit:O,onFocus:G,onBlur:H,placeholder:J,disabled:M,readOnly:P,maxLength:Q,name:R,className:S,keyboard:U,componentKey:X,themeVariant:Y,placeholderI18n:Z,ariaLabelI18n:$,...z}){const _=B(U),q=C({defaultComponentKey:"Input",componentKey:X,themeVariant:Y,className:S,style:z.style,placeholder:J,placeholderI18n:Z,ariaLabelI18n:$});return N(j,{...q.themed.props,...z,className:q.themed.className,style:q.themed.style,value:A,defaultValue:D,onChange:E,onFocus:G,onBlur:H,placeholder:q.placeholder,"aria-label":q.ariaLabel,disabled:M,readOnly:P,maxLength:Q,name:R,..._})}
1
+ import{jsx as N}from"react/jsx-runtime";import{Input as j}from"@contractspec/lib.ui-kit-web/ui/input";import{mapKeyboardToWeb as B}from"../../lib/keyboard";import{useThemedTextField as C}from"../primitives/control";export function Input({value:D,defaultValue:E,onChange:G,onSubmit:O,onFocus:H,onBlur:J,placeholder:M,disabled:P,readOnly:Q,maxLength:R,name:S,className:U,keyboard:z,componentKey:X,themeVariant:Y,placeholderI18n:Z,ariaLabelI18n:$,...A}){const _=z?B(z):{},q=C({defaultComponentKey:"Input",componentKey:X,themeVariant:Y,className:U,style:A.style,placeholder:M,placeholderI18n:Z,ariaLabelI18n:$});return N(j,{...q.themed.props,..._,...A,className:q.themed.className,style:q.themed.style,value:D,defaultValue:E,onChange:G,onFocus:H,onBlur:J,placeholder:q.placeholder,"aria-label":q.ariaLabel,disabled:P,readOnly:Q,maxLength:R,name:S})}
@@ -1 +1 @@
1
- import{jsx as A,jsxs as J}from"react/jsx-runtime";import{Command as k,CommandEmpty as S,CommandGroup as b,CommandInput as f,CommandItem as C,CommandList as T}from"@contractspec/lib.ui-kit-web/ui/command";import{Text as Y}from"@contractspec/lib.ui-kit-web/ui/text";import{Button as V}from"../../atoms/Button";import{HStack as w,VStack as Z}from"../../layout/Stack";import{useThemedPrimitive as v,useTranslatedText as _}from"../../primitives/themed";function M(F){return typeof F==="string"?F:String(F??"")}export function Autocomplete({query:F,options:$,selectedOptions:U,onQueryChange:E,onSelectOption:G,onRemoveOption:H,multiple:L,placeholder:P,placeholderI18n:g,readOnly:W,disabled:X,className:q,componentKey:B,themeVariant:K,emptyText:N="No results found."}){const D=_(),Q=v({defaultComponentKey:"Autocomplete",componentKey:B,themeVariant:K,className:q});return J(Z,{gap:"sm",className:Q.className,children:[J(k,{shouldFilter:!1,className:"rounded-md border border-input",children:[A(f,{value:F,onValueChange:E,placeholder:D(g??P),disabled:X||W}),J(T,{children:[A(S,{children:D(N)}),A(b,{children:$.map((z)=>{const R=U.some((I)=>M(I.value)===M(z.value));return J(C,{value:D(z.labelI18n)??z.labelI18n,onSelect:()=>G?.(z),disabled:X||z.disabled||W,children:[J(Z,{gap:"xs",children:[A(Y,{children:D(z.labelI18n)}),z.descriptionI18n?A(Y,{className:"text-muted-foreground text-xs",children:D(z.descriptionI18n)}):null]}),R?A(Y,{className:"ml-auto text-muted-foreground text-xs",children:D("Selected")}):null]},M(z.value))})})]})]}),U.length?A(w,{gap:"sm",wrap:"wrap",children:U.map((z)=>A(V,{type:"button",variant:"outline",size:"sm",onClick:()=>H?.(z),disabled:!L||W||X,children:D(z.labelI18n)},`selected-${M(z.value)}`))}):null]})}
1
+ import{jsx as v}from"react/jsx-runtime";import{Combobox as I}from"@contractspec/lib.ui-kit-web/ui/combobox";import{useThemedPrimitive as T,useTranslatedText as b}from"../../primitives/themed";function H(E){return typeof E==="string"?E:String(E??"")}function g(E,U){const F=new Set,J=[];for(const L of[...U,...E]){const M=H(L.value);if(F.has(M))continue;F.add(M);J.push(L)}return J}export function Autocomplete({query:E,options:U,selectedOptions:F,onQueryChange:J,onSelectOption:L,onRemoveOption:M,multiple:W,placeholder:X,placeholderI18n:Y,readOnly:_,disabled:j,className:q,componentKey:w,themeVariant:D,emptyText:K="No results found.",loadingText:N="Loading options...",errorText:Q="Unable to load options.",loading:R,error:Z,id:S,name:k,"aria-invalid":C,"aria-describedby":B}){const A=b(),$=T({defaultComponentKey:"Autocomplete",componentKey:w,themeVariant:D,className:q}),f=g(U,F),P=new Map(f.map((z)=>[H(z.value),z]));return v(I,{...$.props,id:S,name:k,className:$.className,options:f.map((z)=>({value:H(z.value),label:A(z.labelI18n)??z.labelI18n,description:z.descriptionI18n?A(z.descriptionI18n)??z.descriptionI18n:void 0,disabled:z.disabled})),value:W?void 0:H(F[0]?.value??""),selectedValues:W?F.map((z)=>H(z.value)):void 0,query:E,onQueryChange:J,onValueChange:(z)=>{const G=P.get(z);if(G)L?.(G)},onRemoveValue:(z)=>{const G=P.get(z);if(G)M?.(G)},multiple:W,placeholder:A(Y??X),searchPlaceholder:A(Y??X),emptyText:A(K),loadingText:A(N),errorText:A(Q),loading:R,error:Z?A(Z):null,readOnly:_,disabled:j,"aria-invalid":C,"aria-describedby":B})}
@@ -1 +1 @@
1
- import{jsx as A,jsxs as k}from"react/jsx-runtime";import{SelectContent,SelectGroup,SelectItem,SelectTrigger,SelectValue,Select as Y}from"@contractspec/lib.ui-kit-web/ui/select";import{useThemedPrimitive as Z,useTranslatedText as $}from"../../primitives/themed";function B(z){return typeof z==="string"?z:String(z??"")}export function Select({options:z,value:D,onChange:F,placeholder:H,disabled:J,className:L,componentKey:M,themeVariant:O,placeholderI18n:Q,...R}){const E=$(),U=Z({defaultComponentKey:"Select",componentKey:M,themeVariant:O,className:L});return k(Y,{value:D==null?"":B(D),onValueChange:(q)=>F?.(q),disabled:J,...R,children:[A(SelectTrigger,{className:U.className,children:A(SelectValue,{placeholder:E(Q??H)})}),A(SelectContent,{children:A(SelectGroup,{children:z?.map((q,X)=>A(SelectItem,{value:B(q.value),disabled:q.disabled,children:E(q.labelI18n)??B(q.labelI18n)},`${B(q.value)}-${X}`))})})]})}export{SelectContent,SelectGroup,SelectItem,SelectTrigger,SelectValue};
1
+ import{jsx as z,jsxs as M}from"react/jsx-runtime";import{SelectContent,SelectGroup,SelectItem,SelectLabel,SelectTrigger,SelectValue,Select as K}from"@contractspec/lib.ui-kit-web/ui/select";import{useThemedPrimitive as O,useTranslatedText as T}from"../../primitives/themed";import{selectGroupKey as v,selectGroupLabel as w,selectOptionGroups as G,selectOptionLabel as L,selectOptionValue as D}from"./select-options";export function Select({options:Q,groups:R,value:E,onChange:U,placeholder:X,disabled:Y,className:Z,componentKey:$,themeVariant:k,placeholderI18n:P,...W}){const B=T(),N=O({defaultComponentKey:"Select",componentKey:$,themeVariant:k,className:Z}),C=G({options:Q,groups:R});return M(K,{value:E==null?"":D(E),onValueChange:(q)=>U?.(q),disabled:Y,...W,children:[z(SelectTrigger,{className:N.className,children:z(SelectValue,{placeholder:B(P??X)})}),z(SelectContent,{children:C.map((q,F)=>{const H=v(q,F),J=w(q,B);return M(SelectGroup,{children:[J?z(SelectLabel,{children:J}):null,q.options.map((A,f)=>z(SelectItem,{value:D(A.value),disabled:A.disabled,children:L(A,B)},`${H}-${D(A.value)}-${f}`))]},`${H}-${F}`)})})]})}export{SelectContent,SelectGroup,SelectItem,SelectLabel,SelectTrigger,SelectValue};
@@ -0,0 +1 @@
1
+ export function selectOptionValue(e){return typeof e==="string"?e:String(e??"")}export function selectOptionLabel(e,t){return t(e.labelI18n)??selectOptionValue(e.labelI18n)}export function selectGroupLabel(e,t){return t(e.labelI18n??e.label)}export function selectGroupKey(e,t){return e.key??e.labelI18n??e.label??`group-${t}`}export function selectOptionGroups({options:e,groups:t}){return t?.length?t:[{options:e??[]}]}
@@ -1,9 +1,9 @@
1
- const a=["light","dark"];function n(e,s){const r=Object.entries(s).sort(([t],[i])=>t.localeCompare(i)).map(([t,i])=>` ${t}: ${i};`).join(`
1
+ const o=["light","dark"],l={background:["card","popover"],foreground:["card-foreground","popover-foreground"],border:["input"]};function n(e,s){const t=Object.entries(s).sort(([r],[i])=>r.localeCompare(i)).map(([r,i])=>` ${r}: ${i};`).join(`
2
2
  `);return`${e} {
3
- ${r}
4
- }`}function l(e){return Object.assign({},...Object.values(e.modes))}function d(e){if(e.startsWith("--ds-color-"))return`--color-${e.slice(11)}`;if(e.startsWith("--ds-radius-"))return`--radius-${e.slice(12)}`;if(e.startsWith("--ds-space-"))return`--spacing-${e.slice(11)}`;if(e.startsWith("--ds-typography-"))return`--text-${e.slice(16)}`;return}function o(e){return`@theme inline {
5
- ${Object.keys(l(e)).sort().flatMap((r)=>{const t=d(r);return t?[` ${t}: var(${r});`]:[]}).join(`
3
+ ${t}
4
+ }`}function c(e){return Object.assign({},...Object.values(e.modes))}function d(e){if(e.startsWith("--ds-color-"))return`--color-${e.slice(11)}`;if(e.startsWith("--ds-radius-"))return`--radius-${e.slice(12)}`;if(e.startsWith("--ds-space-"))return`--spacing-${e.slice(11)}`;if(e.startsWith("--ds-typography-"))return`--text-${e.slice(16)}`;return}function u(e){if(!e.startsWith("--ds-color-"))return[];const s=e.slice(11);return(l[s]??[]).map((r)=>`--color-${r}`)}function h(e){return`@theme inline {
5
+ ${Object.keys(c(e)).sort().flatMap((t)=>{const r=d(t),i=u(t);return[...r?[` ${r}: var(${t});`]:[],...i.map((a)=>` ${a}: var(${t});`)]}).join(`
6
6
  `)}
7
- }`}export function themeSpecToTailwindCss(e,s={}){return[s.includeCustomVariant?"@custom-variant dark (&:where(.dark, .dark *));":void 0,n(s.rootSelector??":root",e.light),n(s.darkSelector??".dark",e.dark),...Object.entries(e.modes).filter(([t])=>!a.includes(t)).map(([t,i])=>n(`[data-theme="${t}"]`,i)),s.includeTheme===!1?void 0:o(e)].filter(Boolean).join(`
7
+ }`}export function themeSpecToTailwindCss(e,s={}){return[s.includeCustomVariant?"@custom-variant dark (&:where(.dark, .dark *));":void 0,n(s.rootSelector??":root",e.light),n(s.darkSelector??".dark",e.dark),...Object.entries(e.modes).filter(([r])=>!o.includes(r)).map(([r,i])=>n(`[data-theme="${r}"]`,i)),s.includeTheme===!1?void 0:h(e)].filter(Boolean).join(`
8
8
 
9
9
  `)}
@@ -1 +1 @@
1
- import{jsx as N}from"react/jsx-runtime";import{Input as j}from"@contractspec/lib.ui-kit-web/ui/input";import{mapKeyboardToWeb as B}from"../../lib/keyboard";import{useThemedTextField as C}from"../primitives/control";export function Input({value:A,defaultValue:D,onChange:E,onSubmit:O,onFocus:G,onBlur:H,placeholder:J,disabled:M,readOnly:P,maxLength:Q,name:R,className:S,keyboard:U,componentKey:X,themeVariant:Y,placeholderI18n:Z,ariaLabelI18n:$,...z}){const _=B(U),q=C({defaultComponentKey:"Input",componentKey:X,themeVariant:Y,className:S,style:z.style,placeholder:J,placeholderI18n:Z,ariaLabelI18n:$});return N(j,{...q.themed.props,...z,className:q.themed.className,style:q.themed.style,value:A,defaultValue:D,onChange:E,onFocus:G,onBlur:H,placeholder:q.placeholder,"aria-label":q.ariaLabel,disabled:M,readOnly:P,maxLength:Q,name:R,..._})}
1
+ import{jsx as N}from"react/jsx-runtime";import{Input as j}from"@contractspec/lib.ui-kit-web/ui/input";import{mapKeyboardToWeb as B}from"../../lib/keyboard";import{useThemedTextField as C}from"../primitives/control";export function Input({value:D,defaultValue:E,onChange:G,onSubmit:O,onFocus:H,onBlur:J,placeholder:M,disabled:P,readOnly:Q,maxLength:R,name:S,className:U,keyboard:z,componentKey:X,themeVariant:Y,placeholderI18n:Z,ariaLabelI18n:$,...A}){const _=z?B(z):{},q=C({defaultComponentKey:"Input",componentKey:X,themeVariant:Y,className:U,style:A.style,placeholder:M,placeholderI18n:Z,ariaLabelI18n:$});return N(j,{...q.themed.props,..._,...A,className:q.themed.className,style:q.themed.style,value:D,defaultValue:E,onChange:G,onFocus:H,onBlur:J,placeholder:q.placeholder,"aria-label":q.ariaLabel,disabled:P,readOnly:Q,maxLength:R,name:S})}
@@ -13,5 +13,13 @@ export interface AutocompleteProps extends ThemedPrimitiveProps {
13
13
  disabled?: boolean;
14
14
  className?: string;
15
15
  emptyText?: string;
16
+ loadingText?: string;
17
+ errorText?: string;
18
+ loading?: boolean;
19
+ error?: string | null;
20
+ id?: string;
21
+ name?: string;
22
+ 'aria-invalid'?: boolean;
23
+ 'aria-describedby'?: string;
16
24
  }
17
- export declare function Autocomplete({ query, options, selectedOptions, onQueryChange, onSelectOption, onRemoveOption, multiple, placeholder, placeholderI18n, readOnly, disabled, className, componentKey, themeVariant, emptyText, }: AutocompleteProps): import("react/jsx-runtime").JSX.Element;
25
+ export declare function Autocomplete({ query, options, selectedOptions, onQueryChange, onSelectOption, onRemoveOption, multiple, placeholder, placeholderI18n, readOnly, disabled, className, componentKey, themeVariant, emptyText, loadingText, errorText, loading, error, id, name, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, }: AutocompleteProps): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- import{jsx as A,jsxs as J}from"react/jsx-runtime";import{Command as k,CommandEmpty as S,CommandGroup as b,CommandInput as f,CommandItem as C,CommandList as T}from"@contractspec/lib.ui-kit-web/ui/command";import{Text as Y}from"@contractspec/lib.ui-kit-web/ui/text";import{Button as V}from"../../atoms/Button";import{HStack as w,VStack as Z}from"../../layout/Stack";import{useThemedPrimitive as v,useTranslatedText as _}from"../../primitives/themed";function M(F){return typeof F==="string"?F:String(F??"")}export function Autocomplete({query:F,options:$,selectedOptions:U,onQueryChange:E,onSelectOption:G,onRemoveOption:H,multiple:L,placeholder:P,placeholderI18n:g,readOnly:W,disabled:X,className:q,componentKey:B,themeVariant:K,emptyText:N="No results found."}){const D=_(),Q=v({defaultComponentKey:"Autocomplete",componentKey:B,themeVariant:K,className:q});return J(Z,{gap:"sm",className:Q.className,children:[J(k,{shouldFilter:!1,className:"rounded-md border border-input",children:[A(f,{value:F,onValueChange:E,placeholder:D(g??P),disabled:X||W}),J(T,{children:[A(S,{children:D(N)}),A(b,{children:$.map((z)=>{const R=U.some((I)=>M(I.value)===M(z.value));return J(C,{value:D(z.labelI18n)??z.labelI18n,onSelect:()=>G?.(z),disabled:X||z.disabled||W,children:[J(Z,{gap:"xs",children:[A(Y,{children:D(z.labelI18n)}),z.descriptionI18n?A(Y,{className:"text-muted-foreground text-xs",children:D(z.descriptionI18n)}):null]}),R?A(Y,{className:"ml-auto text-muted-foreground text-xs",children:D("Selected")}):null]},M(z.value))})})]})]}),U.length?A(w,{gap:"sm",wrap:"wrap",children:U.map((z)=>A(V,{type:"button",variant:"outline",size:"sm",onClick:()=>H?.(z),disabled:!L||W||X,children:D(z.labelI18n)},`selected-${M(z.value)}`))}):null]})}
1
+ import{jsx as v}from"react/jsx-runtime";import{Combobox as I}from"@contractspec/lib.ui-kit-web/ui/combobox";import{useThemedPrimitive as T,useTranslatedText as b}from"../../primitives/themed";function H(E){return typeof E==="string"?E:String(E??"")}function g(E,U){const F=new Set,J=[];for(const L of[...U,...E]){const M=H(L.value);if(F.has(M))continue;F.add(M);J.push(L)}return J}export function Autocomplete({query:E,options:U,selectedOptions:F,onQueryChange:J,onSelectOption:L,onRemoveOption:M,multiple:W,placeholder:X,placeholderI18n:Y,readOnly:_,disabled:j,className:q,componentKey:w,themeVariant:D,emptyText:K="No results found.",loadingText:N="Loading options...",errorText:Q="Unable to load options.",loading:R,error:Z,id:S,name:k,"aria-invalid":C,"aria-describedby":B}){const A=b(),$=T({defaultComponentKey:"Autocomplete",componentKey:w,themeVariant:D,className:q}),f=g(U,F),P=new Map(f.map((z)=>[H(z.value),z]));return v(I,{...$.props,id:S,name:k,className:$.className,options:f.map((z)=>({value:H(z.value),label:A(z.labelI18n)??z.labelI18n,description:z.descriptionI18n?A(z.descriptionI18n)??z.descriptionI18n:void 0,disabled:z.disabled})),value:W?void 0:H(F[0]?.value??""),selectedValues:W?F.map((z)=>H(z.value)):void 0,query:E,onQueryChange:J,onValueChange:(z)=>{const G=P.get(z);if(G)L?.(G)},onRemoveValue:(z)=>{const G=P.get(z);if(G)M?.(G)},multiple:W,placeholder:A(Y??X),searchPlaceholder:A(Y??X),emptyText:A(K),loadingText:A(N),errorText:A(Q),loading:R,error:Z?A(Z):null,readOnly:_,disabled:j,"aria-invalid":C,"aria-describedby":B})}
@@ -13,5 +13,9 @@ export interface AutocompleteProps extends ThemedPrimitiveProps {
13
13
  disabled?: boolean;
14
14
  className?: string;
15
15
  emptyText?: string;
16
+ loadingText?: string;
17
+ errorText?: string;
18
+ loading?: boolean;
19
+ error?: string | null;
16
20
  }
17
- export declare function Autocomplete({ query, options, selectedOptions, onQueryChange, onSelectOption, onRemoveOption, multiple, placeholder, placeholderI18n, readOnly, disabled, className, componentKey, themeVariant, emptyText, }: AutocompleteProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function Autocomplete({ query, options, selectedOptions, onQueryChange, onSelectOption, onRemoveOption, multiple, placeholder, placeholderI18n, readOnly, disabled, className, componentKey, themeVariant, emptyText, loadingText, errorText, loading, error, }: AutocompleteProps): import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,9 @@
1
- import type { FormOption } from '@contractspec/lib.contracts-spec/forms';
2
- import { SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@contractspec/lib.ui-kit-web/ui/select';
1
+ import { SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@contractspec/lib.ui-kit-web/ui/select';
3
2
  import { type ThemedPrimitiveProps } from '../../primitives/themed';
3
+ import { type FormOption, type SelectOptionGroup } from './select-options';
4
4
  export interface SelectProps extends ThemedPrimitiveProps {
5
- options?: FormOption[];
5
+ options?: readonly FormOption[];
6
+ groups?: readonly SelectOptionGroup[];
6
7
  value?: unknown;
7
8
  onChange?: (value: unknown) => void;
8
9
  placeholder?: string;
@@ -11,5 +12,6 @@ export interface SelectProps extends ThemedPrimitiveProps {
11
12
  name?: string;
12
13
  className?: string;
13
14
  }
14
- export declare function Select({ options, value, onChange, placeholder, disabled, className, componentKey, themeVariant, placeholderI18n, ...props }: SelectProps): import("react/jsx-runtime").JSX.Element;
15
- export { SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue };
15
+ export declare function Select({ options, groups, value, onChange, placeholder, disabled, className, componentKey, themeVariant, placeholderI18n, ...props }: SelectProps): import("react/jsx-runtime").JSX.Element;
16
+ export type { SelectOptionGroup };
17
+ export { SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, };
@@ -1 +1 @@
1
- import{jsx as A,jsxs as k}from"react/jsx-runtime";import{SelectContent,SelectGroup,SelectItem,SelectTrigger,SelectValue,Select as Y}from"@contractspec/lib.ui-kit-web/ui/select";import{useThemedPrimitive as Z,useTranslatedText as $}from"../../primitives/themed";function B(z){return typeof z==="string"?z:String(z??"")}export function Select({options:z,value:D,onChange:F,placeholder:H,disabled:J,className:L,componentKey:M,themeVariant:O,placeholderI18n:Q,...R}){const E=$(),U=Z({defaultComponentKey:"Select",componentKey:M,themeVariant:O,className:L});return k(Y,{value:D==null?"":B(D),onValueChange:(q)=>F?.(q),disabled:J,...R,children:[A(SelectTrigger,{className:U.className,children:A(SelectValue,{placeholder:E(Q??H)})}),A(SelectContent,{children:A(SelectGroup,{children:z?.map((q,X)=>A(SelectItem,{value:B(q.value),disabled:q.disabled,children:E(q.labelI18n)??B(q.labelI18n)},`${B(q.value)}-${X}`))})})]})}export{SelectContent,SelectGroup,SelectItem,SelectTrigger,SelectValue};
1
+ import{jsx as z,jsxs as M}from"react/jsx-runtime";import{SelectContent,SelectGroup,SelectItem,SelectLabel,SelectTrigger,SelectValue,Select as K}from"@contractspec/lib.ui-kit-web/ui/select";import{useThemedPrimitive as O,useTranslatedText as T}from"../../primitives/themed";import{selectGroupKey as v,selectGroupLabel as w,selectOptionGroups as G,selectOptionLabel as L,selectOptionValue as D}from"./select-options";export function Select({options:Q,groups:R,value:E,onChange:U,placeholder:X,disabled:Y,className:Z,componentKey:$,themeVariant:k,placeholderI18n:P,...W}){const B=T(),N=O({defaultComponentKey:"Select",componentKey:$,themeVariant:k,className:Z}),C=G({options:Q,groups:R});return M(K,{value:E==null?"":D(E),onValueChange:(q)=>U?.(q),disabled:Y,...W,children:[z(SelectTrigger,{className:N.className,children:z(SelectValue,{placeholder:B(P??X)})}),z(SelectContent,{children:C.map((q,F)=>{const H=v(q,F),J=w(q,B);return M(SelectGroup,{children:[J?z(SelectLabel,{children:J}):null,q.options.map((A,f)=>z(SelectItem,{value:D(A.value),disabled:A.disabled,children:L(A,B)},`${H}-${D(A.value)}-${f}`))]},`${H}-${F}`)})})]})}export{SelectContent,SelectGroup,SelectItem,SelectLabel,SelectTrigger,SelectValue};
@@ -1,13 +1,15 @@
1
- import type { FormOption } from '@contractspec/lib.contracts-spec/forms';
2
- import { SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@contractspec/lib.ui-kit/ui/select';
1
+ import { SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@contractspec/lib.ui-kit/ui/select';
3
2
  import { type ThemedPrimitiveProps } from '../../primitives/themed';
3
+ import { type FormOption, type SelectOptionGroup } from './select-options';
4
4
  export interface SelectProps extends ThemedPrimitiveProps {
5
- options?: FormOption[];
5
+ options?: readonly FormOption[];
6
+ groups?: readonly SelectOptionGroup[];
6
7
  value?: unknown;
7
8
  onChange?: (value: unknown) => void;
8
9
  placeholder?: string;
9
10
  disabled?: boolean;
10
11
  className?: string;
11
12
  }
12
- export declare function Select({ options, value, onChange, placeholder, disabled, className, componentKey, themeVariant, placeholderI18n, }: SelectProps): import("react/jsx-runtime").JSX.Element;
13
- export { SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue };
13
+ export declare function Select({ options, groups, value, onChange, placeholder, disabled, className, componentKey, themeVariant, placeholderI18n, }: SelectProps): import("react/jsx-runtime").JSX.Element;
14
+ export type { SelectOptionGroup };
15
+ export { SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, };
@@ -9,4 +9,4 @@ export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGr
9
9
  export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, } from './InputOTP';
10
10
  export { LoadingButton, type LoadingButtonProps } from './LoadingButton';
11
11
  export { NativeSelect, NativeSelectOptGroup, NativeSelectOption, type NativeSelectProps, } from './NativeSelect';
12
- export { Select, type SelectProps } from './Select';
12
+ export { Select, type SelectOptionGroup, type SelectProps } from './Select';
@@ -0,0 +1,17 @@
1
+ import type { FormOption } from '@contractspec/lib.contracts-spec/forms';
2
+ export type { FormOption };
3
+ export interface SelectOptionGroup {
4
+ key?: string;
5
+ label?: string;
6
+ labelI18n?: string;
7
+ options: readonly FormOption[];
8
+ }
9
+ export type SelectTextTranslator = (value: string | undefined) => string | undefined;
10
+ export declare function selectOptionValue(value: unknown): string;
11
+ export declare function selectOptionLabel(option: FormOption, translate: SelectTextTranslator): string;
12
+ export declare function selectGroupLabel(group: SelectOptionGroup, translate: SelectTextTranslator): string | undefined;
13
+ export declare function selectGroupKey(group: SelectOptionGroup, index: number): string;
14
+ export declare function selectOptionGroups({ options, groups, }: {
15
+ options?: readonly FormOption[];
16
+ groups?: readonly SelectOptionGroup[];
17
+ }): readonly SelectOptionGroup[];
@@ -0,0 +1 @@
1
+ export function selectOptionValue(e){return typeof e==="string"?e:String(e??"")}export function selectOptionLabel(e,t){return t(e.labelI18n)??selectOptionValue(e.labelI18n)}export function selectGroupLabel(e,t){return t(e.labelI18n??e.label)}export function selectGroupKey(e,t){return e.key??e.labelI18n??e.label??`group-${t}`}export function selectOptionGroups({options:e,groups:t}){return t?.length?t:[{options:e??[]}]}
@@ -1 +1 @@
1
- import{jsx as N}from"react/jsx-runtime";import{Input as j}from"@contractspec/lib.ui-kit-web/ui/input";import{mapKeyboardToWeb as B}from"../../lib/keyboard";import{useThemedTextField as C}from"../primitives/control";export function Input({value:A,defaultValue:D,onChange:E,onSubmit:O,onFocus:G,onBlur:H,placeholder:J,disabled:M,readOnly:P,maxLength:Q,name:R,className:S,keyboard:U,componentKey:X,themeVariant:Y,placeholderI18n:Z,ariaLabelI18n:$,...z}){const _=B(U),q=C({defaultComponentKey:"Input",componentKey:X,themeVariant:Y,className:S,style:z.style,placeholder:J,placeholderI18n:Z,ariaLabelI18n:$});return N(j,{...q.themed.props,...z,className:q.themed.className,style:q.themed.style,value:A,defaultValue:D,onChange:E,onFocus:G,onBlur:H,placeholder:q.placeholder,"aria-label":q.ariaLabel,disabled:M,readOnly:P,maxLength:Q,name:R,..._})}
1
+ import{jsx as N}from"react/jsx-runtime";import{Input as j}from"@contractspec/lib.ui-kit-web/ui/input";import{mapKeyboardToWeb as B}from"../../lib/keyboard";import{useThemedTextField as C}from"../primitives/control";export function Input({value:D,defaultValue:E,onChange:G,onSubmit:O,onFocus:H,onBlur:J,placeholder:M,disabled:P,readOnly:Q,maxLength:R,name:S,className:U,keyboard:z,componentKey:X,themeVariant:Y,placeholderI18n:Z,ariaLabelI18n:$,...A}){const _=z?B(z):{},q=C({defaultComponentKey:"Input",componentKey:X,themeVariant:Y,className:U,style:A.style,placeholder:M,placeholderI18n:Z,ariaLabelI18n:$});return N(j,{...q.themed.props,..._,...A,className:q.themed.className,style:q.themed.style,value:D,defaultValue:E,onChange:G,onFocus:H,onBlur:J,placeholder:q.placeholder,"aria-label":q.ariaLabel,disabled:P,readOnly:Q,maxLength:R,name:S})}
@@ -1 +1 @@
1
- import{jsx as C}from"react/jsx-runtime";import{Input as _}from"@contractspec/lib.ui-kit/ui/input";import{mapKeyboardToNative as j}from"../../lib/keyboard";import{useThemedTextField as B}from"../primitives/control";export function Input({value:z,defaultValue:A,onChange:D,onSubmit:E,onFocus:G,onBlur:H,placeholder:J,disabled:M,readOnly:P,maxLength:Q,className:R,keyboard:U,componentKey:W,themeVariant:X,placeholderI18n:Y,ariaLabelI18n:Z,...$}){const w=j(U),q=B({defaultComponentKey:"Input",componentKey:W,themeVariant:X,className:R,placeholder:J,placeholderI18n:Y,ariaLabelI18n:Z});return C(_,{...q.themed.props,...$,className:q.themed.className,value:z,defaultValue:A,onChangeText:D,onSubmitEditing:E,onFocus:G,onBlur:H,placeholder:q.placeholder,accessibilityLabel:q.ariaLabel,editable:!M&&!P,maxLength:Q,...w})}export default Input;
1
+ import{jsx as C}from"react/jsx-runtime";import{Input as _}from"@contractspec/lib.ui-kit/ui/input";import{mapKeyboardToNative as j}from"../../lib/keyboard";import{useThemedTextField as B}from"../primitives/control";export function Input({value:A,defaultValue:D,onChange:E,onSubmit:G,onFocus:H,onBlur:J,placeholder:M,disabled:P,readOnly:Q,maxLength:R,className:U,keyboard:z,componentKey:W,themeVariant:X,placeholderI18n:Y,ariaLabelI18n:Z,...$}){const w=z?j(z):{},q=B({defaultComponentKey:"Input",componentKey:W,themeVariant:X,className:U,placeholder:M,placeholderI18n:Y,ariaLabelI18n:Z});return C(_,{...q.themed.props,...$,className:q.themed.className,value:A,defaultValue:D,onChangeText:E,onSubmitEditing:G,onFocus:H,onBlur:J,placeholder:q.placeholder,accessibilityLabel:q.ariaLabel,editable:!P&&!Q,maxLength:R,...w})}export default Input;
@@ -1 +1 @@
1
- import{jsx as A,jsxs as J}from"react/jsx-runtime";import{Command as k,CommandEmpty as S,CommandGroup as b,CommandInput as f,CommandItem as C,CommandList as T}from"@contractspec/lib.ui-kit-web/ui/command";import{Text as Y}from"@contractspec/lib.ui-kit-web/ui/text";import{Button as V}from"../../atoms/Button";import{HStack as w,VStack as Z}from"../../layout/Stack";import{useThemedPrimitive as v,useTranslatedText as _}from"../../primitives/themed";function M(F){return typeof F==="string"?F:String(F??"")}export function Autocomplete({query:F,options:$,selectedOptions:U,onQueryChange:E,onSelectOption:G,onRemoveOption:H,multiple:L,placeholder:P,placeholderI18n:g,readOnly:W,disabled:X,className:q,componentKey:B,themeVariant:K,emptyText:N="No results found."}){const D=_(),Q=v({defaultComponentKey:"Autocomplete",componentKey:B,themeVariant:K,className:q});return J(Z,{gap:"sm",className:Q.className,children:[J(k,{shouldFilter:!1,className:"rounded-md border border-input",children:[A(f,{value:F,onValueChange:E,placeholder:D(g??P),disabled:X||W}),J(T,{children:[A(S,{children:D(N)}),A(b,{children:$.map((z)=>{const R=U.some((I)=>M(I.value)===M(z.value));return J(C,{value:D(z.labelI18n)??z.labelI18n,onSelect:()=>G?.(z),disabled:X||z.disabled||W,children:[J(Z,{gap:"xs",children:[A(Y,{children:D(z.labelI18n)}),z.descriptionI18n?A(Y,{className:"text-muted-foreground text-xs",children:D(z.descriptionI18n)}):null]}),R?A(Y,{className:"ml-auto text-muted-foreground text-xs",children:D("Selected")}):null]},M(z.value))})})]})]}),U.length?A(w,{gap:"sm",wrap:"wrap",children:U.map((z)=>A(V,{type:"button",variant:"outline",size:"sm",onClick:()=>H?.(z),disabled:!L||W||X,children:D(z.labelI18n)},`selected-${M(z.value)}`))}):null]})}
1
+ import{jsx as v}from"react/jsx-runtime";import{Combobox as I}from"@contractspec/lib.ui-kit-web/ui/combobox";import{useThemedPrimitive as T,useTranslatedText as b}from"../../primitives/themed";function H(E){return typeof E==="string"?E:String(E??"")}function g(E,U){const F=new Set,J=[];for(const L of[...U,...E]){const M=H(L.value);if(F.has(M))continue;F.add(M);J.push(L)}return J}export function Autocomplete({query:E,options:U,selectedOptions:F,onQueryChange:J,onSelectOption:L,onRemoveOption:M,multiple:W,placeholder:X,placeholderI18n:Y,readOnly:_,disabled:j,className:q,componentKey:w,themeVariant:D,emptyText:K="No results found.",loadingText:N="Loading options...",errorText:Q="Unable to load options.",loading:R,error:Z,id:S,name:k,"aria-invalid":C,"aria-describedby":B}){const A=b(),$=T({defaultComponentKey:"Autocomplete",componentKey:w,themeVariant:D,className:q}),f=g(U,F),P=new Map(f.map((z)=>[H(z.value),z]));return v(I,{...$.props,id:S,name:k,className:$.className,options:f.map((z)=>({value:H(z.value),label:A(z.labelI18n)??z.labelI18n,description:z.descriptionI18n?A(z.descriptionI18n)??z.descriptionI18n:void 0,disabled:z.disabled})),value:W?void 0:H(F[0]?.value??""),selectedValues:W?F.map((z)=>H(z.value)):void 0,query:E,onQueryChange:J,onValueChange:(z)=>{const G=P.get(z);if(G)L?.(G)},onRemoveValue:(z)=>{const G=P.get(z);if(G)M?.(G)},multiple:W,placeholder:A(Y??X),searchPlaceholder:A(Y??X),emptyText:A(K),loadingText:A(N),errorText:A(Q),loading:R,error:Z?A(Z):null,readOnly:_,disabled:j,"aria-invalid":C,"aria-describedby":B})}
@@ -1 +1 @@
1
- import{jsx as A,jsxs as S}from"react/jsx-runtime";import{Text as J}from"@contractspec/lib.ui-kit/ui/text";import{Button as U}from"../../atoms/Button";import{Input as R}from"../../atoms/Input";import{HStack as B,VStack as W}from"../../layout/Stack";import{useThemedPrimitive as I,useTranslatedText as k}from"../../primitives/themed";function X(D){return typeof D==="string"?D:String(D??"")}export function Autocomplete({query:D,options:L,selectedOptions:M,onQueryChange:Y,onSelectOption:Z,onRemoveOption:$,multiple:H,placeholder:P,placeholderI18n:g,readOnly:F,disabled:G,className:q,componentKey:C,themeVariant:K,emptyText:N="No results found."}){const E=k(),Q=I({defaultComponentKey:"Autocomplete",componentKey:C,themeVariant:K,className:q});return S(W,{gap:"sm",className:Q.className,children:[A(R,{value:D,onChange:(z)=>{if(typeof z==="string")Y?.(z)},placeholder:E(g??P),disabled:G||F}),A(W,{gap:"xs",children:L.length?L.map((z)=>A(U,{variant:"ghost",onPress:()=>Z?.(z),disabled:G||z.disabled||F,children:A(J,{children:E(z.labelI18n)})},X(z.value))):A(J,{children:E(N)})}),M.length?A(B,{gap:"sm",wrap:"wrap",children:M.map((z)=>A(U,{variant:"outline",size:"sm",onPress:()=>$?.(z),disabled:!H||F||G,children:A(J,{children:E(z.labelI18n)})},`selected-${X(z.value)}`))}):null]})}
1
+ import{jsx as A,jsxs as w}from"react/jsx-runtime";import{Text as F}from"@contractspec/lib.ui-kit/ui/text";import{Button as W}from"../../atoms/Button";import{Input as S}from"../../atoms/Input";import{HStack as V,VStack as X}from"../../layout/Stack";import{useThemedPrimitive as b,useTranslatedText as f}from"../../primitives/themed";function Y(E){return typeof E==="string"?E:String(E??"")}export function Autocomplete({query:E,options:L,selectedOptions:M,onQueryChange:Z,onSelectOption:$,onRemoveOption:H,multiple:P,placeholder:q,placeholderI18n:C,readOnly:G,disabled:J,className:K,componentKey:N,themeVariant:Q,emptyText:R="No results found.",loadingText:B="Loading options...",errorText:I="Unable to load options.",loading:k,error:U}){const D=f(),g=b({defaultComponentKey:"Autocomplete",componentKey:N,themeVariant:Q,className:K});return w(X,{gap:"sm",className:g.className,children:[A(S,{value:E,onChange:(z)=>{if(typeof z==="string")Z?.(z)},placeholder:D(C??q),disabled:J||G}),A(X,{gap:"xs",children:k?A(F,{children:D(B)}):U?A(F,{children:D(U)??D(I)}):L.length?L.map((z)=>A(W,{variant:"ghost",onPress:()=>$?.(z),disabled:J||z.disabled||G,children:A(F,{children:D(z.labelI18n)})},Y(z.value))):A(F,{children:D(R)})}),M.length?A(V,{gap:"sm",wrap:"wrap",children:M.map((z)=>A(W,{variant:"outline",size:"sm",onPress:()=>H?.(z),disabled:!P||G||J,children:A(F,{children:D(z.labelI18n)})},`selected-${Y(z.value)}`))}):null]})}
@@ -1 +1 @@
1
- import{jsx as A,jsxs as k}from"react/jsx-runtime";import{SelectContent,SelectGroup,SelectItem,SelectTrigger,SelectValue,Select as Y}from"@contractspec/lib.ui-kit-web/ui/select";import{useThemedPrimitive as Z,useTranslatedText as $}from"../../primitives/themed";function B(z){return typeof z==="string"?z:String(z??"")}export function Select({options:z,value:D,onChange:F,placeholder:H,disabled:J,className:L,componentKey:M,themeVariant:O,placeholderI18n:Q,...R}){const E=$(),U=Z({defaultComponentKey:"Select",componentKey:M,themeVariant:O,className:L});return k(Y,{value:D==null?"":B(D),onValueChange:(q)=>F?.(q),disabled:J,...R,children:[A(SelectTrigger,{className:U.className,children:A(SelectValue,{placeholder:E(Q??H)})}),A(SelectContent,{children:A(SelectGroup,{children:z?.map((q,X)=>A(SelectItem,{value:B(q.value),disabled:q.disabled,children:E(q.labelI18n)??B(q.labelI18n)},`${B(q.value)}-${X}`))})})]})}export{SelectContent,SelectGroup,SelectItem,SelectTrigger,SelectValue};
1
+ import{jsx as z,jsxs as M}from"react/jsx-runtime";import{SelectContent,SelectGroup,SelectItem,SelectLabel,SelectTrigger,SelectValue,Select as K}from"@contractspec/lib.ui-kit-web/ui/select";import{useThemedPrimitive as O,useTranslatedText as T}from"../../primitives/themed";import{selectGroupKey as v,selectGroupLabel as w,selectOptionGroups as G,selectOptionLabel as L,selectOptionValue as D}from"./select-options";export function Select({options:Q,groups:R,value:E,onChange:U,placeholder:X,disabled:Y,className:Z,componentKey:$,themeVariant:k,placeholderI18n:P,...W}){const B=T(),N=O({defaultComponentKey:"Select",componentKey:$,themeVariant:k,className:Z}),C=G({options:Q,groups:R});return M(K,{value:E==null?"":D(E),onValueChange:(q)=>U?.(q),disabled:Y,...W,children:[z(SelectTrigger,{className:N.className,children:z(SelectValue,{placeholder:B(P??X)})}),z(SelectContent,{children:C.map((q,F)=>{const H=v(q,F),J=w(q,B);return M(SelectGroup,{children:[J?z(SelectLabel,{children:J}):null,q.options.map((A,f)=>z(SelectItem,{value:D(A.value),disabled:A.disabled,children:L(A,B)},`${H}-${D(A.value)}-${f}`))]},`${H}-${F}`)})})]})}export{SelectContent,SelectGroup,SelectItem,SelectLabel,SelectTrigger,SelectValue};
@@ -1 +1 @@
1
- import{jsx as B,jsxs as $}from"react/jsx-runtime";import{Select as X,SelectContent,SelectGroup,SelectItem,SelectTrigger,SelectValue}from"@contractspec/lib.ui-kit/ui/select";import{useThemedPrimitive as Y,useTranslatedText as Z}from"../../primitives/themed";function A(z){return typeof z==="string"?z:String(z??"")}export function Select({options:z,value:D,onChange:F,placeholder:H,disabled:J,className:L,componentKey:M,themeVariant:O,placeholderI18n:Q}){const E=Z(),U=Y({defaultComponentKey:"Select",componentKey:M,themeVariant:O,className:L});return $(X,{value:D==null?void 0:{value:A(D),label:A(D)},onValueChange:(q)=>F?.(q?.value),children:[B(SelectTrigger,{disabled:J,className:U.className,children:B(SelectValue,{placeholder:E(Q??H)??""})}),B(SelectContent,{children:B(SelectGroup,{children:z?.map((q,W)=>B(SelectItem,{value:A(q.value),label:E(q.labelI18n)??A(q.labelI18n),disabled:q.disabled},`${A(q.value)}-${W}`))})})]})}export{SelectContent,SelectGroup,SelectItem,SelectTrigger,SelectValue};
1
+ import{jsx as B,jsxs as X}from"react/jsx-runtime";import{Select as v,SelectContent,SelectGroup,SelectItem,SelectLabel,SelectTrigger,SelectValue}from"@contractspec/lib.ui-kit/ui/select";import{useThemedPrimitive as G,useTranslatedText as _}from"../../primitives/themed";import{selectGroupKey as L,selectGroupLabel as j,selectOptionGroups as y,selectOptionLabel as W,selectOptionValue as A}from"./select-options";export function Select({options:Y,groups:Z,value:H,onChange:$,placeholder:k,disabled:P,className:R,componentKey:N,themeVariant:C,placeholderI18n:f}){const D=_(),w=G({defaultComponentKey:"Select",componentKey:N,themeVariant:C,className:R}),J=y({options:Y,groups:Z}),z=H==null?void 0:A(H),F=J.flatMap((q)=>q.options).find((q)=>A(q.value)===z),K=F?W(F,D)??A(F.value):z;return X(v,{value:z==null?void 0:{value:z,label:K??z},onValueChange:(q)=>$?.(q?.value),children:[B(SelectTrigger,{disabled:P,className:w.className,children:B(SelectValue,{placeholder:D(f??k)??""})}),B(SelectContent,{children:J.map((q,M)=>{const Q=L(q,M),U=j(q,D);return X(SelectGroup,{children:[U?B(SelectLabel,{children:U}):null,q.options.map((E,T)=>B(SelectItem,{value:A(E.value),label:W(E,D),disabled:E.disabled},`${Q}-${A(E.value)}-${T}`))]},`${Q}-${M}`)})})]})}export{SelectContent,SelectGroup,SelectItem,SelectLabel,SelectTrigger,SelectValue};
@@ -0,0 +1 @@
1
+ export function selectOptionValue(e){return typeof e==="string"?e:String(e??"")}export function selectOptionLabel(e,t){return t(e.labelI18n)??selectOptionValue(e.labelI18n)}export function selectGroupLabel(e,t){return t(e.labelI18n??e.label)}export function selectGroupKey(e,t){return e.key??e.labelI18n??e.label??`group-${t}`}export function selectOptionGroups({options:e,groups:t}){return t?.length?t:[{options:e??[]}]}
@@ -1,9 +1,9 @@
1
- const a=["light","dark"];function n(e,s){const r=Object.entries(s).sort(([t],[i])=>t.localeCompare(i)).map(([t,i])=>` ${t}: ${i};`).join(`
1
+ const o=["light","dark"],l={background:["card","popover"],foreground:["card-foreground","popover-foreground"],border:["input"]};function n(e,s){const t=Object.entries(s).sort(([r],[i])=>r.localeCompare(i)).map(([r,i])=>` ${r}: ${i};`).join(`
2
2
  `);return`${e} {
3
- ${r}
4
- }`}function l(e){return Object.assign({},...Object.values(e.modes))}function d(e){if(e.startsWith("--ds-color-"))return`--color-${e.slice(11)}`;if(e.startsWith("--ds-radius-"))return`--radius-${e.slice(12)}`;if(e.startsWith("--ds-space-"))return`--spacing-${e.slice(11)}`;if(e.startsWith("--ds-typography-"))return`--text-${e.slice(16)}`;return}function o(e){return`@theme inline {
5
- ${Object.keys(l(e)).sort().flatMap((r)=>{const t=d(r);return t?[` ${t}: var(${r});`]:[]}).join(`
3
+ ${t}
4
+ }`}function c(e){return Object.assign({},...Object.values(e.modes))}function d(e){if(e.startsWith("--ds-color-"))return`--color-${e.slice(11)}`;if(e.startsWith("--ds-radius-"))return`--radius-${e.slice(12)}`;if(e.startsWith("--ds-space-"))return`--spacing-${e.slice(11)}`;if(e.startsWith("--ds-typography-"))return`--text-${e.slice(16)}`;return}function u(e){if(!e.startsWith("--ds-color-"))return[];const s=e.slice(11);return(l[s]??[]).map((r)=>`--color-${r}`)}function h(e){return`@theme inline {
5
+ ${Object.keys(c(e)).sort().flatMap((t)=>{const r=d(t),i=u(t);return[...r?[` ${r}: var(${t});`]:[],...i.map((a)=>` ${a}: var(${t});`)]}).join(`
6
6
  `)}
7
- }`}export function themeSpecToTailwindCss(e,s={}){return[s.includeCustomVariant?"@custom-variant dark (&:where(.dark, .dark *));":void 0,n(s.rootSelector??":root",e.light),n(s.darkSelector??".dark",e.dark),...Object.entries(e.modes).filter(([t])=>!a.includes(t)).map(([t,i])=>n(`[data-theme="${t}"]`,i)),s.includeTheme===!1?void 0:o(e)].filter(Boolean).join(`
7
+ }`}export function themeSpecToTailwindCss(e,s={}){return[s.includeCustomVariant?"@custom-variant dark (&:where(.dark, .dark *));":void 0,n(s.rootSelector??":root",e.light),n(s.darkSelector??".dark",e.dark),...Object.entries(e.modes).filter(([r])=>!o.includes(r)).map(([r,i])=>n(`[data-theme="${r}"]`,i)),s.includeTheme===!1?void 0:h(e)].filter(Boolean).join(`
8
8
 
9
9
  `)}
@@ -1,9 +1,9 @@
1
- const a=["light","dark"];function n(e,s){const r=Object.entries(s).sort(([t],[i])=>t.localeCompare(i)).map(([t,i])=>` ${t}: ${i};`).join(`
1
+ const o=["light","dark"];const l={background:["card","popover"],foreground:["card-foreground","popover-foreground"],border:["input"]};function n(e,s){const t=Object.entries(s).sort(([r],[i])=>r.localeCompare(i)).map(([r,i])=>` ${r}: ${i};`).join(`
2
2
  `);return`${e} {
3
- ${r}
4
- }`}function l(e){return Object.assign({},...Object.values(e.modes))}function d(e){if(e.startsWith("--ds-color-"))return`--color-${e.slice(11)}`;if(e.startsWith("--ds-radius-"))return`--radius-${e.slice(12)}`;if(e.startsWith("--ds-space-"))return`--spacing-${e.slice(11)}`;if(e.startsWith("--ds-typography-"))return`--text-${e.slice(16)}`;return}function o(e){return`@theme inline {
5
- ${Object.keys(l(e)).sort().flatMap((r)=>{const t=d(r);return t?[` ${t}: var(${r});`]:[]}).join(`
3
+ ${t}
4
+ }`}function c(e){return Object.assign({},...Object.values(e.modes))}function d(e){if(e.startsWith("--ds-color-"))return`--color-${e.slice(11)}`;if(e.startsWith("--ds-radius-"))return`--radius-${e.slice(12)}`;if(e.startsWith("--ds-space-"))return`--spacing-${e.slice(11)}`;if(e.startsWith("--ds-typography-"))return`--text-${e.slice(16)}`;return}function u(e){if(!e.startsWith("--ds-color-"))return[];const s=e.slice(11);return(l[s]??[]).map((r)=>`--color-${r}`)}function h(e){return`@theme inline {
5
+ ${Object.keys(c(e)).sort().flatMap((t)=>{const r=d(t),i=u(t);return[...r?[` ${r}: var(${t});`]:[],...i.map((a)=>` ${a}: var(${t});`)]}).join(`
6
6
  `)}
7
- }`}export function themeSpecToTailwindCss(e,s={}){return[s.includeCustomVariant?"@custom-variant dark (&:where(.dark, .dark *));":void 0,n(s.rootSelector??":root",e.light),n(s.darkSelector??".dark",e.dark),...Object.entries(e.modes).filter(([t])=>!a.includes(t)).map(([t,i])=>n(`[data-theme="${t}"]`,i)),s.includeTheme===!1?void 0:o(e)].filter(Boolean).join(`
7
+ }`}export function themeSpecToTailwindCss(e,s={}){return[s.includeCustomVariant?"@custom-variant dark (&:where(.dark, .dark *));":void 0,n(s.rootSelector??":root",e.light),n(s.darkSelector??".dark",e.dark),...Object.entries(e.modes).filter(([r])=>!o.includes(r)).map(([r,i])=>n(`[data-theme="${r}"]`,i)),s.includeTheme===!1?void 0:h(e)].filter(Boolean).join(`
8
8
 
9
9
  `)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/lib.design-system",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "Design tokens and theming primitives",
5
5
  "keywords": [
6
6
  "contractspec",
@@ -31,12 +31,12 @@
31
31
  "sideEffects": false,
32
32
  "tree-shake": true,
33
33
  "dependencies": {
34
- "@contractspec/lib.ai-agent": "8.0.12",
35
- "@contractspec/lib.contracts-spec": "5.7.0",
36
- "@contractspec/lib.contracts-runtime-client-react": "3.11.1",
37
- "@contractspec/lib.presentation-runtime-react": "39.0.0",
38
- "@contractspec/lib.ui-kit": "4.1.1",
39
- "@contractspec/lib.ui-kit-web": "3.12.1",
34
+ "@contractspec/lib.ai-agent": "8.0.13",
35
+ "@contractspec/lib.contracts-spec": "6.0.0",
36
+ "@contractspec/lib.contracts-runtime-client-react": "3.12.0",
37
+ "@contractspec/lib.presentation-runtime-react": "39.0.1",
38
+ "@contractspec/lib.ui-kit": "4.1.2",
39
+ "@contractspec/lib.ui-kit-web": "3.13.0",
40
40
  "@hookform/resolvers": "5.2.2",
41
41
  "class-variance-authority": "^0.7.1",
42
42
  "clsx": "^2.1.1",
@@ -464,6 +464,12 @@
464
464
  "bun": "./dist/components/forms/controls/Select.js",
465
465
  "default": "./dist/components/forms/controls/Select.js"
466
466
  },
467
+ "./components/forms/controls/select-options": {
468
+ "types": "./dist/components/forms/controls/select-options.d.ts",
469
+ "browser": "./dist/browser/components/forms/controls/select-options.js",
470
+ "bun": "./dist/components/forms/controls/select-options.js",
471
+ "default": "./dist/components/forms/controls/select-options.js"
472
+ },
467
473
  "./components/forms/controls/Select.native": {
468
474
  "types": "./dist/components/forms/controls/Select.native.d.ts",
469
475
  "react-native": "./dist/native/components/forms/controls/Select.native.js",
@@ -2019,6 +2025,12 @@
2019
2025
  "bun": "./dist/components/forms/controls/Select.js",
2020
2026
  "default": "./dist/components/forms/controls/Select.js"
2021
2027
  },
2028
+ "./components/forms/controls/select-options": {
2029
+ "types": "./dist/components/forms/controls/select-options.d.ts",
2030
+ "browser": "./dist/browser/components/forms/controls/select-options.js",
2031
+ "bun": "./dist/components/forms/controls/select-options.js",
2032
+ "default": "./dist/components/forms/controls/select-options.js"
2033
+ },
2022
2034
  "./components/forms/controls/Select.native": {
2023
2035
  "types": "./dist/components/forms/controls/Select.native.d.ts",
2024
2036
  "react-native": "./dist/native/components/forms/controls/Select.native.js",