@momoi-labs/kiso-react 0.2.0 → 0.4.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 (71) hide show
  1. package/README.md +115 -14
  2. package/dist/alert.d.ts +10 -0
  3. package/dist/alert.js +27 -0
  4. package/dist/app-shell.d.ts +28 -0
  5. package/dist/app-shell.js +22 -0
  6. package/dist/breadcrumb.d.ts +10 -0
  7. package/dist/breadcrumb.js +23 -0
  8. package/dist/command-palette.d.ts +17 -0
  9. package/dist/command-palette.js +78 -0
  10. package/dist/dialog.d.ts +14 -0
  11. package/dist/dialog.js +39 -0
  12. package/dist/dot.d.ts +9 -0
  13. package/dist/dot.js +21 -0
  14. package/dist/drawer.d.ts +9 -0
  15. package/dist/drawer.js +17 -0
  16. package/dist/dropdown-menu.d.ts +13 -0
  17. package/dist/dropdown-menu.js +32 -0
  18. package/dist/empty-state.d.ts +14 -0
  19. package/dist/empty-state.js +30 -0
  20. package/dist/form-field.d.ts +15 -5
  21. package/dist/form-field.js +19 -6
  22. package/dist/header.d.ts +3 -0
  23. package/dist/header.js +8 -0
  24. package/dist/index.d.ts +31 -0
  25. package/dist/index.js +31 -0
  26. package/dist/kv.d.ts +5 -0
  27. package/dist/kv.js +12 -0
  28. package/dist/link.d.ts +10 -0
  29. package/dist/link.js +15 -0
  30. package/dist/log-view.d.ts +17 -0
  31. package/dist/log-view.js +56 -0
  32. package/dist/navigation.d.ts +12 -0
  33. package/dist/navigation.js +23 -0
  34. package/dist/page-header.d.ts +9 -0
  35. package/dist/page-header.js +19 -0
  36. package/dist/pagination.d.ts +10 -0
  37. package/dist/pagination.js +21 -0
  38. package/dist/popover.d.ts +8 -0
  39. package/dist/popover.js +21 -0
  40. package/dist/search.d.ts +5 -0
  41. package/dist/search.js +9 -0
  42. package/dist/select.d.ts +11 -0
  43. package/dist/select.js +30 -0
  44. package/dist/separator.d.ts +4 -0
  45. package/dist/separator.js +9 -0
  46. package/dist/sidebar.d.ts +6 -0
  47. package/dist/sidebar.js +17 -0
  48. package/dist/skeleton.d.ts +7 -0
  49. package/dist/skeleton.js +15 -0
  50. package/dist/spinner.d.ts +9 -0
  51. package/dist/spinner.js +15 -0
  52. package/dist/split.d.ts +11 -0
  53. package/dist/split.js +64 -0
  54. package/dist/stat.d.ts +12 -0
  55. package/dist/stat.js +32 -0
  56. package/dist/styles.css +156 -1
  57. package/dist/switch.d.ts +4 -0
  58. package/dist/switch.js +11 -0
  59. package/dist/tabs.d.ts +7 -0
  60. package/dist/tabs.js +18 -0
  61. package/dist/textarea.d.ts +3 -0
  62. package/dist/textarea.js +6 -0
  63. package/dist/toast.d.ts +23 -0
  64. package/dist/toast.js +69 -0
  65. package/dist/tooltip.d.ts +7 -0
  66. package/dist/tooltip.js +20 -0
  67. package/dist/use-isomorphic-layout-effect.d.ts +2 -0
  68. package/dist/use-isomorphic-layout-effect.js +4 -0
  69. package/dist/validation-message.d.ts +3 -0
  70. package/dist/validation-message.js +8 -0
  71. package/package.json +2 -2
package/README.md CHANGED
@@ -11,7 +11,7 @@ Import the stylesheet once, before application overrides:
11
11
 
12
12
  ```tsx
13
13
  import '@momoi-labs/kiso-react/styles.css';
14
- import { Button, FormField } from '@momoi-labs/kiso-react';
14
+ import { Button, FormField, Textarea } from '@momoi-labs/kiso-react';
15
15
 
16
16
  export function ApplicationForm() {
17
17
  return (
@@ -23,6 +23,15 @@ export function ApplicationForm() {
23
23
  }
24
24
  ```
25
25
 
26
+ FormField renders an Input by default. Pass one control as its child when the
27
+ field uses another input, and add `error` for wired validation feedback:
28
+
29
+ ```tsx
30
+ <FormField label="Compose file" hint="Docker Compose YAML." error={error}>
31
+ <Textarea rows={12} />
32
+ </FormField>
33
+ ```
34
+
26
35
  `@momoi-labs/kiso` is a regular dependency. The stylesheet imports its tokens
27
36
  and component layer; consumers do not need to import those again. React and
28
37
  React DOM are peer dependencies supplied by the application. No Tailwind setup
@@ -30,21 +39,116 @@ is required. The Kiso base stylesheet includes global styles and Google Fonts.
30
39
 
