prime-ui-kit 0.9.1 → 0.9.2

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 (107) hide show
  1. package/README.md +22 -8
  2. package/dist/chunks/{chunk-KCQFOORX.js → chunk-IQELQNMR.js} +1 -1
  3. package/dist/chunks/{chunk-DB2Y3XXA.js → chunk-LXGRKN34.js} +2323 -1500
  4. package/dist/chunks/{chunk-NHOWNIAR.js → chunk-ZEFCDEEQ.js} +790 -536
  5. package/dist/color-picker.js +2 -2
  6. package/dist/components/data-table/DataTable.d.ts +6 -1
  7. package/dist/components/data-table/types.d.ts +5 -0
  8. package/dist/components/dnd/Dnd.d.ts +1 -1
  9. package/dist/components/dnd/dragSession.d.ts +9 -0
  10. package/dist/components/dnd/useDropTarget.d.ts +5 -0
  11. package/dist/components/dnd/useFlipList.d.ts +3 -3
  12. package/dist/components/drawer/Drawer.d.ts +8 -5
  13. package/dist/components/dropdown/Dropdown.d.ts +17 -0
  14. package/dist/components/index.d.ts +5 -1
  15. package/dist/components/kanban/Kanban.d.ts +129 -0
  16. package/dist/components/modal/Modal.d.ts +5 -2
  17. package/dist/components/page-toolbar/PageToolbar.d.ts +53 -0
  18. package/dist/components/segmented-control/SegmentedControl.d.ts +5 -2
  19. package/dist/components/tabs/Tabs.d.ts +5 -2
  20. package/dist/hooks/useEdgeOverflow.d.ts +12 -0
  21. package/dist/hooks/useMediaQuery.d.ts +7 -0
  22. package/dist/hooks/useSwipeDismiss.d.ts +34 -0
  23. package/dist/index.css +2271 -1163
  24. package/dist/index.js +10 -2
  25. package/dist/internal/overlay/FloatingPanel.d.ts +3 -1
  26. package/dist/internal/overlay/useFloatingLayer.d.ts +11 -1
  27. package/dist/internal/touchTarget.d.ts +4 -0
  28. package/dist/layout/app-header/AppHeader.d.ts +110 -0
  29. package/dist/layout/app-shell/AppShell.d.ts +14 -9
  30. package/dist/layout/bottom-nav/BottomNav.d.ts +80 -0
  31. package/dist/layout/index.d.ts +5 -1
  32. package/dist/tokens/primitives.d.ts +4 -0
  33. package/dist/tokens/semantic.d.ts +56 -0
  34. package/dist/tokens/themes/dark.d.ts +4 -0
  35. package/package.json +3 -2
  36. package/src/components/accordion/COMPONENT.md +1 -1
  37. package/src/components/badge/COMPONENT.md +2 -2
  38. package/src/components/banner/COMPONENT.md +1 -1
  39. package/src/components/checkbox/examples/examples.module.css +4 -2
  40. package/src/components/crossfade/COMPONENT.md +1 -1
  41. package/src/components/data-table/COMPONENT.md +19 -6
  42. package/src/components/data-table/examples/columns-visibility.tsx +167 -0
  43. package/src/components/digit-input/COMPONENT.md +10 -10
  44. package/src/components/digit-input/examples/examples.module.css +8 -0
  45. package/src/components/digit-input/examples/in-form.tsx +2 -5
  46. package/src/components/digit-input/examples/sizes.tsx +1 -1
  47. package/src/components/divider/COMPONENT.md +1 -1
  48. package/src/components/dnd/COMPONENT.md +3 -3
  49. package/src/components/drawer/COMPONENT.md +17 -9
  50. package/src/components/drawer/examples/date-sheet.tsx +41 -0
  51. package/src/components/drawer/examples/examples.module.css +5 -0
  52. package/src/components/drawer/examples/placement.tsx +4 -2
  53. package/src/components/dropdown/COMPONENT.md +19 -5
  54. package/src/components/dropdown/examples/checkbox-items.tsx +48 -0
  55. package/src/components/empty-page/COMPONENT.md +1 -1
  56. package/src/components/kanban/COMPONENT.md +181 -0
  57. package/src/components/kanban/examples/controlled.tsx +78 -0
  58. package/src/components/kanban/examples/examples.module.css +31 -0
  59. package/src/components/kanban/examples/limits.tsx +58 -0
  60. package/src/components/kanban/examples/narrow.tsx +76 -0
  61. package/src/components/kanban/examples/overview.tsx +130 -0
  62. package/src/components/kanban/examples/states.tsx +75 -0
  63. package/src/components/kanban/examples/structure.tsx +76 -0
  64. package/src/components/login-form/COMPONENT.md +1 -1
  65. package/src/components/modal/COMPONENT.md +9 -6
  66. package/src/components/notification/COMPONENT.md +2 -2
  67. package/src/components/page-content/COMPONENT.md +1 -1
  68. package/src/components/page-toolbar/COMPONENT.md +142 -0
  69. package/src/components/page-toolbar/examples/examples.module.css +16 -0
  70. package/src/components/page-toolbar/examples/narrow.tsx +103 -0
  71. package/src/components/page-toolbar/examples/overview.tsx +113 -0
  72. package/src/components/page-toolbar/examples/save-changes.tsx +40 -0
  73. package/src/components/page-toolbar/examples/without-search.tsx +60 -0
  74. package/src/components/popover/COMPONENT.md +4 -3
  75. package/src/components/progress-bar/COMPONENT.md +1 -1
  76. package/src/components/progress-circle/COMPONENT.md +1 -1
  77. package/src/components/scroll-container/COMPONENT.md +1 -1
  78. package/src/components/segmented-control/COMPONENT.md +8 -8
  79. package/src/components/segmented-control/examples/full-width.tsx +1 -1
  80. package/src/components/select/COMPONENT.md +2 -1
  81. package/src/components/skeleton/COMPONENT.md +1 -1
  82. package/src/components/smart-filter/COMPONENT.md +2 -0
  83. package/src/components/spinner/COMPONENT.md +1 -1
  84. package/src/components/tabs/COMPONENT.md +11 -8
  85. package/src/components/tabs/examples/closable.tsx +1 -1
  86. package/src/layout/app-header/COMPONENT.md +178 -0
  87. package/src/layout/app-header/examples/breadcrumbs.tsx +36 -0
  88. package/src/layout/app-header/examples/examples.module.css +47 -0
  89. package/src/layout/app-header/examples/in-app-shell.tsx +70 -0
  90. package/src/layout/app-header/examples/narrow.tsx +29 -0
  91. package/src/layout/app-header/examples/overview.tsx +36 -0
  92. package/src/layout/app-shell/COMPONENT.md +27 -21
  93. package/src/layout/app-shell/examples/examples.module.css +15 -0
  94. package/src/layout/app-shell/examples/footer.tsx +59 -0
  95. package/src/layout/app-shell/examples/overview.tsx +19 -8
  96. package/src/layout/bottom-nav/COMPONENT.md +153 -0
  97. package/src/layout/bottom-nav/examples/examples.module.css +39 -0
  98. package/src/layout/bottom-nav/examples/floating.tsx +89 -0
  99. package/src/layout/bottom-nav/examples/icon-only.tsx +41 -0
  100. package/src/layout/bottom-nav/examples/in-app-shell.tsx +64 -0
  101. package/src/layout/bottom-nav/examples/overview.tsx +44 -0
  102. package/src/layout/bottom-nav/examples/router.tsx +31 -0
  103. package/src/layout/bottom-nav/examples/structure.tsx +47 -0
  104. package/src/layout/sidebar/COMPONENT.md +11 -10
  105. package/src/styles/theme-dark.css +3 -0
  106. package/src/styles/theme-light.css +24 -0
  107. package/src/styles/tokens.css +2 -0
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import {
2
2
  Accordion,
3
+ AppHeader,
3
4
  AppShell,
4
5
  Avatar,
5
6
  Badge,
6
7
  Banner,
8
+ BottomNav,
7
9
  Breadcrumb,
8
10
  ButtonGroup,
9
11
  Card,
@@ -20,6 +22,7 @@ import {
20
22
  Dropdown,
21
23
  ExampleFrame,
22
24
  FileUpload,
25
+ Kanban,
23
26
  Kbd,
24
27
  LinkButton,
25
28
  LoginForm,
@@ -28,6 +31,7 @@ import {
28
31
  NotificationCard,
29
32
  NotificationProvider,
30
33
  PageContent,
34
+ PageToolbar,
31
35
  Pagination,
32
36
  Popover,
33
37
  ProgressBar,
@@ -57,7 +61,7 @@ import {
57
61
  suspendTransitions,
58
62
  useNotifications,
59
63
  useSidebar
60
- } from "./chunks/chunk-DB2Y3XXA.js";
64
+ } from "./chunks/chunk-LXGRKN34.js";
61
65
  import {
62
66
  Button,
63
67
  COLOR_PRESETS,
@@ -83,13 +87,15 @@ import {
83
87
  tones,
84
88
  useOptionalControlSize,
85
89
  variants
86
- } from "./chunks/chunk-NHOWNIAR.js";
90
+ } from "./chunks/chunk-ZEFCDEEQ.js";
87
91
  export {
88
92
  Accordion,
93
+ AppHeader,
89
94
  AppShell,
90
95
  Avatar,
91
96
  Badge,
92
97
  Banner,
98
+ BottomNav,
93
99
  Breadcrumb,
94
100
  Button,
95
101
  ButtonGroup,
@@ -116,6 +122,7 @@ export {
116
122
  Hint,
117
123
  Icon,
118
124
  Input,
125
+ Kanban,
119
126
  Kbd,
120
127
  Label,
121
128
  LinkButton,
@@ -125,6 +132,7 @@ export {
125
132
  NotificationCard,
126
133
  NotificationProvider,
127
134
  PageContent,
135
+ PageToolbar,
128
136
  Pagination,
129
137
  Popover,
130
138
  ProgressBar,
@@ -15,7 +15,9 @@ export type FloatingPanelProps = Omit<React.HTMLAttributes<HTMLElement>, "onAnim
15
15
  * The panel of a floating layer: portaled to `<body>` when it opens (so it stacks above every
16
16
  * layer opened before it, on the one overlay z-index), positioned, animated from `data-state` /
17
17
  * `data-side` (foundation §8), a size context for the controls inside, and a layer context so
18
- * layers opened inside stack above it in the layer stack. Renders nothing while closed.
18
+ * layers opened inside stack above it in the layer stack. Renders nothing while closed. A layer in
19
+ * sheet mode (`floating.sheet`) renders a scrim and a bottom sheet with a grab handle around the
20
+ * same panel element; the consumer ref stays on the panel.
19
21
  */
20
22
  export declare function FloatingPanel({ floating, size, scroll, surface, className, onKeyDown, children, ref, ...rest }: FloatingPanelProps): import("react/jsx-runtime").JSX.Element | null;
21
23
  export type FloatingTriggerProps = {
@@ -30,6 +30,12 @@ export type UseFloatingLayerOptions = PositionOptions & {
30
30
  exitDuration?: MotionDurationToken;
31
31
  /** Unmount at once on close, skipping the exit animation (a Tooltip replaced by its neighbour). */
32
32
  skipExit?: boolean;
33
+ /**
34
+ * Below 640px of viewport the panel is a bottom sheet instead of an anchored panel: a scrim,
35
+ * a grab handle, swipe down to close, page scroll locked. For panels the user works in (menus,
36
+ * listboxes, pickers); not for a panel driven by typing in its anchor.
37
+ */
38
+ sheet?: boolean;
33
39
  };
34
40
  export type FloatingLayer = {
35
41
  open: boolean;
@@ -38,6 +44,10 @@ export type FloatingLayer = {
38
44
  mounted: boolean;
39
45
  /** The side after flipping. */
40
46
  side: PositionSide;
47
+ /** Rendered as a bottom sheet (`sheet` on a narrow viewport). */
48
+ sheet: boolean;
49
+ /** Swipe-to-close of the sheet; part of the sheet's `onPointerDown`. */
50
+ onSheetPointerDown: (event: React.PointerEvent<HTMLElement>) => void;
41
51
  /** Attach to the panel element (merged with a consumer ref). */
42
52
  panelRef: React.RefCallback<HTMLElement>;
43
53
  /** The panel element while mounted. */
@@ -57,4 +67,4 @@ export type FloatingLayer = {
57
67
  * policy (foundation §8): focus returns to the trigger after Escape, a pick, Tab or a close — not
58
68
  * after a press outside, where focus follows the pointer. Render the panel with `FloatingPanel`.
59
69
  */
60
- export declare function useFloatingLayer({ open, onOpenChange, triggerRef, closeOnEscape, closeOnOutsideClick, dismiss, focusOnOpen, trap, tabExit, exitDuration, skipExit, ...positionOptions }: UseFloatingLayerOptions): FloatingLayer;
70
+ export declare function useFloatingLayer({ open, onOpenChange, triggerRef, closeOnEscape, closeOnOutsideClick, dismiss, focusOnOpen, trap, tabExit, exitDuration, skipExit, sheet: sheetOption, ...positionOptions }: UseFloatingLayerOptions): FloatingLayer;
@@ -0,0 +1,4 @@
1
+ /** A 44px hit area on coarse pointers, both axes, the visual size unchanged (`touchTarget.module.css`). */
2
+ export declare const touchTargetClass: string;
3
+ /** The same hit area grown in height only: a segment beside other content of its host. */
4
+ export declare const touchTargetBlockClass: string;
@@ -0,0 +1,110 @@
1
+ import * as React from "react";
2
+ import { type DividerProps } from "@/components/divider/Divider";
3
+ export type AppHeaderLabels = {
4
+ /** Name of the menu button that opens the off-canvas Sidebar. */
5
+ menu: string;
6
+ };
7
+ type HeaderProps = React.HTMLAttributes<HTMLElement> & {
8
+ ref?: React.Ref<HTMLElement>;
9
+ };
10
+ type DivProps = React.HTMLAttributes<HTMLDivElement> & {
11
+ ref?: React.Ref<HTMLDivElement>;
12
+ };
13
+ export type AppHeaderRootProps = HeaderProps & {
14
+ labels?: Partial<AppHeaderLabels>;
15
+ };
16
+ /**
17
+ * The bar at the very top of the content panel: where you are, global search, a few actions.
18
+ * One row as high as the Sidebar brand row, so the two read as one line; sticky; lays itself out
19
+ * from its own width (narrow: the search folds into an icon, the title truncates).
20
+ */
21
+ declare function AppHeaderRoot({ labels, className, children, ...rest }: AppHeaderRootProps): import("react/jsx-runtime").JSX.Element;
22
+ declare namespace AppHeaderRoot {
23
+ var displayName: string;
24
+ }
25
+ export type AppHeaderStartProps = DivProps;
26
+ /** The leading zone: the menu button, a back button, the title or breadcrumbs. Takes the free width. */
27
+ declare function AppHeaderStart({ className, ...rest }: AppHeaderStartProps): import("react/jsx-runtime").JSX.Element;
28
+ declare namespace AppHeaderStart {
29
+ var displayName: string;
30
+ }
31
+ export type AppHeaderTitleProps = DivProps;
32
+ /**
33
+ * Where you are: an optional `AppHeader.Icon`, the name and an optional `AppHeader.Description`
34
+ * under it — the same anatomy as the Sidebar brand. The name truncates.
35
+ */
36
+ declare function AppHeaderTitle({ className, children, ...rest }: AppHeaderTitleProps): import("react/jsx-runtime").JSX.Element;
37
+ declare namespace AppHeaderTitle {
38
+ var displayName: string;
39
+ }
40
+ export type AppHeaderIconProps = React.HTMLAttributes<HTMLSpanElement> & {
41
+ ref?: React.Ref<HTMLSpanElement>;
42
+ };
43
+ /**
44
+ * Decorative glyph before the title on a tile shaped like the bar's soft buttons (control m).
45
+ * Not a Thumbnail: its tiers (32 · 40) miss the control height the buttons beside it have.
46
+ */
47
+ declare function AppHeaderIcon({ className, ...rest }: AppHeaderIconProps): import("react/jsx-runtime").JSX.Element;
48
+ declare namespace AppHeaderIcon {
49
+ var displayName: string;
50
+ }
51
+ export type AppHeaderDescriptionProps = React.HTMLAttributes<HTMLSpanElement> & {
52
+ ref?: React.Ref<HTMLSpanElement>;
53
+ };
54
+ /** Muted second line under the title (a workspace, a period); hidden on a narrow header. */
55
+ declare function AppHeaderDescription({ className, ...rest }: AppHeaderDescriptionProps): import("react/jsx-runtime").JSX.Element;
56
+ declare namespace AppHeaderDescription {
57
+ var displayName: string;
58
+ }
59
+ export type AppHeaderSeparatorProps = Omit<DividerProps, "orientation" | "children">;
60
+ /** A short vertical line between groups in a zone (a back button | the path), with air on both sides. */
61
+ declare function AppHeaderSeparator({ className, ...rest }: AppHeaderSeparatorProps): import("react/jsx-runtime").JSX.Element;
62
+ declare namespace AppHeaderSeparator {
63
+ var displayName: string;
64
+ }
65
+ export type AppHeaderSearchProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type" | "children"> & {
66
+ /** Placeholder text; also the button's name when the header is narrow and the field folds. */
67
+ children: React.ReactNode;
68
+ /** Key hint at the end. Default `⌘K`; `null` hides it. */
69
+ shortcut?: React.ReactNode;
70
+ ref?: React.Ref<HTMLButtonElement>;
71
+ };
72
+ /**
73
+ * Global search entry: looks like a field, works as a button that opens your CommandMenu (wire
74
+ * `onClick` and the shortcut). On a narrow header it folds into a square search button.
75
+ */
76
+ declare function AppHeaderSearch({ children, shortcut, className, ...rest }: AppHeaderSearchProps): import("react/jsx-runtime").JSX.Element;
77
+ declare namespace AppHeaderSearch {
78
+ var displayName: string;
79
+ }
80
+ export type AppHeaderActionsProps = DivProps;
81
+ /** Buttons at the end: one primary action, notifications, the account. Never wraps. */
82
+ declare function AppHeaderActions({ className, ...rest }: AppHeaderActionsProps): import("react/jsx-runtime").JSX.Element;
83
+ declare namespace AppHeaderActions {
84
+ var displayName: string;
85
+ }
86
+ export type AppHeaderMenuButtonProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type" | "children"> & {
87
+ /**
88
+ * `narrow` (default): shown below 768px, where an `offCanvas="auto"` Sidebar leaves the layout;
89
+ * `always`: on every width (`offCanvas="always"`).
90
+ */
91
+ show?: "narrow" | "always";
92
+ ref?: React.Ref<HTMLButtonElement>;
93
+ };
94
+ /** Opens the off-canvas Sidebar: an icon button named by `labels.menu`; wire `onClick` and `aria-expanded`. */
95
+ declare function AppHeaderMenuButton({ show, className, ...rest }: AppHeaderMenuButtonProps): import("react/jsx-runtime").JSX.Element;
96
+ declare namespace AppHeaderMenuButton {
97
+ var displayName: string;
98
+ }
99
+ export declare const AppHeader: {
100
+ Root: typeof AppHeaderRoot;
101
+ Start: typeof AppHeaderStart;
102
+ Title: typeof AppHeaderTitle;
103
+ Icon: typeof AppHeaderIcon;
104
+ Description: typeof AppHeaderDescription;
105
+ Separator: typeof AppHeaderSeparator;
106
+ Search: typeof AppHeaderSearch;
107
+ Actions: typeof AppHeaderActions;
108
+ MenuButton: typeof AppHeaderMenuButton;
109
+ };
110
+ export {};
@@ -20,12 +20,12 @@ declare function AppShellRoot({ fillViewport, className, children, ...rest }: Ap
20
20
  declare namespace AppShellRoot {
21
21
  var displayName: string;
22
22
  }
23
- export type AppShellHeaderProps = React.HTMLAttributes<HTMLElement> & {
24
- ref?: React.Ref<HTMLElement>;
23
+ export type AppShellFooterProps = React.HTMLAttributes<HTMLDivElement> & {
24
+ ref?: React.Ref<HTMLDivElement>;
25
25
  };
26
- /** Top bar of the content panel (breadcrumbs, page actions, mobile menu button). Sticky. */
27
- declare function AppShellHeader({ className, ...rest }: AppShellHeaderProps): import("react/jsx-runtime").JSX.Element;
28
- declare namespace AppShellHeader {
26
+ /** Bottom bar of the content panel (`BottomNav` on a narrow shell). Sticky. */
27
+ declare function AppShellFooter({ className, ...rest }: AppShellFooterProps): import("react/jsx-runtime").JSX.Element;
28
+ declare namespace AppShellFooter {
29
29
  var displayName: string;
30
30
  }
31
31
  /** `full` (default): the whole panel with responsive gutters; `contained`: centered, up to `--prime-layout-content-max-width` (long-read pages). */
@@ -44,23 +44,28 @@ export type AppShellTemplateProps = Omit<AppShellRootProps, "children" | "ref">
44
44
  ref?: React.Ref<HTMLElement>;
45
45
  /** Navigation column content, usually `Sidebar.Root`. */
46
46
  nav?: React.ReactNode;
47
- /** `AppShell.Header` content; no header row when omitted. */
47
+ /** The top bar of the content panel, an `AppHeader.Root`; no header when omitted. */
48
48
  header?: React.ReactNode;
49
+ /** `AppShell.Footer` content (`BottomNav`); no footer when omitted. */
50
+ footer?: React.ReactNode;
49
51
  children?: React.ReactNode;
50
52
  mainProps?: Omit<AppShellMainProps, "children" | "ref">;
51
53
  /** Main scrolls back to the top whenever this value changes (pass the router pathname). */
52
54
  scrollResetKey?: unknown;
53
55
  };
54
- /** Root + Nav + Header + Main in one; main scrolls to the top when `scrollResetKey` changes. */
55
- declare function AppShellTemplate({ ref, nav, header, children, mainProps, scrollResetKey, ...rootProps }: AppShellTemplateProps): import("react/jsx-runtime").JSX.Element;
56
+ /**
57
+ * Root + Nav + the header + Main + Footer in one; main scrolls to the top when `scrollResetKey`
58
+ * changes.
59
+ */
60
+ declare function AppShellTemplate({ ref, nav, header, footer, children, mainProps, scrollResetKey, ...rootProps }: AppShellTemplateProps): import("react/jsx-runtime").JSX.Element;
56
61
  declare namespace AppShellTemplate {
57
62
  var displayName: string;
58
63
  }
59
64
  export declare const AppShell: {
60
65
  Root: typeof AppShellRoot;
61
66
  Nav: typeof AppShellNav;
62
- Header: typeof AppShellHeader;
63
67
  Main: typeof AppShellMain;
68
+ Footer: typeof AppShellFooter;
64
69
  Template: typeof AppShellTemplate;
65
70
  };
66
71
  export {};
@@ -0,0 +1,80 @@
1
+ import * as React from "react";
2
+ import type { PaletteColor, Variant } from "@/internal/states";
3
+ export type BottomNavLabels = {
4
+ /** `aria-label` of the `<nav>` landmark. */
5
+ nav: string;
6
+ };
7
+ export type BottomNavRootProps = React.HTMLAttributes<HTMLElement> & {
8
+ /** Icons without visible labels; the labels still name the items for screen readers. */
9
+ iconOnly?: boolean;
10
+ /**
11
+ * A glass capsule floating over the content (backdrop blur, inset from the edges) instead of
12
+ * a flat bar at the edge. It places itself at the bottom of its positioned container
13
+ * (`AppShell.Footer`), so the page scrolls under it.
14
+ */
15
+ floating?: boolean;
16
+ labels?: Partial<BottomNavLabels>;
17
+ /** The `<nav>` bar. */
18
+ ref?: React.Ref<HTMLElement>;
19
+ };
20
+ /**
21
+ * Phone navigation: a bar of 3–5 sections at the bottom of the screen. Inside `AppShell.Footer`
22
+ * it shows only while the content panel is narrower than 640px; wider, Sidebar navigates.
23
+ */
24
+ declare function BottomNavRoot({ iconOnly, floating, labels, className, ...rest }: BottomNavRootProps): import("react/jsx-runtime").JSX.Element;
25
+ declare namespace BottomNavRoot {
26
+ var displayName: string;
27
+ }
28
+ export type BottomNavItemIconProps = Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> & {
29
+ children: React.ReactNode;
30
+ ref?: React.Ref<HTMLSpanElement>;
31
+ };
32
+ /** The item glyph above the label. */
33
+ declare function BottomNavItemIcon({ className, ...rest }: BottomNavItemIconProps): import("react/jsx-runtime").JSX.Element;
34
+ declare namespace BottomNavItemIcon {
35
+ var displayName: string;
36
+ }
37
+ export type BottomNavItemCountProps = Omit<React.HTMLAttributes<HTMLSpanElement>, "children" | "color"> & {
38
+ /** The number (or a short status). */
39
+ children: React.ReactNode;
40
+ /** Badge hue. Default `red`: a count on a section asks for attention. */
41
+ color?: PaletteColor;
42
+ /** Badge treatment. Default `solid`. */
43
+ variant?: Exclude<Variant, "ghost">;
44
+ /** The Badge `<span>`. */
45
+ ref?: React.Ref<HTMLSpanElement>;
46
+ };
47
+ /** A count on the corner of the icon: a small Badge, read after the label. */
48
+ declare function BottomNavItemCount({ color, variant, className, ...rest }: BottomNavItemCountProps): import("react/jsx-runtime").JSX.Element;
49
+ declare namespace BottomNavItemCount {
50
+ var displayName: string;
51
+ }
52
+ type BottomNavItemOwnProps = {
53
+ /** Current section: `aria-current="page"`. Links rendered by a router may set it themselves. */
54
+ current?: boolean;
55
+ disabled?: boolean;
56
+ /** Render the single child element (a router link) as the item; its children are the content. */
57
+ asChild?: boolean;
58
+ /** `BottomNav.ItemIcon`, an optional `BottomNav.ItemCount` and the label. */
59
+ children?: React.ReactNode;
60
+ };
61
+ export type BottomNavItemProps = BottomNavItemOwnProps & Omit<React.ComponentPropsWithoutRef<"button">, keyof BottomNavItemOwnProps> & {
62
+ /** Renders an `<a>` instead of a `<button>`. */
63
+ href?: string;
64
+ target?: string;
65
+ rel?: string;
66
+ /** The `<a>`, `<button>` or the `asChild` element. */
67
+ ref?: React.Ref<HTMLElement>;
68
+ };
69
+ /** A section of the bar: the icon above a short label, both in the primary color while current. */
70
+ declare function BottomNavItem({ current, disabled, asChild, href, className, children, onClick, type, ref, ...rest }: BottomNavItemProps): import("react/jsx-runtime").JSX.Element;
71
+ declare namespace BottomNavItem {
72
+ var displayName: string;
73
+ }
74
+ export declare const BottomNav: {
75
+ Root: typeof BottomNavRoot;
76
+ Item: typeof BottomNavItem;
77
+ ItemIcon: typeof BottomNavItemIcon;
78
+ ItemCount: typeof BottomNavItemCount;
79
+ };
80
+ export {};
@@ -1,4 +1,8 @@
1
- export type { AppShellContentWidth, AppShellHeaderProps, AppShellMainProps, AppShellNavProps, AppShellRootProps, AppShellTemplateProps, } from "./app-shell/AppShell";
1
+ export type { AppHeaderActionsProps, AppHeaderDescriptionProps, AppHeaderIconProps, AppHeaderLabels, AppHeaderMenuButtonProps, AppHeaderRootProps, AppHeaderSearchProps, AppHeaderSeparatorProps, AppHeaderStartProps, AppHeaderTitleProps, } from "./app-header/AppHeader";
2
+ export { AppHeader } from "./app-header/AppHeader";
3
+ export type { AppShellContentWidth, AppShellFooterProps, AppShellMainProps, AppShellNavProps, AppShellRootProps, AppShellTemplateProps, } from "./app-shell/AppShell";
2
4
  export { AppShell } from "./app-shell/AppShell";
5
+ export type { BottomNavItemCountProps, BottomNavItemIconProps, BottomNavItemProps, BottomNavLabels, BottomNavRootProps, } from "./bottom-nav/BottomNav";
6
+ export { BottomNav } from "./bottom-nav/BottomNav";
3
7
  export type { SidebarAccountProps, SidebarBrandLogoProps, SidebarBrandProps, SidebarContentProps, SidebarFooterProps, SidebarGroupProps, SidebarHeaderProps, SidebarItemActionProps, SidebarItemCountProps, SidebarItemIconProps, SidebarItemProps, SidebarItemShortcutProps, SidebarLabels, SidebarMode, SidebarRootProps, SidebarSubContentProps, SidebarSubProps, SidebarSubTriggerProps, SidebarToggleProps, } from "./sidebar/Sidebar";
4
8
  export { Sidebar, useSidebar } from "./sidebar/Sidebar";
@@ -134,6 +134,8 @@ export declare const primitiveTokens: {
134
134
  };
135
135
  /** Modular scale, ~1.2 in the body range, ~1.25 for headings. */
136
136
  readonly size: {
137
+ /** Only for tab-bar labels under an icon (BottomNav, iOS tab bar 10pt); text roles start at 12. */
138
+ readonly 10: "0.625rem";
137
139
  readonly 12: "0.75rem";
138
140
  readonly 13: "0.8125rem";
139
141
  readonly 14: "0.875rem";
@@ -147,6 +149,8 @@ export declare const primitiveTokens: {
147
149
  readonly 60: "3.75rem";
148
150
  };
149
151
  readonly lineHeight: {
152
+ /** Only for tab-bar labels (BottomNav). */
153
+ readonly 12: "0.75rem";
150
154
  readonly 16: "1rem";
151
155
  readonly 20: "1.25rem";
152
156
  readonly 24: "1.5rem";
@@ -22,6 +22,15 @@ export declare const semanticTokens: {
22
22
  readonly sunken: "{color.gray.75}";
23
23
  readonly inverse: "{color.gray.925}";
24
24
  readonly scrim: "rgba(17, 19, 24, 0.44)";
25
+ /** Soft shade over an edge that hides scrolled content (DataTable columns). */
26
+ readonly edgeShadow: "rgba(17, 19, 24, 0.14)";
27
+ /**
28
+ * Translucent glass over content (floating BottomNav), always with a light backdrop blur:
29
+ * clear enough that the content reads through it, as Liquid Glass.
30
+ */
31
+ readonly glass: "color-mix(in srgb, var(--prime-ref-color-gray-0) 58%, transparent)";
32
+ /** The specular top edge of a glass surface: the line that makes it read as glass. */
33
+ readonly glassEdge: "rgba(255, 255, 255, 0.85)";
25
34
  };
26
35
  readonly fill: {
27
36
  /** Transparent wash: ghost hover, row hover. Works on any background. */
@@ -430,6 +439,13 @@ export declare const semanticTokens: {
430
439
  readonly choice: "{icon.24}";
431
440
  readonly track: "0.5rem";
432
441
  };
442
+ /**
443
+ * Coarse pointers (`@media (pointer: coarse)`): the hit area of a control below this size grows
444
+ * to it (WCAG 2.5.5); the visual size stays the tier's.
445
+ */
446
+ readonly touchTarget: "2.75rem";
447
+ /** Touch screens and narrow viewports: the least text size of an editable value (iOS zoom). */
448
+ readonly touchTextSize: "{font.size.16}";
433
449
  };
434
450
  /** Badge / Kbd tiers. Inside a control of tier T use the badge tier one step down. */
435
451
  readonly badge: {
@@ -569,6 +585,46 @@ export declare const semanticTokens: {
569
585
  readonly widthL: "40rem";
570
586
  readonly widthXl: "50rem";
571
587
  };
588
+ /** Bottom sheets: Drawer `side="bottom"`, Modal and floating layers on a narrow viewport. */
589
+ readonly sheet: {
590
+ readonly radius: "{radius.16}";
591
+ /** The grab bar at the top edge and the strip that holds it. */
592
+ readonly handleWidth: "2.25rem";
593
+ readonly handleHeight: "{space.1}";
594
+ readonly handleArea: "{space.5}";
595
+ /** Room kept above a sheet so the page behind stays visible. */
596
+ readonly topGap: "{space.10}";
597
+ /** A bottom sheet on a tablet or desktop is never narrower than this (= Modal m). */
598
+ readonly minWidth: "35rem";
599
+ };
600
+ readonly bottomNav: {
601
+ /** Bar height without the safe-area inset: icon 20 + gap 4 + label 12 and air around them. */
602
+ readonly height: "3.25rem";
603
+ /** An icon-only flat bar: no label row, so it is lower. */
604
+ readonly iconOnlyHeight: "{space.12}";
605
+ /**
606
+ * Floating capsule (iOS 26 tab bar): items 44 high — icon-only items are 44 squares, the touch
607
+ * size — inset 4 inside the capsule, so the selection capsule sits clear of its edge (52 in all).
608
+ */
609
+ readonly floatingItemSize: "2.75rem";
610
+ readonly floatingPadding: "{space.1}";
611
+ readonly paddingX: "{space.2}";
612
+ /** Between the icon and the label. */
613
+ readonly itemGap: "{space.1}";
614
+ /** The box that holds the icon and anchors the count. */
615
+ readonly indicatorWidth: "{space.7}";
616
+ readonly indicatorHeight: "{space.5}";
617
+ /** A light icon (20) over a small label (10, as the iOS tab bar): the bar stays quiet. */
618
+ readonly iconSize: "{icon.20}";
619
+ readonly labelSize: "{font.size.10}";
620
+ readonly labelLineHeight: "{font.lineHeight.12}";
621
+ /**
622
+ * Floating: the capsule's gap from the screen edges and the blur behind it — light, as Liquid
623
+ * Glass: the content stays recognisable under the glass, only softened.
624
+ */
625
+ readonly floatingInset: "{space.3}";
626
+ readonly blur: "0.5rem";
627
+ };
572
628
  readonly tooltip: {
573
629
  readonly radius: "{radius.6}";
574
630
  readonly paddingX: "{space.2}";
@@ -8,6 +8,10 @@ export declare const darkThemeOverrides: {
8
8
  readonly sunken: "{color.gray.950}";
9
9
  readonly inverse: "{color.gray.100}";
10
10
  readonly scrim: "rgba(0, 0, 0, 0.6)";
11
+ /** Darker than the scrim's share: a shade on a 900 surface needs more ink to read. */
12
+ readonly edgeShadow: "rgba(0, 0, 0, 0.5)";
13
+ readonly glass: "color-mix(in srgb, var(--prime-ref-color-gray-875) 56%, transparent)";
14
+ readonly glassEdge: "rgba(255, 255, 255, 0.16)";
11
15
  };
12
16
  readonly fill: {
13
17
  readonly subtle: "rgba(233, 235, 240, 0.05)";
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "prime-ui-kit",
3
- "version": "0.9.1",
4
- "description": "React 19 UI kit for product interfaces: 57 composable components on one design contract — forms, selects, tables, overlays, navigation, app shell. CSS Modules, --prime-* tokens, light and dark themes, TypeScript, a11y. Ships COMPONENT.md docs and copyable examples.",
3
+ "version": "0.9.2",
4
+ "packageManager": "bun@1.3.13",
5
+ "description": "React 19 UI kit for product interfaces: 61 composable components on one design contract — forms, selects, tables, overlays, navigation, app shell. CSS Modules, --prime-* tokens, light and dark themes, TypeScript, a11y. Ships COMPONENT.md docs and copyable examples.",
5
6
  "main": "./dist/index.js",
6
7
  "module": "./dist/index.js",
7
8
  "types": "./dist/index.d.ts",
@@ -1,6 +1,6 @@
1
1
  # Accordion
2
2
 
3
- **Category:** layout
3
+ **Category:** data-display
4
4
  **Kind:** navigation
5
5
 
6
6
  > Collapsible sections: FAQ, settings groups, checkout steps.
@@ -30,7 +30,7 @@ Badge.Root <span>: fill, tier dimensions
30
30
  ├─ [start segment] Badge.Icon or Badge.Dot at the start edge: full height, mark centred
31
31
  ├─ body text, Badge.Dot, inline Badge.Icon
32
32
  │ (a <button> with onPress; a <span> with a trailing segment; none when read-only)
33
- ├─ Badge.Action optional end segment revealed on hover / focus
33
+ ├─ Badge.Action optional end segment revealed on hover / focus (always shown on touch screens)
34
34
  └─ remove segment with onRemove: full height, the whole end is the hit area (Icon action.close)
35
35
  ```
36
36
 
@@ -70,7 +70,7 @@ Badge.Root <span>: fill, tier dimensions
70
70
  | `…rest` | `HTMLAttributes<HTMLSpanElement>` | — | `className` and the other span attributes. |
71
71
 
72
72
  ### Badge.Action
73
- `ref` → `HTMLButtonElement`. A `<button>` segment at the end, revealed on hover and focus; the badge reserves its room, so the width never changes. One per badge, not together with `onRemove`.
73
+ `ref` → `HTMLButtonElement`. A `<button>` segment at the end, revealed on hover and focus, always shown on touch screens; the badge reserves its room, so the width never changes. One per badge, not together with `onRemove`.
74
74
 
75
75
  | Prop | Type | Default | Description |
76
76
  |---|---|---|---|
@@ -1,6 +1,6 @@
1
1
  # Banner
2
2
 
3
- **Category:** feedback
3
+ **Category:** status
4
4
  **Kind:** primitive
5
5
 
6
6
  > Full-width in-flow message for a page, section or card: status icon, title, description, actions and dismiss.
@@ -57,8 +57,10 @@
57
57
  var(--prime-motion-easing-standard);
58
58
  }
59
59
 
60
- .option:hover {
61
- background: var(--prime-color-fill-subtle);
60
+ @media (hover: hover) {
61
+ .option:hover {
62
+ background: var(--prime-color-fill-subtle);
63
+ }
62
64
  }
63
65
 
64
66
  .option:focus-visible {
@@ -1,6 +1,6 @@
1
1
  # Crossfade
2
2
 
3
- **Category:** feedback
3
+ **Category:** status
4
4
  **Kind:** layout
5
5
 
6
6
  > A region that cross-fades between its states (loading → data → empty → error) and glides to the new height, so the page below does not jump.