@kennycorrea/ui 0.9.1 → 0.11.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +120 -14
  2. package/README.md +204 -273
  3. package/dist/atoms/ActionSheet/ActionSheet.d.ts +30 -0
  4. package/dist/atoms/ActionSheet/ActionSheet.js +42 -0
  5. package/dist/atoms/ActionSheet/confirm.d.ts +21 -0
  6. package/dist/atoms/ActionSheet/confirm.js +65 -0
  7. package/dist/atoms/ActionSheet/index.d.ts +2 -0
  8. package/dist/atoms/ActionSheet/index.js +2 -0
  9. package/dist/atoms/Button/Button.js +3 -3
  10. package/dist/atoms/Button/Button.types.d.ts +7 -1
  11. package/dist/atoms/Card/Card.d.ts +28 -7
  12. package/dist/atoms/Card/Card.js +45 -9
  13. package/dist/atoms/ChipGroup/ChipGroup.d.ts +31 -0
  14. package/dist/atoms/ChipGroup/ChipGroup.js +69 -0
  15. package/dist/atoms/ChipGroup/index.d.ts +1 -0
  16. package/dist/atoms/ChipGroup/index.js +1 -0
  17. package/dist/atoms/Drawer/Drawer.d.ts +1 -1
  18. package/dist/atoms/Drawer/Drawer.js +9 -13
  19. package/dist/atoms/Input/Input.js +7 -1
  20. package/dist/atoms/List/List.d.ts +73 -0
  21. package/dist/atoms/List/List.js +88 -0
  22. package/dist/atoms/List/index.d.ts +1 -0
  23. package/dist/atoms/List/index.js +1 -0
  24. package/dist/atoms/List/swipe.d.ts +68 -0
  25. package/dist/atoms/List/swipe.js +207 -0
  26. package/dist/atoms/NavBar/BackButton.d.ts +10 -0
  27. package/dist/atoms/NavBar/BackButton.js +11 -0
  28. package/dist/atoms/NavBar/NavBar.d.ts +22 -0
  29. package/dist/atoms/NavBar/NavBar.js +29 -0
  30. package/dist/atoms/NavBar/index.d.ts +2 -0
  31. package/dist/atoms/NavBar/index.js +2 -0
  32. package/dist/atoms/NotificationCard/NotificationCard.d.ts +52 -0
  33. package/dist/atoms/NotificationCard/NotificationCard.js +78 -0
  34. package/dist/atoms/NotificationCard/index.d.ts +1 -0
  35. package/dist/atoms/NotificationCard/index.js +1 -0
  36. package/dist/atoms/PullToRefresh/PullToRefresh.d.ts +31 -0
  37. package/dist/atoms/PullToRefresh/PullToRefresh.js +110 -0
  38. package/dist/atoms/PullToRefresh/index.d.ts +1 -0
  39. package/dist/atoms/PullToRefresh/index.js +1 -0
  40. package/dist/atoms/ResponsiveDialog/ResponsiveDialog.d.ts +13 -0
  41. package/dist/atoms/ResponsiveDialog/ResponsiveDialog.js +27 -0
  42. package/dist/atoms/ResponsiveDialog/index.d.ts +1 -0
  43. package/dist/atoms/ResponsiveDialog/index.js +1 -0
  44. package/dist/atoms/ScrollStrip/ScrollStrip.d.ts +17 -0
  45. package/dist/atoms/ScrollStrip/ScrollStrip.js +15 -0
  46. package/dist/atoms/ScrollStrip/index.d.ts +1 -0
  47. package/dist/atoms/ScrollStrip/index.js +1 -0
  48. package/dist/atoms/SegmentedControl/SegmentedControl.d.ts +23 -0
  49. package/dist/atoms/SegmentedControl/SegmentedControl.js +41 -0
  50. package/dist/atoms/SegmentedControl/index.d.ts +1 -0
  51. package/dist/atoms/SegmentedControl/index.js +1 -0
  52. package/dist/atoms/Select/Select.js +1 -1
  53. package/dist/atoms/Sheet/Sheet.d.ts +63 -0
  54. package/dist/atoms/Sheet/Sheet.js +261 -0
  55. package/dist/atoms/Sheet/index.d.ts +1 -0
  56. package/dist/atoms/Sheet/index.js +1 -0
  57. package/dist/atoms/StatTile/StatTile.d.ts +36 -0
  58. package/dist/atoms/StatTile/StatTile.js +17 -0
  59. package/dist/atoms/StatTile/index.d.ts +1 -0
  60. package/dist/atoms/StatTile/index.js +1 -0
  61. package/dist/atoms/TabBar/TabBar.d.ts +42 -0
  62. package/dist/atoms/TabBar/TabBar.js +36 -0
  63. package/dist/atoms/TabBar/index.d.ts +1 -0
  64. package/dist/atoms/TabBar/index.js +1 -0
  65. package/dist/atoms/Textarea/Textarea.d.ts +4 -0
  66. package/dist/atoms/Textarea/Textarea.js +1 -1
  67. package/dist/atoms/Toast/Toast.d.ts +8 -2
  68. package/dist/atoms/Toast/Toast.js +19 -4
  69. package/dist/atoms/index.d.ts +12 -0
  70. package/dist/atoms/index.js +12 -0
  71. package/dist/primitives/index.d.ts +1 -1
  72. package/dist/primitives/index.js +1 -1
  73. package/dist/strings.d.ts +13 -3
  74. package/dist/strings.js +5 -0
  75. package/dist/utils/themePortal.d.ts +19 -0
  76. package/dist/utils/themePortal.js +28 -0
  77. package/package.json +4 -2
  78. package/tokens.css +454 -0