31
40
  ## Available components
32
41
 
42
+ Controls and forms
43
+
33
44
  - Button and `buttonVariants`; Badge and `badgeVariants`.
34
- - BrandMark and TerminalIcon, the momoi-labs terminal prompt glyph.
35
- - Input, Label, Checkbox, and FormField.
45
+ - Input, Textarea, Search, Label, Checkbox, Switch, and FormField.
46
+ - Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup,
47
+ SelectLabel, and SelectSeparator.
48
+ - ValidationMessage, for a field error referenced by `aria-describedby`.
49
+
50
+ Data and structure
51
+
36
52
  - Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter.
37
53
  - Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption.
38
- - AlertDialog, Trigger, Portal, Overlay, Content, Header, Footer, Title,
39
- Description, Action, and Cancel (each prefixed with `AlertDialog`).
54
+ - EmptyState, EmptyStateIcon, EmptyStateTitle, EmptyStateDescription, EmptyStateActions.
55
+ - Header, PageHeader, PageHeaderTitle, PageHeaderDescription.
56
+ - Sidebar, SidebarHeader, SidebarBody, SidebarFooter.
57
+ - AppShell and AppShellMain, the low-level columns of a console.
58
+ - ApplicationShell, the standard brand, navigation, header, footer, and page
59
+ arrangement.
60
+ - Split, Pane, and Splitter, a list-detail layout with a resizable divider.
61
+ - LogView, LogViewLine, LogViewTime, and LogViewLevel.
62
+ - Stat, StatHeader, StatLabel, StatValue, StatFoot, and StatDelta.
63
+ - KV, KVKey, and KVValue, a description list of fixed facts.
64
+ - Separator, horizontal or vertical, and Dot and `dotVariants`.
65
+ - BrandMark and TerminalIcon, the momoi-labs terminal prompt glyph.
66
+
67
+ Navigation
68
+
69
+ - Navigation, NavigationGroup, NavigationList, NavigationItem, NavigationLink.
70
+ - Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage,
71
+ BreadcrumbSeparator.
72
+ - Link and `linkVariants`; Pagination, PaginationPrevious, PaginationNext,
73
+ PaginationPage, PaginationEllipsis.
74
+ - Tabs, TabsList, TabsTrigger, TabsContent.
40
75
  - ThemeSelector, a controlled selector. The application owns theme persistence
41
76
  and applies `data-theme="light"` or `data-theme="dark"` to the document root.
42
77
  Remove the attribute for system mode.
43
78
 
79
+ Feedback
80
+
81
+ - Alert, AlertContent, AlertTitle, AlertDescription, and `alertVariants`.
82
+ - Spinner, Skeleton, and their variants.
83
+ - Toasts and `useToast`, for notifications raised from descendant event
84
+ handlers.
85
+ - ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription,
86
+ ToastContent, ToastAction, ToastClose, for controlled composition.
87
+
88
+ Overlays
89
+
90
+ - Dialog, DialogTrigger, DialogContent, DialogHeader, DialogBody, DialogFooter,
91
+ DialogTitle, DialogDescription, DialogClose.
92
+ - AlertDialog, Trigger, Portal, Overlay, Content, Header, Footer, Title,
93
+ Description, Action, and Cancel (each prefixed with `AlertDialog`).
94
+ - Drawer, with `placement="bottom"` or `"side"`, and the matching `Drawer*` parts.
95
+ - Popover, DropdownMenu, and Tooltip, with their trigger and content parts.
96
+ - CommandPalette, CommandPaletteInput, CommandPaletteList, CommandPaletteGroup,
97
+ CommandPaletteItem, CommandPaletteEmpty.
98
+
44
99
  Button variants are `default`, `primary`, `destructive`, and `ghost`; sizes are
45
100
  `xs`, `sm`, `md`, and `lg`. Badge variants are `neutral`, `info`, `success`,
