cleanplate 0.3.22 → 0.3.24
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/CHANGELOG.md +4 -0
- package/dist/components/feedback-state/FeedbackState.d.ts +36 -0
- package/dist/components/feedback-state/FeedbackState.d.ts.map +1 -0
- package/dist/components/feedback-state/index.d.ts +4 -0
- package/dist/components/feedback-state/index.d.ts.map +1 -0
- package/dist/components/form-controls/Checkbox.d.ts +7 -2
- package/dist/components/form-controls/Checkbox.d.ts.map +1 -1
- package/dist/components/form-controls/Radio.d.ts +7 -2
- package/dist/components/form-controls/Radio.d.ts.map +1 -1
- package/dist/components/icon/material-icon-names.d.ts +2 -2
- package/dist/components/icon/material-icon-names.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.css +1 -1
- package/dist/index.es.js +4 -4
- package/dist/index.js +4 -4
- package/docs/FeedbackState.md +179 -0
- package/docs/FormControls.md +6 -6
- package/llms.txt +9 -1
- package/package.json +1 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# FeedbackState Component
|
|
2
|
+
|
|
3
|
+
Purpose: Unified empty and error **region** for cards, panels, tables, and main content areas — when a section has no data or failed to load. Use `Alert` for short inline banners and `Toast` for transient messages. **Margin** uses the **framework-wide spacing suffix rule** (same for all components); see `llms.txt`.
|
|
4
|
+
|
|
5
|
+
**Illustrations:** CleanPlate does not host artwork. Pass your own image URL (`png`, `jpg`, `svg`) or a custom `ReactNode`, or use the `icon` prop with a Material icon name when no image is needed.
|
|
6
|
+
|
|
7
|
+
## Props / Inputs
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Required | Default | Description |
|
|
10
|
+
| --- | --- | --- | --- | --- |
|
|
11
|
+
| variant | `"empty" \| "error"` | yes | — | Drives default ARIA role and error tone |
|
|
12
|
+
| title | string | yes | — | Primary headline |
|
|
13
|
+
| titleTag | `"h1"` … `"h6" \| "p"` | no | `"h2"` | Semantic element for the title |
|
|
14
|
+
| description | string \| ReactNode | no | — | Supporting copy |
|
|
15
|
+
| illustration | string \| ReactNode | no | — | Image URL or custom media node |
|
|
16
|
+
| illustrationAlt | string | no | `""` | `alt` for URL images; empty = decorative |
|
|
17
|
+
| icon | MaterialIconName | no | — | Material icon when `illustration` is omitted |
|
|
18
|
+
| size | `"small" \| "medium" \| "large"` | no | `"medium"` | Overall scale (spacing, media box, icon size) |
|
|
19
|
+
| primaryAction | ActionConfig | no | — | Solid primary button |
|
|
20
|
+
| secondaryAction | ActionConfig | no | — | Ghost secondary button |
|
|
21
|
+
| onRetry | `() => void` | no | — | Shorthand primary “Try again” when `primaryAction` is absent |
|
|
22
|
+
| retryLabel | string | no | `"Try again"` | Label when `onRetry` is used |
|
|
23
|
+
| errorCode | string \| number | no | — | Visual error code (not the sole indicator) |
|
|
24
|
+
| errorDetails | string | no | — | Technical detail in a `<details>` disclosure |
|
|
25
|
+
| role | `"alert" \| "status" \| "none"` | no | `status` (empty) / `alert` (error) | Root ARIA role |
|
|
26
|
+
| margin | string \| SpacingOption[] | no | `"0"` | Spacing **suffix**; component adds `m-` prefix |
|
|
27
|
+
| className | string | no | `""` | Extra class on root for consumer CSS overrides |
|
|
28
|
+
| dataTestId | string | no | — | `data-testid` on root |
|
|
29
|
+
|
|
30
|
+
### ActionConfig
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
type ActionConfig = {
|
|
34
|
+
label: string;
|
|
35
|
+
onClick: () => void;
|
|
36
|
+
};
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Actions use `Button` only — there is no `href`. Use `onClick` for navigation (e.g. router).
|
|
40
|
+
|
|
41
|
+
## Types
|
|
42
|
+
|
|
43
|
+
### FeedbackStateVariant
|
|
44
|
+
```typescript
|
|
45
|
+
type FeedbackStateVariant = "empty" | "error";
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### FeedbackStateSize
|
|
49
|
+
```typescript
|
|
50
|
+
type FeedbackStateSize = "small" | "medium" | "large";
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### FeedbackStateTitleTag
|
|
54
|
+
```typescript
|
|
55
|
+
type FeedbackStateTitleTag = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p";
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### FeedbackStateRole
|
|
59
|
+
```typescript
|
|
60
|
+
type FeedbackStateRole = "alert" | "status" | "none";
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### FeedbackStateProps
|
|
64
|
+
```typescript
|
|
65
|
+
interface FeedbackStateProps {
|
|
66
|
+
variant: FeedbackStateVariant;
|
|
67
|
+
title: string;
|
|
68
|
+
titleTag?: FeedbackStateTitleTag;
|
|
69
|
+
description?: string | React.ReactNode;
|
|
70
|
+
illustration?: string | React.ReactNode;
|
|
71
|
+
illustrationAlt?: string;
|
|
72
|
+
icon?: MaterialIconName;
|
|
73
|
+
size?: FeedbackStateSize;
|
|
74
|
+
primaryAction?: ActionConfig;
|
|
75
|
+
secondaryAction?: ActionConfig;
|
|
76
|
+
onRetry?: () => void;
|
|
77
|
+
retryLabel?: string;
|
|
78
|
+
errorCode?: string | number;
|
|
79
|
+
errorDetails?: string;
|
|
80
|
+
role?: FeedbackStateRole;
|
|
81
|
+
margin?: string | SpacingOption[];
|
|
82
|
+
className?: string;
|
|
83
|
+
dataTestId?: string;
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Usage Examples
|
|
88
|
+
|
|
89
|
+
### Empty state with icon
|
|
90
|
+
|
|
91
|
+
```jsx
|
|
92
|
+
import { FeedbackState } from "cleanplate";
|
|
93
|
+
|
|
94
|
+
export const ProjectsEmpty = ({ onCreate }) => (
|
|
95
|
+
<FeedbackState
|
|
96
|
+
variant="empty"
|
|
97
|
+
title="No projects yet"
|
|
98
|
+
description="Create your first project to get started."
|
|
99
|
+
icon="folder_open"
|
|
100
|
+
primaryAction={{ label: "New project", onClick: onCreate }}
|
|
101
|
+
/>
|
|
102
|
+
);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Empty state with module illustration
|
|
106
|
+
|
|
107
|
+
```jsx
|
|
108
|
+
<FeedbackState
|
|
109
|
+
variant="empty"
|
|
110
|
+
title="No search results"
|
|
111
|
+
description="Try adjusting your filters."
|
|
112
|
+
illustration="/assets/modules/search-empty.png"
|
|
113
|
+
illustrationAlt=""
|
|
114
|
+
primaryAction={{ label: "Clear filters", onClick: clearFilters }}
|
|
115
|
+
/>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Error with retry
|
|
119
|
+
|
|
120
|
+
```jsx
|
|
121
|
+
<FeedbackState
|
|
122
|
+
variant="error"
|
|
123
|
+
title="Could not load projects"
|
|
124
|
+
description="Check your connection and try again."
|
|
125
|
+
icon="cloud_off"
|
|
126
|
+
errorCode={503}
|
|
127
|
+
onRetry={refetch}
|
|
128
|
+
/>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Error with technical details
|
|
132
|
+
|
|
133
|
+
```jsx
|
|
134
|
+
<FeedbackState
|
|
135
|
+
variant="error"
|
|
136
|
+
title="Request failed"
|
|
137
|
+
errorDetails={error.message}
|
|
138
|
+
dataTestId="projects-error"
|
|
139
|
+
/>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Custom styles via className
|
|
143
|
+
|
|
144
|
+
```jsx
|
|
145
|
+
<FeedbackState
|
|
146
|
+
variant="empty"
|
|
147
|
+
title="No items"
|
|
148
|
+
className="my-module-empty"
|
|
149
|
+
icon="inbox"
|
|
150
|
+
/>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```css
|
|
154
|
+
.my-module-empty.cp-feedback-state {
|
|
155
|
+
min-height: 280px;
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Behavior Notes
|
|
160
|
+
|
|
161
|
+
- **Media precedence:** `illustration` → `icon` → no media. If both `illustration` and `icon` are set, illustration wins.
|
|
162
|
+
- **Action precedence:** `primaryAction` overrides `onRetry`.
|
|
163
|
+
- **Layout:** Stacked only (media above text, centered actions).
|
|
164
|
+
- **Accessibility:** Root `aria-labelledby` points at the title; decorative media uses `aria-hidden` when `illustrationAlt` is empty and a title is present.
|
|
165
|
+
- **Motion:** Subtle mount fade; disabled when `prefers-reduced-motion: reduce`.
|
|
166
|
+
|
|
167
|
+
### Stable slot classes (for CSS overrides)
|
|
168
|
+
|
|
169
|
+
- `cp-feedback-state` — root
|
|
170
|
+
- `cp-feedback-state__media`, `cp-feedback-state__media-img`
|
|
171
|
+
- `cp-feedback-state__content`, `cp-feedback-state__title`, `cp-feedback-state__description`
|
|
172
|
+
- `cp-feedback-state__error-code`, `cp-feedback-state__actions`, `cp-feedback-state__details`
|
|
173
|
+
|
|
174
|
+
## Related Components / Links
|
|
175
|
+
|
|
176
|
+
- Alert (inline feedback)
|
|
177
|
+
- Toast (transient messages)
|
|
178
|
+
- Button, Icon, Typography (composed internally)
|
|
179
|
+
- Container (wrap for layout in stories and apps)
|
package/docs/FormControls.md
CHANGED
|
@@ -10,8 +10,8 @@ FormControls is a set of form primitives exported as a namespace: `FormControls.
|
|
|
10
10
|
| TextArea | Multi-line text | placeholder, value, onChange(e) |
|
|
11
11
|
| Select | Floating UI combobox: desktop portalled list; **≤768px** bottom sheet; sync or async options, search, groups, multi chips + cap | `mode` / `isMulti`, `options`, `onSearch`, `searchable`, `groups`, `maxSelect`, `triggerMaxItems`, `panelMinWidth`, `name`, `placeholder`, `error` |
|
|
12
12
|
| Date | Calendar date picker (`date-fns` + Floating UI); **Cancel** / **OK** staging; desktop **popover** (~**400px** max width, viewport-capped); **≤768px** **bottom sheet** + backdrop; **month** / **year** subviews with back + titled headers; trigger **`calendar_month`** icon | `value`/`defaultValue` (`Date \| null`), `onChange`, `minDate`/`maxDate`/`disabledDates`/`disabledDaysOfWeek`, `locale`, `weekStartsOn`, `dateFormat`, `clearable`, `readOnly`, `name` (hidden **yyyy-MM-dd**), `popoverPlacement`, `onOpen`/`onClose` |
|
|
13
|
-
| Checkbox | Checkbox group (array-based, multi-select) | name, label, options, value (CheckboxValue[]), defaultValue, onChange(values, e), orientation, variant |
|
|
14
|
-
| Radio | Radio group (array-based) | name, label, options, value, defaultValue, onChange(value, e), orientation, variant |
|
|
13
|
+
| Checkbox | Checkbox group (array-based, multi-select) | name, label, options, value (CheckboxValue[]), defaultValue, onChange(values, e), orientation, variant, cardControlAlign |
|
|
14
|
+
| Radio | Radio group (array-based) | name, label, options, value, defaultValue, onChange(value, e), orientation, variant, cardControlAlign |
|
|
15
15
|
| File | File picker with `button` / `card` variants, drag-and-drop, and a removable file list | name, label, variant, multiple, accept, value (File[]), onChange(files, e), buttonLabel, dropZoneText |
|
|
16
16
|
| Toggle | On/off switch | checked, defaultChecked, onChange(checked: boolean) |
|
|
17
17
|
| Stepper | Numeric value with integrated − / + (integer text field + `min` / `max` / `step`) | placeholder, value, onChange(e), min, max, step, layout |
|
|
@@ -163,9 +163,9 @@ interface InputProps {
|
|
|
163
163
|
- **TextAreaProps**: label, value/defaultValue, onChange, isDisabled, isRequired, isFluid, className, error, **`dataTestId`** (on `<textarea>`; `-error` — see overview).
|
|
164
164
|
- **SelectProps**: … **`dataTestId`** (wrapper root; `-trigger`, `-panel`, `-option-{value}`, … — see **Select — E2E / test selectors**).
|
|
165
165
|
- **FileProps**: `name`, `label`, `variant` (`"button" | "card"`, default `"button"`), `multiple`, `accept`, `value: File[]` (controlled), `defaultValue: File[]` (uncontrolled initial visual list), `onChange(files: File[], e?)`, `buttonLabel` (default `"Browse file"`), `dropZoneText` (default `"Drag files to upload"`, card variant only), plus the common `isDisabled`, `isRequired`, `isFluid`, `className`, `error`, **`dataTestId`** (on file input; `-trigger`, `-list`, `-item-{i}`, `-remove-{i}` — see **File — E2E / test selectors**). The card variant supports drag-and-drop. **FileVariant** = `"button" | "card"`.
|
|
166
|
-
- **RadioProps**: `options` (non-empty `RadioOption[]`), `name`, `label` (group `<legend>`), optional `id`, `value`, `defaultValue`, `onChange(value, e)`, `orientation` (`"vertical" | "horizontal"`), `variant` (`"default" | "card"`), `isDisabled`, `isRequired`, `isFluid`, `className`, `error`, **`dataTestId`** (root on `<fieldset>`; suffixed ids on options container, rows, inputs, and labels — see **Checkbox and Radio — E2E / test selectors**).
|
|
166
|
+
- **RadioProps**: `options` (non-empty `RadioOption[]`), `name`, `label` (group `<legend>`), optional `id`, `value`, `defaultValue`, `onChange(value, e)`, `orientation` (`"vertical" | "horizontal"`), `variant` (`"default" | "card"`), `cardControlAlign` (`"start" | "end"`, default `"end"` — card variant only; top-inline-start vs top-inline-end corner), `isDisabled`, `isRequired`, `isFluid`, `className`, `error`, **`dataTestId`** (root on `<fieldset>`; suffixed ids on options container, rows, inputs, and labels — see **Checkbox and Radio — E2E / test selectors**).
|
|
167
167
|
- **RadioOption**: `{ label, value, isDisabled?, description?, icon?, dataTestId?, id? }`. `description` is rendered under the option label as muted secondary text and linked via `aria-describedby`. `icon` accepts any `ReactNode` (e.g. `<Icon />`, `<img />`, custom SVG) and renders to the left of the label/description. **`dataTestId`** on an option overrides the group-derived `-input-{value}` id for that option's native `<input>`.
|
|
168
|
-
- **CheckboxProps**: `options` (non-empty `CheckboxOption[]`), `name`, `label` (group `<legend>`), optional `id`, `value` (`CheckboxValue[]`), `defaultValue` (`CheckboxValue[]`), `onChange(values, e)`, `orientation` (`"vertical" | "horizontal"`), `variant` (`"default" | "card"`), `isDisabled`, `isRequired`, `isFluid`, `className`, `error`, **`dataTestId`** (root on `<fieldset>`; suffixed ids on options container, rows, inputs, and labels — see **Checkbox and Radio — E2E / test selectors**).
|
|
168
|
+
- **CheckboxProps**: `options` (non-empty `CheckboxOption[]`), `name`, `label` (group `<legend>`), optional `id`, `value` (`CheckboxValue[]`), `defaultValue` (`CheckboxValue[]`), `onChange(values, e)`, `orientation` (`"vertical" | "horizontal"`), `variant` (`"default" | "card"`), `cardControlAlign` (`"start" | "end"`, default `"end"` — card variant only; top-inline-start vs top-inline-end corner), `isDisabled`, `isRequired`, `isFluid`, `className`, `error`, **`dataTestId`** (root on `<fieldset>`; suffixed ids on options container, rows, inputs, and labels — see **Checkbox and Radio — E2E / test selectors**).
|
|
169
169
|
- **CheckboxOption**: `{ label, value, isDisabled?, description?, icon?, dataTestId?, id? }`. `description` is rendered under the option label as muted secondary text and linked via `aria-describedby`. `icon` accepts any `ReactNode` (e.g. `<Icon />`, `<img />`, custom SVG) and renders to the left of the label/description. **`dataTestId`** on an option overrides the group-derived `-input-{value}` id for that option's native `<input>`. `CheckboxValue = string | number`.
|
|
170
170
|
- **DateProps**: `value` / `defaultValue` (`Date | null`), `onChange(date: Date | null)`, `placeholder`, **`dateFormat`** (display string via `date-fns` + `locale`, default `MMM dd, yyyy`), **`name`** (renders a hidden `<input>` that submits **`yyyy-MM-dd`** for the committed calendar date), **`minDate`** / **`maxDate`** (inclusive navigation + selection bounds), **`disabledDates`** / **`disabledDaysOfWeek`** (greyed cells), **`locale`** (`date-fns` `Locale` — grid, subview copy, and field text), **`weekStartsOn`** (`0`–`6`, default `0` = Sunday), **`clearable`** (default `true`; shows clear control when a value exists), **`readOnly`** (no picker; value fixed), **`popoverPlacement`** (Floating UI placement for desktop; default `bottom-start`), **`onOpen`** / **`onClose`**, plus shared `label`, `isDisabled`, `isRequired`, `isFluid`, `className`, `error`, **`dataTestId`** (see **Date — E2E / test selectors**).
|
|
171
171
|
- **ToggleProps**: checked, defaultChecked, onChange(checked: boolean), label, isDisabled, isRequired, isFluid, className, error, **`dataTestId`** (on switch input; `-label`, `-error`).
|
|
@@ -584,8 +584,8 @@ Pagination uses `FormControls.Select` for rows-per-page. Pills uses `FormControl
|
|
|
584
584
|
- **File (`dataTestId`):** On file input plus `-trigger`, `-list`, `-item-{i}`, `-remove-{i}`. See **File — E2E / test selectors**.
|
|
585
585
|
- **Select:** Built on **Floating UI** — desktop uses a **portalled** panel with flip/shift to stay in the viewport; panel **width** matches the trigger, with optional **`panelMinWidth`** when options need more horizontal space; **`searchable={false}`** hides the panel search field (full static list, or async `onSearch("")` on open); **≤768px** uses a **bottom sheet** (`role="dialog"`, `aria-modal`, `aria-labelledby` to the field label when the label exists). **Option** shape supports `group`, `icon`, `avatar`, `meta`, `disabled`. **`mode`** (`'single' | 'multi'`) replaces **`isMulti`** (still supported, deprecated). Single mode: **`onChange(Option | null)`** — `null` when cleared. Multi mode: **`onChange(Option[])`** — use **`[]`** for clear. **`name` + hidden `<input>`:** native form submit posts the selected **`value`**(s); **multi** joins with **commas** — avoid comma characters inside `value` if you rely on `FormData`, or parse manually. **`options={null}` + `onSearch`:** async loading; show loading/empty/error states in the panel. **`groups`:** sticky headings for shared `Option.group`. **`maxSelect`:** multi only; **`triggerMaxItems`:** chip overflow **`+N`**. **`aria-controls`** on the combobox trigger and panel search point at the listbox **only while open**. **`aria-invalid`** reflects **`error`** on trigger, search field, and listbox. Validation message uses **`role="alert"`** (via shared field error pattern).
|
|
586
586
|
- **Date:** **`Date | null`** with **`onChange`**. Opens a **`role="dialog"`** calendar: **staging** applies on day tap; **Cancel** reverts to the last committed value; **OK** commits (and clears staging). **Desktop:** portalled Floating UI panel with flip/shift, fixed **max width ~400px** (capped by viewport). **≤768px:** bottom sheet fixed to the lower viewport + dimmed backdrop, `aria-modal`, body scroll lock while open (same breakpoint idea as Select). **Header:** month cluster + year cluster (44px arrow hits); tapping month/year opens **scrollable subviews** with **back (`arrow_back`)** and headings **“Select a month of {yyyy}”** / **“Select a year for {MMMM}”** (locale-aware via `locale`). **Trigger:** **`calendar_month`** trailing icon (not Select chevrons); optional **clear** when `clearable`. **`readOnly`** and **`isDisabled`** block interaction. Constraints: **`minDate`/`maxDate`** (inclusive), **`disabledDates`**, **`disabledDaysOfWeek`**. **`dateFormat`** + **`locale`** control the field string; grid labels follow **`locale`** and **`weekStartsOn`**. **`name`:** hidden input posts **`yyyy-MM-dd`** for the **committed** value only. **`onOpen`/`onClose`** fire when the panel opens/closes. **`popoverPlacement`** adjusts desktop anchor (default `bottom-start`). **`error`** / **`isRequired`** use the shared field error pattern (`aria-invalid`, message under the field).
|
|
587
|
-
- **Radio:** Group-first API — pass `options: RadioOption[]`. Renders `<fieldset>` + `<legend>` with a single `value` and `onChange(value, e)`. `isRequired` puts `*` on the legend and adds `required`/`aria-required` to the first enabled option (HTML5 only requires one input in the group to carry it). Custom ring/dot follows the native `:checked` state so uncontrolled groups stay visually correct. Pass `variant="card"` for tile-style options (ring in top-right
|
|
588
|
-
- **Checkbox:** Group-first API — pass `options: CheckboxOption[]`. Renders `<fieldset>` + `<legend>` with a `value: CheckboxValue[]` and `onChange(values, e)`. `isRequired` puts `*` on the legend and sets `aria-required` on the group; native HTML5 doesn't enforce "at least one" for checkbox groups, so add custom validation at the form layer. Custom box/tick follows the native `:checked` state. Pass `variant="card"` for tile-style options (
|
|
587
|
+
- **Radio:** Group-first API — pass `options: RadioOption[]`. Renders `<fieldset>` + `<legend>` with a single `value` and `onChange(value, e)`. `isRequired` puts `*` on the legend and adds `required`/`aria-required` to the first enabled option (HTML5 only requires one input in the group to carry it). Custom ring/dot follows the native `:checked` state so uncontrolled groups stay visually correct. Pass `variant="card"` for tile-style options; `cardControlAlign` (`start` | `end`, default `end`) places the ring in the top-inline-start or top-inline-end corner (left / right in LTR). Optional `icon` beside label/description; primary-brand border + tint when selected. **`dataTestId`** on the group maps to the fieldset and emits suffixed ids (`-options`, `-option-{value}`, `-input-{value}`, `-label-{value}`); per-option `dataTestId` overrides the input suffix only.
|
|
588
|
+
- **Checkbox:** Group-first API — pass `options: CheckboxOption[]`. Renders `<fieldset>` + `<legend>` with a `value: CheckboxValue[]` and `onChange(values, e)`. `isRequired` puts `*` on the legend and sets `aria-required` on the group; native HTML5 doesn't enforce "at least one" for checkbox groups, so add custom validation at the form layer. Custom box/tick follows the native `:checked` state. Pass `variant="card"` for tile-style options; `cardControlAlign` (`start` | `end`, default `end`) places the box in the top-inline-start or top-inline-end corner (left / right in LTR). For a single checkbox, pass a one-element `options` array — `value=[]` is unchecked, `value=[opt.value]` is checked. **`dataTestId`** uses the same suffix scheme as Radio.
|
|
589
589
|
- **File:** Native `<input type="file">` is visually hidden but stays in the a11y tree. Manages a `File[]` selection internally; `onChange(files, e)` fires for picker selections, drops, and removals (the underlying event is `undefined` for non-picker triggers). With `multiple`, subsequent picks/drops append; without, the new selection replaces the old. The card variant supports drag-and-drop and tints primary-brand on hover. Removing a file resets the native input so re-selecting the same file still emits a change. `defaultValue` seeds the visual list only — browsers don't allow programmatic pre-population of file inputs.
|
|
590
590
|
- **isFluid:** Full-width field wrapper.
|
|
591
591
|
|
package/llms.txt
CHANGED
|
@@ -101,6 +101,13 @@ All component documentation is located in the `docs/` folder. The following docu
|
|
|
101
101
|
- Types: AlertProps, AlertSize, AlertVariant, AlertMargin, SpacingOption
|
|
102
102
|
- Related Components: Typography, Container, Button, Icon (used internally)
|
|
103
103
|
|
|
104
|
+
### FeedbackState Component
|
|
105
|
+
- File: `docs/FeedbackState.md`
|
|
106
|
+
- Purpose: Unified empty and error region for cards, panels, tables, and content areas. Consumer-supplied illustration URL (png/jpg/svg) or Material `icon`; optional primary/secondary actions (`onClick` only).
|
|
107
|
+
- Key Features: variant empty|error, sizes small|medium|large, stacked layout, errorCode/errorDetails, onRetry shorthand, className overrides, dataTestId, margin suffix API
|
|
108
|
+
- Types: FeedbackStateProps, FeedbackStateVariant, FeedbackStateSize, FeedbackStateTitleTag, FeedbackStateRole, ActionConfig, FeedbackStateMargin, SpacingOption
|
|
109
|
+
- Related Components: Typography, Button, Icon (used internally); Alert (inline); Toast (transient)
|
|
110
|
+
|
|
104
111
|
### Spinner Component
|
|
105
112
|
- File: `docs/Spinner.md`
|
|
106
113
|
- Purpose: Loading indicator that shows a rotating Material icon. Use for progress or activity states.
|
|
@@ -259,6 +266,7 @@ All documentation files follow a consistent format:
|
|
|
259
266
|
| Container | `docs/Container.md` | Layout, spacing, and flex structure |
|
|
260
267
|
| Dropdown | `docs/Dropdown.md` | Menus and floating panels |
|
|
261
268
|
| Alert | `docs/Alert.md` | Inline feedback and notices |
|
|
269
|
+
| FeedbackState | `docs/FeedbackState.md` | Empty/error content regions |
|
|
262
270
|
| Spinner | `docs/Spinner.md` | Loading and activity indicator |
|
|
263
271
|
| Stepper | `docs/Stepper.md` | Wizard / checkout **step progress** (not numeric +/−; that is **FormControls.Stepper** in FormControls) |
|
|
264
272
|
| BreadCrumb | `docs/BreadCrumb.md` | Navigation trail and page hierarchy |
|
|
@@ -296,5 +304,5 @@ npm install cleanplate
|
|
|
296
304
|
## Usage
|
|
297
305
|
|
|
298
306
|
```jsx
|
|
299
|
-
import { Button, Typography, Icon, MediaObject, Avatar, Container, Dropdown, Alert, Spinner, Stepper, BreadCrumb, Accordion, ConfirmDialog, Modal, Pagination, Table, Badge, Pills, Animated, FormControls, Toast, MenuList, Header, PageHeader, BottomSheet, Footer, AppShell } from "cleanplate";
|
|
307
|
+
import { Button, Typography, Icon, MediaObject, Avatar, Container, Dropdown, Alert, FeedbackState, Spinner, Stepper, BreadCrumb, Accordion, ConfirmDialog, Modal, Pagination, Table, Badge, Pills, Animated, FormControls, Toast, MenuList, Header, PageHeader, BottomSheet, Footer, AppShell } from "cleanplate";
|
|
300
308
|
```
|