prime-ui-kit 0.17.0 → 0.19.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 +2 -1
- package/dist/chunks/{chunk-PRP4B6OG.js → chunk-IVS3J7AS.js} +1 -1
- package/dist/chunks/{chunk-2ODXLPW3.js → chunk-QFHE5GKW.js} +1 -0
- package/dist/chunks/{chunk-7WWZYGRC.js → chunk-RZNGLELR.js} +4497 -3896
- package/dist/chunks/{chunk-A4WE3UNC.js → chunk-WYCTXD63.js} +18399 -17624
- package/dist/chunks/{chunk-SVFWPLNW.js → chunk-ZTZ2ML2B.js} +14 -3
- package/dist/color-picker.js +3 -3
- package/dist/components/badge/Badge.d.ts +17 -0
- package/dist/components/breadcrumb/Breadcrumb.d.ts +11 -2
- package/dist/components/button/Button.d.ts +1 -1
- package/dist/components/button-group/ButtonGroup.d.ts +1 -1
- package/dist/components/card/Card.d.ts +8 -4
- package/dist/components/chat/Chat.d.ts +3 -3
- package/dist/components/chat/MessageList.d.ts +5 -1
- package/dist/components/chat/groupMessages.d.ts +12 -4
- package/dist/components/chat-list/ChatList.d.ts +18 -9
- package/dist/components/chat-list/formatChatTime.d.ts +3 -3
- package/dist/components/checkbox/Checkbox.d.ts +6 -1
- package/dist/components/color-field/ColorField.d.ts +1 -1
- package/dist/components/color-picker/ColorPicker.d.ts +6 -1
- package/dist/components/color-picker/ColorPresets.d.ts +9 -1
- package/dist/components/crossfade/Crossfade.d.ts +1 -1
- package/dist/components/data-table/ColumnsMenu.d.ts +16 -20
- package/dist/components/data-table/DataTable.d.ts +16 -11
- package/dist/components/data-table/Head.d.ts +10 -1
- package/dist/components/data-table/Row.d.ts +7 -1
- package/dist/components/data-table/StateRows.d.ts +3 -1
- package/dist/components/data-table/types.d.ts +5 -0
- package/dist/components/digit-input/DigitInput.d.ts +1 -1
- package/dist/components/drawer/Drawer.d.ts +3 -2
- package/dist/components/field-list/FieldList.d.ts +24 -12
- package/dist/components/hint/Hint.d.ts +8 -2
- package/dist/components/index.d.ts +7 -4
- package/dist/components/input/Input.d.ts +27 -5
- package/dist/components/input/inputSuggestions.d.ts +39 -0
- package/dist/components/kanban/Kanban.d.ts +8 -9
- package/dist/components/list/List.d.ts +25 -6
- package/dist/components/message/Message.d.ts +15 -3
- package/dist/components/message/MessageSticker.d.ts +27 -0
- package/dist/components/message/formatMessageTime.d.ts +5 -2
- package/dist/components/modal/Modal.d.ts +3 -2
- package/dist/components/native-select/NativeSelect.d.ts +1 -1
- package/dist/components/radio/Radio.d.ts +11 -2
- package/dist/components/rich-text/RichText.d.ts +23 -0
- package/dist/components/scroll-container/ScrollContainer.d.ts +1 -1
- package/dist/components/scroll-container/scrollGlide.d.ts +26 -0
- package/dist/components/scroll-container/useScrollMotion.d.ts +25 -0
- package/dist/components/segmented-control/SegmentedControl.d.ts +1 -1
- package/dist/components/select/selectContext.d.ts +7 -0
- package/dist/components/slider/Slider.d.ts +1 -1
- package/dist/components/switch/Switch.d.ts +6 -1
- package/dist/components/tag-select/TagSelect.d.ts +1 -1
- package/dist/components/textarea/Textarea.d.ts +6 -1
- package/dist/components/timeline/Timeline.d.ts +1 -1
- package/dist/icon-set.js +2 -2
- package/dist/index.css +1 -1
- package/dist/index.js +5 -3
- package/dist/internal/ChoiceField.d.ts +3 -1
- package/dist/internal/FieldFrame.d.ts +8 -2
- package/dist/internal/fieldCell.d.ts +7 -1
- package/dist/internal/formatClock.d.ts +23 -2
- package/dist/internal/leaveGuard.d.ts +27 -0
- package/dist/internal/messageList.d.ts +2 -0
- package/dist/internal/overlay/DialogGuard.d.ts +3 -2
- package/dist/internal/overlay/DialogParts.d.ts +40 -6
- package/dist/internal/swatch.d.ts +5 -0
- package/dist/internal/tokenDefaults.d.ts +1 -0
- package/dist/layout/index.d.ts +1 -1
- package/dist/layout/page/Page.d.ts +48 -15
- package/dist/skill/anti-slop.md +28 -0
- package/dist/skill/api-contract.md +14 -7
- package/dist/skill/cheatsheet.md +28 -9
- package/dist/skill/checklist.md +9 -0
- package/dist/skill/choosing.md +25 -12
- package/dist/skill/components.md +1 -0
- package/dist/skill/composition.md +88 -16
- package/dist/skill/layouts.md +6 -4
- package/dist/skill/reference/components/badge/COMPONENT.md +14 -1
- package/dist/skill/reference/components/badge/examples/examples.module.css +7 -0
- package/dist/skill/reference/components/badge/examples/tag-row.tsx +34 -0
- package/dist/skill/reference/components/breadcrumb/COMPONENT.md +9 -4
- package/dist/skill/reference/components/breadcrumb/examples/router.tsx +17 -0
- package/dist/skill/reference/components/button/COMPONENT.md +1 -1
- package/dist/skill/reference/components/button-group/COMPONENT.md +1 -0
- package/dist/skill/reference/components/card/COMPONENT.md +7 -1
- package/dist/skill/reference/components/card/examples/states.tsx +59 -0
- package/dist/skill/reference/components/chat/COMPONENT.md +4 -1
- package/dist/skill/reference/components/chat/examples/time-zone.tsx +83 -0
- package/dist/skill/reference/components/chat-list/COMPONENT.md +12 -6
- package/dist/skill/reference/components/chat-list/examples/links.tsx +1 -1
- package/dist/skill/reference/components/chat-list/examples/router.tsx +63 -0
- package/dist/skill/reference/components/checkbox/COMPONENT.md +1 -0
- package/dist/skill/reference/components/color-field/COMPONENT.md +2 -1
- package/dist/skill/reference/components/color-picker/COMPONENT.md +14 -5
- package/dist/skill/reference/components/color-picker/examples/presets-custom.tsx +31 -0
- package/dist/skill/reference/components/color-swatches/COMPONENT.md +1 -0
- package/dist/skill/reference/components/confirm-dialog/COMPONENT.md +1 -1
- package/dist/skill/reference/components/crossfade/COMPONENT.md +1 -1
- package/dist/skill/reference/components/data-table/COMPONENT.md +46 -41
- package/dist/skill/reference/components/data-table/examples/actions-column.tsx +154 -0
- package/dist/skill/reference/components/data-table/examples/columns-visibility.tsx +3 -12
- package/dist/skill/reference/components/data-table/examples/controlled.tsx +1 -1
- package/dist/skill/reference/components/data-table/examples/narrow.tsx +4 -11
- package/dist/skill/reference/components/data-table/examples/numeric.tsx +9 -2
- package/dist/skill/reference/components/data-table/examples/row-link.tsx +18 -22
- package/dist/skill/reference/components/data-table/examples/screen.tsx +12 -1
- package/dist/skill/reference/components/data-table/examples/toolbar.tsx +26 -32
- package/dist/skill/reference/components/datepicker/COMPONENT.md +3 -1
- package/dist/skill/reference/components/datepicker/examples/deadline.tsx +33 -0
- package/dist/skill/reference/components/digit-input/COMPONENT.md +1 -0
- package/dist/skill/reference/components/dnd/COMPONENT.md +4 -3
- package/dist/skill/reference/components/dnd/examples/examples.module.css +4 -3
- package/dist/skill/reference/components/dnd/examples/handle.tsx +5 -5
- package/dist/skill/reference/components/dnd/examples/locked.tsx +1 -1
- package/dist/skill/reference/components/dnd/examples/table.tsx +6 -6
- package/dist/skill/reference/components/drawer/COMPONENT.md +38 -9
- package/dist/skill/reference/components/drawer/examples/client-card.tsx +32 -8
- package/dist/skill/reference/components/drawer/examples/header-actions.tsx +1 -1
- package/dist/skill/reference/components/drawer/examples/loading.tsx +58 -0
- package/dist/skill/reference/components/field-list/COMPONENT.md +40 -24
- package/dist/skill/reference/components/field-list/examples/base-row.tsx +2 -1
- package/dist/skill/reference/components/field-list/examples/locked.tsx +11 -11
- package/dist/skill/reference/components/field-list/examples/reorder.tsx +1 -1
- package/dist/skill/reference/components/field-list/examples/saving.tsx +83 -0
- package/dist/skill/reference/components/field-list/examples/screen.module.css +1 -1
- package/dist/skill/reference/components/field-list/examples/screen.tsx +168 -162
- package/dist/skill/reference/components/field-list/examples/totals.tsx +83 -0
- package/dist/skill/reference/components/file-upload/COMPONENT.md +1 -0
- package/dist/skill/reference/components/hint/COMPONENT.md +16 -2
- package/dist/skill/reference/components/hint/examples/variants.tsx +48 -0
- package/dist/skill/reference/components/input/COMPONENT.md +39 -9
- package/dist/skill/reference/components/input/examples/affixes.tsx +4 -2
- package/dist/skill/reference/components/input/examples/dismiss.tsx +29 -0
- package/dist/skill/reference/components/input/examples/suggestions.tsx +26 -0
- package/dist/skill/reference/components/input/examples/time.tsx +24 -0
- package/dist/skill/reference/components/input/examples/with-select.tsx +44 -0
- package/dist/skill/reference/components/kanban/COMPONENT.md +12 -8
- package/dist/skill/reference/components/kanban/examples/columns.tsx +4 -2
- package/dist/skill/reference/components/kanban/examples/states.tsx +7 -5
- package/dist/skill/reference/components/list/COMPONENT.md +39 -13
- package/dist/skill/reference/components/list/examples/reorder.tsx +42 -7
- package/dist/skill/reference/components/list/examples/row-controls.tsx +80 -0
- package/dist/skill/reference/components/list/examples/with-icon.tsx +23 -2
- package/dist/skill/reference/components/login-form/COMPONENT.md +8 -7
- package/dist/skill/reference/components/login-form/examples/states.tsx +12 -14
- package/dist/skill/reference/components/message/COMPONENT.md +30 -9
- package/dist/skill/reference/components/message/examples/preview.tsx +28 -0
- package/dist/skill/reference/components/message/examples/sticker.tsx +35 -0
- package/dist/skill/reference/components/modal/COMPONENT.md +35 -10
- package/dist/skill/reference/components/modal/examples/long-content.tsx +37 -18
- package/dist/skill/reference/components/native-select/COMPONENT.md +1 -0
- package/dist/skill/reference/components/notification/COMPONENT.md +1 -1
- package/dist/skill/reference/components/radio/COMPONENT.md +2 -0
- package/dist/skill/reference/components/rich-text/COMPONENT.md +93 -0
- package/dist/skill/reference/components/rich-text/examples/overview.tsx +19 -0
- package/dist/skill/reference/components/scroll-container/COMPONENT.md +8 -5
- package/dist/skill/reference/components/segmented-control/COMPONENT.md +4 -2
- package/dist/skill/reference/components/segmented-control/examples/in-form.tsx +1 -1
- package/dist/skill/reference/components/select/COMPONENT.md +7 -3
- package/dist/skill/reference/components/sheet/COMPONENT.md +18 -7
- package/dist/skill/reference/components/slider/COMPONENT.md +1 -0
- package/dist/skill/reference/components/slider/examples/controlled.tsx +1 -1
- package/dist/skill/reference/components/switch/COMPONENT.md +1 -0
- package/dist/skill/reference/components/tag-select/COMPONENT.md +1 -0
- package/dist/skill/reference/components/textarea/COMPONENT.md +1 -0
- package/dist/skill/reference/components/timeline/COMPONENT.md +3 -3
- package/dist/skill/reference/components/timeline/examples/structure.tsx +2 -1
- package/dist/skill/reference/layout/app-shell/COMPONENT.md +2 -2
- package/dist/skill/reference/layout/bottom-nav/COMPONENT.md +1 -0
- package/dist/skill/reference/layout/page/COMPONENT.md +42 -20
- package/dist/skill/reference/layout/page/examples/examples.module.css +7 -0
- package/dist/skill/reference/layout/page/examples/guard.tsx +87 -0
- package/dist/skill/reference/layout/page/examples/loading.tsx +57 -0
- package/dist/skill/reference/layout/page/examples/screen.module.css +1 -1
- package/dist/skill/reference/layout/page/examples/screen.tsx +93 -104
- package/dist/skill/reference/layout/page/examples/sections.tsx +2 -15
- package/dist/skill/reference/layout/sidebar/COMPONENT.md +1 -0
- package/dist/skill/responsive.md +19 -12
- package/dist/skill/ux.md +5 -3
- package/dist/tokens/semantic.d.ts +3 -1
- package/dist/tokens/themes/dark.d.ts +1 -1
- package/package.json +2 -2
- package/src/components/badge/COMPONENT.md +14 -1
- package/src/components/badge/examples/examples.module.css +7 -0
- package/src/components/badge/examples/tag-row.tsx +34 -0
- package/src/components/breadcrumb/COMPONENT.md +9 -4
- package/src/components/breadcrumb/examples/router.tsx +17 -0
- package/src/components/button/COMPONENT.md +1 -1
- package/src/components/button-group/COMPONENT.md +1 -0
- package/src/components/card/COMPONENT.md +7 -1
- package/src/components/card/examples/states.tsx +59 -0
- package/src/components/chat/COMPONENT.md +4 -1
- package/src/components/chat/examples/time-zone.tsx +83 -0
- package/src/components/chat-list/COMPONENT.md +12 -6
- package/src/components/chat-list/examples/links.tsx +1 -1
- package/src/components/chat-list/examples/router.tsx +63 -0
- package/src/components/checkbox/COMPONENT.md +1 -0
- package/src/components/color-field/COMPONENT.md +2 -1
- package/src/components/color-picker/COMPONENT.md +14 -5
- package/src/components/color-picker/examples/presets-custom.tsx +31 -0
- package/src/components/color-swatches/COMPONENT.md +1 -0
- package/src/components/confirm-dialog/COMPONENT.md +1 -1
- package/src/components/crossfade/COMPONENT.md +1 -1
- package/src/components/data-table/COMPONENT.md +46 -41
- package/src/components/data-table/examples/actions-column.tsx +154 -0
- package/src/components/data-table/examples/columns-visibility.tsx +3 -12
- package/src/components/data-table/examples/controlled.tsx +1 -1
- package/src/components/data-table/examples/narrow.tsx +4 -11
- package/src/components/data-table/examples/numeric.tsx +9 -2
- package/src/components/data-table/examples/row-link.tsx +18 -22
- package/src/components/data-table/examples/screen.tsx +12 -1
- package/src/components/data-table/examples/toolbar.tsx +26 -32
- package/src/components/datepicker/COMPONENT.md +3 -1
- package/src/components/datepicker/examples/deadline.tsx +33 -0
- package/src/components/digit-input/COMPONENT.md +1 -0
- package/src/components/dnd/COMPONENT.md +4 -3
- package/src/components/dnd/examples/examples.module.css +4 -3
- package/src/components/dnd/examples/handle.tsx +5 -5
- package/src/components/dnd/examples/locked.tsx +1 -1
- package/src/components/dnd/examples/table.tsx +6 -6
- package/src/components/drawer/COMPONENT.md +38 -9
- package/src/components/drawer/examples/client-card.tsx +32 -8
- package/src/components/drawer/examples/header-actions.tsx +1 -1
- package/src/components/drawer/examples/loading.tsx +58 -0
- package/src/components/field-list/COMPONENT.md +40 -24
- package/src/components/field-list/examples/base-row.tsx +2 -1
- package/src/components/field-list/examples/locked.tsx +11 -11
- package/src/components/field-list/examples/reorder.tsx +1 -1
- package/src/components/field-list/examples/saving.tsx +83 -0
- package/src/components/field-list/examples/screen.module.css +1 -1
- package/src/components/field-list/examples/screen.tsx +168 -162
- package/src/components/field-list/examples/totals.tsx +83 -0
- package/src/components/file-upload/COMPONENT.md +1 -0
- package/src/components/hint/COMPONENT.md +16 -2
- package/src/components/hint/examples/variants.tsx +48 -0
- package/src/components/input/COMPONENT.md +39 -9
- package/src/components/input/examples/affixes.tsx +4 -2
- package/src/components/input/examples/dismiss.tsx +29 -0
- package/src/components/input/examples/suggestions.tsx +26 -0
- package/src/components/input/examples/time.tsx +24 -0
- package/src/components/input/examples/with-select.tsx +44 -0
- package/src/components/kanban/COMPONENT.md +12 -8
- package/src/components/kanban/examples/columns.tsx +4 -2
- package/src/components/kanban/examples/states.tsx +7 -5
- package/src/components/list/COMPONENT.md +39 -13
- package/src/components/list/examples/reorder.tsx +42 -7
- package/src/components/list/examples/row-controls.tsx +80 -0
- package/src/components/list/examples/with-icon.tsx +23 -2
- package/src/components/login-form/COMPONENT.md +8 -7
- package/src/components/login-form/examples/states.tsx +12 -14
- package/src/components/message/COMPONENT.md +30 -9
- package/src/components/message/examples/preview.tsx +28 -0
- package/src/components/message/examples/sticker.tsx +35 -0
- package/src/components/modal/COMPONENT.md +35 -10
- package/src/components/modal/examples/long-content.tsx +37 -18
- package/src/components/native-select/COMPONENT.md +1 -0
- package/src/components/notification/COMPONENT.md +1 -1
- package/src/components/radio/COMPONENT.md +2 -0
- package/src/components/rich-text/COMPONENT.md +93 -0
- package/src/components/rich-text/examples/overview.tsx +19 -0
- package/src/components/scroll-container/COMPONENT.md +8 -5
- package/src/components/segmented-control/COMPONENT.md +4 -2
- package/src/components/segmented-control/examples/in-form.tsx +1 -1
- package/src/components/select/COMPONENT.md +7 -3
- package/src/components/sheet/COMPONENT.md +18 -7
- package/src/components/slider/COMPONENT.md +1 -0
- package/src/components/slider/examples/controlled.tsx +1 -1
- package/src/components/switch/COMPONENT.md +1 -0
- package/src/components/tag-select/COMPONENT.md +1 -0
- package/src/components/textarea/COMPONENT.md +1 -0
- package/src/components/timeline/COMPONENT.md +3 -3
- package/src/components/timeline/examples/structure.tsx +2 -1
- package/src/layout/app-shell/COMPONENT.md +2 -2
- package/src/layout/bottom-nav/COMPONENT.md +1 -0
- package/src/layout/page/COMPONENT.md +42 -20
- package/src/layout/page/examples/examples.module.css +7 -0
- package/src/layout/page/examples/guard.tsx +87 -0
- package/src/layout/page/examples/loading.tsx +57 -0
- package/src/layout/page/examples/screen.module.css +1 -1
- package/src/layout/page/examples/screen.tsx +93 -104
- package/src/layout/page/examples/sections.tsx +2 -15
- package/src/layout/sidebar/COMPONENT.md +1 -0
- package/src/styles/theme-dark.css +1 -1
- package/src/styles/theme-light.css +2 -1
- package/dist/components/data-table/context.d.ts +0 -14
- package/dist/components/scroll-container/useWheelToInline.d.ts +0 -10
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** A record editor as a document page, a long form whose title, description and save stand in the content header: a plan's name, its specs and prices
|
|
1
|
+
/** A record editor as a document page, a long form whose title, description and save stand in the content header and whose blocks are titled cards one under another: a plan's name, its specs and prices; repeating records as FieldList rows with the headings once, an icon and its color side by side, a base price pinned above its changes, one value in three currencies in one row — `getLocked`, `compact`. */
|
|
2
2
|
import {
|
|
3
3
|
Button,
|
|
4
4
|
Card,
|
|
@@ -29,9 +29,9 @@ type Period = { id: string; from: string; price: string; base?: boolean };
|
|
|
29
29
|
|
|
30
30
|
const SPEC_COLUMNS: FieldListColumn[] = [
|
|
31
31
|
{ label: "Иконка", width: "compact" },
|
|
32
|
+
{ label: "Цвет", width: "compact" },
|
|
32
33
|
{ label: "Параметр" },
|
|
33
34
|
{ label: "Значение" },
|
|
34
|
-
{ label: "Цвет", width: "compact" },
|
|
35
35
|
];
|
|
36
36
|
|
|
37
37
|
const SPEC_ICONS: { name: IconName; label: string }[] = [
|
|
@@ -97,6 +97,7 @@ const SAVED_MS = 2000;
|
|
|
97
97
|
|
|
98
98
|
export default function FieldListScreenExample() {
|
|
99
99
|
const formId = React.useId();
|
|
100
|
+
const specsTitleId = React.useId();
|
|
100
101
|
const [specs, setSpecs] = React.useState(SPECS);
|
|
101
102
|
const [periods, setPeriods] = React.useState(PERIODS);
|
|
102
103
|
const [nameError, setNameError] = React.useState<string>();
|
|
@@ -134,182 +135,187 @@ export default function FieldListScreenExample() {
|
|
|
134
135
|
</Page.Actions>
|
|
135
136
|
</Page.Header>
|
|
136
137
|
<Page.Body>
|
|
137
|
-
<
|
|
138
|
-
<
|
|
139
|
-
<Card.
|
|
140
|
-
<Card.
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
<form id={formId} noValidate onSubmit={save}>
|
|
139
|
+
<Card.Root variant="panel">
|
|
140
|
+
<Card.Header>
|
|
141
|
+
<Card.Title as="h2">Основное</Card.Title>
|
|
142
|
+
</Card.Header>
|
|
143
|
+
<Card.Body>
|
|
144
|
+
<Fieldset disabled={saving} aria-label="Основное">
|
|
145
|
+
<Input.Root label="Название" error={nameError}>
|
|
146
|
+
<Input.Wrapper>
|
|
147
|
+
<Input.Field name="name" defaultValue="Команда" />
|
|
148
|
+
</Input.Wrapper>
|
|
149
|
+
</Input.Root>
|
|
150
|
+
<Textarea.Root
|
|
151
|
+
name="summary"
|
|
152
|
+
label="Описание"
|
|
153
|
+
optional
|
|
154
|
+
rows={2}
|
|
155
|
+
defaultValue="Для отделов до 50 человек: задачи, документы и отчёты в одном месте."
|
|
156
|
+
/>
|
|
157
|
+
</Fieldset>
|
|
158
|
+
</Card.Body>
|
|
159
|
+
</Card.Root>
|
|
160
|
+
</form>
|
|
161
|
+
<Card.Root variant="panel">
|
|
162
|
+
<Card.Header>
|
|
163
|
+
<Card.Title as="h2" id={specsTitleId}>
|
|
164
|
+
Характеристики
|
|
165
|
+
</Card.Title>
|
|
166
|
+
<Card.Description>Первые три закреплены: их видно в карточке тарифа.</Card.Description>
|
|
167
|
+
</Card.Header>
|
|
168
|
+
<Card.Body>
|
|
169
|
+
<FieldList
|
|
170
|
+
aria-labelledby={specsTitleId}
|
|
171
|
+
disabled={saving}
|
|
172
|
+
columns={SPEC_COLUMNS}
|
|
173
|
+
reorderable
|
|
174
|
+
value={specs}
|
|
175
|
+
onValueChange={setSpecs}
|
|
176
|
+
getId={(spec) => spec.id}
|
|
177
|
+
getLabel={(spec) => spec.name}
|
|
178
|
+
getLocked={(spec) => spec.pinned ?? false}
|
|
179
|
+
createItem={(): Spec => ({
|
|
180
|
+
id: crypto.randomUUID(),
|
|
181
|
+
icon: "object.globe",
|
|
182
|
+
name: "",
|
|
183
|
+
value: "",
|
|
184
|
+
color: "#14b8a6",
|
|
185
|
+
})}
|
|
186
|
+
addLabel="Добавить характеристику"
|
|
187
|
+
renderItem={(spec, row) => (
|
|
188
|
+
<>
|
|
189
|
+
<Select.Root
|
|
190
|
+
value={spec.icon}
|
|
191
|
+
onValueChange={(icon) => row.update({ icon: icon as IconName })}
|
|
192
|
+
>
|
|
193
|
+
<Select.Trigger>
|
|
194
|
+
<Select.TriggerIcon>
|
|
195
|
+
<Icon name={spec.icon} />
|
|
196
|
+
</Select.TriggerIcon>
|
|
197
|
+
</Select.Trigger>
|
|
198
|
+
<Select.Content>
|
|
199
|
+
{SPEC_ICONS.map((icon) => (
|
|
200
|
+
<Select.Item key={icon.name} value={icon.name}>
|
|
201
|
+
<Select.ItemIcon>
|
|
202
|
+
<Icon name={icon.name} />
|
|
203
|
+
</Select.ItemIcon>
|
|
204
|
+
{icon.label}
|
|
205
|
+
</Select.Item>
|
|
206
|
+
))}
|
|
207
|
+
</Select.Content>
|
|
208
|
+
</Select.Root>
|
|
209
|
+
<ColorPresets.Root
|
|
210
|
+
value={spec.color}
|
|
211
|
+
onValueChange={(color) => row.update({ color: color ?? spec.color })}
|
|
212
|
+
>
|
|
213
|
+
<ColorPresets.Trigger>
|
|
214
|
+
<ColorPresets.SwatchButton />
|
|
215
|
+
</ColorPresets.Trigger>
|
|
216
|
+
<ColorPresets.Content />
|
|
217
|
+
</ColorPresets.Root>
|
|
218
|
+
<Input.Root>
|
|
143
219
|
<Input.Wrapper>
|
|
144
|
-
<Input.Field
|
|
220
|
+
<Input.Field
|
|
221
|
+
value={spec.name}
|
|
222
|
+
onChange={(event) => row.update({ name: event.target.value })}
|
|
223
|
+
/>
|
|
145
224
|
</Input.Wrapper>
|
|
146
225
|
</Input.Root>
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
<
|
|
161
|
-
<Card.
|
|
162
|
-
<Card.
|
|
226
|
+
<Input.Root>
|
|
227
|
+
<Input.Wrapper>
|
|
228
|
+
<Input.Field
|
|
229
|
+
value={spec.value}
|
|
230
|
+
onChange={(event) => row.update({ value: event.target.value })}
|
|
231
|
+
/>
|
|
232
|
+
</Input.Wrapper>
|
|
233
|
+
</Input.Root>
|
|
234
|
+
</>
|
|
235
|
+
)}
|
|
236
|
+
/>
|
|
237
|
+
</Card.Body>
|
|
238
|
+
</Card.Root>
|
|
239
|
+
<Card.Root variant="panel">
|
|
240
|
+
<Card.Header>
|
|
241
|
+
<Card.Title as="h2">Стоимость</Card.Title>
|
|
242
|
+
</Card.Header>
|
|
243
|
+
<Card.Body className={styles.groups}>
|
|
244
|
+
<Fieldset label="За месяц" disabled={saving}>
|
|
163
245
|
<FieldList
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
createItem={(): Spec => ({
|
|
174
|
-
id: crypto.randomUUID(),
|
|
175
|
-
icon: "object.globe",
|
|
176
|
-
name: "",
|
|
177
|
-
value: "",
|
|
178
|
-
color: "#14b8a6",
|
|
179
|
-
})}
|
|
180
|
-
addLabel="Добавить характеристику"
|
|
181
|
-
renderItem={(spec, row) => (
|
|
246
|
+
columns={PRICE_COLUMNS}
|
|
247
|
+
value={periods}
|
|
248
|
+
onValueChange={setPeriods}
|
|
249
|
+
getId={(period) => period.id}
|
|
250
|
+
getLocked={(period) => period.base ?? false}
|
|
251
|
+
labels={{ lockedReason: "Базовую цену нельзя удалить" }}
|
|
252
|
+
createItem={() => ({ id: crypto.randomUUID(), from: "", price: "" })}
|
|
253
|
+
addLabel="Добавить изменение цены"
|
|
254
|
+
renderItem={(period, row) => (
|
|
182
255
|
<>
|
|
183
|
-
|
|
184
|
-
value={spec.icon}
|
|
185
|
-
onValueChange={(icon) => row.update({ icon: icon as IconName })}
|
|
186
|
-
>
|
|
187
|
-
<Select.Trigger>
|
|
188
|
-
<Select.TriggerIcon>
|
|
189
|
-
<Icon name={spec.icon} />
|
|
190
|
-
</Select.TriggerIcon>
|
|
191
|
-
</Select.Trigger>
|
|
192
|
-
<Select.Content>
|
|
193
|
-
{SPEC_ICONS.map((icon) => (
|
|
194
|
-
<Select.Item key={icon.name} value={icon.name}>
|
|
195
|
-
<Select.ItemIcon>
|
|
196
|
-
<Icon name={icon.name} />
|
|
197
|
-
</Select.ItemIcon>
|
|
198
|
-
{icon.label}
|
|
199
|
-
</Select.Item>
|
|
200
|
-
))}
|
|
201
|
-
</Select.Content>
|
|
202
|
-
</Select.Root>
|
|
203
|
-
<Input.Root>
|
|
204
|
-
<Input.Wrapper>
|
|
205
|
-
<Input.Field
|
|
206
|
-
value={spec.name}
|
|
207
|
-
onChange={(event) => row.update({ name: event.target.value })}
|
|
208
|
-
/>
|
|
209
|
-
</Input.Wrapper>
|
|
210
|
-
</Input.Root>
|
|
211
|
-
<Input.Root>
|
|
212
|
-
<Input.Wrapper>
|
|
213
|
-
<Input.Field
|
|
214
|
-
value={spec.value}
|
|
215
|
-
onChange={(event) => row.update({ value: event.target.value })}
|
|
216
|
-
/>
|
|
217
|
-
</Input.Wrapper>
|
|
218
|
-
</Input.Root>
|
|
219
|
-
<ColorPresets.Root
|
|
220
|
-
value={spec.color}
|
|
221
|
-
onValueChange={(color) => row.update({ color: color ?? spec.color })}
|
|
222
|
-
>
|
|
223
|
-
<ColorPresets.Trigger>
|
|
224
|
-
<ColorPresets.SwatchButton />
|
|
225
|
-
</ColorPresets.Trigger>
|
|
226
|
-
<ColorPresets.Content />
|
|
227
|
-
</ColorPresets.Root>
|
|
228
|
-
</>
|
|
229
|
-
)}
|
|
230
|
-
/>
|
|
231
|
-
</Card.Body>
|
|
232
|
-
</Card.Root>
|
|
233
|
-
</Page.Section>
|
|
234
|
-
|
|
235
|
-
<Page.Section layout="aside" label="Стоимость">
|
|
236
|
-
<Card.Root variant="panel">
|
|
237
|
-
<Card.Body className={styles.groups}>
|
|
238
|
-
<Fieldset label="За месяц" disabled={saving}>
|
|
239
|
-
<FieldList
|
|
240
|
-
columns={PRICE_COLUMNS}
|
|
241
|
-
value={periods}
|
|
242
|
-
onValueChange={setPeriods}
|
|
243
|
-
getId={(period) => period.id}
|
|
244
|
-
getLocked={(period) => period.base ?? false}
|
|
245
|
-
createItem={() => ({ id: crypto.randomUUID(), from: "", price: "" })}
|
|
246
|
-
addLabel="Добавить изменение цены"
|
|
247
|
-
renderItem={(period, row) => (
|
|
248
|
-
<>
|
|
249
|
-
{period.base ? (
|
|
250
|
-
<Input.Root>
|
|
251
|
-
<Input.Wrapper>
|
|
252
|
-
<Input.Field value="Всегда, если нет изменений" readOnly />
|
|
253
|
-
</Input.Wrapper>
|
|
254
|
-
</Input.Root>
|
|
255
|
-
) : (
|
|
256
|
-
<Select.Root
|
|
257
|
-
value={period.from}
|
|
258
|
-
onValueChange={(from) => row.update({ from })}
|
|
259
|
-
placeholder="Выберите месяц"
|
|
260
|
-
>
|
|
261
|
-
<Select.Trigger>
|
|
262
|
-
<Select.Value />
|
|
263
|
-
</Select.Trigger>
|
|
264
|
-
<Select.Content>
|
|
265
|
-
{MONTHS.map((month) => (
|
|
266
|
-
<Select.Item key={month.value} value={month.value}>
|
|
267
|
-
{month.label}
|
|
268
|
-
</Select.Item>
|
|
269
|
-
))}
|
|
270
|
-
</Select.Content>
|
|
271
|
-
</Select.Root>
|
|
272
|
-
)}
|
|
256
|
+
{period.base ? (
|
|
273
257
|
<Input.Root>
|
|
274
258
|
<Input.Wrapper>
|
|
275
|
-
<Input.Field
|
|
276
|
-
value={period.price}
|
|
277
|
-
inputMode="decimal"
|
|
278
|
-
placeholder="0"
|
|
279
|
-
onChange={(event) => row.update({ price: event.target.value })}
|
|
280
|
-
/>
|
|
281
|
-
<Input.InlineAffix side="end">₽</Input.InlineAffix>
|
|
259
|
+
<Input.Field value="Всегда, если нет изменений" readOnly />
|
|
282
260
|
</Input.Wrapper>
|
|
283
261
|
</Input.Root>
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
262
|
+
) : (
|
|
263
|
+
<Select.Root
|
|
264
|
+
value={period.from}
|
|
265
|
+
onValueChange={(from) => row.update({ from })}
|
|
266
|
+
placeholder="Выберите месяц"
|
|
267
|
+
>
|
|
268
|
+
<Select.Trigger>
|
|
269
|
+
<Select.Value />
|
|
270
|
+
</Select.Trigger>
|
|
271
|
+
<Select.Content>
|
|
272
|
+
{MONTHS.map((month) => (
|
|
273
|
+
<Select.Item key={month.value} value={month.value}>
|
|
274
|
+
{month.label}
|
|
275
|
+
</Select.Item>
|
|
276
|
+
))}
|
|
277
|
+
</Select.Content>
|
|
278
|
+
</Select.Root>
|
|
279
|
+
)}
|
|
280
|
+
<Input.Root>
|
|
296
281
|
<Input.Wrapper>
|
|
297
282
|
<Input.Field
|
|
298
|
-
|
|
299
|
-
aria-label={fee.label}
|
|
283
|
+
value={period.price}
|
|
300
284
|
inputMode="decimal"
|
|
301
285
|
placeholder="0"
|
|
302
|
-
|
|
286
|
+
onChange={(event) => row.update({ price: event.target.value })}
|
|
303
287
|
/>
|
|
304
|
-
<Input.InlineAffix side="end"
|
|
288
|
+
<Input.InlineAffix side="end">₽</Input.InlineAffix>
|
|
305
289
|
</Input.Wrapper>
|
|
306
290
|
</Input.Root>
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
</
|
|
311
|
-
|
|
312
|
-
|
|
291
|
+
</>
|
|
292
|
+
)}
|
|
293
|
+
/>
|
|
294
|
+
</Fieldset>
|
|
295
|
+
<Fieldset
|
|
296
|
+
label="Подключение"
|
|
297
|
+
description="Разовый платёж; пустая валюта не выставляется."
|
|
298
|
+
disabled={saving}
|
|
299
|
+
>
|
|
300
|
+
<div className={styles.currencies}>
|
|
301
|
+
{SETUP_FEE.map((fee) => (
|
|
302
|
+
<Input.Root key={fee.name}>
|
|
303
|
+
<Input.Wrapper>
|
|
304
|
+
<Input.Field
|
|
305
|
+
name={fee.name}
|
|
306
|
+
aria-label={fee.label}
|
|
307
|
+
inputMode="decimal"
|
|
308
|
+
placeholder="0"
|
|
309
|
+
defaultValue={fee.value}
|
|
310
|
+
/>
|
|
311
|
+
<Input.InlineAffix side="end">{fee.currency}</Input.InlineAffix>
|
|
312
|
+
</Input.Wrapper>
|
|
313
|
+
</Input.Root>
|
|
314
|
+
))}
|
|
315
|
+
</div>
|
|
316
|
+
</Fieldset>
|
|
317
|
+
</Card.Body>
|
|
318
|
+
</Card.Root>
|
|
313
319
|
</Page.Body>
|
|
314
320
|
</Page.Root>
|
|
315
321
|
);
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** A deal bonus split between the team: the share takes a narrow column, and the totals row under the lines sums the shares and the amounts, each ending where its fields end their numbers — `renderTotals`, `width`. */
|
|
2
|
+
import { FieldList, type FieldListColumn, Input } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
type Share = { id: string; member: string; percent: string };
|
|
6
|
+
|
|
7
|
+
const BONUS = 240_000;
|
|
8
|
+
|
|
9
|
+
const COLUMNS: FieldListColumn[] = [
|
|
10
|
+
{ label: "Участник" },
|
|
11
|
+
{ label: "Доля", width: "xs" },
|
|
12
|
+
{ label: "Сумма", width: "m" },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const SHARES: Share[] = [
|
|
16
|
+
{ id: "sokolova", member: "Анна Соколова", percent: "50" },
|
|
17
|
+
{ id: "demin", member: "Олег Демин", percent: "30" },
|
|
18
|
+
{ id: "kotova", member: "Ирина Котова", percent: "20" },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const AMOUNT = new Intl.NumberFormat("ru-RU", { maximumFractionDigits: 0 });
|
|
22
|
+
|
|
23
|
+
const percentOf = (share: Share) => Number(share.percent.replace(",", ".")) || 0;
|
|
24
|
+
|
|
25
|
+
export default function FieldListTotalsExample() {
|
|
26
|
+
const [shares, setShares] = React.useState(SHARES);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<FieldList
|
|
30
|
+
label="Бонус по сделке"
|
|
31
|
+
hint="Доли в сумме дают 100 %."
|
|
32
|
+
columns={COLUMNS}
|
|
33
|
+
value={shares}
|
|
34
|
+
onValueChange={setShares}
|
|
35
|
+
getId={(share) => share.id}
|
|
36
|
+
getLabel={(share) => share.member}
|
|
37
|
+
createItem={() => ({ id: crypto.randomUUID(), member: "", percent: "" })}
|
|
38
|
+
addLabel="Добавить участника"
|
|
39
|
+
renderItem={(share, row) => (
|
|
40
|
+
<>
|
|
41
|
+
<Input.Root>
|
|
42
|
+
<Input.Wrapper>
|
|
43
|
+
<Input.Field
|
|
44
|
+
value={share.member}
|
|
45
|
+
onChange={(event) => row.update({ member: event.target.value })}
|
|
46
|
+
/>
|
|
47
|
+
</Input.Wrapper>
|
|
48
|
+
</Input.Root>
|
|
49
|
+
<Input.Root>
|
|
50
|
+
<Input.Wrapper>
|
|
51
|
+
<Input.Field
|
|
52
|
+
value={share.percent}
|
|
53
|
+
inputMode="decimal"
|
|
54
|
+
onChange={(event) => row.update({ percent: event.target.value })}
|
|
55
|
+
/>
|
|
56
|
+
<Input.InlineAffix side="end">%</Input.InlineAffix>
|
|
57
|
+
</Input.Wrapper>
|
|
58
|
+
</Input.Root>
|
|
59
|
+
<Input.Root>
|
|
60
|
+
<Input.Wrapper>
|
|
61
|
+
<Input.Field
|
|
62
|
+
value={AMOUNT.format((BONUS * percentOf(share)) / 100)}
|
|
63
|
+
inputMode="decimal"
|
|
64
|
+
readOnly
|
|
65
|
+
/>
|
|
66
|
+
<Input.InlineAffix side="end">₽</Input.InlineAffix>
|
|
67
|
+
</Input.Wrapper>
|
|
68
|
+
</Input.Root>
|
|
69
|
+
</>
|
|
70
|
+
)}
|
|
71
|
+
renderTotals={(items) => {
|
|
72
|
+
const percent = items.reduce((sum, share) => sum + percentOf(share), 0);
|
|
73
|
+
return (
|
|
74
|
+
<>
|
|
75
|
+
{null}
|
|
76
|
+
{`${percent} %`}
|
|
77
|
+
{`${AMOUNT.format((BONUS * percent) / 100)} ₽`}
|
|
78
|
+
</>
|
|
79
|
+
);
|
|
80
|
+
}}
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
@@ -120,6 +120,7 @@ A rejection of `upload` fails the file with its message as the reason; retry que
|
|
|
120
120
|
| `required` | `boolean` | — | Red `*` after the label and native `required` on the input. |
|
|
121
121
|
| `optional` | `boolean` | — | Muted marker right after the label text (`labels.optional`). |
|
|
122
122
|
| `hint` | `ReactNode` | — | Help text under the field. Hidden while `error` is shown. |
|
|
123
|
+
| `hintTone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of `hint` («Осталось 12 дней» in `warning`). The words carry the status, the color repeats it; an `error` replaces the hint and its tone. A validation error is `error`, never a `danger` hint. |
|
|
123
124
|
| `error` | `ReactNode` | — | Error message under the field (a rejected file, too few files); implies `invalid`. |
|
|
124
125
|
| `invalid` | `boolean` | — | Danger line and icon of the zone, `aria-invalid` on the input. A non-empty `error` implies it. |
|
|
125
126
|
| `focusRing` | `boolean` | `true` | `false` hides only the visual focus ring of the drop zone and the add tile (`data-focus-ring="false"`); focus, keyboard and ARIA stay. The picker Button keeps its ring. |
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
## When to use
|
|
9
9
|
- Under a control without `hint` / `error` props (an embedded `Datepicker.Panel`, a custom control), where you wire the ids yourself: format rules, limits, where the value comes from.
|
|
10
10
|
- As the error message of such a control (`invalid`), in the same slot as the hint.
|
|
11
|
+
- A status the field's value has (a deadline that nears, a check that passed): `tone`, with the status in the words.
|
|
11
12
|
|
|
12
13
|
## When not to use
|
|
13
14
|
- Input, Textarea, Select, Checkbox, Slider, SegmentedControl and other fields with `hint` / `error` props → pass the props; they render Hint and link the ids ([Input](../input/COMPONENT.md), [Textarea](../textarea/COMPONENT.md), [Checkbox](../checkbox/COMPONENT.md), [Slider](../slider/COMPONENT.md)).
|
|
@@ -36,6 +37,7 @@ Hint.Root <p> with the text
|
|
|
36
37
|
| Prop | Type | Default | Description |
|
|
37
38
|
|---|---|---|---|
|
|
38
39
|
| `size` | `"xs" \| "s" \| "m" \| "l" \| "xl"` | host tier, else `"m"` | Tier of the paired field: 12/16 for xs–m, 13/20 for l and xl. Without it the tier of its host, else `m`. |
|
|
40
|
+
| `tone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of the text (a deadline that nears, a check that passed). The words carry the status, the color repeats it; `invalid` and `disabled` take over the color. |
|
|
39
41
|
| `invalid` | `boolean` | `false` | Error styling: danger text that drops in (fade + 4 px from above). |
|
|
40
42
|
| `disabled` | `boolean` | `false` | Disabled text color, next to a disabled control. A disabled `Fieldset` around the hint sets it too. |
|
|
41
43
|
| `children` | `ReactNode` | — | Text, optionally with `Hint.Icon` first. |
|
|
@@ -49,7 +51,15 @@ Hint.Root <p> with the text
|
|
|
49
51
|
| `…rest` | `HTMLAttributes<HTMLSpanElement>` | — | `children` (the glyph), `className` and the other span attributes. |
|
|
50
52
|
|
|
51
53
|
## Variants
|
|
52
|
-
|
|
54
|
+
### tone
|
|
55
|
+
| Value | Looks like | Use when | Default |
|
|
56
|
+
|---|---|---|---|
|
|
57
|
+
| `neutral` | Muted text | Format rules, limits, where the value comes from | yes |
|
|
58
|
+
| `success` | Success text | The value passed a check («ИНН проверен») | |
|
|
59
|
+
| `warning` | Warning text | The value needs attention soon («Осталось 12 дней») | |
|
|
60
|
+
| `danger` | Danger text, no `aria-invalid` | A status of the data, not a validation error («Срок истёк») | |
|
|
61
|
+
|
|
62
|
+
The words carry the status; the color only repeats it, and a `Hint.Icon` with the status glyph adds a shape. A validation error is `invalid` (or a field's `error`), never `tone="danger"`. `invalid` and `disabled` take over the tone's color.
|
|
53
63
|
|
|
54
64
|
### size
|
|
55
65
|
| Value | Looks like | Use when | Default |
|
|
@@ -68,11 +78,12 @@ The hint is always smaller than the field text; use the field's size.
|
|
|
68
78
|
| `invalid` | Danger text, drops in | Validation error | `false` |
|
|
69
79
|
| `disabled` | Disabled text | Under a disabled control | `false` |
|
|
70
80
|
|
|
71
|
-
**Combinations** — one element switches between the hint text and the error text with `invalid` (no layout jump); a standalone hint that changes after an action stays mounted with `aria-live="polite"` (inside a field the frame does it). `invalid` and `disabled` together make no sense.
|
|
81
|
+
**Combinations** — one element switches between the hint text and the error text with `invalid` (no layout jump); a standalone hint that changes after an action stays mounted with `aria-live="polite"` (inside a field the frame does it). `invalid` and `disabled` together make no sense. A result of the whole form goes to a [Banner](../banner/COMPONENT.md), not a toned hint.
|
|
72
82
|
|
|
73
83
|
## States
|
|
74
84
|
| State | Driven by | DOM |
|
|
75
85
|
|---|---|---|
|
|
86
|
+
| status | `tone` | `data-tone` with the shared text tone (none for `neutral`, and none while `invalid` or `disabled`); the color eases between tones |
|
|
76
87
|
| error | `invalid` | `data-invalid="true"`; the message drops in over `fast` (fade + `--prime-space-1` from above, no shake, no layout shift) and the color eases from the hint color |
|
|
77
88
|
| disabled | `disabled`, or a disabled `Fieldset` around it | `data-disabled="true"` |
|
|
78
89
|
| size | `size`, else the host tier | `data-size` |
|
|
@@ -106,6 +117,7 @@ No `labels`.
|
|
|
106
117
|
| Example | Shows |
|
|
107
118
|
|---|---|
|
|
108
119
|
| [overview.tsx](examples/overview.tsx) | Help text under a calendar that has no hint of its own, linked to it through `id` and `aria-describedby` — `id`. |
|
|
120
|
+
| [variants.tsx](examples/variants.tsx) | Status hints whose words carry the status and the color repeats it — `tone`. |
|
|
109
121
|
| [sizes.tsx](examples/sizes.tsx) | Every size tier, one per field tier: 12/16 for xs–m, 13/20 for l and xl — `size`. |
|
|
110
122
|
| [states.tsx](examples/states.tsx) | Default help text next to an error and a hint under a disabled control — `invalid`, `disabled`. |
|
|
111
123
|
| [with-icon.tsx](examples/with-icon.tsx) | A leading icon centred on the first line, in the default and the error state — `Hint.Icon`. |
|
|
@@ -116,6 +128,8 @@ No `labels`.
|
|
|
116
128
|
- A separate hint and error element at the same time → one element; the error replaces the hint.
|
|
117
129
|
- Hint without `id` + `aria-describedby` → the screen reader does not connect it to the field.
|
|
118
130
|
- Hint size different from the field size → use the same `size`, or none inside a sized host.
|
|
131
|
+
- `tone="danger"` for a validation error → `invalid` (or the field's `error`): only it sets `aria-invalid`.
|
|
132
|
+
- A status by color alone («12 д.» in orange) → the words say it («Осталось 12 дней»), the tone repeats it.
|
|
119
133
|
- `role="alert"` on a field error → none; the field frame announces it, a standalone hint takes `aria-live="polite"`.
|
|
120
134
|
|
|
121
135
|
## Related
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Status hints whose words carry the status and the color repeats it — `tone`. */
|
|
2
|
+
import { Hint, Icon, Typography } from "prime-ui-kit";
|
|
3
|
+
|
|
4
|
+
export default function HintVariantsExample() {
|
|
5
|
+
return (
|
|
6
|
+
<div>
|
|
7
|
+
<div>
|
|
8
|
+
<Hint.Root>Действует до 30 ноября.</Hint.Root>
|
|
9
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
10
|
+
neutral
|
|
11
|
+
</Typography>
|
|
12
|
+
</div>
|
|
13
|
+
<div>
|
|
14
|
+
<Hint.Root tone="success">
|
|
15
|
+
<Hint.Icon>
|
|
16
|
+
<Icon name="status.success" />
|
|
17
|
+
</Hint.Icon>
|
|
18
|
+
ИНН проверен в ФНС.
|
|
19
|
+
</Hint.Root>
|
|
20
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
21
|
+
success
|
|
22
|
+
</Typography>
|
|
23
|
+
</div>
|
|
24
|
+
<div>
|
|
25
|
+
<Hint.Root tone="warning">
|
|
26
|
+
<Hint.Icon>
|
|
27
|
+
<Icon name="status.warning" />
|
|
28
|
+
</Hint.Icon>
|
|
29
|
+
Осталось 12 дней.
|
|
30
|
+
</Hint.Root>
|
|
31
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
32
|
+
warning
|
|
33
|
+
</Typography>
|
|
34
|
+
</div>
|
|
35
|
+
<div>
|
|
36
|
+
<Hint.Root tone="danger">
|
|
37
|
+
<Hint.Icon>
|
|
38
|
+
<Icon name="status.danger" />
|
|
39
|
+
</Hint.Icon>
|
|
40
|
+
Срок истёк 3 дня назад.
|
|
41
|
+
</Hint.Root>
|
|
42
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
43
|
+
danger
|
|
44
|
+
</Typography>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|