@sole-ui/react 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -2
- package/dist/components/shell/app-frame.d.ts +14 -0
- package/dist/components/shell/app-frame.js +8 -0
- package/dist/components/shell/command-palette.d.ts +32 -0
- package/dist/components/shell/command-palette.js +30 -0
- package/dist/components/shell/index.d.ts +4 -0
- package/dist/components/shell/index.js +4 -0
- package/dist/components/shell/page.d.ts +25 -0
- package/dist/components/shell/page.js +22 -0
- package/dist/components/shell/sidebar.d.ts +81 -0
- package/dist/components/shell/sidebar.js +113 -0
- package/dist/components/sole/avatar.d.ts +19 -0
- package/dist/components/sole/avatar.js +37 -0
- package/dist/components/sole/banner.d.ts +24 -0
- package/dist/components/sole/banner.js +27 -0
- package/dist/components/sole/column-header.d.ts +15 -0
- package/dist/components/sole/column-header.js +15 -0
- package/dist/components/sole/copy-field.d.ts +10 -0
- package/dist/components/sole/copy-field.js +32 -0
- package/dist/components/sole/count-badge.d.ts +8 -0
- package/dist/components/sole/count-badge.js +8 -0
- package/dist/components/sole/field.d.ts +24 -0
- package/dist/components/sole/field.js +27 -0
- package/dist/components/sole/filters.d.ts +33 -0
- package/dist/components/sole/filters.js +48 -0
- package/dist/components/sole/index.d.ts +17 -0
- package/dist/components/sole/index.js +17 -0
- package/dist/components/sole/kbd.d.ts +7 -0
- package/dist/components/sole/kbd.js +14 -0
- package/dist/components/sole/label-tag.d.ts +18 -0
- package/dist/components/sole/label-tag.js +17 -0
- package/dist/components/sole/layout.d.ts +54 -0
- package/dist/components/sole/layout.js +48 -0
- package/dist/components/sole/logo.d.ts +13 -0
- package/dist/components/sole/logo.js +17 -0
- package/dist/components/sole/nav.d.ts +22 -0
- package/dist/components/sole/nav.js +32 -0
- package/dist/components/sole/person-chip.d.ts +8 -0
- package/dist/components/sole/person-chip.js +19 -0
- package/dist/components/sole/person-header.d.ts +21 -0
- package/dist/components/sole/person-header.js +22 -0
- package/dist/components/sole/pill.d.ts +9 -0
- package/dist/components/sole/pill.js +14 -0
- package/dist/components/sole/states.d.ts +48 -0
- package/dist/components/sole/states.js +53 -0
- package/dist/components/sole/table.d.ts +23 -0
- package/dist/components/sole/table.js +32 -0
- package/dist/components/ui/alert-dialog.d.ts +27 -0
- package/dist/components/ui/alert-dialog.js +33 -0
- package/dist/components/ui/badge.d.ts +11 -0
- package/dist/components/ui/badge.js +30 -0
- package/dist/components/ui/button.d.ts +13 -0
- package/dist/components/ui/button.js +49 -0
- package/dist/components/ui/calendar.d.ts +9 -0
- package/dist/components/ui/calendar.js +79 -0
- package/dist/components/ui/checkbox.d.ts +4 -0
- package/dist/components/ui/checkbox.js +11 -0
- package/dist/components/ui/command.d.ts +90 -0
- package/dist/components/ui/command.js +36 -0
- package/dist/components/ui/dialog.d.ts +18 -0
- package/dist/components/ui/dialog.js +33 -0
- package/dist/components/ui/dropdown-menu.d.ts +25 -0
- package/dist/components/ui/dropdown-menu.js +42 -0
- package/dist/components/ui/index.d.ts +23 -0
- package/dist/components/ui/index.js +23 -0
- package/dist/components/ui/input.d.ts +3 -0
- package/dist/components/ui/input.js +12 -0
- package/dist/components/ui/label.d.ts +4 -0
- package/dist/components/ui/label.js +10 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/popover.js +22 -0
- package/dist/components/ui/scroll-area.d.ts +5 -0
- package/dist/components/ui/scroll-area.js +14 -0
- package/dist/components/ui/select.d.ts +15 -0
- package/dist/components/ui/select.js +30 -0
- package/dist/components/ui/separator.d.ts +4 -0
- package/dist/components/ui/separator.js +10 -0
- package/dist/components/ui/sheet.d.ts +14 -0
- package/dist/components/ui/sheet.js +35 -0
- package/dist/components/ui/skeleton.d.ts +3 -0
- package/dist/components/ui/skeleton.js +10 -0
- package/dist/components/ui/sonner.d.ts +5 -0
- package/dist/components/ui/sonner.js +63 -0
- package/dist/components/ui/switch.d.ts +6 -0
- package/dist/components/ui/switch.js +10 -0
- package/dist/components/ui/tabs.d.ts +7 -0
- package/dist/components/ui/tabs.js +24 -0
- package/dist/components/ui/textarea.d.ts +3 -0
- package/dist/components/ui/textarea.js +9 -0
- package/dist/components/ui/toggle-group.d.ts +14 -0
- package/dist/components/ui/toggle-group.js +24 -0
- package/dist/components/ui/toggle.d.ts +12 -0
- package/dist/components/ui/toggle.js +28 -0
- package/dist/components/ui/tooltip.d.ts +7 -0
- package/dist/components/ui/tooltip.js +18 -0
- package/dist/hq/activity-line.d.ts +21 -0
- package/dist/hq/activity-line.js +26 -0
- package/dist/hq/board-card.d.ts +12 -0
- package/dist/hq/board-card.js +21 -0
- package/dist/hq/board-chip.d.ts +12 -0
- package/dist/hq/board-chip.js +20 -0
- package/dist/hq/checklist-item.d.ts +14 -0
- package/dist/hq/checklist-item.js +13 -0
- package/dist/hq/comment.d.ts +26 -0
- package/dist/hq/comment.js +15 -0
- package/dist/hq/due-chip.d.ts +11 -0
- package/dist/hq/due-chip.js +25 -0
- package/dist/hq/group-header.d.ts +27 -0
- package/dist/hq/group-header.js +22 -0
- package/dist/hq/inbox-row.d.ts +22 -0
- package/dist/hq/inbox-row.js +13 -0
- package/dist/hq/index.d.ts +21 -0
- package/dist/hq/index.js +21 -0
- package/dist/hq/link-row.d.ts +13 -0
- package/dist/hq/link-row.js +13 -0
- package/dist/hq/mention-chip.d.ts +23 -0
- package/dist/hq/mention-chip.js +28 -0
- package/dist/hq/page-row.d.ts +26 -0
- package/dist/hq/page-row.js +30 -0
- package/dist/hq/priority-icon.d.ts +9 -0
- package/dist/hq/priority-icon.js +23 -0
- package/dist/hq/property-type-icon.d.ts +7 -0
- package/dist/hq/property-type-icon.js +22 -0
- package/dist/hq/recent-item.d.ts +11 -0
- package/dist/hq/recent-item.js +12 -0
- package/dist/hq/review-badge.d.ts +37 -0
- package/dist/hq/review-badge.js +77 -0
- package/dist/hq/state-icon.d.ts +12 -0
- package/dist/hq/state-icon.js +41 -0
- package/dist/hq/state-pill.d.ts +9 -0
- package/dist/hq/state-pill.js +18 -0
- package/dist/hq/sticky.d.ts +13 -0
- package/dist/hq/sticky.js +22 -0
- package/dist/hq/template-card.d.ts +10 -0
- package/dist/hq/template-card.js +9 -0
- package/dist/hq/types.d.ts +49 -0
- package/dist/hq/types.js +7 -0
- package/dist/hq/work-item-row.d.ts +16 -0
- package/dist/hq/work-item-row.js +23 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +12 -0
- package/dist/lib/cn.d.ts +2 -0
- package/dist/lib/cn.js +15 -0
- package/dist/lib/colour.d.ts +8 -0
- package/dist/lib/colour.js +28 -0
- package/dist/lib/dates.d.ts +62 -0
- package/dist/lib/dates.js +182 -0
- package/dist/lib/hue.d.ts +3 -0
- package/dist/lib/hue.js +1 -0
- package/dist/lib/person.d.ts +16 -0
- package/dist/lib/person.js +17 -0
- package/dist/lib/platform.d.ts +4 -0
- package/dist/lib/platform.js +12 -0
- package/dist/lib/sole-provider.d.ts +35 -0
- package/dist/lib/sole-provider.js +52 -0
- package/dist/styles.css +64 -0
- package/dist/tokens.css +231 -0
- package/dist/tokens.generated.d.ts +219 -0
- package/dist/tokens.generated.js +679 -0
- package/dist/tokens.json +677 -0
- package/package.json +82 -4
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from '../../lib/cn.js';
|
|
5
|
+
const TONES = {
|
|
6
|
+
success: 'border-success-border bg-success-soft text-success-text',
|
|
7
|
+
warning: 'border-warning-border bg-warning-soft text-warning-text',
|
|
8
|
+
neutral: 'border-transparent bg-neutral-soft text-neutral-text',
|
|
9
|
+
info: 'border-transparent bg-accent text-accent-foreground',
|
|
10
|
+
};
|
|
11
|
+
export const Pill = React.forwardRef(function Pill({ tone = 'neutral', icon, children, className, ...props }, ref) {
|
|
12
|
+
return (_jsxs("span", { ref: ref, "data-pill": tone, className: cn('inline-flex h-[22px] max-w-full shrink-0 items-center gap-[5px] rounded-md border px-2 text-label whitespace-nowrap [&>svg]:size-3 [&>svg]:shrink-0', TONES[tone], className), ...props, children: [icon, _jsx("span", { className: "truncate", children: children })] }));
|
|
13
|
+
});
|
|
14
|
+
Pill.displayName = 'Pill';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type LucideIcon } from 'lucide-react';
|
|
3
|
+
export interface CenteredStateProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare const CenteredState: React.ForwardRefExoticComponent<CenteredStateProps & React.RefAttributes<HTMLDivElement>>;
|
|
7
|
+
export interface EmptyStateProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'title' | 'children'> {
|
|
8
|
+
icon?: LucideIcon;
|
|
9
|
+
/** A fact, as a sentence: "Nothing is assigned to you right now." */
|
|
10
|
+
title: string;
|
|
11
|
+
body?: React.ReactNode;
|
|
12
|
+
/** The next move: one secondary button or link. */
|
|
13
|
+
action?: React.ReactNode;
|
|
14
|
+
framed?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const EmptyState: React.ForwardRefExoticComponent<EmptyStateProps & React.RefAttributes<HTMLDivElement>>;
|
|
17
|
+
export interface ErrorStateProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'title' | 'children'> {
|
|
18
|
+
/** "Could not load the wiki". */
|
|
19
|
+
title: string;
|
|
20
|
+
body?: React.ReactNode;
|
|
21
|
+
/** Shows the Try again button. */
|
|
22
|
+
onRetry?: () => void;
|
|
23
|
+
framed?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare const ErrorState: React.ForwardRefExoticComponent<ErrorStateProps & React.RefAttributes<HTMLDivElement>>;
|
|
26
|
+
export interface NoAccessProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {
|
|
27
|
+
/** What they cannot open, finishing "You do not have access to ...": "the Payroll board". */
|
|
28
|
+
what: string;
|
|
29
|
+
body?: React.ReactNode;
|
|
30
|
+
framed?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare const NoAccess: React.ForwardRefExoticComponent<NoAccessProps & React.RefAttributes<HTMLDivElement>>;
|
|
33
|
+
/** True once `ms` have passed. Loading states wait 300ms so quick loads never flash. */
|
|
34
|
+
export declare function useDelayed(ms?: number): boolean;
|
|
35
|
+
export interface SkeletonRowsProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {
|
|
36
|
+
rows?: number;
|
|
37
|
+
/** row: a 36px work item row. page: a 52px two-line row. */
|
|
38
|
+
variant?: 'row' | 'page';
|
|
39
|
+
/** Milliseconds to show nothing for, so a quick load never flashes. */
|
|
40
|
+
delay?: number;
|
|
41
|
+
/** What screen readers hear while it loads. */
|
|
42
|
+
label?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Skeleton rows shaped like the real rows. Shows nothing for the first 300ms, then
|
|
46
|
+
* 12px bars pulsing at 1.4s. One loading state per screen (U20).
|
|
47
|
+
*/
|
|
48
|
+
export declare const SkeletonRows: React.ForwardRefExoticComponent<SkeletonRowsProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Lock, RotateCw, TriangleAlert } from 'lucide-react';
|
|
5
|
+
import { cn } from '../../lib/cn.js';
|
|
6
|
+
import { Button } from '../ui/button.js';
|
|
7
|
+
import { Skeleton } from '../ui/skeleton.js';
|
|
8
|
+
// Empty, error, no access and loading (brand-and-ux 5.15). Error and empty are never
|
|
9
|
+
// the same screen: a failed load does not claim there is nothing there (U51).
|
|
10
|
+
// The designed states (02-components.png, 99.1 to 99.3): a 24px icon, a 14/500 title,
|
|
11
|
+
// one or two 13px lines, and at most one secondary button. `framed` puts them in the
|
|
12
|
+
// 420px bordered card a whole screen uses; bare, they sit inside a list or a card.
|
|
13
|
+
// CenteredState places a framed state a little above the middle of the page body.
|
|
14
|
+
const stateBox = (framed, className) => cn('flex flex-col items-center text-center', framed ? 'w-full max-w-[420px] rounded-xl border border-border bg-card px-6 py-12' : 'px-4 py-16', className);
|
|
15
|
+
export const CenteredState = React.forwardRef(function CenteredState({ children, className, ...props }, ref) {
|
|
16
|
+
return (_jsx("div", { ref: ref, className: cn('flex min-h-full items-center justify-center px-6 pt-10 pb-20', className), ...props, children: children }));
|
|
17
|
+
});
|
|
18
|
+
CenteredState.displayName = 'CenteredState';
|
|
19
|
+
export const EmptyState = React.forwardRef(function EmptyState({ icon: Icon, title, body, action, framed, className, ...props }, ref) {
|
|
20
|
+
return (_jsxs("div", { ref: ref, role: "status", className: stateBox(framed, className), ...props, children: [Icon && _jsx(Icon, { size: 24, strokeWidth: 1.8, "aria-hidden": "true", className: "mb-1.5 text-subtle-foreground" }), _jsx("p", { className: "text-strong font-medium text-muted-foreground", children: title }), body && _jsx("p", { className: "mt-1.5 max-w-96 text-body text-subtle-foreground", children: body }), action && _jsx("div", { className: "mt-5", children: action })] }));
|
|
21
|
+
});
|
|
22
|
+
EmptyState.displayName = 'EmptyState';
|
|
23
|
+
export const ErrorState = React.forwardRef(function ErrorState({ title, body = 'The server did not answer. Try again in a moment.', onRetry, framed, className, ...props }, ref) {
|
|
24
|
+
return (_jsxs("div", { ref: ref, role: "alert", className: stateBox(framed, className), ...props, children: [_jsx(TriangleAlert, { size: 24, strokeWidth: 1.8, "aria-hidden": "true", className: "mb-1.5 text-warning" }), _jsx("p", { className: "text-strong font-medium text-muted-foreground", children: title }), body && _jsx("p", { className: "mt-1.5 max-w-96 text-body text-subtle-foreground", children: body }), onRetry && (_jsxs(Button, { variant: "secondary", className: "mt-5", onClick: onRetry, children: [_jsx(RotateCw, { "aria-hidden": "true" }), "Try again"] }))] }));
|
|
25
|
+
});
|
|
26
|
+
ErrorState.displayName = 'ErrorState';
|
|
27
|
+
export const NoAccess = React.forwardRef(function NoAccess({ what, body = 'Ask an admin to add you.', framed, className, ...props }, ref) {
|
|
28
|
+
return (_jsxs("div", { ref: ref, role: "status", className: stateBox(framed, className), ...props, children: [_jsx(Lock, { size: 24, strokeWidth: 1.8, "aria-hidden": "true", className: "mb-1.5 text-subtle-foreground" }), _jsxs("p", { className: "text-strong font-medium text-muted-foreground", children: ["You do not have access to ", what, "."] }), body && _jsx("p", { className: "mt-1.5 max-w-96 text-body text-subtle-foreground", children: body })] }));
|
|
29
|
+
});
|
|
30
|
+
NoAccess.displayName = 'NoAccess';
|
|
31
|
+
/** True once `ms` have passed. Loading states wait 300ms so quick loads never flash. */
|
|
32
|
+
export function useDelayed(ms = 300) {
|
|
33
|
+
const [ready, setReady] = React.useState(ms <= 0);
|
|
34
|
+
React.useEffect(() => {
|
|
35
|
+
if (ms <= 0)
|
|
36
|
+
return;
|
|
37
|
+
const t = setTimeout(() => setReady(true), ms);
|
|
38
|
+
return () => clearTimeout(t);
|
|
39
|
+
}, [ms]);
|
|
40
|
+
return ready;
|
|
41
|
+
}
|
|
42
|
+
const WIDTHS = ['62%', '48%', '71%', '55%', '66%', '44%', '58%', '69%'];
|
|
43
|
+
/**
|
|
44
|
+
* Skeleton rows shaped like the real rows. Shows nothing for the first 300ms, then
|
|
45
|
+
* 12px bars pulsing at 1.4s. One loading state per screen (U20).
|
|
46
|
+
*/
|
|
47
|
+
export const SkeletonRows = React.forwardRef(function SkeletonRows({ rows = 6, variant = 'row', delay = 300, label = 'Loading', className, ...props }, ref) {
|
|
48
|
+
const visible = useDelayed(delay);
|
|
49
|
+
if (!visible)
|
|
50
|
+
return _jsx("div", { ref: ref, "aria-busy": "true", "aria-label": label, className: className, ...props });
|
|
51
|
+
return (_jsx("div", { ref: ref, "aria-busy": "true", "aria-label": label, className: cn('flex flex-col', className), ...props, children: Array.from({ length: rows }, (_, i) => (_jsx("div", { className: cn('flex items-center gap-3 border-b border-hairline px-3', variant === 'row' ? 'h-9' : 'h-[52px]'), children: variant === 'row' ? (_jsxs(_Fragment, { children: [_jsx(Skeleton, { className: "w-4" }), _jsx(Skeleton, { className: "w-12" }), _jsx(Skeleton, { style: { width: WIDTHS[i % WIDTHS.length] } }), _jsx(Skeleton, { className: "ml-auto w-12" })] })) : (_jsxs("div", { className: "flex flex-1 flex-col gap-2", children: [_jsx(Skeleton, { style: { width: WIDTHS[i % WIDTHS.length] } }), _jsx(Skeleton, { className: "h-2.5 w-40" })] })) }, i))) }));
|
|
52
|
+
});
|
|
53
|
+
SkeletonRows.displayName = 'SkeletonRows';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { SolePerson } from '../../lib/person.ts';
|
|
3
|
+
/** The card around a table. `label` names it for screen readers ("People"). */
|
|
4
|
+
export declare const Table: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "aria-label" | "role"> & {
|
|
5
|
+
label: string;
|
|
6
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
7
|
+
/** A row: 52px (People row), or pass `min-h-14` for the 56px Access row. */
|
|
8
|
+
export declare const TableRow: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
9
|
+
export declare const TableCell: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
10
|
+
/**
|
|
11
|
+
* The person in a row (People row, Access row): the 32px avatar, the name at 13/500 with
|
|
12
|
+
* an Admin pill, and a 12px line under it (their title, or their email).
|
|
13
|
+
*/
|
|
14
|
+
export declare const PersonCell: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "children"> & {
|
|
15
|
+
person: SolePerson;
|
|
16
|
+
admin?: boolean;
|
|
17
|
+
/** "Founder", "ava@example.com". */
|
|
18
|
+
detail?: React.ReactNode;
|
|
19
|
+
/** A switched-off person: the name in the subtle grey. */
|
|
20
|
+
muted?: boolean;
|
|
21
|
+
/** Replaces the plain name, e.g. with a link to their page. */
|
|
22
|
+
name?: React.ReactNode;
|
|
23
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from '../../lib/cn.js';
|
|
5
|
+
import { personName } from '../../lib/person.js';
|
|
6
|
+
import { Avatar } from './avatar.js';
|
|
7
|
+
import { Pill } from './pill.js';
|
|
8
|
+
// Tables (02-components.png 02.9; 80.1 People, 90.1 Access): a 12px card, the
|
|
9
|
+
// TableHeader (layout.tsx), then rows with a hairline between them. Give the header and
|
|
10
|
+
// every row the same grid template, e.g. `grid-cols-[1fr_240px_96px]`, so the columns line up.
|
|
11
|
+
/** The card around a table. `label` names it for screen readers ("People"). */
|
|
12
|
+
export const Table = React.forwardRef(function Table({ label, className, ...props }, ref) {
|
|
13
|
+
return _jsx("div", { ref: ref, ...props, role: "table", "aria-label": label, className: cn('overflow-hidden rounded-xl border border-border bg-card', className) });
|
|
14
|
+
});
|
|
15
|
+
Table.displayName = 'Table';
|
|
16
|
+
/** A row: 52px (People row), or pass `min-h-14` for the 56px Access row. */
|
|
17
|
+
export const TableRow = React.forwardRef(function TableRow({ className, ...props }, ref) {
|
|
18
|
+
return _jsx("div", { ref: ref, role: "row", className: cn('grid min-h-[52px] items-center gap-4 border-t border-hairline px-4 py-1', className), ...props });
|
|
19
|
+
});
|
|
20
|
+
TableRow.displayName = 'TableRow';
|
|
21
|
+
export const TableCell = React.forwardRef(function TableCell({ className, ...props }, ref) {
|
|
22
|
+
return _jsx("div", { ref: ref, role: "cell", className: cn('min-w-0 truncate text-body text-foreground', className), ...props });
|
|
23
|
+
});
|
|
24
|
+
TableCell.displayName = 'TableCell';
|
|
25
|
+
/**
|
|
26
|
+
* The person in a row (People row, Access row): the 32px avatar, the name at 13/500 with
|
|
27
|
+
* an Admin pill, and a 12px line under it (their title, or their email).
|
|
28
|
+
*/
|
|
29
|
+
export const PersonCell = React.forwardRef(function PersonCell({ person, admin = false, detail, muted = false, name, className, ...props }, ref) {
|
|
30
|
+
return (_jsxs("div", { ref: ref, className: cn('flex min-w-0 items-center gap-2.5', className), ...props, children: [_jsx(Avatar, { person: person, size: 32 }), _jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex h-[18px] min-w-0 items-center gap-[7px]", children: [_jsx("span", { className: cn('truncate text-body leading-[18px] font-medium', muted ? 'text-subtle-foreground' : 'text-foreground'), children: name ?? personName(person) }), admin && _jsx(Pill, { tone: "neutral", children: "Admin" })] }), detail && _jsx("p", { className: "truncate text-label font-normal text-subtle-foreground", children: detail })] })] }));
|
|
31
|
+
});
|
|
32
|
+
PersonCell.displayName = 'PersonCell';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { AlertDialog as AlertDialogPrimitive } from 'radix-ui';
|
|
3
|
+
declare function AlertDialog({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
declare const AlertDialogTrigger: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
declare function AlertDialogPortal({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>): React.JSX.Element;
|
|
6
|
+
declare const AlertDialogOverlay: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
7
|
+
declare const AlertDialogContent: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
8
|
+
size?: 'default' | 'sm';
|
|
9
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
10
|
+
declare const AlertDialogHeader: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
11
|
+
declare const AlertDialogFooter: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
|
+
declare const AlertDialogTitle: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
|
|
13
|
+
declare const AlertDialogDescription: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
|
|
14
|
+
declare const AlertDialogMedia: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
declare const AlertDialogAction: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogActionProps & React.RefAttributes<HTMLButtonElement>, "ref"> & Pick<Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & import("class-variance-authority").VariantProps<(props?: ({
|
|
16
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
17
|
+
size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | null | undefined;
|
|
18
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & {
|
|
19
|
+
asChild?: boolean;
|
|
20
|
+
} & React.RefAttributes<HTMLButtonElement>, "ref">, "size" | "variant"> & React.RefAttributes<HTMLButtonElement>>;
|
|
21
|
+
declare const AlertDialogCancel: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogCancelProps & React.RefAttributes<HTMLButtonElement>, "ref"> & Pick<Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & import("class-variance-authority").VariantProps<(props?: ({
|
|
22
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
23
|
+
size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | null | undefined;
|
|
24
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & {
|
|
25
|
+
asChild?: boolean;
|
|
26
|
+
} & React.RefAttributes<HTMLButtonElement>, "ref">, "size" | "variant"> & React.RefAttributes<HTMLButtonElement>>;
|
|
27
|
+
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { AlertDialog as AlertDialogPrimitive } from 'radix-ui';
|
|
5
|
+
import { cn } from '../../lib/cn.js';
|
|
6
|
+
import { Button } from './button.js';
|
|
7
|
+
function AlertDialog({ ...props }) {
|
|
8
|
+
return _jsx(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", ...props });
|
|
9
|
+
}
|
|
10
|
+
const AlertDialogTrigger = React.forwardRef((props, ref) => _jsx(AlertDialogPrimitive.Trigger, { ref: ref, "data-slot": "alert-dialog-trigger", ...props }));
|
|
11
|
+
AlertDialogTrigger.displayName = 'AlertDialogTrigger';
|
|
12
|
+
function AlertDialogPortal({ ...props }) {
|
|
13
|
+
return _jsx(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props });
|
|
14
|
+
}
|
|
15
|
+
const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(AlertDialogPrimitive.Overlay, { ref: ref, "data-slot": "alert-dialog-overlay", className: cn('fixed inset-0 z-50 bg-black/30 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0', className), ...props })));
|
|
16
|
+
AlertDialogOverlay.displayName = 'AlertDialogOverlay';
|
|
17
|
+
const AlertDialogContent = React.forwardRef(({ className, size = 'default', ...props }, ref) => (_jsxs(AlertDialogPortal, { children: [_jsx(AlertDialogOverlay, {}), _jsx(AlertDialogPrimitive.Content, { ref: ref, "data-slot": "alert-dialog-content", "data-size": size, className: cn('group/alert-dialog-content fixed top-[38%] left-[50%] z-50 grid max-h-[calc(76dvh-32px)] w-[calc(100%-2rem)] overflow-y-auto max-w-[400px] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-2xl border bg-popover p-5 text-popover-foreground shadow-lg duration-200 ease-rise outline-none data-[size=sm]:max-w-xs data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95', className), ...props })] })));
|
|
18
|
+
AlertDialogContent.displayName = 'AlertDialogContent';
|
|
19
|
+
const AlertDialogHeader = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, "data-slot": "alert-dialog-header", className: cn('grid grid-rows-[auto_1fr] place-items-start gap-1 text-left has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4', className), ...props })));
|
|
20
|
+
AlertDialogHeader.displayName = 'AlertDialogHeader';
|
|
21
|
+
const AlertDialogFooter = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, "data-slot": "alert-dialog-footer", className: cn('flex flex-row justify-end gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2', className), ...props })));
|
|
22
|
+
AlertDialogFooter.displayName = 'AlertDialogFooter';
|
|
23
|
+
const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => (_jsx(AlertDialogPrimitive.Title, { ref: ref, "data-slot": "alert-dialog-title", className: cn('text-title group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2', className), ...props })));
|
|
24
|
+
AlertDialogTitle.displayName = 'AlertDialogTitle';
|
|
25
|
+
const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx(AlertDialogPrimitive.Description, { ref: ref, "data-slot": "alert-dialog-description", className: cn('text-body text-muted-foreground', className), ...props })));
|
|
26
|
+
AlertDialogDescription.displayName = 'AlertDialogDescription';
|
|
27
|
+
const AlertDialogMedia = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, "data-slot": "alert-dialog-media", className: cn("inline-flex size-10 items-center justify-center rounded-lg bg-muted row-span-2 *:[svg:not([class*='size-'])]:size-5", className), ...props })));
|
|
28
|
+
AlertDialogMedia.displayName = 'AlertDialogMedia';
|
|
29
|
+
const AlertDialogAction = React.forwardRef(({ className, variant = 'default', size = 'default', ...props }, ref) => (_jsx(Button, { variant: variant, size: size, asChild: true, children: _jsx(AlertDialogPrimitive.Action, { ref: ref, "data-slot": "alert-dialog-action", className: cn(className), ...props }) })));
|
|
30
|
+
AlertDialogAction.displayName = 'AlertDialogAction';
|
|
31
|
+
const AlertDialogCancel = React.forwardRef(({ className, variant = 'outline', size = 'default', ...props }, ref) => (_jsx(Button, { variant: variant, size: size, asChild: true, children: _jsx(AlertDialogPrimitive.Cancel, { ref: ref, "data-slot": "alert-dialog-cancel", className: cn(className), ...props }) })));
|
|
32
|
+
AlertDialogCancel.displayName = 'AlertDialogCancel';
|
|
33
|
+
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { VariantProps } from 'class-variance-authority';
|
|
3
|
+
declare const badgeVariants: (props?: ({
|
|
4
|
+
variant?: "accent" | "danger" | "default" | "outline" | "overdue" | "success" | "warning" | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
+
declare const Badge: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & VariantProps<(props?: ({
|
|
7
|
+
variant?: "accent" | "danger" | "default" | "outline" | "overdue" | "success" | "warning" | null | undefined;
|
|
8
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & {
|
|
9
|
+
asChild?: boolean;
|
|
10
|
+
} & React.RefAttributes<HTMLSpanElement>>;
|
|
11
|
+
export { Badge, badgeVariants };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cva } from 'class-variance-authority';
|
|
5
|
+
import { Slot } from 'radix-ui';
|
|
6
|
+
import { cn } from '../../lib/cn.js';
|
|
7
|
+
// A badge is the 22px chip (brand-and-ux 5.5): 6px corners, 12/500, so it reads as a
|
|
8
|
+
// data label and never as a button. Colour follows the four meanings in 5.3.
|
|
9
|
+
const badgeVariants = cva('inline-flex h-[22px] w-fit shrink-0 items-center justify-center gap-[5px] overflow-hidden rounded-md border px-2 text-label whitespace-nowrap [&>svg]:pointer-events-none [&>svg]:size-3', {
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: 'border-transparent bg-neutral-soft text-neutral-text',
|
|
13
|
+
outline: 'border-border bg-transparent text-muted-foreground',
|
|
14
|
+
accent: 'border-transparent bg-accent text-accent-foreground',
|
|
15
|
+
danger: 'border-danger-border bg-danger-soft text-danger-text',
|
|
16
|
+
warning: 'border-warning-border bg-warning-soft text-warning-text',
|
|
17
|
+
success: 'border-success-border bg-success-soft text-success-text',
|
|
18
|
+
overdue: 'border-transparent bg-overdue text-overdue-foreground',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: {
|
|
22
|
+
variant: 'default',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
const Badge = React.forwardRef(function Badge({ className, variant = 'default', asChild = false, ...props }, ref) {
|
|
26
|
+
const Comp = asChild ? Slot.Root : 'span';
|
|
27
|
+
return (_jsx(Comp, { ref: ref, "data-slot": "badge", "data-variant": variant, className: cn(badgeVariants({ variant }), className), ...props }));
|
|
28
|
+
});
|
|
29
|
+
Badge.displayName = 'Badge';
|
|
30
|
+
export { Badge, badgeVariants };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { VariantProps } from 'class-variance-authority';
|
|
3
|
+
declare const buttonVariants: (props?: ({
|
|
4
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
5
|
+
size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
declare const Button: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
|
|
8
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
9
|
+
size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | null | undefined;
|
|
10
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & {
|
|
11
|
+
asChild?: boolean;
|
|
12
|
+
} & React.RefAttributes<HTMLButtonElement>>;
|
|
13
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cva } from 'class-variance-authority';
|
|
5
|
+
import { Slot } from 'radix-ui';
|
|
6
|
+
import { cn } from '../../lib/cn.js';
|
|
7
|
+
// Sole sizes (brand-and-ux 5.5): sm 28px, default 32px, lg 36px, icon 32x32. Desktop
|
|
8
|
+
// only (D32), so there are no touch sizes. Press moves the button down half a pixel.
|
|
9
|
+
const buttonVariants = cva("inline-flex shrink-0 items-center justify-center gap-1.5 rounded-lg font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-[120ms] outline-none select-none active:translate-y-[0.5px] focus-visible:border-ring focus-visible:shadow-[var(--focus-ring)] disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5", {
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: 'border border-transparent bg-primary text-primary-foreground shadow-xs hover:bg-primary-hover',
|
|
13
|
+
destructive: 'border border-transparent bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90',
|
|
14
|
+
// The design's outline button sits on the canvas grey (60.5 Change date, 60.10
|
|
15
|
+
// Cancel); an outline icon button is white (90.1 row menu), set below.
|
|
16
|
+
outline: 'border border-border bg-background text-foreground shadow-xs hover:bg-sidebar-hover',
|
|
17
|
+
secondary: 'border border-transparent bg-secondary text-secondary-foreground hover:bg-sidebar-hover',
|
|
18
|
+
ghost: 'border border-transparent text-muted-foreground hover:bg-sidebar-hover hover:text-foreground',
|
|
19
|
+
link: 'border border-transparent px-0 text-link underline-offset-4 hover:underline',
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
default: 'h-8 px-3 text-body',
|
|
23
|
+
xs: "h-6 gap-1 rounded-md px-2 text-label [&_svg:not([class*='size-'])]:size-3",
|
|
24
|
+
sm: 'h-7 px-2.5 text-label',
|
|
25
|
+
lg: 'h-9 px-3.5 text-strong font-semibold',
|
|
26
|
+
icon: 'size-8',
|
|
27
|
+
'icon-xs': "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
|
|
28
|
+
'icon-sm': 'size-7 rounded-md',
|
|
29
|
+
'icon-lg': 'size-9',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
compoundVariants: [
|
|
33
|
+
{
|
|
34
|
+
variant: 'outline',
|
|
35
|
+
size: ['icon', 'icon-xs', 'icon-sm', 'icon-lg'],
|
|
36
|
+
class: 'bg-card text-muted-foreground hover:bg-row-hover hover:text-foreground',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
defaultVariants: {
|
|
40
|
+
variant: 'default',
|
|
41
|
+
size: 'default',
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
const Button = React.forwardRef(function Button({ className, variant = 'default', size = 'default', asChild = false, ...props }, ref) {
|
|
45
|
+
const Comp = asChild ? Slot.Root : 'button';
|
|
46
|
+
return (_jsx(Comp, { ref: ref, "data-slot": "button", "data-variant": variant, "data-size": size, className: cn(buttonVariants({ variant, size, className })), ...props }));
|
|
47
|
+
});
|
|
48
|
+
Button.displayName = 'Button';
|
|
49
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { DayPicker } from 'react-day-picker';
|
|
3
|
+
import type { DayButton } from 'react-day-picker';
|
|
4
|
+
import { Button } from './button.tsx';
|
|
5
|
+
declare function Calendar({ className, classNames, showOutsideDays, captionLayout, buttonVariant, formatters, components, ...props }: React.ComponentProps<typeof DayPicker> & {
|
|
6
|
+
buttonVariant?: React.ComponentProps<typeof Button>['variant'];
|
|
7
|
+
}): React.JSX.Element;
|
|
8
|
+
declare function CalendarDayButton({ className, day, modifiers, ...props }: React.ComponentProps<typeof DayButton>): React.JSX.Element;
|
|
9
|
+
export { Calendar, CalendarDayButton };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';
|
|
5
|
+
import { DayPicker, getDefaultClassNames } from 'react-day-picker';
|
|
6
|
+
import { cn } from '../../lib/cn.js';
|
|
7
|
+
import { Button, buttonVariants } from './button.js';
|
|
8
|
+
// DayPicker's custom parts live out here, not inside Calendar's render: a component defined
|
|
9
|
+
// inline is a new type on every render, so the whole month would remount whenever the
|
|
10
|
+
// parent re-rendered (on each selection in a controlled calendar).
|
|
11
|
+
function CalendarRoot({ className, rootRef, ...props }) {
|
|
12
|
+
return _jsx("div", { "data-slot": "calendar", ref: rootRef, className: cn(className), ...props });
|
|
13
|
+
}
|
|
14
|
+
function CalendarChevron({ className, orientation, ...props }) {
|
|
15
|
+
if (orientation === 'left') {
|
|
16
|
+
return _jsx(ChevronLeftIcon, { className: cn('size-4', className), ...props });
|
|
17
|
+
}
|
|
18
|
+
if (orientation === 'right') {
|
|
19
|
+
return _jsx(ChevronRightIcon, { className: cn('size-4', className), ...props });
|
|
20
|
+
}
|
|
21
|
+
return _jsx(ChevronDownIcon, { className: cn('size-4', className), ...props });
|
|
22
|
+
}
|
|
23
|
+
function CalendarWeekNumber({ children, week: _week, ...props }) {
|
|
24
|
+
return (_jsx("td", { ...props, children: _jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children: children }) }));
|
|
25
|
+
}
|
|
26
|
+
function Calendar({ className, classNames, showOutsideDays = true, captionLayout = 'label', buttonVariant = 'ghost', formatters, components, ...props }) {
|
|
27
|
+
const defaultClassNames = getDefaultClassNames();
|
|
28
|
+
return (_jsx(DayPicker, { showOutsideDays: showOutsideDays, className: cn('group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent', String.raw `rtl:**:[.rdp-button\_next>svg]:rotate-180`, String.raw `rtl:**:[.rdp-button\_previous>svg]:rotate-180`, className), captionLayout: captionLayout, formatters: {
|
|
29
|
+
formatMonthDropdown: (date) => date.toLocaleString('default', { month: 'short' }),
|
|
30
|
+
...formatters,
|
|
31
|
+
}, classNames: {
|
|
32
|
+
root: cn('w-fit', defaultClassNames.root),
|
|
33
|
+
months: cn('relative flex flex-row gap-4', defaultClassNames.months),
|
|
34
|
+
month: cn('flex w-full flex-col gap-4', defaultClassNames.month),
|
|
35
|
+
nav: cn('absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1', defaultClassNames.nav),
|
|
36
|
+
button_previous: cn(buttonVariants({ variant: buttonVariant }), 'size-(--cell-size) p-0 select-none aria-disabled:opacity-50', defaultClassNames.button_previous),
|
|
37
|
+
button_next: cn(buttonVariants({ variant: buttonVariant }), 'size-(--cell-size) p-0 select-none aria-disabled:opacity-50', defaultClassNames.button_next),
|
|
38
|
+
month_caption: cn('flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)', defaultClassNames.month_caption),
|
|
39
|
+
dropdowns: cn('flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-body font-medium', defaultClassNames.dropdowns),
|
|
40
|
+
dropdown_root: cn('relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50', defaultClassNames.dropdown_root),
|
|
41
|
+
dropdown: cn('absolute inset-0 bg-popover opacity-0', defaultClassNames.dropdown),
|
|
42
|
+
caption_label: cn('font-medium select-none', captionLayout === 'label'
|
|
43
|
+
? 'text-body'
|
|
44
|
+
: 'flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-body [&>svg]:size-3.5 [&>svg]:text-muted-foreground', defaultClassNames.caption_label),
|
|
45
|
+
month_grid: cn('w-full border-collapse', defaultClassNames.month_grid),
|
|
46
|
+
weekdays: cn('flex', defaultClassNames.weekdays),
|
|
47
|
+
weekday: cn('flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none', defaultClassNames.weekday),
|
|
48
|
+
week: cn('mt-2 flex w-full', defaultClassNames.week),
|
|
49
|
+
week_number_header: cn('w-(--cell-size) select-none', defaultClassNames.week_number_header),
|
|
50
|
+
week_number: cn('text-[0.8rem] text-muted-foreground select-none', defaultClassNames.week_number),
|
|
51
|
+
day: cn('group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md', props.showWeekNumber
|
|
52
|
+
? '[&:nth-child(2)[data-selected=true]_button]:rounded-l-md'
|
|
53
|
+
: '[&:first-child[data-selected=true]_button]:rounded-l-md', defaultClassNames.day),
|
|
54
|
+
range_start: cn('rounded-l-md bg-accent', defaultClassNames.range_start),
|
|
55
|
+
range_middle: cn('rounded-none', defaultClassNames.range_middle),
|
|
56
|
+
range_end: cn('rounded-r-md bg-accent', defaultClassNames.range_end),
|
|
57
|
+
today: cn('rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none', defaultClassNames.today),
|
|
58
|
+
outside: cn('text-muted-foreground aria-selected:text-muted-foreground', defaultClassNames.outside),
|
|
59
|
+
disabled: cn('text-muted-foreground opacity-50', defaultClassNames.disabled),
|
|
60
|
+
hidden: cn('invisible', defaultClassNames.hidden),
|
|
61
|
+
...classNames,
|
|
62
|
+
}, components: {
|
|
63
|
+
Root: CalendarRoot,
|
|
64
|
+
Chevron: CalendarChevron,
|
|
65
|
+
DayButton: CalendarDayButton,
|
|
66
|
+
WeekNumber: CalendarWeekNumber,
|
|
67
|
+
...components,
|
|
68
|
+
}, ...props }));
|
|
69
|
+
}
|
|
70
|
+
function CalendarDayButton({ className, day, modifiers, ...props }) {
|
|
71
|
+
const defaultClassNames = getDefaultClassNames();
|
|
72
|
+
const ref = React.useRef(null);
|
|
73
|
+
React.useEffect(() => {
|
|
74
|
+
if (modifiers.focused)
|
|
75
|
+
ref.current?.focus();
|
|
76
|
+
}, [modifiers.focused]);
|
|
77
|
+
return (_jsx(Button, { ref: ref, variant: "ghost", size: "icon", "data-day": day.date.toLocaleDateString(), "data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle, "data-range-start": modifiers.range_start, "data-range-end": modifiers.range_end, "data-range-middle": modifiers.range_middle, className: cn('flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:shadow-[var(--focus-ring)] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground [&>span]:text-label [&>span]:opacity-70', defaultClassNames.day, className), ...props }));
|
|
78
|
+
}
|
|
79
|
+
export { Calendar, CalendarDayButton };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Checkbox as CheckboxPrimitive } from 'radix-ui';
|
|
3
|
+
declare const Checkbox: React.ForwardRefExoticComponent<Omit<CheckboxPrimitive.CheckboxProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
4
|
+
export { Checkbox };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { CheckIcon } from 'lucide-react';
|
|
5
|
+
import { Checkbox as CheckboxPrimitive } from 'radix-ui';
|
|
6
|
+
import { cn } from '../../lib/cn.js';
|
|
7
|
+
const Checkbox = React.forwardRef(function Checkbox({ className, ...props }, ref) {
|
|
8
|
+
return (_jsx(CheckboxPrimitive.Root, { ref: ref, "data-slot": "checkbox", className: cn('peer size-4 shrink-0 rounded-[4px] border border-input shadow-xs transition-shadow outline-none focus-visible:border-ring focus-visible:shadow-[var(--focus-ring)] disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground', className), ...props, children: _jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", className: "grid place-content-center text-current transition-none", children: _jsx(CheckIcon, { className: "size-3.5" }) }) }));
|
|
9
|
+
});
|
|
10
|
+
Checkbox.displayName = 'Checkbox';
|
|
11
|
+
export { Checkbox };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Dialog } from './dialog.tsx';
|
|
3
|
+
declare const Command: React.ForwardRefExoticComponent<Omit<{
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
6
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
7
|
+
} & {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}, "asChild" | "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
10
|
+
label?: string;
|
|
11
|
+
shouldFilter?: boolean;
|
|
12
|
+
filter?: (value: string, search: string, keywords?: string[]) => number;
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
onValueChange?: (value: string) => void;
|
|
16
|
+
loop?: boolean;
|
|
17
|
+
disablePointerSelection?: boolean;
|
|
18
|
+
vimBindings?: boolean;
|
|
19
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
20
|
+
declare function CommandDialog({ title, description, children, className, showCloseButton, footer, shouldFilter, commandValue, onCommandValueChange, ...props }: React.ComponentProps<typeof Dialog> & {
|
|
21
|
+
title?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
className?: string;
|
|
24
|
+
showCloseButton?: boolean;
|
|
25
|
+
footer?: React.ReactNode;
|
|
26
|
+
/** false when the caller filters and ranks the items itself (server search results). */
|
|
27
|
+
shouldFilter?: boolean;
|
|
28
|
+
/** The highlighted item's value, when the caller controls it. */
|
|
29
|
+
commandValue?: string;
|
|
30
|
+
onCommandValueChange?: (value: string) => void;
|
|
31
|
+
}): React.JSX.Element;
|
|
32
|
+
declare const CommandInput: React.ForwardRefExoticComponent<Omit<Omit<Pick<Pick<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof React.InputHTMLAttributes<HTMLInputElement>> & {
|
|
33
|
+
ref?: React.Ref<HTMLInputElement>;
|
|
34
|
+
} & {
|
|
35
|
+
asChild?: boolean;
|
|
36
|
+
}, "asChild" | "key" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "onChange" | "type" | "value"> & {
|
|
37
|
+
value?: string;
|
|
38
|
+
onValueChange?: (search: string) => void;
|
|
39
|
+
} & React.RefAttributes<HTMLInputElement>, "ref"> & {
|
|
40
|
+
trailing?: React.ReactNode;
|
|
41
|
+
} & React.RefAttributes<HTMLInputElement>>;
|
|
42
|
+
declare const CommandList: React.ForwardRefExoticComponent<Omit<{
|
|
43
|
+
children?: React.ReactNode;
|
|
44
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
45
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
46
|
+
} & {
|
|
47
|
+
asChild?: boolean;
|
|
48
|
+
}, "asChild" | "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
49
|
+
label?: string;
|
|
50
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
51
|
+
declare const CommandEmpty: React.ForwardRefExoticComponent<Omit<{
|
|
52
|
+
children?: React.ReactNode;
|
|
53
|
+
} & Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
54
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
55
|
+
} & {
|
|
56
|
+
asChild?: boolean;
|
|
57
|
+
}, "asChild" | "key" | keyof React.HTMLAttributes<HTMLDivElement>> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
58
|
+
declare const CommandGroup: React.ForwardRefExoticComponent<Omit<{
|
|
59
|
+
children?: React.ReactNode;
|
|
60
|
+
} & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
61
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
62
|
+
} & {
|
|
63
|
+
asChild?: boolean;
|
|
64
|
+
}, "asChild" | "key" | keyof React.HTMLAttributes<HTMLDivElement>>, "heading" | "value"> & {
|
|
65
|
+
heading?: React.ReactNode;
|
|
66
|
+
value?: string;
|
|
67
|
+
forceMount?: boolean;
|
|
68
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
69
|
+
declare const CommandSeparator: React.ForwardRefExoticComponent<Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
70
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
71
|
+
} & {
|
|
72
|
+
asChild?: boolean;
|
|
73
|
+
}, "asChild" | "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
74
|
+
alwaysRender?: boolean;
|
|
75
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
76
|
+
declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
|
|
77
|
+
children?: React.ReactNode;
|
|
78
|
+
} & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
79
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
80
|
+
} & {
|
|
81
|
+
asChild?: boolean;
|
|
82
|
+
}, "asChild" | "key" | keyof React.HTMLAttributes<HTMLDivElement>>, "disabled" | "onSelect" | "value"> & {
|
|
83
|
+
disabled?: boolean;
|
|
84
|
+
onSelect?: (value: string) => void;
|
|
85
|
+
value?: string;
|
|
86
|
+
keywords?: string[];
|
|
87
|
+
forceMount?: boolean;
|
|
88
|
+
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
89
|
+
declare const CommandShortcut: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
|
|
90
|
+
export { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator, };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Command as CommandPrimitive } from 'cmdk';
|
|
5
|
+
import { SearchIcon } from 'lucide-react';
|
|
6
|
+
import { cn } from '../../lib/cn.js';
|
|
7
|
+
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from './dialog.js';
|
|
8
|
+
const Command = React.forwardRef(({ className, ...props }, ref) => (_jsx(CommandPrimitive, { ref: ref, "data-slot": "command", className: cn('flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground', className), ...props })));
|
|
9
|
+
Command.displayName = 'Command';
|
|
10
|
+
// Cmd+K (20.2-command-palette-cmd-k.png): 640px, anchored near the top so it does not
|
|
11
|
+
// jump as results change, on a lighter overlay than a dialog's, with a footer that
|
|
12
|
+
// names the keys. Pass `footer` to replace the default Move and Open hints.
|
|
13
|
+
// A dialog root renders no element, so CommandDialog takes no ref.
|
|
14
|
+
function CommandDialog({ title = 'Command palette', description = 'Search, or jump to a screen', children, className, showCloseButton = false, footer, shouldFilter, commandValue, onCommandValueChange, ...props }) {
|
|
15
|
+
return (_jsxs(Dialog, { ...props, children: [_jsxs(DialogHeader, { className: "sr-only", children: [_jsx(DialogTitle, { children: title }), _jsx(DialogDescription, { children: description })] }), _jsxs(DialogContent, { overlayClassName: "bg-black/20", className: cn('top-[12dvh] max-h-[calc(88dvh-32px)] max-w-[640px] translate-y-0 gap-0 overflow-hidden rounded-xl p-0', className), showCloseButton: showCloseButton, children: [_jsx(Command, { shouldFilter: shouldFilter, value: commandValue, onValueChange: onCommandValueChange, className: "rounded-xl [&_[cmdk-group]]:px-1.5 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0", children: children }), footer ?? (_jsxs("div", { "data-slot": "command-footer", className: "flex h-9 shrink-0 items-center gap-2 border-t border-border bg-muted px-3.5 text-label font-normal text-subtle-foreground", children: [_jsx(CommandKey, { children: "\u2191\u2193" }), _jsx("span", { className: "mr-2", children: "Move" }), _jsx(CommandKey, { children: "Enter" }), _jsx("span", { children: "Open" })] }))] })] }));
|
|
16
|
+
}
|
|
17
|
+
/** A key in the palette's own chrome: the same box as Kbd, without its import. */
|
|
18
|
+
function CommandKey({ children }) {
|
|
19
|
+
return (_jsx("kbd", { className: "inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-sm border border-border bg-card px-1 font-sans text-[11px] leading-none font-medium text-muted-foreground", children: children }));
|
|
20
|
+
}
|
|
21
|
+
// The ref goes to the input; the search icon and `trailing` sit in a wrapper around it.
|
|
22
|
+
const CommandInput = React.forwardRef(({ className, trailing, ...props }, ref) => (_jsxs("div", { "data-slot": "command-input-wrapper", className: "flex h-12 shrink-0 items-center gap-2.5 border-b border-border px-4", children: [_jsx(SearchIcon, { className: "size-4 shrink-0 text-subtle-foreground" }), _jsx(CommandPrimitive.Input, { ref: ref, "data-slot": "command-input", className: cn('flex h-full w-full bg-transparent text-[15px] outline-hidden placeholder:text-subtle-foreground disabled:cursor-not-allowed disabled:opacity-50', className), ...props }), trailing] })));
|
|
23
|
+
CommandInput.displayName = 'CommandInput';
|
|
24
|
+
const CommandList = React.forwardRef(({ className, ...props }, ref) => (_jsx(CommandPrimitive.List, { ref: ref, "data-slot": "command-list", className: cn('max-h-[min(400px,calc(88dvh-120px))] scroll-py-1.5 overflow-x-hidden overflow-y-auto py-1.5', className), ...props })));
|
|
25
|
+
CommandList.displayName = 'CommandList';
|
|
26
|
+
const CommandEmpty = React.forwardRef((props, ref) => (_jsx(CommandPrimitive.Empty, { ref: ref, "data-slot": "command-empty", className: "py-6 text-center text-body text-muted-foreground", ...props })));
|
|
27
|
+
CommandEmpty.displayName = 'CommandEmpty';
|
|
28
|
+
const CommandGroup = React.forwardRef(({ className, ...props }, ref) => (_jsx(CommandPrimitive.Group, { ref: ref, "data-slot": "command-group", className: cn('overflow-hidden text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:pt-1.5 [&_[cmdk-group-heading]]:pb-1 [&_[cmdk-group-heading]]:text-[11px] [&_[cmdk-group-heading]]:leading-4 [&_[cmdk-group-heading]]:font-semibold [&_[cmdk-group-heading]]:tracking-[0.06em] [&_[cmdk-group-heading]]:uppercase [&_[cmdk-group-heading]]:text-subtle-foreground', className), ...props })));
|
|
29
|
+
CommandGroup.displayName = 'CommandGroup';
|
|
30
|
+
const CommandSeparator = React.forwardRef(({ className, ...props }, ref) => (_jsx(CommandPrimitive.Separator, { ref: ref, "data-slot": "command-separator", className: cn('-mx-1 h-px bg-border', className), ...props })));
|
|
31
|
+
CommandSeparator.displayName = 'CommandSeparator';
|
|
32
|
+
const CommandItem = React.forwardRef(({ className, ...props }, ref) => (_jsx(CommandPrimitive.Item, { ref: ref, "data-slot": "command-item", className: cn("group/item relative flex h-8 cursor-default items-center gap-2 rounded-md px-2.5 text-body outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 [&_svg:not([class*='text-'])]:text-muted-foreground data-[selected=true]:[&_svg:not([class*='text-'])]:text-accent-foreground", className), ...props })));
|
|
33
|
+
CommandItem.displayName = 'CommandItem';
|
|
34
|
+
const CommandShortcut = React.forwardRef(({ className, ...props }, ref) => (_jsx("span", { ref: ref, "data-slot": "command-shortcut", className: cn('ml-auto shrink-0 text-label font-normal text-subtle-foreground', className), ...props })));
|
|
35
|
+
CommandShortcut.displayName = 'CommandShortcut';
|
|
36
|
+
export { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator, };
|