@juwel-development/design-system 3.6.0 → 3.8.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.
package/README.md CHANGED
@@ -32,6 +32,68 @@ If the host already imports Tailwind and only wants the palette, take the tokens
32
32
  @import "@juwel-development/design-system/tokens.css";
33
33
  ```
34
34
 
35
+ ## Select
36
+
37
+ `Select` is a compound namespace: `Select.Root` renders a labelled, uncontrolled native
38
+ single-select field and `Select.Option` renders one text-only native option. Root starts on
39
+ an empty, selectable placeholder; `required` makes that empty value invalid without choosing an
40
+ option for the user.
41
+
42
+ ```tsx
43
+ import { Select } from '@juwel-development/design-system';
44
+ import { Subject } from 'rxjs';
45
+
46
+ const marketChange$ = new Subject<string>();
47
+
48
+ <Select.Root
49
+ label={'Home market'}
50
+ name={'homeMarket'}
51
+ required={true}
52
+ placeholder={'Choose a market'}
53
+ onChange$={marketChange$}
54
+ >
55
+ <Select.Option value={'de'}>{'Germany'}</Select.Option>
56
+ <Select.Option value={'gb'}>{'United Kingdom'}</Select.Option>
57
+ </Select.Root>;
58
+ ```
59
+
60
+ `Root` requires `label`, `name`, and `placeholder`; its `children` compose `Select.Option`
61
+ members, including arrays, fragments, conditional children and consumer components that
62
+ render options. An empty field can omit children. Each `Option` requires a `value` and a
63
+ text-only `children` label, and accepts an optional `testId`. Option values must be
64
+ unique, stable, nonempty strings; every label and message is worded by the consumer.
65
+ The empty string is reserved for the placeholder, which remains selectable so an optional
66
+ field can be cleared. The browser owns keyboard navigation and the native popup.
67
+
68
+ Optional props are `required`, `disabled`, `defaultValue`, `onChange$`, `optionalLabel`,
69
+ `hint`, `invalid`, `errorMessage`, and `testId`. Labels always name the control; hints and
70
+ visible errors describe it. `invalid` exposes the consumer's validation state through
71
+ `aria-invalid`, and `errorMessage` renders only while invalid. Styling follows Input's
72
+ control, typography, focus-ring, motion, and state tokens.
73
+
74
+ `defaultValue` initializes a matching option on mount; omitted or unmatched values start
75
+ empty. Later `defaultValue` changes do not overwrite the user's selection. Reordered or
76
+ relabeled options preserve a surviving selected value; removing that option returns the
77
+ control to empty. Options arriving later do not apply an earlier unmatched default.
78
+
79
+ `onChange$` emits the selected string once per user change, including `''` on clearing.
80
+ Rendering, option replacement, and native form reset do not emit. The consumer owns the
81
+ Subject and must reconcile its own domain state when replacing options or resetting a form.
82
+ Native form reset restores the original default while that option remains mounted; if it
83
+ is removed, reset returns to empty. A newly mounted option does not inherit an earlier
84
+ option's reset default, even when it reuses its value. Keep React keys stable (use the
85
+ option value) across translation and reordering to preserve native selection and reset
86
+ state. No `reset$` prop is needed. A new record can initialize through a remount. Forms can
87
+ also read the current value directly by `name`, without any event subscription.
88
+
89
+ The previous unpublished `<Select options={...} />` API has been removed. For Home Market
90
+ in `g-label-manager` #125, put the existing field props on `Select.Root` and map market
91
+ records to `<Select.Option key={market.id} value={market.id}>{translatedName}</Select.Option>`
92
+ children. Keep `required` and the localized `placeholder` on Root; the empty option is
93
+ provided by Root, so callers do not compose another empty Option. Derive types with
94
+ `ComponentProps<typeof Select.Root>` or `ComponentProps<typeof Select.Option>` from React.
95
+ The consumer still awaits a published library release before changing its dependency.
96
+
35
97
  ## Collection
36
98
 
37
99
  `Collection` is a vertical group of freely composed items with internal hairlines and