package/CHANGELOG.md CHANGED
@@ -1,16 +1,122 @@
1
1
  # Changelog
2
2
 
3
- ## 0.9.1 — 2026-10-18
3
+ ## 0.11.0 — 2026-10-19
4
+
5
+ - **Touch feedback** — Button, list rows, `StatTile` and `TabBar` items share a pressed state (`:active` scale `--press-scale` 0.97 + tint, `--press-duration` 120 ms); hover styles are in `@media (hover: hover)`. TabBar no longer dims on press.
6
+ - **`Button size="touch"`** (44px) and **`iconOnly`**, which grows the hit area to 44px on coarse pointers via `::before` without changing the visual size.
7
+ - **`Toaster`** — `position` adds `top-center` / `bottom-center` (vertical swipe-to-dismiss); `offset` takes any CSS length (e.g. `var(--tabbar-height)`).
8
+ - **Fields** — `Input`, `Textarea` and the `Select` trigger are 16px on coarse pointers (no iOS focus zoom); `inputMode` / `enterKeyHint` passthrough documented.
9
+
10
+ - **`PullToRefresh`** — wraps the page (`scroller="document"`, default) or its own scroll container (`"self"`). A touch drag from scroll-top past `threshold` shows a spinner and calls `onRefresh(): Promise<void>`, holding until it settles. Active only with `(pointer: coarse)` and only when the scroller is at the top; no effect on desktop. No transitions under `prefers-reduced-motion`. Label from `UiStrings.refreshing` (default "Refreshing"). A shortcut only: the parent must still offer a visible refresh action.
11
+
12
+ - **`StatTile`** — a compact KPI tile on `Card` (`variant`, `density`): `label`, `value` (tabular numerals), optional `delta` `{ value, direction, tone, label }` with an arrow and a positive/negative/neutral tone independent of direction, a `sparkline` slot, and `href` / `onClick` that make the whole tile a link or button with a chevron.
13
+ - **`ScrollStrip`** — a horizontal scroll-snap row (`snap-x mandatory`, scroll padding equal to `--page-gutter`, hidden scrollbar, items peek at the edge via `itemWidth`) that becomes a `columns`-wide CSS grid from `gridFrom` (default `md`). For KPI rows and card carousels.
14
+ - New token: `--page-gutter` (optional; falls back to 16px).
15
+
16
+ - **`SegmentedControl`** — one choice from 2–5 `options` `{ value, label, disabled? }` on a pill track with a sliding thumb (CSS transform, off under `prefers-reduced-motion`). Equal-width segments, `fullWidth`, `size` `sm` | `md`. Radio semantics with a roving tabindex: arrow keys move and select (wrapping, skipping disabled), Home/End jump. Hand-built; no new dependency.
17
+ - **`ChipGroup`** — horizontally scrolling filter chips, single (`value: string | null`, click the selected chip to clear) or `multiple` (`value: string[]`). Scroll-snap, fade edges that show only where there is more to scroll, and the selected chip scrolled into view. Chips are `aria-pressed` buttons; Left/Right/Home/End move focus.
18
+ - **Breaking:** `SegmentedControl` is now the new atom; Radix Themes' one moved to `RadixSegmentedControl` in `primitives`.
19
+
20
+ #
21
+ - **`NavBar`** — a sticky top bar for small screens: `title`, `leading` (a back-button slot) and
22
+ `trailing` (icon buttons). With `largeTitle`, a large left-aligned title sits in the content flow
23
+ and collapses into a small centred title in the bar as the page scrolls past it. The bar gains
24
+ `--material-bar` and a hairline only once scrolled; one `IntersectionObserver`, no scroll
25
+ listeners. Pads for `--safe-top`; height exposed as `--navbar-height`. Accessible: the large title
26
+ is the single `h1` and the small copy is `aria-hidden` (without `largeTitle` the small title is
27
+ the `h1`).
28
+ - **`BackButton`** — chevron plus optional `label`, 44px target; with no label its name is `UiStrings.back`.
29
+ - `UiStrings.back` (default "Back").
30
+ - **`TabBar`** / **`TabBarSpacer`** — fixed bottom navigation, 3–5 `items` `{ value, label, icon, activeIcon?, badge?, render? }`; `render` receives the props to spread on a router link (`aria-current="page"` on the active one). 49px + `--safe-bottom` (exposed as `--tabbar-height`), `--material-bar` ground, hairline top, brand-coloured active item, `:active` press feedback, hidden from `hideFrom` (default `md`).
31
+ - **`ActionSheet`** — `{ label, tone, icon?, onSelect }[]` with optional `title` / `message` and a
32
+ separated Cancel, on the grouped surface. Below `md` it is anchored to the bottom; at `md` and up
33
+ a small centred dialog. Built on Radix `AlertDialog`: no outside-click dismissal, and focus lands
34
+ on Cancel so Enter never fires a destructive action. Escape and Cancel run nothing.
35
+ - **`confirm({ title, message, confirmLabel, cancelLabel, tone })`** — resolves `true` on accept and
36
+ `false` on Cancel, Escape or any other dismissal; never rejects. Callable from anywhere, like
37
+ `toast()`. Mount one `<ConfirmProvider />` inside `<Theme>`; concurrent calls queue.
38
+ - `UiStrings.cancel` and `UiStrings.confirm` (defaults "Cancel", "Confirm").
39
+ - New dependency: `@radix-ui/react-alert-dialog`.
40
+ - **`Sheet`** — a bottom sheet on Radix Dialog: drag handle, `detent` `medium` | `large` | `fit`
41
+ (several at once via `detents`), velocity-based dismiss, a scrolling body that hands off to the
42
+ drag only at scroll-top, a footer above `--safe-bottom` and the keyboard (`visualViewport`), and
43
+ opt-in `scaleBackground` at `large`. Portals into the nearest Theme like the other floating atoms.
44
+ - **`ResponsiveDialog`** — `Dialog`'s props plus `sheetDetent`; a Dialog at `md` and up, a Sheet below.
45
+ - New dependency: `@radix-ui/react-dialog`.
46
+ - **`ListRow` `swipeActions`** `{ leading?, trailing? }` of `{ label, icon?, tone?, onAction }`, and opt-in
47
+ `fullSwipe` (past 60% of the row runs the first trailing action). Drag reveals the actions with
48
+ rubber-banding; one row open per `ListSection`; tap outside, Escape or tapping the row closes it.
49
+ The gesture is offered only on touch and without `prefers-reduced-motion`. The same actions are
50
+ always in the row's context menu (right-click, long-press) and in an overflow button — visible
51
+ when the gesture is off, visually hidden but focusable when it is on.
52
+ - `UiStrings.moreActions` — the overflow button's accessible name (default "More actions").
53
+
54
+
55
+ - **`StatTile`** — a compact KPI tile on `Card` (`variant`, `density`): `label`, `value` (tabular numerals), optional `delta` `{ value, direction, tone, label }` with an arrow and a positive/negative/neutral tone independent of direction, a `sparkline` slot, and `href` / `onClick` that make the whole tile a link or button with a chevron.
56
+ - **`ScrollStrip`** — a horizontal scroll-snap row (`snap-x mandatory`, scroll padding equal to `--page-gutter`, hidden scrollbar, items peek at the edge via `itemWidth`) that becomes a `columns`-wide CSS grid from `gridFrom` (default `md`). For KPI rows and card carousels.
57
+ - New token: `--page-gutter` (optional; falls back to 16px).
58
+
59
+ ### Added
60
+ - **`ListSection`, `ListRow` and `ListRowSkeleton`** — a native-style grouped list. A section
61
+ wraps rows on the grouped surface, with optional `header` and `footer` text outside the group
62
+ and `variant: 'inset' | 'full'`. Hairlines start after the leading slot. A row takes
63
+ `leading`, `title`, `subtitle`, `trailing`, `chevron`, `disabled` and `destructive`, and renders
64
+ a `button` (`onClick`), an `a` (`href`), your own element (`asChild`) or a plain `div`. Rows
65
+ are at least `--tap-min` tall with a pressed state; hover applies only under
66
+ `@media (hover: hover)`. Titles truncate, trailing values use tabular numerals. The list is
67
+ `<ul role="list">`. The skeleton announces `loading` from the strings provider.
68
+
69
+
70
+ - **`StatTile`** — a compact KPI tile on `Card` (`variant`, `density`): `label`, `value` (tabular numerals), optional `delta` `{ value, direction, tone, label }` with an arrow and a positive/negative/neutral tone independent of direction, a `sparkline` slot, and `href` / `onClick` that make the whole tile a link or button with a chevron.
71
+ - **`ScrollStrip`** — a horizontal scroll-snap row (`snap-x mandatory`, scroll padding equal to `--page-gutter`, hidden scrollbar, items peek at the edge via `itemWidth`) that becomes a `columns`-wide CSS grid from `gridFrom` (default `md`). For KPI rows and card carousels.
72
+ - New token: `--page-gutter` (optional; falls back to 16px).
73
+
74
+ ### Added
75
+ - **Mobile presentation layer in `tokens.css`** — an opt-in "grouped" surface style (cards on a
76
+ tinted canvas). Tokens: `--surface-grouped`, `--canvas-grouped`, `--separator-inset`,
77
+ `--radius-group` (12px), `--space-row-y` / `--space-row-x` (10 / 12px), `--tap-min` (44px),
78
+ `--safe-top/right/bottom/left` (`env(safe-area-inset-*)`, 0 fallback) and a translucent
79
+ `--material-bar` with `--material-bar-filter` (`saturate(180%) blur(20px)`).
80
+ - Tailwind utilities: `bg-grouped`, `bg-canvas-grouped`, `border-separator-inset`,
81
+ `rounded-group`, `min-h-tap`, `pt-safe`, `pb-safe`, `px-safe`, `bg-material`.
82
+ - Gray-11 and gray-12 text passes WCAG AA on the card, canvas and bar in light and dark
83
+ (`test/grouped.test.tsx`). README section with a before/after example.
84
+
85
+ - **`Card` `variant` and `density`** (also on `CardHeader`, `CardBody`; `density` on
86
+ `CardTitle`). `variant`: `outlined` (default, the current look), `grouped` (no border or
87
+ shadow, `bg-grouped`, `rounded-group`) or `plain` (no surface). `density`: `comfortable`
88
+ (default) or `compact` (row spacing tokens, smaller title). Both take Radix-style responsive
89
+ objects (`{ initial: 'grouped', md: 'outlined' }`, breakpoints `initial`, `xs`, `sm`, `md`,
90
+ `lg`, `xl`). Parts inherit from the `Card` and can override. `raised` is kept, and ignored by
91
+ `grouped` and `plain`. Exports `CardVariant`, `CardDensity`, `Responsive`. Responsive values
92
+ are data attributes matched by media queries in `tokens.css` (Radix breakpoints, not
93
+ Tailwind's). Example in `examples/Cards.tsx`, tests in `test/Card.test.tsx`.
94
+
95
+ No visual change to existing atoms.
96
+
97
+ ## 0.10.0 — 2026-10-19
98
+
99
+ ### Added
100
+ - **`NotificationCard`** — a persistent rich toast in a viewport corner: icon, title,
101
+ description, collapsible body and actions; controlled or uncontrolled; `onDismiss(reason)`;
102
+ non-modal, Escape only while focused; a labelled `section`, not a live region.
103
+
104
+ ### Changed
105
+ - **`Drawer` never portals to `<body>`.** Without a `<Theme>` above it, it renders in place;
106
+ inside one, its portal is wrapped in a nested `<Theme>` so it keeps the appearance.
107
+ - README rewritten as a generic presentation of the library.
108
+
109
+ ## 0.9.1 — 2026-10-18
4
110
 
5
111
  ### Fixed
6
112
  - **`Drawer` renders inside the nearest `<Theme>`** (`.radix-themes`) instead of under
7
113
  `<body>`. Outside a Theme none of the house tokens or the accent are defined, so in 0.9.0 the
8
- sheet lost the app's appearance — a dark app got a light sheet. Falls back to `<body>` when
114
+ sheet lost the app's appearance — a dark app got a light sheet. Falls back to `<body>` when
9
115
  there is no Theme; `container` still overrides it.
10
116
  - In `modal` mode, everything outside the sheet goes `inert` at every level up to `<body>`, not
11
117
  only the sheet's siblings, now that the sheet sits inside the Theme rather than beside it.
12
118
 
13
- ## 0.9.0 — 2026-10-18
119
+ ## 0.9.0 — 2026-10-18
14
120
 
15
121
  ### Added
16
122
  - **`Drawer`**, a bottom sheet with `collapsed` and `expanded` snap points, in two modes:
@@ -25,7 +131,7 @@
25
131
  ### Not verified
26
132
  - Only exercised in jsdom with simulated pointer events, not on a real touch device.
27
133
 
28
- ## 0.8.1 — 2026-10-11
134
+ ## 0.8.1 — 2026-10-11
29
135
 
30
136
  ### Fixed
31
137
  - **`Badge` text passes WCAG AA in both appearances.** Soft badges wrote their text in step a11
@@ -46,7 +152,7 @@
46
152
  ### Docs
47
153
  - README: the colour scales the atoms need, and their order relative to `base.css`.
48
154
 
49
- ## 0.8.0 — 2026-10-09
155
+ ## 0.8.0 — 2026-10-09
50
156
 
51
157
  ### Added
52
158
  - **Every Radix Themes component the atoms do not wrap**, re-exported unchanged from
@@ -56,11 +162,11 @@
56
162
  RadioCards, RadioGroup, ScrollArea, SegmentedControl, TabNav, Table, Tabs, TextField,
57
163
  AccessibleIcon, Portal, Reset, Slot, Slottable, ThemePanel, VisuallyHidden. Where an atom
58
164
  exists it remains the export under that name.
59
- - **`ThemeRoot`** — Themes' `<Theme>`, renamed because `Theme` is already this package's type.
165
+ - **`ThemeRoot`** — Themes' `<Theme>`, renamed because `Theme` is already this package's type.
60
166
  - **All of Radix Icons** (`@radix-ui/react-icons`, 320 `*Icon` components). `Icon` is
61
167
  unchanged and still the house glyph set.
62
168
 
63
- ## 0.7.0 — 2026-10-09
169
+ ## 0.7.0 — 2026-10-09
64
170
 
65
171
  ### Added
66
172
  - **`Alert`**: an inline message with `type` (`info` default, `warning`, `success`, `error`,
@@ -69,7 +175,7 @@
69
175
  theme's own accent. Errors and warnings are `role="alert"`, the rest `role="status"`.
70
176
  - **`Skeleton`** (Themes' skeleton) and **`SkeletonText`** (a `lines`-long paragraph placeholder).
71
177
 
72
- ## 0.6.1 — 2026-10-08
178
+ ## 0.6.1 — 2026-10-08
73
179
 
74
180
  ### Fixed
75
181
  - **`Slider` thumbs always have an accessible name.** Without `fillFrom`, `label` landed on the
@@ -79,7 +185,7 @@
79
185
  Radix's bare "Minimum"/"Maximum". Consumers using `fillFrom={min}` only to get a name can
80
186
  drop it.
81
187
 
82
- ## 0.6.0 — 2026-10-07
188
+ ## 0.6.0 — 2026-10-07
83
189
 
84
190
  ### Added
85
191
  - **`RichText`**: a Tiptap editor (StarterKit) under a Radix `Toolbar`. Marks (bold, italic,
@@ -87,22 +193,22 @@
87
193
  one, so the toolbar is one tab stop with arrow keys. `value`/`onChange` speak HTML; also
88
194
  `placeholder`, `disabled`, `invalid`, `rows`, `aria-label`/`aria-labelledby`, and a ref
89
195
  exposing `{ editor, focus }`.
90
- Styled as a Themes `TextArea` (surface, size 2) from public tokens — border, focus ring,
91
- background, invalid and disabled states — in `.ui-richtext*` in `tokens.css`.
196
+ Styled as a Themes `TextArea` (surface, size 2) from public tokens — border, focus ring,
197
+ background, invalid and disabled states — in `.ui-richtext*` in `tokens.css`.
92
198
  - `UiStrings` gains `formatting`, `bold`, `italic`, `strike`, `heading`, `bulletList`,
93
199
  `orderedList` (English defaults; hosts should translate them).
94
200
 
95
201
  ### Requires
96
202
  - `tokens.css` imported; the editor is unstyled without it.
97
203
 
98
- ## 0.5.0 — 2026-10-06
204
+ ## 0.5.0 — 2026-10-06
99
205
 
100
206
  ### Added
101
207
  - **`Slider` `fillFrom`**: fills from a fixed value to the thumb, in either direction, instead of
102
208
  from `min`. Same units as `value`, clamped to [min, max]; nothing is filled when the thumb sits
103
209
  on it. The fill's ends line up with the thumb's centre at every value, using Radix's own
104
210
  in-bounds offset. Built on `@radix-ui/react-slider` and styled from Themes' public tokens
105
- (`.ui-slider*` in `tokens.css`), because Themes' slider gives no way to place its range —
211
+ (`.ui-slider*` in `tokens.css`), because Themes' slider gives no way to place its range —
106
212
  consumers overriding `.rt-SliderRange` can drop that CSS.
107
213
  Single horizontal left-to-right thumb only: with two thumbs, `orientation="vertical"`,
108
214
  `inverted` or `dir="rtl"` it is ignored with a development warning. Margin props are not
@@ -115,7 +221,7 @@
115
221
  - Without `fillFrom`, `Slider` is still the Radix Themes slider, rendered exactly as in 0.4.0.
116
222
 
117
223
  ### Requires
118
- - `tokens.css` imported, as it already must be for toasts — the `fillFrom` path is unstyled
224
+ - `tokens.css` imported, as it already must be for toasts — the `fillFrom` path is unstyled
119
225
  without it.
120
226
 
121
227
  ## 0.4.0