@ceed/ads 1.37.0-next.1 → 1.38.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,8 @@
1
1
  import React, { ComponentProps } from 'react';
2
2
  import { Select as JoySelect, type SelectProps as JoySelectProps } from '@mui/joy';
3
+ import FormControl from '../FormControl';
4
+ import FormLabel from '../FormLabel';
5
+ import FormHelperText from '../FormHelperText';
3
6
  import { SelectValue } from '@mui/base';
4
7
  export type { JoySelectProps };
5
8
  export type { OptionProps } from '@mui/joy';
@@ -24,11 +27,16 @@ export { Option };
24
27
  export type InferOptionValue<OptionValue> = OptionValue extends {
25
28
  value: infer V;
26
29
  } ? V : OptionValue;
27
- export interface SelectProps<OptionValue extends OptionType, Multiple extends boolean = false> extends Omit<ComponentProps<typeof JoySelect<OptionValue, any, Multiple>>, 'value' | 'onChange' | 'multiple'> {
30
+ export interface SelectProps<OptionValue extends OptionType, Multiple extends boolean = false> extends Omit<ComponentProps<typeof JoySelect<OptionValue, any, Multiple>>, 'value' | 'onChange' | 'multiple' | 'slotProps'> {
28
31
  options: OptionValue[];
29
32
  label?: string;
30
33
  helperText?: string;
31
34
  error?: boolean;
35
+ slotProps?: ComponentProps<typeof JoySelect<OptionValue, any, Multiple>>['slotProps'] & {
36
+ formControl?: ComponentProps<typeof FormControl>;
37
+ formLabel?: ComponentProps<typeof FormLabel>;
38
+ formHelperText?: ComponentProps<typeof FormHelperText>;
39
+ };
32
40
  value?: SelectValue<InferOptionValue<OptionValue>, Multiple>;
33
41
  onChange?: (event: Omit<React.SyntheticEvent<HTMLElement>, 'target'> & {
34
42
  target: {
@@ -19,7 +19,7 @@ Badge supports multiple colors, variants, and sizes for flexible visual customiz
19
19
  | badgeContent | 배지에 표시될 내용 | 4 |
20
20
  | color | 배지 색상 | "primary" |
21
21
  | variant | 배지 스타일 변형 | "solid" |
22
- | size | 배지 크기 | "md" |
22
+ | size | 배지 크기 | |
23
23
  | invisible | 배지 숨김 여부 | — |
24
24
  | showZero | 0일 때 표시 여부 | — |
25
25
  | max | 최대 표시 숫자 (99 → 99+) | — |
@@ -13,7 +13,7 @@ The Chip component is a compact UI element used to represent inputs, attributes,
13
13
  | children | Chip 내용 | "Chip" |
14
14
  | color | Chip 색상 | "primary" |
15
15
  | variant | Chip 스타일 변형 | "solid" |
16
- | size | Chip 크기 | "md" |
16
+ | size | Chip 크기 | |
17
17
  | disabled | 비활성화 상태 | — |
18
18
 
19
19
  ## Usage
@@ -17,7 +17,7 @@ Button is the primary interactive element for triggering actions. Built on Joy U
17
17
  | Field | Description | Default |
18
18
  | ------- | ----------- | --------- |
19
19
  | color | — | "primary" |
20
- | size | — | "md" |
20
+ | size | — | |
21
21
  | variant | — | "solid" |
22
22
 
23
23
  ## Usage
@@ -73,7 +73,6 @@ Shows a loading indicator during async operations. The button is automatically d
73
73
  disabled={false}
74
74
  loading
75
75
  color="primary"
76
- size="md"
77
76
  variant="solid"
78
77
  />
79
78
  ```
@@ -18,7 +18,7 @@ By applying shared props like `color`, `variant`, `size`, and `orientation` at t
18
18
  | ----------- | ----------- | ------------ |
19
19
  | color | 버튼 그룹 색상 | "primary" |
20
20
  | variant | 버튼 스타일 변형 | "solid" |
21
- | size | 버튼 크기 | "md" |
21
+ | size | 버튼 크기 | |
22
22
  | orientation | 방향 | "horizontal" |
23
23
  | disabled | 비활성화 상태 | false |
24
24
 
@@ -15,7 +15,7 @@ Because IconButton omits visible text, it relies entirely on the icon's clarity
15
15
  | children | 아이콘 요소 | \<Add /> |
16
16
  | color | 버튼 색상 | "primary" |
17
17
  | variant | 버튼 스타일 변형 | "solid" |
18
- | size | 버튼 크기 | "md" |
18
+ | size | 버튼 크기 | |
19
19
  | disabled | 비활성화 상태 | — |
20
20
  | loading | 로딩 상태 | — |
21
21
 
@@ -207,6 +207,58 @@ Combining `label`, `helperText`, and `error` produces a complete form field. Her
207
207
  </>
208
208
  ```
209
209
 
210
+ ## Slot Props and Deterministic Ids
211
+
212
+ The `slotProps` prop targets both Joy Select's own slots (`button`, `listbox`, `root`, …) and the wrapper slots that `Select` composes around it (`formControl`, `formLabel`, `formHelperText`). Pass `id` (or `slotProps.formControl.id`) to pin the field's ids deterministically — `FormControl` derives the button `id` and the label `id` (`${id}-label`) from it, which keeps `byLabelText` / `byRole('combobox', { name })` queries stable in tests.
213
+
214
+ ```tsx
215
+ <Stack
216
+ spacing={3}
217
+ sx={{
218
+ minWidth: 240
219
+ }}
220
+ >
221
+ {/* id seeds deterministic FormControl ids: button#pet, label#pet-label (testable via byLabelText/byRole) */}
222
+ <Select
223
+ id="pet"
224
+ label="Pet"
225
+ defaultValue="cat"
226
+ options={options}
227
+ slotProps={{
228
+ formLabel: {
229
+ sx: {
230
+ color: "primary.500"
231
+ }
232
+ },
233
+ formHelperText: {
234
+ sx: {
235
+ fontStyle: "italic"
236
+ }
237
+ },
238
+ button: {
239
+ "aria-describedby": "pet-extra"
240
+ }
241
+ }}
242
+ helperText="Wired via slotProps"
243
+ />
244
+ </Stack>
245
+ ```
246
+
247
+ ```tsx
248
+ <Select
249
+ id="pet"
250
+ label="Pet"
251
+ helperText="Wired via slotProps"
252
+ options={options}
253
+ slotProps={{
254
+ formLabel: { sx: { color: 'primary.500' } },
255
+ formHelperText: { sx: { fontStyle: 'italic' } },
256
+ button: { 'aria-describedby': 'pet-extra' },
257
+ }}
258
+ />
259
+ // → renders button#pet and label#pet-label, connected via aria-labelledby
260
+ ```
261
+
210
262
  ## Required Field
211
263
 
212
264
  Set `required` to mark the field as required. An asterisk is added to the label automatically.
@@ -557,25 +609,27 @@ function LocationSelect() {
557
609
 
558
610
  ### Key Props
559
611
 
560
- | Prop | Type | Default | Description |
561
- | ---------------- | ---------------------------------------------------------------- | ----------------- | ---------------------------------------------------- |
562
- | `options` | `OptionType[]` | `[]` | Array of options (objects or primitives) |
563
- | `value` | `InferOptionValue<OptionType> \| InferOptionValue<OptionType>[]` | - | Selected value(s) for controlled mode |
564
- | `defaultValue` | `InferOptionValue<OptionType> \| InferOptionValue<OptionType>[]` | - | Initial value for uncontrolled mode |
565
- | `onChange` | `(event: { target: { name?, value } }, newValue) => void` | - | Callback when selection changes |
566
- | `multiple` | `boolean` | `false` | Allow multiple selections (value becomes an array) |
567
- | `label` | `string` | - | Form label displayed above the select |
568
- | `helperText` | `string` | - | Helper text displayed below the select |
569
- | `error` | `boolean` | `false` | Applies danger color to indicate validation error |
570
- | `required` | `boolean` | `false` | Marks the field as required (adds asterisk to label) |
571
- | `disabled` | `boolean` | `false` | Disables the select |
572
- | `placeholder` | `string` | `'Choose one...'` | Placeholder text when no value is selected |
573
- | `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` | Select size |
574
- | `variant` | `'outlined' \| 'plain' \| 'solid' \| 'soft'` | `'outlined'` | Visual style variant |
575
- | `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Color scheme |
576
- | `startDecorator` | `ReactNode` | - | Content rendered before the select trigger text |
577
- | `endDecorator` | `ReactNode` | - | Content rendered after the select trigger text |
578
- | `sx` | `SxProps` | - | Custom styles using the MUI system |
612
+ | Prop | Type | Default | Description |
613
+ | ---------------- | ----------------------------------------------------------------------- | ----------------- | -------------------------------------------------------------- |
614
+ | `options` | `OptionType[]` | `[]` | Array of options (objects or primitives) |
615
+ | `value` | `InferOptionValue<OptionType> \| InferOptionValue<OptionType>[]` | - | Selected value(s) for controlled mode |
616
+ | `defaultValue` | `InferOptionValue<OptionType> \| InferOptionValue<OptionType>[]` | - | Initial value for uncontrolled mode |
617
+ | `onChange` | `(event: { target: { name?, value } }, newValue) => void` | - | Callback when selection changes |
618
+ | `multiple` | `boolean` | `false` | Allow multiple selections (value becomes an array) |
619
+ | `label` | `string` | - | Form label displayed above the select |
620
+ | `helperText` | `string` | - | Helper text displayed below the select |
621
+ | `error` | `boolean` | `false` | Applies danger color to indicate validation error |
622
+ | `required` | `boolean` | `false` | Marks the field as required (adds asterisk to label) |
623
+ | `disabled` | `boolean` | `false` | Disables the select |
624
+ | `placeholder` | `string` | `'Choose one...'` | Placeholder text when no value is selected |
625
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'sm'` | Select size |
626
+ | `variant` | `'outlined' \| 'plain' \| 'solid' \| 'soft'` | `'outlined'` | Visual style variant |
627
+ | `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'neutral'` | Color scheme |
628
+ | `startDecorator` | `ReactNode` | - | Content rendered before the select trigger text |
629
+ | `endDecorator` | `ReactNode` | - | Content rendered after the select trigger text |
630
+ | `id` | `string` | - | Seeds deterministic ids: button `id`, label `${id}-label` |
631
+ | `slotProps` | `{ formControl?, formLabel?, formHelperText?, button?, listbox?, ... }` | - | Props forwarded to composed wrapper slots and Joy Select slots |
632
+ | `sx` | `SxProps` | - | Custom styles using the MUI system |
579
633
 
580
634
  ### Option Type
581
635
 
@@ -611,7 +665,8 @@ const options = [
611
665
 
612
666
  ## Accessibility
613
667
 
614
- - **Label association**: When you use the `label` prop, the component automatically connects the label to the select element via `aria-labelledby`. Always provide a label for screen reader users.
668
+ - **Label association**: When you use the `label` prop, the component automatically connects the label to the select element via `aria-labelledby` (the internal `FormControl` propagates a `labelId` to both the label and the button slot). You do not need to wire `useId` or a custom `FormLabel` externally. Always provide a label for screen reader users.
669
+ - **Deterministic ids for tests**: Pass `id` (or `slotProps.formControl.id`) to fix the generated ids, so `byLabelText` / `byRole('combobox', { name })` resolve to a stable accessible name.
615
670
  - **Keyboard navigation**: The select can be opened with Enter or Space, navigated with Arrow Up/Down and Home/End, confirmed with Enter, and dismissed with Escape.
616
671
  - **Error announcement**: When `error` is set, `aria-invalid` is applied. Pair it with a descriptive `helperText` so assistive technology can announce the error reason.
617
672
  - **Required state**: The `required` prop adds `aria-required` and a visible asterisk to the label, communicating the requirement both visually and programmatically.
@@ -26,7 +26,7 @@ Tabs follow a composition pattern: the `Tabs` container manages state, `TabList`
26
26
  | Field | Description | Default |
27
27
  | ------- | ----------- | --------- |
28
28
  | color | — | "primary" |
29
- | size | — | "md" |
29
+ | size | — | |
30
30
  | variant | — | "plain" |
31
31
 
32
32
  ## Usage
@@ -26,7 +26,7 @@ Card is composed of five subcomponents: `Card`, `CardContent`, `CardCover`, `Car
26
26
  | ------- | ----------- | ---------- |
27
27
  | variant | 카드 스타일 변형 | "outlined" |
28
28
  | color | 카드 색상 | "neutral" |
29
- | size | 카드 크기 | "md" |
29
+ | size | 카드 크기 | |
30
30
 
31
31
  ## Usage
32
32