46
- `warning`, and `danger`. Native props and refs pass through to the underlying
47
- control. FormField adds `label` and optional `hint` to Input's props.
101
+ `warning`, and `danger`. Alert and Toast variants follow their contracts:
102
+ `info` / `success` / `warning` / `error`, and `neutral` / `success` / `warning`
103
+ / `error`. Native props and refs pass through to the underlying control.
104
+ FormField adds `label`, optional `hint`, and optional `error` to Input's props.
105
+ With one child, it wires those parts to that control instead of rendering an
106
+ Input. Use `fieldClassName` to style the wrapper.
107
+
108
+ Wrap an application in Toasts and call `useToast()` below it. The returned
109
+ function takes a variant, title, and optional body:
110
+
111
+ ```tsx
112
+ const notify = useToast();
113
+ notify('error', `Could not stop ${app.name}`, details);
114
+ ```
115
+
116
+ ApplicationShell takes navigation groups as data. Destinations keep routing in
117
+ the product through `{ href, active, onClick? }`; the package owns the repeated
118
+ Sidebar, Navigation, Header, and main arrangement.
119
+
120
+ Navigation, Sidebar, and Link know nothing about routing. Mark the current
121
+ destination with `active`, and pass `asChild` to render a router's own link
122
+ component. CommandPalette is controlled: it owns the overlay, focus, and its
123
+ Arrow / Enter / Escape keys, while the product owns the shortcut that opens it
124
+ and the filtering that decides which items to render.
125
+
126
+ Dot variants match Badge's: `neutral`, `info`, `success`, `warning`, and
127
+ `danger`, plus `size` and `pulse`. A `neutral` Dot inherits `currentColor`, so
128
+ it takes the colour of the row it sits in. StatDelta takes the same variants.
129
+
130
+ Splitter owns the pane size, so dropping one between two Panes is the whole
131
+ setup. It writes a percentage to the pane before it, starts at `defaultSize`
132
+ and stays between `min` and `max`, and reports changes through `onSizeChange`.
133
+ It is a real `separator`: focus it and the arrow keys move it by `step`, Home
134
+ and End take it to the bounds.
135
+
136
+ LogView owns its scroller and follows the tail. New lines pin the view to the
137
+ end until the reader scrolls away, and returning to the end resumes. Drive that
138
+ from a control of your own with `follow` and `onFollowChange`, or scroll to the
139
+ end imperatively through the ref:
140
+
141
+ ```tsx
142
+ const log = useRef<LogViewHandle>(null);
143
+
144
+ <LogView ref={log} follow={follow} onFollowChange={setFollow}>
145
+ <LogViewLine>
146
+ <LogViewTime>09:41:03.901</LogViewTime>
147
+ <LogViewLevel level="warn">WARN </LogViewLevel> redis unavailable
148
+ </LogViewLine>
149
+ </LogView>
150
+ <Button onClick={() => log.current?.scrollToBottom()}>Jump to end</Button>
151
+ ```
48
152
 
49
153
  Compose confirmations with AlertDialogTitle and AlertDialogDescription inside
50
154
  AlertDialogContent, plus AlertDialogCancel and AlertDialogAction. For asynchronous
@@ -68,15 +172,12 @@ import { BrandMark, TerminalIcon } from '@momoi-labs/kiso-react';
68
172
  </div>
