prime-ui-kit 0.13.0 → 0.14.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 +7 -6
- package/dist/chunks/{chunk-ZSJMNA46.js → chunk-P6ZO37JM.js} +1 -1
- package/dist/chunks/{chunk-Z3WKKAS6.js → chunk-SYEX7OVT.js} +3572 -2865
- package/dist/chunks/{chunk-E6SQBSDF.js → chunk-WXKRUVSE.js} +199 -162
- package/dist/color-picker.js +2 -2
- package/dist/components/banner/Banner.d.ts +5 -2
- package/dist/components/chart-frame/ChartFrame.d.ts +19 -6
- package/dist/components/chat/Chat.d.ts +2 -2
- package/dist/components/chat/ChatPinned.d.ts +2 -2
- package/dist/components/chat/MessageList.d.ts +1 -1
- package/dist/components/chat/chatContext.d.ts +1 -1
- package/dist/components/field-list/FieldList.d.ts +90 -0
- package/dist/components/index.d.ts +3 -1
- package/dist/components/input/Input.d.ts +2 -2
- package/dist/components/kanban/Kanban.d.ts +6 -3
- package/dist/components/page-content/PageContent.d.ts +55 -4
- package/dist/components/sparkline/Sparkline.d.ts +64 -15
- package/dist/components/sparkline/geometry.d.ts +26 -0
- package/dist/components/tooltip/Tooltip.d.ts +5 -2
- package/dist/hooks/usePosition.d.ts +15 -4
- package/dist/index.css +1 -1
- package/dist/index.js +4 -2
- package/dist/internal/ChartTooltip.d.ts +26 -0
- package/dist/internal/FieldAction.d.ts +6 -7
- package/dist/internal/fieldCell.d.ts +21 -0
- package/dist/internal/messageList.d.ts +2 -2
- package/dist/internal/palette.d.ts +7 -0
- package/dist/skill/SKILL.md +24 -14
- package/dist/skill/anti-slop.md +77 -4
- package/dist/skill/cheatsheet.md +24 -5
- package/dist/skill/checklist.md +19 -1
- package/dist/skill/choosing.md +10 -5
- package/dist/skill/components.md +4 -3
- package/dist/skill/composition.md +28 -15
- package/dist/skill/foundations.md +8 -6
- package/dist/skill/layouts.md +6 -6
- package/dist/skill/patterns/app-shell.module.css +1 -8
- package/dist/skill/patterns/app-shell.tsx +11 -9
- package/dist/skill/patterns/chat.tsx +23 -5
- package/dist/skill/patterns/dashboard.module.css +1 -31
- package/dist/skill/patterns/dashboard.tsx +150 -136
- package/dist/skill/patterns/detail-page.module.css +0 -3
- package/dist/skill/patterns/detail-page.tsx +4 -7
- package/dist/skill/patterns/form-drawer.tsx +2 -2
- package/dist/skill/patterns/kanban-board.tsx +4 -2
- package/dist/skill/patterns/list-page.tsx +2 -2
- package/dist/skill/patterns/media-library.module.css +0 -22
- package/dist/skill/patterns/media-library.tsx +17 -18
- package/dist/skill/patterns/record-editor.module.css +18 -0
- package/dist/skill/patterns/record-editor.tsx +356 -0
- package/dist/skill/patterns/screen-states.module.css +3 -17
- package/dist/skill/patterns/screen-states.tsx +70 -69
- package/dist/skill/patterns/settings-page.module.css +1 -21
- package/dist/skill/patterns/settings-page.tsx +58 -79
- package/dist/skill/reference/components/avatar/COMPONENT.md +4 -4
- package/dist/skill/reference/components/avatar/examples/presence.tsx +1 -1
- package/dist/skill/reference/components/avatar/examples/states.tsx +1 -1
- package/dist/skill/reference/components/banner/COMPONENT.md +6 -6
- package/dist/skill/reference/components/banner/examples/dismissible.tsx +22 -11
- package/dist/skill/reference/components/banner/examples/examples.module.css +3 -3
- package/dist/skill/reference/components/banner/examples/narrow.tsx +1 -1
- package/dist/skill/reference/components/breadcrumb/COMPONENT.md +1 -1
- package/dist/skill/reference/components/breadcrumb/examples/overflow.tsx +1 -1
- package/dist/skill/reference/components/card/COMPONENT.md +5 -4
- package/dist/skill/reference/components/card/examples/examples.module.css +0 -28
- package/dist/skill/reference/components/card/examples/kpi-media.tsx +13 -11
- package/dist/skill/reference/components/card/examples/narrow.tsx +1 -1
- package/dist/skill/reference/components/card/examples/panel-chart.tsx +45 -22
- package/dist/skill/reference/components/chart-frame/COMPONENT.md +10 -7
- package/dist/skill/reference/components/chart-frame/examples/tooltip.tsx +20 -24
- package/dist/skill/reference/components/chat/COMPONENT.md +3 -3
- package/dist/skill/reference/components/chat/examples/search.tsx +1 -1
- package/dist/skill/reference/components/chat-list/COMPONENT.md +1 -1
- package/dist/skill/reference/components/checkbox/examples/indicator.tsx +24 -2
- package/dist/skill/reference/components/color-picker/COMPONENT.md +2 -2
- package/dist/skill/reference/components/color-swatches/COMPONENT.md +1 -0
- package/dist/skill/reference/components/datepicker/COMPONENT.md +1 -0
- package/dist/skill/reference/components/dnd/COMPONENT.md +3 -3
- package/dist/skill/reference/components/field-list/COMPONENT.md +164 -0
- package/dist/skill/reference/components/field-list/examples/base-row.tsx +76 -0
- package/dist/skill/reference/components/field-list/examples/controlled.tsx +72 -0
- package/dist/skill/reference/components/field-list/examples/errors.tsx +85 -0
- package/dist/skill/reference/components/field-list/examples/examples.module.css +34 -0
- package/dist/skill/reference/components/field-list/examples/limits.tsx +55 -0
- package/dist/skill/reference/components/field-list/examples/locked.tsx +139 -0
- package/dist/skill/reference/components/field-list/examples/narrow.tsx +68 -0
- package/dist/skill/reference/components/field-list/examples/overview.tsx +66 -0
- package/dist/skill/reference/components/field-list/examples/reorder.tsx +42 -0
- package/dist/skill/reference/components/field-list/examples/sizes.tsx +42 -0
- package/dist/skill/reference/components/field-list/examples/states.tsx +51 -0
- package/dist/skill/reference/components/input/examples/examples.module.css +2 -7
- package/dist/skill/reference/components/kanban/COMPONENT.md +13 -9
- package/dist/skill/reference/components/kanban/examples/limits.tsx +2 -1
- package/dist/skill/reference/components/kanban/examples/variants.tsx +16 -8
- package/dist/skill/reference/components/list/COMPONENT.md +1 -1
- package/dist/skill/reference/components/media-viewer/COMPONENT.md +2 -2
- package/dist/skill/reference/components/message/COMPONENT.md +2 -2
- package/dist/skill/reference/components/notification/COMPONENT.md +1 -0
- package/dist/skill/reference/components/page-content/COMPONENT.md +70 -14
- package/dist/skill/reference/components/page-content/examples/grid.tsx +107 -0
- package/dist/skill/reference/components/page-content/examples/overview.tsx +2 -2
- package/dist/skill/reference/components/page-content/examples/sections.tsx +81 -0
- package/dist/skill/reference/components/page-toolbar/COMPONENT.md +1 -1
- package/dist/skill/reference/components/segmented-control/COMPONENT.md +1 -0
- package/dist/skill/reference/components/select/COMPONENT.md +4 -2
- package/dist/skill/reference/components/select/examples/icon-only.tsx +38 -0
- package/dist/skill/reference/components/sparkline/COMPONENT.md +83 -30
- package/dist/skill/reference/components/sparkline/examples/compact.tsx +1 -1
- package/dist/skill/reference/components/sparkline/examples/curve.tsx +28 -0
- package/dist/skill/reference/components/sparkline/examples/gaps.tsx +33 -0
- package/dist/skill/reference/components/sparkline/examples/overview.tsx +11 -2
- package/dist/skill/reference/components/sparkline/examples/period.tsx +7 -2
- package/dist/skill/reference/components/sparkline/examples/reference.tsx +37 -0
- package/dist/skill/reference/components/sparkline/examples/variants.tsx +2 -2
- package/dist/skill/reference/components/tabs/examples/examples.module.css +0 -6
- package/dist/skill/reference/components/tabs/examples/in-drawer.tsx +11 -13
- package/dist/skill/reference/components/timeline/examples/examples.module.css +0 -8
- package/dist/skill/reference/components/timeline/examples/narrow.tsx +2 -2
- package/dist/skill/reference/components/timeline/examples/sizes.tsx +3 -3
- package/dist/skill/reference/components/timeline/examples/variants.tsx +4 -4
- package/dist/skill/reference/components/tooltip/COMPONENT.md +6 -4
- package/dist/skill/reference/components/tooltip/examples/placement.tsx +2 -1
- package/dist/skill/reference/components/video-note/COMPONENT.md +1 -1
- package/dist/skill/reference/components/voice-player/COMPONENT.md +1 -1
- package/dist/skill/reference/layout/app-header/examples/in-app-shell.tsx +2 -2
- package/dist/skill/reference/layout/app-shell/COMPONENT.md +1 -1
- package/dist/skill/reference/layout/app-shell/examples/footer.tsx +2 -2
- package/dist/skill/reference/layout/app-shell/examples/overview.tsx +2 -2
- package/dist/skill/reference/layout/app-shell/examples/template.tsx +2 -2
- package/dist/skill/reference/layout/bottom-nav/examples/floating-action.tsx +2 -2
- package/dist/skill/reference/layout/bottom-nav/examples/floating.tsx +2 -2
- package/dist/skill/reference/layout/bottom-nav/examples/in-app-shell.tsx +2 -2
- package/dist/skill/responsive.md +5 -3
- package/dist/skill/ux.md +145 -0
- package/dist/tokens/semantic.d.ts +2 -0
- package/package.json +1 -1
- package/src/components/avatar/COMPONENT.md +4 -4
- package/src/components/avatar/examples/presence.tsx +1 -1
- package/src/components/avatar/examples/states.tsx +1 -1
- package/src/components/banner/COMPONENT.md +6 -6
- package/src/components/banner/examples/dismissible.tsx +22 -11
- package/src/components/banner/examples/examples.module.css +3 -3
- package/src/components/banner/examples/narrow.tsx +1 -1
- package/src/components/breadcrumb/COMPONENT.md +1 -1
- package/src/components/breadcrumb/examples/overflow.tsx +1 -1
- package/src/components/card/COMPONENT.md +5 -4
- package/src/components/card/examples/examples.module.css +0 -28
- package/src/components/card/examples/kpi-media.tsx +13 -11
- package/src/components/card/examples/narrow.tsx +1 -1
- package/src/components/card/examples/panel-chart.tsx +45 -22
- package/src/components/chart-frame/COMPONENT.md +10 -7
- package/src/components/chart-frame/examples/tooltip.tsx +20 -24
- package/src/components/chat/COMPONENT.md +3 -3
- package/src/components/chat/examples/search.tsx +1 -1
- package/src/components/chat-list/COMPONENT.md +1 -1
- package/src/components/checkbox/examples/indicator.tsx +24 -2
- package/src/components/color-picker/COMPONENT.md +2 -2
- package/src/components/color-swatches/COMPONENT.md +1 -0
- package/src/components/datepicker/COMPONENT.md +1 -0
- package/src/components/dnd/COMPONENT.md +3 -3
- package/src/components/field-list/COMPONENT.md +164 -0
- package/src/components/field-list/examples/base-row.tsx +76 -0
- package/src/components/field-list/examples/controlled.tsx +72 -0
- package/src/components/field-list/examples/errors.tsx +85 -0
- package/src/components/field-list/examples/examples.module.css +34 -0
- package/src/components/field-list/examples/limits.tsx +55 -0
- package/src/components/field-list/examples/locked.tsx +139 -0
- package/src/components/field-list/examples/narrow.tsx +68 -0
- package/src/components/field-list/examples/overview.tsx +66 -0
- package/src/components/field-list/examples/reorder.tsx +42 -0
- package/src/components/field-list/examples/sizes.tsx +42 -0
- package/src/components/field-list/examples/states.tsx +51 -0
- package/src/components/input/examples/examples.module.css +2 -7
- package/src/components/kanban/COMPONENT.md +13 -9
- package/src/components/kanban/examples/limits.tsx +2 -1
- package/src/components/kanban/examples/variants.tsx +16 -8
- package/src/components/list/COMPONENT.md +1 -1
- package/src/components/media-viewer/COMPONENT.md +2 -2
- package/src/components/message/COMPONENT.md +2 -2
- package/src/components/notification/COMPONENT.md +1 -0
- package/src/components/page-content/COMPONENT.md +70 -14
- package/src/components/page-content/examples/grid.tsx +107 -0
- package/src/components/page-content/examples/overview.tsx +2 -2
- package/src/components/page-content/examples/sections.tsx +81 -0
- package/src/components/page-toolbar/COMPONENT.md +1 -1
- package/src/components/segmented-control/COMPONENT.md +1 -0
- package/src/components/select/COMPONENT.md +4 -2
- package/src/components/select/examples/icon-only.tsx +38 -0
- package/src/components/sparkline/COMPONENT.md +83 -30
- package/src/components/sparkline/examples/compact.tsx +1 -1
- package/src/components/sparkline/examples/curve.tsx +28 -0
- package/src/components/sparkline/examples/gaps.tsx +33 -0
- package/src/components/sparkline/examples/overview.tsx +11 -2
- package/src/components/sparkline/examples/period.tsx +7 -2
- package/src/components/sparkline/examples/reference.tsx +37 -0
- package/src/components/sparkline/examples/variants.tsx +2 -2
- package/src/components/tabs/examples/examples.module.css +0 -6
- package/src/components/tabs/examples/in-drawer.tsx +11 -13
- package/src/components/timeline/examples/examples.module.css +0 -8
- package/src/components/timeline/examples/narrow.tsx +2 -2
- package/src/components/timeline/examples/sizes.tsx +3 -3
- package/src/components/timeline/examples/variants.tsx +4 -4
- package/src/components/tooltip/COMPONENT.md +6 -4
- package/src/components/tooltip/examples/placement.tsx +2 -1
- package/src/components/video-note/COMPONENT.md +1 -1
- package/src/components/voice-player/COMPONENT.md +1 -1
- package/src/layout/app-header/examples/in-app-shell.tsx +2 -2
- package/src/layout/app-shell/COMPONENT.md +1 -1
- package/src/layout/app-shell/examples/footer.tsx +2 -2
- package/src/layout/app-shell/examples/overview.tsx +2 -2
- package/src/layout/app-shell/examples/template.tsx +2 -2
- package/src/layout/bottom-nav/examples/floating-action.tsx +2 -2
- package/src/layout/bottom-nav/examples/floating.tsx +2 -2
- package/src/layout/bottom-nav/examples/in-app-shell.tsx +2 -2
- package/src/styles/theme-light.css +1 -0
|
@@ -3,14 +3,17 @@
|
|
|
3
3
|
**Category:** data-display
|
|
4
4
|
**Kind:** primitive
|
|
5
5
|
|
|
6
|
-
> A small line or
|
|
6
|
+
> A small chart — a smooth line over a fading area, a bare line or bars — with its headline: the value at rest, its change and its date; any point can be scrubbed.
|
|
7
7
|
|
|
8
8
|
## When to use
|
|
9
9
|
- A metric card on a dashboard: revenue, orders, sign-ups over the last days or weeks.
|
|
10
10
|
- A trend next to a number where the shape matters more than exact axes.
|
|
11
11
|
- Values with a sign by period — profit, net new customers (`variant="bars"`: up when positive, down when negative), with the current period highlighted (`highlight`).
|
|
12
12
|
- A detail page header that shows how a value moved.
|
|
13
|
-
- A trend per record in a table cell or a list row (`layout="compact"`): revenue by month per client
|
|
13
|
+
- A trend per record in a table cell or a list row (`layout="compact"`): revenue by month per client; one scale for the whole column with `min` / `max`.
|
|
14
|
+
- A daily flow over a period — revenue, orders, sign-ups (`summary="sum"`, `compareTo` the previous period).
|
|
15
|
+
- A metric against its plan or average (`reference`), or its change over the whole period (`change="first"`).
|
|
16
|
+
- A series with missing days — a collector that was down (`value: null` breaks the line).
|
|
14
17
|
|
|
15
18
|
## When not to use
|
|
16
19
|
- Exact values on axes, several series, or a legend → a full chart library on the kit's chart palette (`chartColors`); Sparkline has no axes.
|
|
@@ -28,10 +31,13 @@ import { Sparkline, type SparklinePoint } from "prime-ui-kit";
|
|
|
28
31
|
Sparkline <div>; the headline and the chart; aria-busy while loading
|
|
29
32
|
├─ head title (label) · date of the shown point
|
|
30
33
|
├─ value row value (rolling digits when settled) · change Badge with the trend arrow
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
├─ plot role="slider" over the chart
|
|
35
|
+
│ ├─ reference dashed line at `reference` (aria-hidden)
|
|
36
|
+
│ ├─ area · line: svg gradient area and monotone line, lone points as dots + cursor (guide and dot, aria-hidden)
|
|
37
|
+
│ └─ bars: zero line (chart axis) + a slot per point with its bar (aria-hidden)
|
|
38
|
+
└─ reference text hidden; describes the slider (aria-describedby)
|
|
34
39
|
loading: Skeletons of the date, the value line and the plot
|
|
40
|
+
tooltip: the kit chart tooltip (date · value) right of the pointer, portaled to <body>, aria-hidden
|
|
35
41
|
compact: the plot alone (no head, no value row); loading — the plot Skeleton
|
|
36
42
|
```
|
|
37
43
|
|
|
@@ -40,17 +46,24 @@ compact: the plot alone (no head, no value row); loading — the p
|
|
|
40
46
|
<!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
|
|
41
47
|
|
|
42
48
|
### Sparkline
|
|
43
|
-
`ref` → `HTMLDivElement` (the root). A headline (title · date, value · change) over
|
|
49
|
+
`ref` → `HTMLDivElement` (the root). A headline (title · date, value · change) over an area, line or bar chart; the chart is a `role="slider"` that picks a point, a tooltip beside the pointer shows the value and date. The change hides when a percentage means nothing.
|
|
44
50
|
|
|
45
51
|
| Prop | Type | Default | Description |
|
|
46
52
|
|---|---|---|---|
|
|
47
|
-
| `data` | `SparklinePoint[]` | — (required) | Points oldest first, `{ label, value }`; `label` names the point («8 окт»)
|
|
53
|
+
| `data` | `SparklinePoint[]` | — (required) | Points oldest first, `{ label, value }`; `label` names the point («8 окт»), `value: null` is a point with no data — the line breaks, the bar is absent. A new array cross-fades the chart in. |
|
|
48
54
|
| `label` | `string` | — (required) | Visible title above the value and the accessible name of the chart; with `layout="compact"` only the accessible name. |
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
55
|
+
| `variant` | `"area" \| "line" \| "bars"` | `"area"` | `area` — a line over an accent gradient that fades to the bottom; `line` — the line alone, for many trends side by side; `bars` — a bar per point standing on a zero line: up when positive, down (danger) when negative. |
|
|
56
|
+
| `curve` | `"smooth" \| "linear" \| "step"` | `"smooth"` | Shape of the line (`area`, `line`): `smooth` — a monotone cubic through every point that never overshoots a peak or a trough; `linear` — straight segments; `step` — a level per point, changing halfway between points. |
|
|
57
|
+
| `layout` | `"default" \| "compact"` | `"default"` | `default` — the headline over an 80 px plot; `compact` — the plot alone at an `xs` control height with the dot at rest, for a DataTable cell; the scrubbed point shows in the tooltip and `aria-valuetext`. |
|
|
58
|
+
| `change` | `"previous" \| "first" \| "none"` | `"previous"` | What the change badge of a shown point compares it with: `previous` — the point before it; `first` — the first point with a value (the change over the period); `none` — no badge. |
|
|
59
|
+
| `summary` | `"latest" \| "sum" \| "average"` | `"latest"` | What the headline shows at rest: `latest` — the latest point (or `highlight`), for a level (MRR, conversion); `sum` — the period total, for a flow (revenue per day); `average` — the period mean. |
|
|
60
|
+
| `highlight` | `number` | `the latest point with a value` | Index of the point at rest with `summary="latest"` (the current month): the headline returns to it; `bars` draw the other bars quieter. Not allowed with `sum` / `average`. |
|
|
61
|
+
| `compareTo` | `number` | — | The same summary for the previous period («прошлые 30 дней»): the badge at rest compares the headline with it. Without it a `sum` / `average` headline shows no change at rest. |
|
|
62
|
+
| `min` | `number` | — | The value axis reaches down to at least this value: a floor of zero, or one scale for several sparklines (a table column). Data below widens the scale, never gets cut. |
|
|
63
|
+
| `max` | `number` | — | The value axis reaches up to at least this value; data above widens the scale. |
|
|
64
|
+
| `reference` | `number` | — | A dashed horizontal line at this value — a plan, a target, an average; the scale holds it and the chart is described by `labels.reference`. |
|
|
52
65
|
| `loading` | `boolean` | `false` | The series is on its way: Skeletons of the date, the value and the plot that cross-fade into the data; the title stays, the root is `aria-busy` and the chart is not focusable yet. |
|
|
53
|
-
| `formatValue` | `(value: number) => string` | `Russian digit groups` | Display of a value in the headline and the spoken point («312 400 ₽»). |
|
|
66
|
+
| `formatValue` | `(value: number) => string` | `Russian digit groups` | Display of a value in the headline, the tooltip, the reference description and the spoken point («312 400 ₽»). |
|
|
54
67
|
| `labels` | `Partial<SparklineLabels>` | — | Built-in strings, see Labels. |
|
|
55
68
|
| `…rest` | `Omit<HTMLAttributes<HTMLDivElement>, "children">` | — | `className`, `data-*` and the other div attributes on the root. |
|
|
56
69
|
|
|
@@ -59,19 +72,45 @@ compact: the plot alone (no head, no value row); loading — the p
|
|
|
59
72
|
### variant
|
|
60
73
|
| Value | Looks like | Use when | Default |
|
|
61
74
|
|---|---|---|---|
|
|
62
|
-
| `
|
|
75
|
+
| `area` | an accent line over a gradient that fades to the bottom, a dot on the shown point | a continuous trend in a tile (daily revenue) | yes |
|
|
76
|
+
| `line` | the accent line alone, a dot on the shown point | many trends side by side, a quiet trend in a dense list | |
|
|
63
77
|
| `bars` | a bar per point from a zero line (`--prime-color-chart-axis`): accent up, danger down, value end rounded | values by period, especially with a sign (monthly profit) | |
|
|
64
78
|
|
|
79
|
+
### curve
|
|
80
|
+
| Value | Looks like | Use when | Default |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| `smooth` | a monotone cubic through every point: round, never above a peak or below a trough | most trends | yes |
|
|
83
|
+
| `linear` | straight segments between points | few points where each turn matters | |
|
|
84
|
+
| `step` | a level per point, changing halfway between points | values that hold for a period (a price, a plan, a headcount) | |
|
|
85
|
+
|
|
86
|
+
### change
|
|
87
|
+
| Value | Looks like | Use when | Default |
|
|
88
|
+
|---|---|---|---|
|
|
89
|
+
| `previous` | change against the point before the shown one | period-over-period (this month vs the last) | yes |
|
|
90
|
+
| `first` | change against the first point with a value | the change over the whole range («за полгода») | |
|
|
91
|
+
| `none` | no badge | a percentage means nothing (a rate near zero, a count of events) | |
|
|
92
|
+
|
|
93
|
+
### summary
|
|
94
|
+
| Value | Looks like | Use when | Default |
|
|
95
|
+
|---|---|---|---|
|
|
96
|
+
| `latest` | the latest point (or `highlight`) at rest, its date, the dot on it | a level: MRR, a balance, a price, a conversion rate | yes |
|
|
97
|
+
| `sum` | the period total at rest, the period as its date («9 сен – 8 окт»), no dot | a flow: revenue, orders, sign-ups per day | |
|
|
98
|
+
| `average` | the period mean at rest, the period as its date, no dot | a rate over the period: average check, response time | |
|
|
99
|
+
|
|
100
|
+
Scrubbing always shows the point under the pointer; leaving returns to the summary. With `compareTo` (the same summary for the previous period) the badge at rest is the change against it — «+8% к прошлым 30 дням».
|
|
101
|
+
|
|
65
102
|
### layout
|
|
66
103
|
| Value | Looks like | Use when | Default |
|
|
67
104
|
|---|---|---|---|
|
|
68
105
|
| `default` | the headline (title · date, value · change) over an 80 px plot | a dashboard tile, a page header | yes |
|
|
69
|
-
| `compact` | the plot alone at the height of an `xs` control (28 px), the dot on the point at rest
|
|
106
|
+
| `compact` | the plot alone at the height of an `xs` control (28 px), the dot on the point at rest; scrubbing shows the guide and the tooltip; at least 96 px wide | a DataTable cell or a list row: one trend per record next to its name or total | |
|
|
70
107
|
|
|
71
108
|
### Flags
|
|
72
109
|
| Value | Looks like | Use when | Default |
|
|
73
110
|
|---|---|---|---|
|
|
74
111
|
| `highlight` | the headline rests on that point; in `bars` the other bars are quieter | the current period is not the last point (a year with empty months ahead) | the latest point |
|
|
112
|
+
| `min` · `max` | the scale spans at least this range; data outside widens it | one scale for a table column, a floor of zero | the data's own range |
|
|
113
|
+
| `reference` | a dashed chart-axis line at the value | a plan, a target, an average | — |
|
|
75
114
|
| `loading` | Skeletons of the date, the value and the plot | the series is on its way | `false` |
|
|
76
115
|
|
|
77
116
|
Put it in a `Card` for a dashboard tile.
|
|
@@ -79,21 +118,23 @@ Put it in a `Card` for a dashboard tile.
|
|
|
79
118
|
## States
|
|
80
119
|
| State | Driven by | DOM |
|
|
81
120
|
|---|---|---|
|
|
82
|
-
| at rest |
|
|
83
|
-
| scrubbing | pointer, touch or the arrow keys | `data-scrubbing` on the root; the cursor (or the bar under the pointer) and the headline follow with no easing (direct manipulation), digits change in place |
|
|
121
|
+
| at rest | `summary`, `highlight`, `compareTo` | the latest point or `highlight` (`latest`), or the period total / mean with the period as date and no dot (`sum` / `average`, cursor `data-hidden`); the badge compares with `compareTo` when given; the value rolls its digits when `data` changes or scrubbing ends |
|
|
122
|
+
| scrubbing | pointer, touch or the arrow keys | `data-scrubbing` on the root; the guide and the tooltip (`data-state="open"`, date · value, right of the pointer at its height, left of it only where the right has no room in the viewport; from the keyboard beside the point at mid-height) fade in (`fast`), the cursor (or the bar under the pointer) and the headline follow with no easing (direct manipulation), digits change in place |
|
|
84
123
|
| keyboard | arrows, Home, End on the focused plot | `aria-valuenow` / `aria-valuetext`, `data-scrubbing`; the cursor moves to the point at once (keyboard steps are high-frequency); in `bars` the current bar keeps its fill, the others go quiet (`fast` opacity) |
|
|
85
|
-
| settle | pointer leaves, touch ends, focus leaves | back to the point at rest |
|
|
86
|
-
| change hidden |
|
|
124
|
+
| settle | pointer leaves, touch ends, focus leaves | back to the point at rest; the tooltip fades out (`fast`) |
|
|
125
|
+
| change hidden | `change="none"`, nothing to compare with, a missing value, a base of 0, or a sign flip | no change Badge: a percentage would mean nothing |
|
|
126
|
+
| no data | a point with `value: null` | the line breaks (a point alone between gaps is a dot), no bar; shown, the value reads `labels.empty` (`data-empty`, muted) and the dot fades out, the guide marks the point |
|
|
87
127
|
| new series | a new `data` array | the chart cross-fades in (swap motion); the trend arrow turns half a turn between up and down |
|
|
88
|
-
| compact | `layout="compact"` | `data-layout="compact"` on the root; no headline: `label` names the slider, the point is spoken through `aria-valuetext
|
|
128
|
+
| compact | `layout="compact"` | `data-layout="compact"` on the root; no headline: `label` names the slider, the point is spoken through `aria-valuetext` and shown in the tooltip |
|
|
89
129
|
| loading | `loading` | `aria-busy` on the root; Skeletons in place of the date, the value and the plot; no slider until the data comes; the data cross-fades in |
|
|
90
130
|
|
|
91
131
|
## Layout & spacing
|
|
92
|
-
- Takes the width of its container; the plot is 80 px high and inset by the dot radius so the cursor is never clipped.
|
|
132
|
+
- Takes the width of its container; the plot is 80 px high and inset by the dot radius so the cursor is never clipped. The smooth curve never leaves the plot: a monotone cubic does not overshoot the extremes.
|
|
93
133
|
- Bars share the width equally, 4 px apart; the zero line sits where 0 falls on the scale (the bottom when every value is positive).
|
|
94
134
|
- In a dashboard, wrap it in `Card.Root` + `Card.Body`; several cards go in a grid.
|
|
95
135
|
- When the value row does not fit (a narrow card), the change badge wraps under the value.
|
|
96
|
-
- `layout="compact"` fits a DataTable row of any tier (plot and dot within an `xs` control height) and takes the cell width, at least `--prime-space-24`; give the column a `width` for an even plot per row. Put the number next to it in its own column: the compact plot shows
|
|
136
|
+
- `layout="compact"` fits a DataTable row of any tier (plot and dot within an `xs` control height) and takes the cell width, at least `--prime-space-24`; give the column a `width` for an even plot per row. Put the number next to it in its own column: the compact plot shows a value only in its tooltip while scrubbed.
|
|
137
|
+
- The tooltip is the kit's chart tooltip, placed like every anchored layer (`usePosition`): right of the pointer at its height, on the left only where the right has no room in the viewport — crossing the middle never moves it; from the keyboard right of the point at mid-height. Portaled, so a card or a table scroller never clips it.
|
|
97
138
|
|
|
98
139
|
## Accessibility
|
|
99
140
|
|
|
@@ -102,14 +143,16 @@ Put it in a `Card` for a dashboard tile.
|
|
|
102
143
|
|---|---|
|
|
103
144
|
| `←` · `→` · `↓` · `↑` | Previous or next point: `←` / `↓` back, `→` / `↑` forward, as on a slider. |
|
|
104
145
|
| `Home` · `End` | First or last point. |
|
|
105
|
-
| `Tab` | Focuses the chart; leaving focus returns
|
|
146
|
+
| `Tab` | Focuses the chart; leaving focus returns the headline to rest (`summary`, `highlight`). |
|
|
147
|
+
| `Escape` | Hides the tooltip and returns the headline to rest. |
|
|
106
148
|
|
|
107
149
|
### ARIA
|
|
108
|
-
- The plot is `role="slider"` named by `label`; `aria-valuetext` speaks the point («8 окт: 312 400 ₽», `labels.point`).
|
|
150
|
+
- The plot is `role="slider"` named by `label`; `aria-valuetext` speaks the point («8 окт: 312 400 ₽», `labels.point`); a point with no data speaks `labels.empty` («8 окт: Нет данных»). At rest with `sum` / `average` it speaks the period and the summary («9 сен – 8 окт: 8 914 000 ₽»). With `reference` the slider is described by `labels.reference` («Ориентир: 3%», `aria-describedby`). The headline follows the point under the pointer or the arrows, in text.
|
|
109
151
|
- The headline with the value and change reads as plain text.
|
|
110
152
|
- The change carries a sign and an arrow, never color alone; a negative bar goes down, not only red.
|
|
111
153
|
- While `loading` the root is `aria-busy` and the chart is not in the tab order yet.
|
|
112
|
-
- `layout="compact"`: no visible title; `label` is only the slider's name, the point still goes to `aria-valuetext`.
|
|
154
|
+
- `layout="compact"`: no visible title; `label` is only the slider's name, the point still goes to `aria-valuetext`.
|
|
155
|
+
- The tooltip is `aria-hidden`: it repeats `aria-valuetext` for sighted users. The plot carries `data-row-click-ignore` (and is a slider), so its pointer and keys never open a DataTable row.
|
|
113
156
|
|
|
114
157
|
### Labels
|
|
115
158
|
<!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
|
|
@@ -117,25 +160,35 @@ Put it in a `Card` for a dashboard tile.
|
|
|
117
160
|
| Key | Default | Used for |
|
|
118
161
|
|---|---|---|
|
|
119
162
|
| `point` | `"{label}: {value}"` | Spoken value of the chosen point (`aria-valuetext`); `{label}` and `{value}` are replaced. |
|
|
163
|
+
| `period` | `"{first} – {last}"` | The date line of a `sum` / `average` headline at rest; `{first}` and `{last}` are the labels of the first and the last point. |
|
|
164
|
+
| `empty` | `"Нет данных"` | Shown and spoken in place of the value of a point with `value: null`. |
|
|
165
|
+
| `reference` | `"Ориентир: {value}"` | Description of the chart with a `reference` line (`aria-describedby`); `{value}` is replaced. |
|
|
120
166
|
|
|
121
167
|
## Examples
|
|
122
168
|
| Example | Shows |
|
|
123
169
|
|---|---|
|
|
124
|
-
| [overview.tsx](examples/overview.tsx) | Revenue for 30 days in a dashboard card:
|
|
125
|
-
| [variants.tsx](examples/variants.tsx) | The same week as a line and
|
|
170
|
+
| [overview.tsx](examples/overview.tsx) | Revenue for 30 days in a dashboard card: at rest the total for the period against the previous 30 days, drag across the chart to see a day — `data`, `label`, `summary`, `compareTo`, `formatValue`. |
|
|
171
|
+
| [variants.tsx](examples/variants.tsx) | The same week as an area, a bare line and bars from zero — `variant`. |
|
|
126
172
|
| [states.tsx](examples/states.tsx) | While the series loads the date, the value and the plot are Skeletons in their own places; the title stays — `loading`. |
|
|
127
|
-
| [compact.tsx](examples/compact.tsx) | Revenue by month per client in a list: the plot alone at a row's height with the dot on the current month, the label is the chart's accessible name — `layout`, `label`. |
|
|
173
|
+
| [compact.tsx](examples/compact.tsx) | Revenue by month per client in a list: the plot alone at a row's height with the dot on the current month, scrubbing shows the month in a tooltip, the label is the chart's accessible name — `layout`, `label`. |
|
|
128
174
|
| [signed-bars.tsx](examples/signed-bars.tsx) | Monthly profit with a sign: losses go below the zero line, the current month rests highlighted and any bar shows its value under the pointer or the arrows — `variant`, `highlight`. |
|
|
129
|
-
| [
|
|
175
|
+
| [curve.tsx](examples/curve.tsx) | The same month of active users as a smooth curve, straight segments and steps — `curve`. |
|
|
176
|
+
| [reference.tsx](examples/reference.tsx) | Checkout conversion against its plan: a dashed reference line, the scale from zero and the change over the whole period — `reference`, `min`, `change`. |
|
|
177
|
+
| [gaps.tsx](examples/gaps.tsx) | Daily API requests with days the collector was down: the line breaks over a missing day and the headline says there is no data — `data`, `labels`. |
|
|
178
|
+
| [period.tsx](examples/period.tsx) | Another period swaps the series: the line cross-fades in and the headline digits roll to the new total — `data`, `summary`. |
|
|
130
179
|
|
|
131
180
|
## Mistakes
|
|
132
181
|
- A new array on every render (`data={rows.map(...)}` inline) → the line cross-fades on every render; memoize the series.
|
|
133
182
|
- Formatting inside `label` of a point («312 400 ₽») → the point label is its name («8 окт»); format values with `formatValue`.
|
|
134
183
|
- A Sparkline without a container width (inside an inline flex row) → give it a width or put it in a `Card`.
|
|
135
|
-
- A
|
|
184
|
+
- A Tooltip or a chart library tooltip wrapped around the chart → Sparkline draws its own beside the pointer.
|
|
185
|
+
- A daily flow (revenue per day) with the latest day in the headline → `summary="sum"`: the card is about the period; pass `compareTo` for its change.
|
|
186
|
+
- A missing day as `0` → the line dives to zero; pass `value: null`, the line breaks and the headline says there is no data.
|
|
187
|
+
- Compact sparklines in a column, each on its own scale, when rows must be compared by size → pass the column's `min` / `max` to every row.
|
|
188
|
+
- A plan drawn as a second series → `reference`.
|
|
136
189
|
- A grey box while the series loads → `loading`.
|
|
137
190
|
- A full Sparkline squeezed into a table cell, or its headline hidden with CSS → `layout="compact"`.
|
|
138
191
|
|
|
139
192
|
## Related
|
|
140
|
-
- **Built from:** [Badge](../badge/COMPONENT.md) (change), [Skeleton](../skeleton/COMPONENT.md) (loading), `Icon` (trend arrow)
|
|
141
|
-
- **See also:** [DataTable](../data-table/COMPONENT.md) (a compact Sparkline per row), [Card](../card/COMPONENT.md), [ProgressBar](../progress-bar/COMPONENT.md), [SegmentedControl](../segmented-control/COMPONENT.md)
|
|
193
|
+
- **Built from:** [Badge](../badge/COMPONENT.md) (change), [Skeleton](../skeleton/COMPONENT.md) (loading), `Icon` (trend arrow), `ChartTooltip` (the chart tooltip shared with ChartFrame)
|
|
194
|
+
- **See also:** [ChartFrame](../chart-frame/COMPONENT.md), [DataTable](../data-table/COMPONENT.md) (a compact Sparkline per row), [Card](../card/COMPONENT.md), [ProgressBar](../progress-bar/COMPONENT.md), [SegmentedControl](../segmented-control/COMPONENT.md)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Revenue by month per client in a list: the plot alone at a row's height with the dot on the current month, the label is the chart's accessible name — `layout`, `label`. */
|
|
1
|
+
/** Revenue by month per client in a list: the plot alone at a row's height with the dot on the current month, scrubbing shows the month in a tooltip, the label is the chart's accessible name — `layout`, `label`. */
|
|
2
2
|
import { Card, Sparkline, type SparklinePoint, Typography } from "prime-ui-kit";
|
|
3
3
|
|
|
4
4
|
import styles from "./examples.module.css";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** The same month of active users as a smooth curve, straight segments and steps — `curve`. */
|
|
2
|
+
import { Sparkline, type SparklinePoint, Typography } from "prime-ui-kit";
|
|
3
|
+
|
|
4
|
+
const USERS: SparklinePoint[] = [
|
|
5
|
+
{ label: "сен, 1 нед.", value: 1240 },
|
|
6
|
+
{ label: "сен, 2 нед.", value: 1380 },
|
|
7
|
+
{ label: "сен, 3 нед.", value: 1310 },
|
|
8
|
+
{ label: "сен, 4 нед.", value: 1620 },
|
|
9
|
+
{ label: "окт, 1 нед.", value: 1590 },
|
|
10
|
+
{ label: "окт, 2 нед.", value: 1840 },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const CURVES = ["smooth", "linear", "step"] as const;
|
|
14
|
+
|
|
15
|
+
export default function SparklineCurveExample() {
|
|
16
|
+
return (
|
|
17
|
+
<div>
|
|
18
|
+
{CURVES.map((curve) => (
|
|
19
|
+
<div key={curve}>
|
|
20
|
+
<Sparkline data={USERS} label="Активные пользователи" curve={curve} />
|
|
21
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
22
|
+
{curve}
|
|
23
|
+
</Typography>
|
|
24
|
+
</div>
|
|
25
|
+
))}
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Daily API requests with days the collector was down: the line breaks over a missing day and the headline says there is no data — `data`, `labels`. */
|
|
2
|
+
import { Card, Sparkline, type SparklinePoint } from "prime-ui-kit";
|
|
3
|
+
|
|
4
|
+
import styles from "./examples.module.css";
|
|
5
|
+
|
|
6
|
+
const REQUESTS: SparklinePoint[] = [
|
|
7
|
+
{ label: "29 сен", value: 182_400 },
|
|
8
|
+
{ label: "30 сен", value: 191_800 },
|
|
9
|
+
{ label: "1 окт", value: 176_300 },
|
|
10
|
+
{ label: "2 окт", value: null },
|
|
11
|
+
{ label: "3 окт", value: 168_900 },
|
|
12
|
+
{ label: "4 окт", value: 203_500 },
|
|
13
|
+
{ label: "5 окт", value: 214_100 },
|
|
14
|
+
{ label: "6 окт", value: null },
|
|
15
|
+
{ label: "7 окт", value: null },
|
|
16
|
+
{ label: "8 окт", value: 226_700 },
|
|
17
|
+
{ label: "9 окт", value: 219_200 },
|
|
18
|
+
{ label: "10 окт", value: 238_600 },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export default function SparklineGapsExample() {
|
|
22
|
+
return (
|
|
23
|
+
<Card.Root className={styles.card}>
|
|
24
|
+
<Card.Body>
|
|
25
|
+
<Sparkline
|
|
26
|
+
data={REQUESTS}
|
|
27
|
+
label="Запросы к API в день"
|
|
28
|
+
labels={{ empty: "Сборщик не работал" }}
|
|
29
|
+
/>
|
|
30
|
+
</Card.Body>
|
|
31
|
+
</Card.Root>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Revenue for 30 days in a dashboard card:
|
|
1
|
+
/** Revenue for 30 days in a dashboard card: at rest the total for the period against the previous 30 days, drag across the chart to see a day — `data`, `label`, `summary`, `compareTo`, `formatValue`. */
|
|
2
2
|
import { Card, Sparkline, type SparklinePoint } from "prime-ui-kit";
|
|
3
3
|
|
|
4
4
|
import styles from "./examples.module.css";
|
|
@@ -14,13 +14,22 @@ const REVENUE: SparklinePoint[] = Array.from({ length: 30 }, (_, i) => {
|
|
|
14
14
|
};
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
+
/** Revenue for the 30 days before, 10 August — 8 September 2026. */
|
|
18
|
+
const PREVIOUS_TOTAL = 8_240_000;
|
|
19
|
+
|
|
17
20
|
const formatRubles = (value: number) => `${value.toLocaleString("ru-RU")} ₽`;
|
|
18
21
|
|
|
19
22
|
export default function SparklineOverviewExample() {
|
|
20
23
|
return (
|
|
21
24
|
<Card.Root className={styles.card}>
|
|
22
25
|
<Card.Body>
|
|
23
|
-
<Sparkline
|
|
26
|
+
<Sparkline
|
|
27
|
+
data={REVENUE}
|
|
28
|
+
label="Выручка за 30 дней"
|
|
29
|
+
summary="sum"
|
|
30
|
+
compareTo={PREVIOUS_TOTAL}
|
|
31
|
+
formatValue={formatRubles}
|
|
32
|
+
/>
|
|
24
33
|
</Card.Body>
|
|
25
34
|
</Card.Root>
|
|
26
35
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Another period swaps the series: the line cross-fades in and the headline digits roll to the new total — `data`. */
|
|
1
|
+
/** Another period swaps the series: the line cross-fades in and the headline digits roll to the new total — `data`, `summary`. */
|
|
2
2
|
import { Card, SegmentedControl, Sparkline, type SparklinePoint } from "prime-ui-kit";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
@@ -39,7 +39,12 @@ export default function SparklinePeriodExample() {
|
|
|
39
39
|
<SegmentedControl.Item value="month">Месяц</SegmentedControl.Item>
|
|
40
40
|
<SegmentedControl.Item value="quarter">Квартал</SegmentedControl.Item>
|
|
41
41
|
</SegmentedControl.Root>
|
|
42
|
-
<Sparkline
|
|
42
|
+
<Sparkline
|
|
43
|
+
data={SERIES[period]}
|
|
44
|
+
label="Новые заказы"
|
|
45
|
+
summary="sum"
|
|
46
|
+
formatValue={formatRubles}
|
|
47
|
+
/>
|
|
43
48
|
</Card.Body>
|
|
44
49
|
</Card.Root>
|
|
45
50
|
);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Checkout conversion against its plan: a dashed reference line, the scale from zero and the change over the whole period — `reference`, `min`, `change`. */
|
|
2
|
+
import { Card, Sparkline, type SparklinePoint } from "prime-ui-kit";
|
|
3
|
+
|
|
4
|
+
import styles from "./examples.module.css";
|
|
5
|
+
|
|
6
|
+
const CONVERSION: SparklinePoint[] = [
|
|
7
|
+
{ label: "май", value: 2.1 },
|
|
8
|
+
{ label: "июн", value: 2.4 },
|
|
9
|
+
{ label: "июл", value: 2.2 },
|
|
10
|
+
{ label: "авг", value: 2.8 },
|
|
11
|
+
{ label: "сен", value: 3.1 },
|
|
12
|
+
{ label: "окт", value: 3.4 },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const PLAN = 3;
|
|
16
|
+
|
|
17
|
+
const PERCENT = new Intl.NumberFormat("ru-RU", { maximumFractionDigits: 1 });
|
|
18
|
+
|
|
19
|
+
const formatPercent = (value: number) => `${PERCENT.format(value)}%`;
|
|
20
|
+
|
|
21
|
+
export default function SparklineReferenceExample() {
|
|
22
|
+
return (
|
|
23
|
+
<Card.Root className={styles.card}>
|
|
24
|
+
<Card.Body>
|
|
25
|
+
<Sparkline
|
|
26
|
+
data={CONVERSION}
|
|
27
|
+
label="Конверсия оформления заказа"
|
|
28
|
+
reference={PLAN}
|
|
29
|
+
min={0}
|
|
30
|
+
change="first"
|
|
31
|
+
formatValue={formatPercent}
|
|
32
|
+
labels={{ reference: "План: {value}" }}
|
|
33
|
+
/>
|
|
34
|
+
</Card.Body>
|
|
35
|
+
</Card.Root>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** The same week as a line and
|
|
1
|
+
/** The same week as an area, a bare line and bars from zero — `variant`. */
|
|
2
2
|
import { Sparkline, type SparklinePoint, Typography } from "prime-ui-kit";
|
|
3
3
|
|
|
4
4
|
const ORDERS: SparklinePoint[] = [
|
|
@@ -11,7 +11,7 @@ const ORDERS: SparklinePoint[] = [
|
|
|
11
11
|
{ label: "8 окт", value: 52 },
|
|
12
12
|
];
|
|
13
13
|
|
|
14
|
-
const VARIANTS = ["line", "bars"] as const;
|
|
14
|
+
const VARIANTS = ["area", "line", "bars"] as const;
|
|
15
15
|
|
|
16
16
|
export default function SparklineVariantsExample() {
|
|
17
17
|
return (
|
|
@@ -22,12 +22,6 @@
|
|
|
22
22
|
max-width: calc(10 * var(--prime-control-m-height));
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
/* in-drawer.tsx: blocks of a panel in the drawer body, the full body width. */
|
|
26
|
-
.stack {
|
|
27
|
-
display: grid;
|
|
28
|
-
gap: var(--prime-space-5);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
25
|
/* The same column, which the reader can drag narrower to watch the tabs collapse and scroll. */
|
|
32
26
|
.resizable {
|
|
33
27
|
composes: frame;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/** Order details in a Drawer: the tab bar runs along the bottom of the header, the active tab is the body rising into it, and every panel is the body's own content — `Tabs.Root`, `Tabs.List`, `Tabs.Panel`. */
|
|
2
|
-
import { Badge, Button, DescriptionList, Drawer, Input, Tabs
|
|
3
|
-
|
|
4
|
-
import styles from "./examples.module.css";
|
|
2
|
+
import { Badge, Button, DescriptionList, Drawer, Fieldset, Input, Tabs } from "prime-ui-kit";
|
|
5
3
|
|
|
6
4
|
const ITEMS = [
|
|
7
5
|
{ name: "Кресло «Орион», графит", amount: "2 × 18 900 ₽" },
|
|
@@ -10,9 +8,9 @@ const ITEMS = [
|
|
|
10
8
|
];
|
|
11
9
|
|
|
12
10
|
const HISTORY = [
|
|
13
|
-
"3 октября, 10:14
|
|
14
|
-
"3 октября, 10:20
|
|
15
|
-
"4 октября, 16:02
|
|
11
|
+
{ time: "3 октября, 10:14", event: "Заказ оформлен" },
|
|
12
|
+
{ time: "3 октября, 10:20", event: "Оплата прошла" },
|
|
13
|
+
{ time: "4 октября, 16:02", event: "Передан на склад" },
|
|
16
14
|
];
|
|
17
15
|
|
|
18
16
|
export default function TabsInDrawerExample() {
|
|
@@ -61,7 +59,7 @@ export default function TabsInDrawerExample() {
|
|
|
61
59
|
</Tabs.Panel>
|
|
62
60
|
|
|
63
61
|
<Tabs.Panel value="delivery">
|
|
64
|
-
<
|
|
62
|
+
<Fieldset aria-label="Доставка">
|
|
65
63
|
<Input.Root label="Адрес">
|
|
66
64
|
<Input.Wrapper>
|
|
67
65
|
<Input.Field defaultValue="Москва, Ленинградский проспект, 37, кв. 12" />
|
|
@@ -72,17 +70,17 @@ export default function TabsInDrawerExample() {
|
|
|
72
70
|
<Input.Field defaultValue="Позвонить за час" />
|
|
73
71
|
</Input.Wrapper>
|
|
74
72
|
</Input.Root>
|
|
75
|
-
</
|
|
73
|
+
</Fieldset>
|
|
76
74
|
</Tabs.Panel>
|
|
77
75
|
|
|
78
76
|
<Tabs.Panel value="history">
|
|
79
|
-
<
|
|
77
|
+
<DescriptionList.Root>
|
|
80
78
|
{HISTORY.map((entry) => (
|
|
81
|
-
<
|
|
82
|
-
{entry}
|
|
83
|
-
</
|
|
79
|
+
<DescriptionList.Item key={entry.time} label={entry.time}>
|
|
80
|
+
{entry.event}
|
|
81
|
+
</DescriptionList.Item>
|
|
84
82
|
))}
|
|
85
|
-
</
|
|
83
|
+
</DescriptionList.Root>
|
|
86
84
|
</Tabs.Panel>
|
|
87
85
|
</Drawer.Body>
|
|
88
86
|
</Tabs.Root>
|
|
@@ -6,14 +6,6 @@
|
|
|
6
6
|
width: min(100%, calc(var(--prime-space-24) * 5));
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
.stack {
|
|
10
|
-
display: flex;
|
|
11
|
-
flex-direction: column;
|
|
12
|
-
gap: var(--prime-space-10);
|
|
13
|
-
width: min(100%, calc(var(--prime-space-24) * 5));
|
|
14
|
-
min-width: 0;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
9
|
/* narrow.tsx: a 375px phone column. */
|
|
18
10
|
.phone {
|
|
19
11
|
width: min(100%, calc(var(--prime-space-1) * 93.75));
|
|
@@ -20,7 +20,7 @@ const EVENTS = [
|
|
|
20
20
|
|
|
21
21
|
export default function TimelineNarrowExample() {
|
|
22
22
|
return (
|
|
23
|
-
|
|
23
|
+
<>
|
|
24
24
|
{WIDTHS.map((width) => (
|
|
25
25
|
<Timeline.Root key={width.id} className={width.className}>
|
|
26
26
|
<Timeline.Group label={width.label}>
|
|
@@ -36,6 +36,6 @@ export default function TimelineNarrowExample() {
|
|
|
36
36
|
</Timeline.Group>
|
|
37
37
|
</Timeline.Root>
|
|
38
38
|
))}
|
|
39
|
-
|
|
39
|
+
</>
|
|
40
40
|
);
|
|
41
41
|
}
|
|
@@ -7,9 +7,9 @@ const SIZES = ["xs", "s", "m", "l", "xl"] as const;
|
|
|
7
7
|
|
|
8
8
|
export default function TimelineSizesExample() {
|
|
9
9
|
return (
|
|
10
|
-
|
|
10
|
+
<>
|
|
11
11
|
{SIZES.map((size) => (
|
|
12
|
-
<Timeline.Root key={size} size={size}>
|
|
12
|
+
<Timeline.Root key={size} size={size} className={styles.feed}>
|
|
13
13
|
<Timeline.Group label={size}>
|
|
14
14
|
<Timeline.Item>
|
|
15
15
|
<Timeline.Title>Аренда закончилась · Иван К.</Timeline.Title>
|
|
@@ -28,6 +28,6 @@ export default function TimelineSizesExample() {
|
|
|
28
28
|
</Timeline.Group>
|
|
29
29
|
</Timeline.Root>
|
|
30
30
|
))}
|
|
31
|
-
|
|
31
|
+
</>
|
|
32
32
|
);
|
|
33
33
|
}
|
|
@@ -27,8 +27,8 @@ const TONES: { tone: Tone; title: string; value: string }[] = [
|
|
|
27
27
|
|
|
28
28
|
export default function TimelineVariantsExample() {
|
|
29
29
|
return (
|
|
30
|
-
|
|
31
|
-
<Timeline.Root>
|
|
30
|
+
<>
|
|
31
|
+
<Timeline.Root className={styles.feed}>
|
|
32
32
|
<Timeline.Group label="color">
|
|
33
33
|
{COLORS.map((color) => (
|
|
34
34
|
<Timeline.Item key={color} color={color}>
|
|
@@ -38,7 +38,7 @@ export default function TimelineVariantsExample() {
|
|
|
38
38
|
))}
|
|
39
39
|
</Timeline.Group>
|
|
40
40
|
</Timeline.Root>
|
|
41
|
-
<Timeline.Root>
|
|
41
|
+
<Timeline.Root className={styles.feed}>
|
|
42
42
|
<Timeline.Group label="tone">
|
|
43
43
|
{TONES.map(({ tone, title, value }) => (
|
|
44
44
|
<Timeline.Item key={tone} tone={tone}>
|
|
@@ -51,6 +51,6 @@ export default function TimelineVariantsExample() {
|
|
|
51
51
|
<Timeline.Gap tone="danger">Просрочка 30 дней</Timeline.Gap>
|
|
52
52
|
</Timeline.Group>
|
|
53
53
|
</Timeline.Root>
|
|
54
|
-
|
|
54
|
+
</>
|
|
55
55
|
);
|
|
56
56
|
}
|
|
@@ -70,7 +70,7 @@ No DOM of its own: clones the single child and links it to the tooltip with `ari
|
|
|
70
70
|
| Prop | Type | Default | Description |
|
|
71
71
|
|---|---|---|---|
|
|
72
72
|
| `side` | `"top" \| "bottom" \| "left" \| "right"` | `"top"` | Preferred side; flips to the opposite one when it does not fit, then shifts inside the viewport. |
|
|
73
|
-
| `align` | `"start" \| "center" \| "end"` | `"center"` | Alignment along the trigger:
|
|
73
|
+
| `align` | `"auto" \| "start" \| "center" \| "end"` | `"center"` | Alignment along the trigger: centred by default; `auto` lines the chip up with the trigger edge that has more room beyond it; `start` or `end` fix the edge. The arrow keeps pointing at the trigger. |
|
|
74
74
|
| `size` | `"xs" \| "s" \| "m" \| "l" \| "xl"` | `"m"` | Text and padding tier; also the size context of controls inside (a Kbd). |
|
|
75
75
|
| `children` | `ReactNode` | — (required) | Hint text, optionally with a Kbd. |
|
|
76
76
|
| `…rest` | `Omit<HTMLAttributes<HTMLDivElement>, "id" \| "role" \| "onPointerEnter" \| "onPointerLeave">` | — | `className`, `style` and the other attributes of the chip. |
|
|
@@ -100,9 +100,10 @@ A chip of tier T is as tall as a menu item of tier T; text, padding and radius s
|
|
|
100
100
|
### align (Content)
|
|
101
101
|
| Value | Looks like | Use when | Default |
|
|
102
102
|
|---|---|---|---|
|
|
103
|
-
| `start` | Chip starts at the trigger's start edge | Wide triggers, triggers at a container's start | |
|
|
104
103
|
| `center` | Chip centred on the trigger | Most triggers | yes |
|
|
105
|
-
| `
|
|
104
|
+
| `auto` | Lined up with the trigger edge that has more room: near the end of the screen the end edges meet and the chip grows toward the start, near the start the other way | A long chip on a wide trigger near a screen edge | |
|
|
105
|
+
| `start` | Chip starts at the trigger's start edge | The chip must line up with the start of a block whatever room there is | |
|
|
106
|
+
| `end` | Chip ends at the trigger's end edge | The chip must line up with the end of a block whatever room there is | |
|
|
106
107
|
|
|
107
108
|
**Combinations** — size of the tooltip = size of the trigger control; a Kbd inside takes the tier one step down by itself.
|
|
108
109
|
|
|
@@ -133,6 +134,7 @@ A chip of tier T is as tall as a menu item of tier T; text, padding and radius s
|
|
|
133
134
|
- `Tooltip.Trigger` composes the child's `ref`, sets `data-state` and chains the child's `onPointerEnter`, `onPointerLeave`, `onPointerDown`, `onFocus` and `onBlur`.
|
|
134
135
|
- The tooltip is a description, not the name: an icon-only button needs its own `aria-label`.
|
|
135
136
|
- The pointer may move onto the chip without closing it (WCAG 1.4.13); a touch does not open it, focus does.
|
|
137
|
+
- Tooltip has no `closeOnEscape` / `closeOnOutsideClick` (foundation §8): it closes on pointer-leave, blur, a press on the trigger and Escape, and Escape cannot be turned off — WCAG 1.4.13 requires the chip to be dismissable without moving the pointer or focus.
|
|
136
138
|
- A `disabled` control is wrapped by the kit in a focusable `<span>`: the host takes hover and Tab, the focus ring is drawn on the control.
|
|
137
139
|
- A trigger that is no tab stop (Badge, Avatar, ProgressCircle, `Icon` with `label`) gets `tabIndex={0}` and the focus ring; its name comes from `aria-label` or the icon `label`.
|
|
138
140
|
|
|
@@ -146,7 +148,7 @@ No `labels`.
|
|
|
146
148
|
|---|---|
|
|
147
149
|
| [overview.tsx](examples/overview.tsx) | An icon-only button with a tooltip that repeats its name on hover and keyboard focus — `Tooltip.Trigger`, `Tooltip.Content`. |
|
|
148
150
|
| [sizes.tsx](examples/sizes.tsx) | Every size tier next to buttons of the same tier; take the tier of the control it describes — `size`. |
|
|
149
|
-
| [placement.tsx](examples/placement.tsx) | Every side, and start
|
|
151
|
+
| [placement.tsx](examples/placement.tsx) | Every side, and alignment by room, start and end along the trigger; without room the chip flips and shifts, the arrow keeps pointing at the trigger — `side`, `align`. |
|
|
150
152
|
| [toolbar.tsx](examples/toolbar.tsx) | A formatting toolbar in one group: after the first tooltip the neighbours open at once, each with its name and shortcut — `Tooltip.Provider`. |
|
|
151
153
|
| [disabled-trigger.tsx](examples/disabled-trigger.tsx) | Why an action is unavailable: the disabled button still shows its tooltip on hover and Tab, no wrapper needed — `Tooltip.Trigger`. |
|
|
152
154
|
| [non-interactive-trigger.tsx](examples/non-interactive-trigger.tsx) | A status badge, an avatar and an information icon explain themselves: the kit makes each a tab stop, so the tooltip opens from the keyboard too — `Tooltip.Trigger`. |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Every side, and start
|
|
1
|
+
/** Every side, and alignment by room, start and end along the trigger; without room the chip flips and shifts, the arrow keeps pointing at the trigger — `side`, `align`. */
|
|
2
2
|
import { Button, Tooltip } from "prime-ui-kit";
|
|
3
3
|
|
|
4
4
|
const PLACEMENTS = [
|
|
@@ -6,6 +6,7 @@ const PLACEMENTS = [
|
|
|
6
6
|
{ side: "bottom", align: "center" },
|
|
7
7
|
{ side: "left", align: "center" },
|
|
8
8
|
{ side: "right", align: "center" },
|
|
9
|
+
{ side: "bottom", align: "auto" },
|
|
9
10
|
{ side: "bottom", align: "start" },
|
|
10
11
|
{ side: "bottom", align: "end" },
|
|
11
12
|
] as const;
|
|
@@ -79,7 +79,7 @@ One look. The circle is the video; the play disk and the pills stand on the medi
|
|
|
79
79
|
## States
|
|
80
80
|
| State | Driven by | DOM |
|
|
81
81
|
|---|---|---|
|
|
82
|
-
| loading | the first frame not drawn yet | `data-frame="loading"` on the circle: a Skeleton fills it
|
|
82
|
+
| loading | the first frame not drawn yet | `data-frame="loading"` on the circle: a Skeleton fills it; once loaded the video fades in over it (`base`), then the Skeleton goes |
|
|
83
83
|
| at rest | idle | `data-state="idle"` on the circle; the still first frame (or `poster`) with the play disk and the duration; nothing plays, loops or decodes past the metadata and the first frame — a long chat costs nothing until a press |
|
|
84
84
|
| playing | the disk (or a press on the circle), `playing` / `defaultPlaying` | `data-playing="true"` on the root, `data-state="playing"`; sound from the start, the ring fills over the edge every frame (one CSS variable on the ring), the duration counts down, the disk's glyph turns to pause and the disk fades out (it stays while it has the keyboard focus); `onPlayingChange(true)`; any other sound pauses |
|
|
85
85
|
| paused | the disk or the circle again, another sound starting, `playing={false}` | `data-state="paused"`, the disk with the play glyph comes back, the ring stays; `onPlayingChange(false)` |
|