69
173
  ```
70
174
 
71
- The gallery covers all 36 Kiso catalog entries. Entries labelled Composition
72
- preview are examples, not additional exports from this package. CommandPalette
73
- is a layout preview without complete command keyboard behavior.
74
-
75
175
  ## Development
76
176
 
77
- From the repository root, run `npm ci`, then `npm run prototype`.
78
- The console opens at <http://127.0.0.1:5173/#overview> and the component gallery at
79
- <http://127.0.0.1:5173/#components>. All console data is simulated in memory.
177
+ From the repository root, run `npm ci`, then `npm run prototype`. The component
178
+ gallery opens at <http://127.0.0.1:5173/#components> and covers all 43 Kiso
179
+ catalog entries, each rendering the component this package exports. Its sample
180
+ data is simulated in memory.
80
181
 
81
182
  `npm run check:react` builds the demo and tests packed npm artifacts in an
82
183
  isolated consumer, including TypeScript, CSS bundling, and rendered semantics.
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ import { type VariantProps } from "class-variance-authority";
3
+ declare const alertVariants: (props?: ({
4
+ variant?: "error" | "info" | "success" | "warning" | null | undefined;
5
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
+ declare function Alert({ className, variant, role, ...props }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>): React.JSX.Element;
7
+ declare function AlertContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
8
+ declare function AlertTitle({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
9
+ declare function AlertDescription({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
10
+ export { Alert, AlertContent, AlertTitle, AlertDescription, alertVariants };
package/dist/alert.js ADDED
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cva } from "class-variance-authority";
3
+ import { clsx as cn } from "clsx";
4
+ const alertVariants = cva("alert", {
5
+ variants: {
6
+ variant: {
7
+ info: "alert-info",
8
+ success: "alert-success",
9
+ warning: "alert-warning",
10
+ error: "alert-danger",
11
+ },
12
+ },
13
+ defaultVariants: { variant: "info" },
14
+ });
15
+ function Alert({ className, variant = "info", role, ...props }) {
16
+ return (_jsx("div", { "data-slot": "alert", "data-variant": variant, role: role ?? (variant === "error" ? "alert" : "status"), className: cn(alertVariants({ variant }), className), ...props }));
17
+ }
18
+ function AlertContent({ className, ...props }) {
19
+ return (_jsx("div", { "data-slot": "alert-content", className: cn("stack-xs grow", className), ...props }));
20
+ }
21
+ function AlertTitle({ className, ...props }) {
22
+ return (_jsx("p", { "data-slot": "alert-title", className: cn("alert-title", className), ...props }));
23
+ }
24
+ function AlertDescription({ className, ...props }) {
25
+ return (_jsx("p", { "data-slot": "alert-description", className: cn("alert-body", className), ...props }));
26
+ }
27
+ export { Alert, AlertContent, AlertTitle, AlertDescription, alertVariants };
@@ -0,0 +1,28 @@
1
+ import * as React from "react";
2
+ declare function AppShell({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
3
+ declare function AppShellMain({ className, ...props }: React.ComponentProps<"main">): React.JSX.Element;
4
+ type ApplicationShellDestination = {
5
+ href: string;
6
+ active?: boolean;
7
+ onClick?: () => void;
8
+ label: React.ReactNode;
9
+ leading?: React.ReactNode;
10
+ trailing?: React.ReactNode;
11
+ };
12
+ type ApplicationShellGroup = {
13
+ label?: string;
14
+ destinations: readonly ApplicationShellDestination[];
15
+ empty?: React.ReactNode;
16
+ };
17
+ type ApplicationShellProps = Omit<React.ComponentProps<typeof AppShell>, "children"> & {
18
+ brand: React.ReactNode;
19
+ primaryAction?: React.ReactNode;
20
+ navigation: readonly ApplicationShellGroup[];
21
+ navigationLabel?: string;
22
+ footer?: React.ReactNode;
23
+ header?: React.ReactNode;
24
+ children: React.ReactNode;
25
+ };
26
+ declare function ApplicationShell({ brand, primaryAction, navigation, navigationLabel, footer, header, children, ...props }: ApplicationShellProps): React.JSX.Element;
27
+ export { AppShell, AppShellMain, ApplicationShell };
28
+ export type { ApplicationShellDestination, ApplicationShellGroup, ApplicationShellProps, };
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { clsx as cn } from "clsx";
3
+ import { Header } from "./header.js";
4
+ import { Navigation, NavigationGroup, NavigationItem, NavigationLink, NavigationList, } from "./navigation.js";
5
+ import { Sidebar, SidebarBody, SidebarFooter, SidebarHeader } from "./sidebar.js";
6
+ function AppShell({ className, ...props }) {
7
+ return (_jsx("div", { "data-slot": "app-shell", className: cn("app-shell", className), ...props }));
8
+ }
9
+ /* `grow` carries the `min-width: 0` the main column needs so a wide table or
10
+ log line cannot push the sidebar off the screen. */
11
+ function AppShellMain({ className, ...props }) {
12
+ return (_jsx("main", { "data-slot": "app-shell-main", className: cn("grow", className), ...props }));
13
+ }
14
+ function ApplicationShell({ brand, primaryAction, navigation, navigationLabel = "Primary", footer, header, children, ...props }) {
15
+ return (_jsxs(AppShell, { ...props, children: [_jsxs(Sidebar, { children: [_jsxs(SidebarHeader, { children: [brand, primaryAction] }), _jsx(SidebarBody, { children: _jsx(Navigation, { "aria-label": navigationLabel, children: navigation.map((group, groupIndex) => (_jsx(NavigationGroup, { label: group.label, children: group.destinations.length > 0 ? (_jsx(NavigationList, { children: group.destinations.map((destination, destinationIndex) => (_jsx(NavigationItem, { children: _jsxs(NavigationLink, { href: destination.href, active: destination.active, onClick: (event) => {
16
+ if (!destination.onClick)
17
+ return;
18
+ event.preventDefault();
19
+ destination.onClick();
20
+ }, children: [destination.leading, _jsx("span", { className: "grow truncate", children: destination.label }), destination.trailing] }) }, `${destination.href}-${destinationIndex}`))) })) : group.empty }, group.label ?? groupIndex))) }) }), footer && _jsx(SidebarFooter, { children: footer })] }), _jsxs(AppShellMain, { children: [header && _jsx(Header, { children: header }), children] })] }));
21
+ }
22
+ export { AppShell, AppShellMain, ApplicationShell };
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ declare function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">): React.JSX.Element;
3
+ declare function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">): React.JSX.Element;
4
+ declare function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">): React.JSX.Element;
5
+ declare function BreadcrumbLink({ className, asChild, ...props }: React.ComponentProps<"a"> & {
6
+ asChild?: boolean;
7
+ }): React.JSX.Element;
8
+ declare function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
9
+ declare function BreadcrumbSeparator({ className, children, ...props }: React.ComponentProps<"li">): React.JSX.Element;
10
+ export { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, };
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { clsx as cn } from "clsx";
3
+ import { Slot } from "radix-ui";
4
+ function Breadcrumb({ className, ...props }) {
5
+ return (_jsx("nav", { "data-slot": "breadcrumb", "aria-label": "Breadcrumb", className: cn("", className), ...props }));
6
+ }
7
+ function BreadcrumbList({ className, ...props }) {
8
+ return (_jsx("ol", { "data-slot": "breadcrumb-list", className: cn("breadcrumb", className), ...props }));
9
+ }
10
+ function BreadcrumbItem({ className, ...props }) {
11
+ return (_jsx("li", { "data-slot": "breadcrumb-item", className: cn("", className), ...props }));
12
+ }
13
+ function BreadcrumbLink({ className, asChild = false, ...props }) {
14
+ const Comp = asChild ? Slot.Root : "a";
15
+ return (_jsx(Comp, { "data-slot": "breadcrumb-link", className: cn("", className), ...props }));
16
+ }
17
+ function BreadcrumbPage({ className, ...props }) {
18
+ return (_jsx("span", { "data-slot": "breadcrumb-page", "aria-current": "page", className: cn("", className), ...props }));
19
+ }
20
+ function BreadcrumbSeparator({ className, children, ...props }) {
21
+ return (_jsx("li", { "data-slot": "breadcrumb-separator", "aria-hidden": "true", className: cn("sep", className), ...props, children: children ?? "/" }));
22
+ }
23
+ export { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, };
@@ -0,0 +1,17 @@
1
+ import * as React from "react";
2
+ import { Dialog as DialogPrimitive } from "radix-ui";
3
+ declare function CommandPalette({ className, label, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Root> & {
4
+ className?: string;
5
+ label?: string;
6
+ }): React.JSX.Element;
7
+ declare function CommandPaletteInput({ className, onKeyDown, ...props }: React.ComponentProps<"input">): React.JSX.Element;
8
+ declare function CommandPaletteList({ className, "aria-label": ariaLabel, ...props }: React.ComponentProps<"div">): React.JSX.Element;
9
+ declare function CommandPaletteGroup({ className, heading, children, ...props }: React.ComponentProps<"div"> & {
10
+ heading: string;
11
+ }): React.JSX.Element;
12
+ declare function CommandPaletteItem({ className, disabled, onSelect, onClick, ...props }: React.ComponentProps<"div"> & {
13
+ disabled?: boolean;
14
+ onSelect?: () => void;
15
+ }): React.JSX.Element;
16
+ declare function CommandPaletteEmpty({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
17
+ export { CommandPalette, CommandPaletteInput, CommandPaletteList, CommandPaletteGroup, CommandPaletteItem, CommandPaletteEmpty, };
@@ -0,0 +1,78 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { clsx as cn } from "clsx";
5
+ import { Dialog as DialogPrimitive, VisuallyHidden } from "radix-ui";
6
+ import { DialogOverlay, DialogPortal } from "./dialog.js";
7
+ // The palette owns its overlay, focus, and in-palette keys. Matching is the
8
+ // product's: render the items that match the query. The shortcut that opens it
9
+ // is product chrome too, so the palette stays controlled.
10
+ const CommandPaletteContext = React.createContext(null);
11
+ function useCommandPalette() {
12
+ const context = React.useContext(CommandPaletteContext);
13
+ if (!context) {
14
+ throw new Error("CommandPalette parts must be used inside <CommandPalette>");
15
+ }
16
+ return context;
17
+ }
18
+ function items(list) {
19
+ return Array.from(list?.querySelectorAll('[data-slot="command-palette-item"]:not([aria-disabled="true"])') ?? []);
20
+ }
21
+ function CommandPalette({ className, label = "Command palette", children, ...props }) {
22
+ const [activeId, setActiveId] = React.useState("");
23
+ const listId = React.useId();
24
+ const listRef = React.useRef(null);
25
+ return (_jsx(DialogPrimitive.Root, { "data-slot": "command-palette", ...props, children: _jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { "aria-modal": "true", "data-slot": "command-palette-content", className: cn("palette kiso-react-palette", className), children: [_jsx(VisuallyHidden.Root, { asChild: true, children: _jsx(DialogPrimitive.Title, { children: label }) }), _jsx(CommandPaletteContext.Provider, { value: { activeId, setActiveId, listId, listRef }, children: children })] })] }) }));
26
+ }
27
+ function CommandPaletteInput({ className, onKeyDown, ...props }) {
28
+ const { activeId, setActiveId, listId, listRef } = useCommandPalette();
29
+ // The query changes the list under the highlight, so re-anchor it every
30
+ // render rather than tracking an index that the filter invalidates.
31
+ React.useEffect(() => {
32
+ const visible = items(listRef.current);
33
+ if (!visible.some((item) => item.id === activeId)) {
34
+ setActiveId(visible[0]?.id ?? "");
35
+ }
36
+ });
37
+ function move(event) {
38
+ const visible = items(listRef.current);
39
+ const index = visible.findIndex((item) => item.id === activeId);
40
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
41
+ event.preventDefault();
42
+ if (!visible.length)
43
+ return;
44
+ const step = event.key === "ArrowDown" ? 1 : -1;
45
+ const next = visible[(index + step + visible.length) % visible.length];
46
+ setActiveId(next.id);
47
+ next.scrollIntoView({ block: "nearest" });
48
+ }
49
+ else if (event.key === "Enter") {
50
+ event.preventDefault();
51
+ visible[index]?.click();
52
+ }
53
+ onKeyDown?.(event);
54
+ }
55
+ return (_jsxs("div", { className: "palette-input", "data-slot": "command-palette-input", children: [_jsxs("svg", { className: "icon muted", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "aria-hidden": "true", children: [_jsx("circle", { cx: "7", cy: "7", r: "4.5" }), _jsx("path", { d: "m10.5 10.5 3 3" })] }), _jsx("input", { role: "combobox", "aria-expanded": "true", "aria-controls": listId, "aria-activedescendant": activeId || undefined, "aria-autocomplete": "list", autoComplete: "off", autoFocus: true, onKeyDown: move, className: className, ...props })] }));
56
+ }
57
+ function CommandPaletteList({ className, "aria-label": ariaLabel = "Commands", ...props }) {
58
+ const { listId, listRef } = useCommandPalette();
59
+ return (_jsx("div", { id: listId, ref: listRef, role: "listbox", "aria-label": ariaLabel, "data-slot": "command-palette-list", className: cn("palette-list", className), ...props }));
60
+ }
61
+ function CommandPaletteGroup({ className, heading, children, ...props }) {
62
+ const headingId = React.useId();
63
+ return (_jsxs("div", { role: "group", "aria-labelledby": headingId, "data-slot": "command-palette-group", className: cn("", className), ...props, children: [_jsx("p", { id: headingId, className: "t-caps menu-label", children: heading }), children] }));
64
+ }
65
+ function CommandPaletteItem({ className, disabled = false, onSelect, onClick, ...props }) {
66
+ const id = React.useId();
67
+ const { activeId, setActiveId } = useCommandPalette();
68
+ return (_jsx("div", { id: id, role: "option", "data-slot": "command-palette-item", "aria-selected": activeId === id, "aria-disabled": disabled || undefined, className: cn("menu-item", className), onPointerMove: () => !disabled && setActiveId(id), onClick: (event) => {
69
+ if (disabled)
70
+ return;
71
+ onSelect?.();
72
+ onClick?.(event);
73
+ }, ...props }));
74
+ }
75
+ function CommandPaletteEmpty({ className, ...props }) {
76
+ return (_jsx("p", { "data-slot": "command-palette-empty", className: cn("menu-item muted", className), ...props }));
77
+ }
78
+ export { CommandPalette, CommandPaletteInput, CommandPaletteList, CommandPaletteGroup, CommandPaletteItem, CommandPaletteEmpty, };
@@ -0,0 +1,14 @@
1
+ import * as React from "react";
2
+ import { Dialog as DialogPrimitive } from "radix-ui";
3
+ declare function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>): React.JSX.Element;
4
+ declare function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>): React.JSX.Element;
5
+ declare function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>): React.JSX.Element;
6
+ declare function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>): React.JSX.Element;
7
+ declare function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>): React.JSX.Element;
8
+ declare function DialogContent({ className, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Content>): React.JSX.Element;
9
+ declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
10
+ declare function DialogBody({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
11
+ declare function DialogFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
12
+ declare function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>): React.JSX.Element;
13
+ declare function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>): React.JSX.Element;
14
+ export { Dialog, DialogTrigger, DialogPortal, DialogClose, DialogOverlay, DialogContent, DialogHeader, DialogBody, DialogFooter, DialogTitle, DialogDescription, };
package/dist/dialog.js ADDED
@@ -0,0 +1,39 @@
1
+ // Adapted from shadcn/ui new-york-v4. See ../SHADCN-LICENSE.
2
+ "use client";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import { clsx as cn } from "clsx";
5
+ import { Dialog as DialogPrimitive } from "radix-ui";
6
+ function Dialog({ ...props }) {
7
+ return _jsx(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
8
+ }
9
+ function DialogTrigger({ ...props }) {
10
+ return _jsx(DialogPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
11
+ }
12
+ function DialogPortal({ ...props }) {
13
+ return _jsx(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
14
+ }
15
+ function DialogClose({ ...props }) {
16
+ return _jsx(DialogPrimitive.Close, { "data-slot": "dialog-close", ...props });
17
+ }
18
+ function DialogOverlay({ className, ...props }) {
19
+ return (_jsx(DialogPrimitive.Overlay, { "data-slot": "dialog-overlay", className: cn("kiso-react-overlay", className), ...props }));
20
+ }
21
+ function DialogContent({ className, children, ...props }) {
22
+ return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsx(DialogPrimitive.Content, { "aria-modal": "true", "data-slot": "dialog-content", className: cn("kiso-react-dialog marked", className), ...props, children: children })] }));
23
+ }
24
+ function DialogHeader({ className, ...props }) {
25
+ return (_jsx("div", { "data-slot": "dialog-header", className: cn("dialog-header", className), ...props }));
26
+ }
27
+ function DialogBody({ className, ...props }) {
28
+ return (_jsx("div", { "data-slot": "dialog-body", className: cn("dialog-body", className), ...props }));
29
+ }
30
+ function DialogFooter({ className, ...props }) {
31
+ return (_jsx("div", { "data-slot": "dialog-footer", className: cn("dialog-footer", className), ...props }));
32
+ }
33
+ function DialogTitle({ className, ...props }) {
34
+ return (_jsx(DialogPrimitive.Title, { "data-slot": "dialog-title", className: cn("t-h3", className), ...props }));
35
+ }
36
+ function DialogDescription({ className, ...props }) {
37
+ return (_jsx(DialogPrimitive.Description, { "data-slot": "dialog-description", className: cn("muted", className), ...props }));
38
+ }
39
+ export { Dialog, DialogTrigger, DialogPortal, DialogClose, DialogOverlay, DialogContent, DialogHeader, DialogBody, DialogFooter, DialogTitle, DialogDescription, };
package/dist/dot.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import * as React from "react";
2
+ import { type VariantProps } from "class-variance-authority";
3
+ declare const dotVariants: (props?: ({
4
+ variant?: "danger" | "info" | "neutral" | "success" | "warning" | null | undefined;
5
+ size?: "lg" | "md" | null | undefined;
6
+ pulse?: boolean | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ declare function Dot({ className, variant, size, pulse, ...props }: React.ComponentProps<"span"> & VariantProps<typeof dotVariants>): React.JSX.Element;
9
+ export { Dot, dotVariants };
package/dist/dot.js ADDED
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cva } from "class-variance-authority";
3
+ import { clsx as cn } from "clsx";
4
+ /* `.dot` paints itself with `currentColor`, so the utility classes that carry
5
+ status colour double as the variant. Spelled as a `variant` prop because
6
+ that is how Badge already says the same thing. */
7
+ const dotVariants = cva("dot", {
8
+ variants: {
9
+ variant: {
10
+ neutral: "", info: "info", success: "success",
11
+ warning: "warning", danger: "danger",
12
+ },
13
+ size: { md: "", lg: "dot-lg" },
14
+ pulse: { true: "dot-pulse", false: "" },
15
+ },
16
+ defaultVariants: { variant: "neutral", size: "md", pulse: false },
17
+ });
18
+ function Dot({ className, variant = "neutral", size = "md", pulse = false, ...props }) {
19
+ return (_jsx("span", { "data-slot": "dot", "data-variant": variant, className: cn(dotVariants({ variant, size, pulse }), className), "aria-hidden": "true", ...props }));
20
+ }
21
+ export { Dot, dotVariants };
@@ -0,0 +1,9 @@
1
+ import * as React from "react";
2
+ import { Dialog as DialogPrimitive } from "radix-ui";
3
+ import { DialogBody, DialogClose, DialogFooter, DialogHeader, DialogTitle, DialogDescription } from "./dialog.js";
4
+ declare function Drawer({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>): React.JSX.Element;
5
+ declare function DrawerTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>): React.JSX.Element;
6
+ declare function DrawerContent({ className, placement, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Content> & {
7
+ placement?: "bottom" | "side";
8
+ }): React.JSX.Element;
9
+ export { Drawer, DrawerTrigger, DrawerContent, DialogClose as DrawerClose, DialogHeader as DrawerHeader, DialogBody as DrawerBody, DialogFooter as DrawerFooter, DialogTitle as DrawerTitle, DialogDescription as DrawerDescription, };
package/dist/drawer.js ADDED
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { clsx as cn } from "clsx";
4
+ import { Dialog as DialogPrimitive } from "radix-ui";
5
+ import { DialogBody, DialogClose, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogDescription, } from "./dialog.js";
6
+ // A Drawer is a Dialog anchored to an edge: same task semantics, same
7
+ // accessible name, different placement.
8
+ function Drawer({ ...props }) {
9
+ return _jsx(DialogPrimitive.Root, { "data-slot": "drawer", ...props });
10
+ }
11
+ function DrawerTrigger({ ...props }) {
12
+ return _jsx(DialogPrimitive.Trigger, { "data-slot": "drawer-trigger", ...props });
13
+ }
14
+ function DrawerContent({ className, placement = "bottom", children, ...props }) {
15
+ return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsx(DialogPrimitive.Content, { "aria-modal": "true", "data-slot": "drawer-content", "data-placement": placement, className: cn("kiso-react-drawer marked", className), ...props, children: children })] }));
16
+ }
17
+ export { Drawer, DrawerTrigger, DrawerContent, DialogClose as DrawerClose, DialogHeader as DrawerHeader, DialogBody as DrawerBody, DialogFooter as DrawerFooter, DialogTitle as DrawerTitle, DialogDescription as DrawerDescription, };
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
3
+ declare function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>): React.JSX.Element;
4
+ declare function DropdownMenuTrigger({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>): React.JSX.Element;
5
+ declare function DropdownMenuContent({ className, sideOffset, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>): React.JSX.Element;
6
+ declare function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>): React.JSX.Element;
7
+ declare function DropdownMenuItem({ className, variant, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
8
+ variant?: "action" | "link" | "destructive";
9
+ }): React.JSX.Element;
10
+ declare function DropdownMenuLabel({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Label>): React.JSX.Element;
11
+ declare function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>): React.JSX.Element;
12
+ declare function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
13
+ export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, };
@@ -0,0 +1,32 @@
1
+ // Adapted from shadcn/ui new-york-v4. See ../SHADCN-LICENSE.
2
+ "use client";
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ import { clsx as cn } from "clsx";
5
+ import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
6
+ function DropdownMenu({ ...props }) {
7
+ return _jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
8
+ }
9
+ function DropdownMenuTrigger({ ...props }) {
10
+ return (_jsx(DropdownMenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props }));
11
+ }
12
+ function DropdownMenuContent({ className, sideOffset = 4, ...props }) {
13
+ return (_jsx(DropdownMenuPrimitive.Portal, { children: _jsx(DropdownMenuPrimitive.Content, { "data-slot": "dropdown-menu-content", sideOffset: sideOffset, className: cn("menu kiso-react-floating", className), ...props }) }));
14
+ }
15
+ function DropdownMenuGroup({ ...props }) {
16
+ return (_jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props }));
17
+ }
18
+ // `link` renders a real anchor through asChild, so open-in-new-tab keeps
19
+ // working; `destructive` is the only colour an item may carry.
20
+ function DropdownMenuItem({ className, variant = "action", ...props }) {
21
+ return (_jsx(DropdownMenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-variant": variant, className: cn("menu-item", variant === "destructive" && "is-danger", className), ...props }));
22
+ }
23
+ function DropdownMenuLabel({ className, ...props }) {
24
+ return (_jsx(DropdownMenuPrimitive.Label, { "data-slot": "dropdown-menu-label", className: cn("menu-label t-caps", className), ...props }));
25
+ }
26
+ function DropdownMenuSeparator({ className, ...props }) {
27
+ return (_jsx(DropdownMenuPrimitive.Separator, { "data-slot": "dropdown-menu-separator", className: cn("menu-separator", className), ...props }));
28
+ }
29
+ function DropdownMenuShortcut({ className, ...props }) {
30
+ return (_jsx("span", { "data-slot": "dropdown-menu-shortcut", className: cn("kbd", className), ...props }));
31
+ }
32
+ export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, };
@@ -0,0 +1,14 @@
1
+ import * as React from "react";
2
+ import { type VariantProps } from "class-variance-authority";
3
+ declare const emptyStateVariants: (props?: ({
4
+ variant?: "first-run" | "informational" | "no-results" | null | undefined;
5
+ size?: "md" | "sm" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ declare function EmptyState({ className, variant, size, ...props }: React.ComponentProps<"div"> & VariantProps<typeof emptyStateVariants>): React.JSX.Element;
8
+ declare function EmptyStateIcon({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
9
+ declare function EmptyStateTitle({ className, asChild, ...props }: React.ComponentProps<"h3"> & {
10
+ asChild?: boolean;
11
+ }): React.JSX.Element;
12
+ declare function EmptyStateDescription({ className, ...props }: React.ComponentProps<"p">): React.JSX.Element;
13
+ declare function EmptyStateActions({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
14
+ export { EmptyState, EmptyStateIcon, EmptyStateTitle, EmptyStateDescription, EmptyStateActions, emptyStateVariants, };
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cva } from "class-variance-authority";
3
+ import { clsx as cn } from "clsx";
4
+ import { Slot } from "radix-ui";
5
+ // Emptiness is not an error: the variants change which action belongs here, not
6
+ // the colour of the surface.
7
+ const emptyStateVariants = cva("empty", {
8
+ variants: {
9
+ variant: { "first-run": "", "no-results": "", informational: "" },
10
+ size: { md: "", sm: "empty-sm" },
11
+ },
12
+ defaultVariants: { variant: "first-run", size: "md" },
13
+ });
14
+ function EmptyState({ className, variant = "first-run", size = "md", ...props }) {
15
+ return (_jsx("div", { "data-slot": "empty-state", "data-variant": variant, "data-size": size, className: cn(emptyStateVariants({ variant, size }), className), ...props }));
16
+ }
17
+ function EmptyStateIcon({ className, ...props }) {
18
+ return (_jsx("div", { "data-slot": "empty-state-icon", "aria-hidden": "true", className: cn("empty-icon", className), ...props }));
19
+ }
20
+ function EmptyStateTitle({ className, asChild = false, ...props }) {
21
+ const Comp = asChild ? Slot.Root : "h3";
22
+ return (_jsx(Comp, { "data-slot": "empty-state-title", className: cn("t-h3", className), ...props }));
23
+ }
24
+ function EmptyStateDescription({ className, ...props }) {
25
+ return (_jsx("p", { "data-slot": "empty-state-description", className: cn("", className), ...props }));
26
+ }
27
+ function EmptyStateActions({ className, ...props }) {
28
+ return (_jsx("div", { "data-slot": "empty-state-actions", className: cn("row-wrap", className), ...props }));
29
+ }
30
+ export { EmptyState, EmptyStateIcon, EmptyStateTitle, EmptyStateDescription, EmptyStateActions, emptyStateVariants, };