@neasg/design-system 0.4.35 → 0.4.113
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 +9 -0
- package/dist/activity-card.d.ts +31 -0
- package/dist/activity-card.js +65 -0
- package/dist/alert.d.ts +1 -1
- package/dist/autocomplete.d.ts +84 -0
- package/dist/autocomplete.js +267 -0
- package/dist/avatar.d.ts +3 -1
- package/dist/avatar.js +27 -10
- package/dist/badge.d.ts +1 -1
- package/dist/badge.js +1 -1
- package/dist/button.d.ts +2 -2
- package/dist/button.js +3 -1
- package/dist/calendar.js +1 -1
- package/dist/card.d.ts +1 -1
- package/dist/card.js +1 -1
- package/dist/changelog-action-panel.d.ts +17 -0
- package/dist/changelog-action-panel.js +14 -0
- package/dist/checklist.d.ts +63 -0
- package/dist/checklist.js +30 -0
- package/dist/compound-search-input.d.ts +10 -0
- package/dist/compound-search-input.js +19 -0
- package/dist/date-input.js +3 -3
- package/dist/dialog.d.ts +4 -1
- package/dist/dialog.js +7 -2
- package/dist/draggable-tabs.js +9 -8
- package/dist/dropdown-button.js +1 -0
- package/dist/editable-table.js +2 -2
- package/dist/field-counter.d.ts +7 -0
- package/dist/field-counter.js +5 -0
- package/dist/index.d.ts +22 -4
- package/dist/index.js +12 -2
- package/dist/input.d.ts +2 -0
- package/dist/input.js +11 -3
- package/dist/label-value-grid.js +6 -4
- package/dist/layout.d.ts +39 -6
- package/dist/layout.js +118 -42
- package/dist/lib/utils.js +1 -0
- package/dist/message-action-panel.d.ts +12 -0
- package/dist/message-action-panel.js +11 -0
- package/dist/message-item.d.ts +23 -3
- package/dist/message-item.js +115 -16
- package/dist/notification.d.ts +14 -3
- package/dist/notification.js +36 -7
- package/dist/page-section.d.ts +2 -1
- package/dist/page-section.js +2 -2
- package/dist/popover-menu.d.ts +4 -2
- package/dist/popover-menu.js +65 -5
- package/dist/popover.d.ts +10 -2
- package/dist/popover.js +7 -3
- package/dist/rich-text-editor.d.ts +2 -1
- package/dist/rich-text-editor.js +29 -6
- package/dist/routing-action-panel.d.ts +38 -0
- package/dist/routing-action-panel.js +19 -0
- package/dist/routing-timeline.d.ts +7 -2
- package/dist/routing-timeline.js +67 -29
- package/dist/search-input.d.ts +6 -0
- package/dist/search-input.js +6 -4
- package/dist/select-primitive.js +1 -1
- package/dist/select.d.ts +3 -1
- package/dist/select.js +9 -4
- package/dist/status-dot.d.ts +13 -0
- package/dist/status-dot.js +19 -0
- package/dist/styles.css +0 -19
- package/dist/table-add-row.d.ts +8 -0
- package/dist/table-add-row.js +7 -0
- package/dist/table-column-filter.js +7 -5
- package/dist/table.d.ts +9 -1
- package/dist/table.js +25 -11
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +6 -4
- package/dist/tailwind-preset.js +10 -0
- package/dist/textarea.d.ts +5 -0
- package/dist/textarea.js +18 -3
- package/dist/theme-switcher.d.ts +3 -1
- package/dist/theme-switcher.js +8 -2
- package/package.json +1 -1
package/dist/card.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
export interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
|
|
3
3
|
title: React.ReactNode;
|
|
4
4
|
description?: React.ReactNode;
|
|
5
|
-
variant?: "default" | "elevated" | "gradient";
|
|
5
|
+
variant?: "default" | "subtle" | "elevated" | "gradient";
|
|
6
6
|
size?: "default" | "compact";
|
|
7
7
|
/** Large value displayed above the title — use for stat/metric cards. */
|
|
8
8
|
stat?: React.ReactNode;
|
package/dist/card.js
CHANGED
|
@@ -106,7 +106,7 @@ const Card = React.forwardRef(({ title, description, variant = "default", size =
|
|
|
106
106
|
};
|
|
107
107
|
const renderedTitle = React.isValidElement(title) ? (title) : (_jsx(Typography, { as: "p", variant: hasStat ? "caption" : "body", color: variant === "gradient" ? "inherit" : hasStat ? "muted" : "foreground", className: cn(hasStat && "font-medium", !hasStat && "font-semibold", variant === "gradient" && "opacity-80"), children: title }));
|
|
108
108
|
const renderedDescription = description == null ? null : React.isValidElement(description) ? (description) : (_jsx(Typography, { as: "p", variant: "caption", color: variant === "gradient" ? "inherit" : undefined, className: variant === "gradient" ? "opacity-70" : undefined, children: description }));
|
|
109
|
-
return (_jsxs("div", { ref: ref, onClick: onClick, onKeyDown: handleKeyDown, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onFocus: handleFocus, onBlur: handleBlur, role: role !== null && role !== void 0 ? role : (interactive ? "button" : props["aria-label"] || props["aria-labelledby"] ? "region" : undefined), tabIndex: tabIndex !== null && tabIndex !== void 0 ? tabIndex : (interactive ? 0 : undefined), "aria-pressed": ariaPressed !== null && ariaPressed !== void 0 ? ariaPressed : (interactive && active !== undefined ? Boolean(active) : undefined), className: cn("group/card rounded-surface border border-[hsl(var(--card-border))] text-card-foreground", variant === "default" && "bg-card", variant === "elevated" && "bg-card shadow-sm", variant === "gradient" &&
|
|
109
|
+
return (_jsxs("div", { ref: ref, onClick: onClick, onKeyDown: handleKeyDown, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onFocus: handleFocus, onBlur: handleBlur, role: role !== null && role !== void 0 ? role : (interactive ? "button" : props["aria-label"] || props["aria-labelledby"] ? "region" : undefined), tabIndex: tabIndex !== null && tabIndex !== void 0 ? tabIndex : (interactive ? 0 : undefined), "aria-pressed": ariaPressed !== null && ariaPressed !== void 0 ? ariaPressed : (interactive && active !== undefined ? Boolean(active) : undefined), className: cn("group/card rounded-surface border border-[hsl(var(--card-border))] text-card-foreground", variant === "default" && "bg-card", variant === "subtle" && "bg-muted/40", variant === "elevated" && "bg-card shadow-sm", variant === "gradient" &&
|
|
110
110
|
"border-[hsl(var(--card-gradient-border))]/30 bg-gradient-to-br from-[hsl(var(--card-gradient-from))] to-[hsl(var(--card-gradient-to))] text-[hsl(var(--card-gradient-foreground))]", active && "border-primary bg-primary/[0.04] ring-1 ring-primary/20", accent === "primary" &&
|
|
111
111
|
"border-[hsl(var(--card-border))] shadow-[inset_4px_0_0_0_hsl(var(--primary))]", interactive &&
|
|
112
112
|
"cursor-pointer transition-[border-color,background-color,box-shadow,transform] duration-150 ease-out hover:border-primary/50 hover:bg-primary/5 hover:shadow-md motion-safe:hover:-translate-y-0.5 motion-safe:active:translate-y-0 motion-safe:active:scale-[0.99] focus-visible:border-primary/50 focus-visible:bg-primary/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", className), ...props, children: [_jsxs("div", { className: cn("relative flex flex-col gap-2", size === "default" && "p-4", size === "compact" && "p-3", showIcon && size === "default" && "pr-12", showIcon && size === "compact" && "pr-10"), children: [showIcon ? (_jsx("span", { "aria-hidden": "true", "data-slot": "card-icon", className: cn("pointer-events-none absolute right-3 top-3 inline-flex size-7 items-center justify-center rounded-control border border-[hsl(var(--card-border))] bg-background/80 text-muted-foreground shadow-sm transition-[background-color,color,transform] duration-150 ease-out group-hover/card:scale-105 group-hover/card:bg-highlight group-hover/card:text-highlight-foreground group-focus-visible/card:bg-highlight group-focus-visible/card:text-highlight-foreground motion-reduce:transition-colors [&_svg]:size-3.5", size === "compact" && "right-2.5 top-2.5 size-6 [&_svg]:size-3", active &&
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type DashboardActionPanelProps } from "./layout";
|
|
3
|
+
import { type NotificationItemData } from "./notification";
|
|
4
|
+
export interface ChangelogActionPanelProps extends Omit<DashboardActionPanelProps, "children" | "headerSpacing" | "title"> {
|
|
5
|
+
title?: React.ReactNode;
|
|
6
|
+
notifications: NotificationItemData[];
|
|
7
|
+
isLoading?: boolean;
|
|
8
|
+
loadingLabel?: string;
|
|
9
|
+
emptyMessage?: React.ReactNode;
|
|
10
|
+
emptyDescription?: React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Shared change-log panel. Consumers map their domain events to notification
|
|
14
|
+
* items; this component owns the complete list, loading, and empty-state UI.
|
|
15
|
+
*/
|
|
16
|
+
declare function ChangelogActionPanel({ title, subtitle, notifications, isLoading, loadingLabel, emptyMessage, emptyDescription, ...panelProps }: ChangelogActionPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export { ChangelogActionPanel };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { History } from "lucide-react";
|
|
4
|
+
import { DashboardActionPanel, DashboardActionPanelEmptyState, DashboardRightPanelBody, } from "./layout";
|
|
5
|
+
import { NotificationList, } from "./notification";
|
|
6
|
+
import { Spinner } from "./spinner";
|
|
7
|
+
/**
|
|
8
|
+
* Shared change-log panel. Consumers map their domain events to notification
|
|
9
|
+
* items; this component owns the complete list, loading, and empty-state UI.
|
|
10
|
+
*/
|
|
11
|
+
function ChangelogActionPanel({ title = "Change log", subtitle = "Review all activity recorded here.", notifications, isLoading = false, loadingLabel = "Loading change log", emptyMessage = "No change log entries yet", emptyDescription = "Changes will be recorded here.", ...panelProps }) {
|
|
12
|
+
return (_jsx(DashboardActionPanel, { headerSpacing: "comfortable", title: title, subtitle: subtitle, ...panelProps, children: _jsx(DashboardRightPanelBody, { spacing: "comfortable", topInset: "none", children: isLoading ? (_jsx("div", { "data-slot": "changelog-action-panel-loading", className: "absolute inset-0 flex items-center justify-center", children: _jsx(Spinner, { size: "md", label: loadingLabel }) })) : notifications.length === 0 ? (_jsx(DashboardActionPanelEmptyState, { icon: History, message: emptyMessage, description: emptyDescription })) : (_jsx(NotificationList, { density: "compact", notifications: notifications, descriptionLines: 3, emptyState: null, variant: "bordered" })) }) }));
|
|
13
|
+
}
|
|
14
|
+
export { ChangelogActionPanel };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type SelectOption } from "./select";
|
|
3
|
+
export interface ChecklistPanelProps {
|
|
4
|
+
title: React.ReactNode;
|
|
5
|
+
action?: React.ReactNode;
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export declare function ChecklistPanel({ title, action, children }: ChecklistPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export interface ChecklistSectionProps {
|
|
10
|
+
title: string;
|
|
11
|
+
progress?: string;
|
|
12
|
+
/** Independent control displayed beside the section chevron. */
|
|
13
|
+
action?: React.ReactNode;
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
defaultOpen?: boolean;
|
|
16
|
+
open?: boolean;
|
|
17
|
+
onOpenChange?: (open: boolean) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function ChecklistSection({ title, progress, action, children, defaultOpen, open, onOpenChange }: ChecklistSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export interface ChecklistSelectionProps {
|
|
21
|
+
title: string;
|
|
22
|
+
description: string;
|
|
23
|
+
typeOptions: SelectOption[];
|
|
24
|
+
subtypeOptions: SelectOption[];
|
|
25
|
+
type: string;
|
|
26
|
+
subtype: string;
|
|
27
|
+
onTypeChange: (value: string) => void;
|
|
28
|
+
onSubtypeChange: (value: string) => void;
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
loading?: boolean;
|
|
31
|
+
action?: React.ReactNode;
|
|
32
|
+
}
|
|
33
|
+
export declare function ChecklistSelection({ title, description, typeOptions, subtypeOptions, type, subtype, onTypeChange, onSubtypeChange, disabled, loading, action }: ChecklistSelectionProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export interface ChecklistQuestionOption {
|
|
35
|
+
value: string;
|
|
36
|
+
label: string;
|
|
37
|
+
tone?: "positive" | "negative" | "neutral";
|
|
38
|
+
}
|
|
39
|
+
export interface ChecklistQuestionProps {
|
|
40
|
+
label: string;
|
|
41
|
+
options: ChecklistQuestionOption[];
|
|
42
|
+
value: string;
|
|
43
|
+
onValueChange: (value: string) => void;
|
|
44
|
+
disabled?: boolean;
|
|
45
|
+
remarks: string;
|
|
46
|
+
onRemarksChange: (value: string) => void;
|
|
47
|
+
remarksLimit?: number;
|
|
48
|
+
/** Count and limit characters instead of words when supplied. */
|
|
49
|
+
remarksMaxLength?: number;
|
|
50
|
+
remarksRequired?: boolean;
|
|
51
|
+
evidence?: React.ReactNode;
|
|
52
|
+
evidenceCount?: number;
|
|
53
|
+
}
|
|
54
|
+
export declare function ChecklistQuestion({ label, options, value, onValueChange, disabled, remarks, onRemarksChange, remarksLimit, remarksMaxLength, remarksRequired, evidence, evidenceCount }: ChecklistQuestionProps): import("react/jsx-runtime").JSX.Element;
|
|
55
|
+
export interface ChecklistAttachmentsProps {
|
|
56
|
+
items: {
|
|
57
|
+
key: string;
|
|
58
|
+
name: string;
|
|
59
|
+
url: string;
|
|
60
|
+
}[];
|
|
61
|
+
onRemove?: (key: string) => void;
|
|
62
|
+
}
|
|
63
|
+
export declare function ChecklistAttachments({ items, onRemove }: ChecklistAttachmentsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
5
|
+
import { Camera, ChevronDown, ClipboardList, LoaderCircle, MessageSquareText, Trash2 } from "lucide-react";
|
|
6
|
+
import { Button } from "./button";
|
|
7
|
+
import { Select } from "./select";
|
|
8
|
+
import { Textarea } from "./textarea";
|
|
9
|
+
import { cn } from "./lib/utils";
|
|
10
|
+
export function ChecklistPanel({ title, action, children }) {
|
|
11
|
+
return _jsxs("div", { "data-slot": "checklist-panel", className: "rounded-xl border border-border bg-card p-4 shadow-xs", children: [_jsxs("div", { className: "mb-4 flex items-center justify-between gap-4", children: [_jsx("h3", { className: "text-base font-medium text-card-foreground", children: title }), action] }), children] });
|
|
12
|
+
}
|
|
13
|
+
export function ChecklistSection({ title, progress, action, children, defaultOpen = false, open, onOpenChange }) {
|
|
14
|
+
return _jsxs(CollapsiblePrimitive.Root, { open: open, onOpenChange: onOpenChange, defaultOpen: defaultOpen, className: "border-b border-border last:border-0", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs(CollapsiblePrimitive.Trigger, { className: "group flex min-w-0 flex-1 items-center gap-1.5 py-3 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [_jsx("span", { className: "text-base font-medium", children: title }), progress ? _jsx("span", { className: "text-sm text-muted-foreground", children: progress }) : null, !action ? _jsx(ChevronDown, { "aria-hidden": "true", className: "ml-auto size-4 shrink-0 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" }) : null] }), action ? _jsxs(_Fragment, { children: [_jsx("div", { "data-slot": "checklist-section-action", className: "shrink-0", children: action }), _jsx(CollapsiblePrimitive.Trigger, { "aria-label": `Toggle ${title}`, className: "group py-3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(ChevronDown, { "aria-hidden": "true", className: "size-4 shrink-0 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" }) })] }) : null] }), _jsx(CollapsiblePrimitive.Content, { className: "overflow-hidden data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up motion-reduce:data-[state=open]:animate-none motion-reduce:data-[state=closed]:animate-none", children: _jsx("div", { className: "flex flex-col gap-4 pb-4", children: children }) })] });
|
|
15
|
+
}
|
|
16
|
+
export function ChecklistSelection({ title, description, typeOptions, subtypeOptions, type, subtype, onTypeChange, onSubtypeChange, disabled, loading, action }) {
|
|
17
|
+
const Icon = loading ? LoaderCircle : ClipboardList;
|
|
18
|
+
return _jsxs("div", { "data-slot": "checklist-selection", "aria-busy": loading, className: "flex flex-col items-center gap-4 rounded-lg bg-muted/30 p-6 text-center", children: [_jsx(Icon, { "aria-hidden": "true", className: cn("size-8", loading && "animate-spin") }), _jsxs("div", { className: "space-y-2", children: [_jsx("p", { className: "text-sm font-medium", children: title }), _jsx("p", { className: "text-sm text-muted-foreground", children: description })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-center gap-4", children: [_jsx(Select, { className: "w-auto", triggerClassName: "w-auto min-w-0", label: "Type", hideLabel: true, placeholder: "Type", options: typeOptions, value: type, onValueChange: onTypeChange, disabled: disabled || loading }), _jsx(Select, { className: "w-auto", triggerClassName: "w-auto min-w-0", label: "Sub-Type", hideLabel: true, placeholder: "Sub-Type", options: subtypeOptions, value: subtype, onValueChange: onSubtypeChange, disabled: disabled || loading || !type }), action] })] });
|
|
19
|
+
}
|
|
20
|
+
export function ChecklistQuestion({ label, options, value, onValueChange, disabled, remarks, onRemarksChange, remarksLimit = 500, remarksMaxLength, remarksRequired = false, evidence, evidenceCount = 0 }) {
|
|
21
|
+
const name = React.useId();
|
|
22
|
+
React.useEffect(() => { if (remarksRequired)
|
|
23
|
+
setShowRemarks(true); }, [remarksRequired, value]);
|
|
24
|
+
const [showRemarks, setShowRemarks] = React.useState(Boolean(remarks));
|
|
25
|
+
const [showEvidence, setShowEvidence] = React.useState(false);
|
|
26
|
+
return _jsxs("div", { "data-slot": "checklist-question", className: "rounded-xl border border-border bg-card p-4 shadow-xs", children: [_jsx("p", { id: `${name}-label`, className: "mb-4 text-sm font-medium", children: label }), _jsxs("div", { className: "flex flex-wrap items-center gap-6", children: [_jsx("fieldset", { disabled: disabled, "aria-labelledby": `${name}-label`, className: cn("flex min-w-0 border-0 p-0", disabled && "opacity-50"), children: options.map((option, index) => _jsxs("label", { className: cn("relative cursor-pointer border border-input px-2.5 py-2 text-sm font-medium focus-within:z-10 focus-within:ring-2 focus-within:ring-ring", index > 0 && "-ml-px", index === 0 && "rounded-l-md", index === options.length - 1 && "rounded-r-md", disabled && "cursor-not-allowed", value === option.value ? option.tone === "negative" ? "bg-destructive/20" : option.tone === "positive" ? "bg-primary/20" : "bg-muted" : "bg-background"), children: [_jsx("input", { className: "absolute inset-0 size-full cursor-inherit opacity-0", type: "radio", name: name, value: option.value, checked: value === option.value, onChange: () => onValueChange(option.value) }), option.label] }, option.value)) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { variant: "ghost", size: "compactIcon", "aria-label": "Add remarks", disabled: disabled, onClick: () => setShowRemarks(true), children: _jsx(MessageSquareText, { "aria-hidden": "true", size: 16 }) }), _jsx(Button, { variant: "ghost", size: "compactIcon", "aria-label": "Add photos", disabled: disabled, onClick: () => setShowEvidence((open) => !open), children: _jsx(Camera, { "aria-hidden": "true", size: 16 }) })] })] }), showRemarks || remarks ? _jsx("div", { className: "mt-2 space-y-2", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx("div", { className: "min-w-0 flex-1", children: _jsx(Textarea, { label: "Remarks", hideLabel: true, placeholder: "Type...", value: remarks, disabled: disabled, rows: 2, onChange: (event) => onRemarksChange(event.target.value), maxWords: remarksMaxLength === undefined ? remarksLimit : undefined, maxLength: remarksMaxLength, showCount: remarksMaxLength !== undefined }) }), _jsx(Button, { variant: "ghost", size: "compactIcon", "aria-label": "Remove remarks", disabled: disabled, onClick: () => { onRemarksChange(""); setShowRemarks(false); }, children: _jsx(Trash2, { "aria-hidden": "true", size: 16 }) })] }) }) : null, (showEvidence || evidenceCount > 0) && evidence ? _jsx("div", { className: "mt-2", children: evidence }) : null] });
|
|
27
|
+
}
|
|
28
|
+
export function ChecklistAttachments({ items, onRemove }) {
|
|
29
|
+
return _jsx("div", { className: "flex flex-wrap gap-2", children: items.map((item) => _jsxs("div", { className: "relative", children: [_jsx("a", { href: item.url, target: "_blank", rel: "noreferrer", children: _jsx("img", { src: item.url, alt: item.name, className: "size-20 rounded-md border border-border object-cover" }) }), onRemove ? _jsx(Button, { variant: "outline", size: "compactIcon", "aria-label": `Remove ${item.name}`, onClick: () => onRemove(item.key), children: _jsx(Trash2, { "aria-hidden": "true", size: 16 }) }) : null] }, item.key)) });
|
|
30
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface CompoundSearchInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {
|
|
3
|
+
/** Display a character counter when maxLength is set. */
|
|
4
|
+
showCount?: boolean;
|
|
5
|
+
actions?: React.ReactNode;
|
|
6
|
+
criteria?: React.ReactNode;
|
|
7
|
+
selected?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare const CompoundSearchInput: React.ForwardRefExoticComponent<CompoundSearchInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
10
|
+
export { CompoundSearchInput };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { SearchIcon } from "lucide-react";
|
|
4
|
+
import { FieldCounter } from "./field-counter";
|
|
5
|
+
import { cn } from "./lib/utils";
|
|
6
|
+
const CompoundSearchInput = React.forwardRef(({ actions, showCount = false, value, defaultValue, onChange, "aria-invalid": ariaInvalid, className, criteria, selected = false, ...props }, ref) => {
|
|
7
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue !== null && defaultValue !== void 0 ? defaultValue : "");
|
|
8
|
+
const generatedId = React.useId();
|
|
9
|
+
const limitId = showCount && props.maxLength !== undefined ? `search-limit-${generatedId}` : undefined;
|
|
10
|
+
return (_jsxs("div", { className: "grid gap-2", children: [_jsxs("div", { "data-slot": "compound-search-input", "data-selected": selected ? "true" : "false", className: cn("flex min-h-12 w-full min-w-0 flex-wrap items-center gap-1.5 rounded-control border border-input bg-background p-1.5 transition-[border-color,box-shadow] focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50 data-[selected=true]:border-interactive data-[selected=true]:bg-highlight data-[selected=true]:ring-[3px] data-[selected=true]:ring-interactive/20", ariaInvalid === true || ariaInvalid === "true"
|
|
11
|
+
? "border-destructive ring-destructive/20"
|
|
12
|
+
: undefined), children: [_jsx(SearchIcon, { "aria-hidden": "true", className: "ml-1.5 h-4 w-4 shrink-0 text-muted-foreground" }), criteria, _jsx("input", { ref: ref, "aria-invalid": ariaInvalid, className: cn("h-8 min-w-44 basis-52 flex-1 bg-transparent px-1.5 text-sm outline-none placeholder:text-muted-foreground", className), ...props, "aria-describedby": [props["aria-describedby"], limitId].filter(Boolean).join(" ") || undefined, value: value, defaultValue: defaultValue, onChange: (event) => {
|
|
13
|
+
if (value === undefined)
|
|
14
|
+
setUncontrolledValue(event.target.value);
|
|
15
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(event);
|
|
16
|
+
} }), actions ? (_jsx("span", { className: "ml-auto inline-flex h-8 shrink-0 items-center gap-1 text-muted-foreground", children: actions })) : null] }), limitId && _jsx(FieldCounter, { id: limitId, count: String(value !== null && value !== void 0 ? value : uncontrolledValue).length, limit: props.maxLength })] }));
|
|
17
|
+
});
|
|
18
|
+
CompoundSearchInput.displayName = "CompoundSearchInput";
|
|
19
|
+
export { CompoundSearchInput };
|
package/dist/date-input.js
CHANGED
|
@@ -164,11 +164,11 @@ const DateInput = React.forwardRef((props, ref) => {
|
|
|
164
164
|
}
|
|
165
165
|
};
|
|
166
166
|
const disabledDays = (date) => isDateOutsideBounds(date, minDate, maxDate);
|
|
167
|
-
const calendarContent = (_jsx(_Fragment, { children: props.mode === "range" ? (_jsx(Calendar, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, defaultMonth: (_b = selectedRange === null || selectedRange === void 0 ? void 0 : selectedRange.from) !== null && _b !== void 0 ? _b : selectedRange === null || selectedRange === void 0 ? void 0 : selectedRange.to, numberOfMonths: (_c = props.numberOfMonths) !== null && _c !== void 0 ? _c : 2, showOutsideDays: false, autoFocus: true })) : (_jsx(Calendar, { mode: "single", selected: selectedDate, onSelect: handleSelect, disabled: disabledDays, defaultMonth: selectedDate, autoFocus: true })) }));
|
|
167
|
+
const calendarContent = (_jsx(_Fragment, { children: props.mode === "range" ? (_jsx(Calendar, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, defaultMonth: (_b = selectedRange === null || selectedRange === void 0 ? void 0 : selectedRange.from) !== null && _b !== void 0 ? _b : selectedRange === null || selectedRange === void 0 ? void 0 : selectedRange.to, numberOfMonths: (_c = props.numberOfMonths) !== null && _c !== void 0 ? _c : 2, showOutsideDays: false, className: "[&_.rdp-month:not(:first-of-type)]:hidden sm:[&_.rdp-month:not(:first-of-type)]:flex", autoFocus: true })) : (_jsx(Calendar, { mode: "single", selected: selectedDate, onSelect: handleSelect, disabled: disabledDays, defaultMonth: selectedDate, autoFocus: true })) }));
|
|
168
168
|
if (appearance === "inline") {
|
|
169
|
-
return (_jsxs("span", { className: cn("inline-flex", className), "data-disabled": disabled ? "true" : undefined, "data-invalid": isInvalid ? "true" : undefined, children: [_jsx(Popover, { open: open, onOpenChange: handleOpenChange, align: "start", title: popoverTitle, surface: popoverTitle ? "menu" : "panel", contentClassName: "w-auto p-0", trigger: _jsxs("button", { ref: ref, type: "button", id: inputId, disabled: disabled, "aria-invalid": isInvalid ? "true" : undefined, "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || undefined, className: cn("inline-flex cursor-pointer items-baseline rounded-sm border-0 bg-transparent p-0 font-medium text-interactive underline decoration-interactive/40 underline-offset-4 transition-colors hover:decoration-interactive focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50", !displayValue && "text-muted-foreground decoration-border", isInvalid && "text-destructive decoration-destructive", triggerClassName), children: [_jsxs("span", { className: "sr-only", children: [label, ": "] }), _jsx("span", { children: displayValue !== null && displayValue !== void 0 ? displayValue : placeholder })] }), children: calendarContent }), showDescription ? (_jsx("span", { id: descriptionId, className: "sr-only", children: description })) : null, error ? (_jsx("span", { id: errorId, role: "alert", className: "sr-only", children: error })) : null] }));
|
|
169
|
+
return (_jsxs("span", { className: cn("inline-flex", className), "data-disabled": disabled ? "true" : undefined, "data-invalid": isInvalid ? "true" : undefined, children: [_jsx(Popover, { open: open, onOpenChange: handleOpenChange, align: "start", title: popoverTitle, surface: popoverTitle ? "menu" : "panel", collisionPadding: 8, contentClassName: "max-h-[var(--radix-popover-content-available-height)] w-auto overflow-auto p-0 [&_[data-slot=popover-title]]:p-3", trigger: _jsxs("button", { ref: ref, type: "button", id: inputId, disabled: disabled, "aria-invalid": isInvalid ? "true" : undefined, "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || undefined, className: cn("inline-flex cursor-pointer items-baseline rounded-sm border-0 bg-transparent p-0 font-medium text-interactive underline decoration-interactive/40 underline-offset-4 transition-colors hover:decoration-interactive focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50", !displayValue && "text-muted-foreground decoration-border", isInvalid && "text-destructive decoration-destructive", triggerClassName), children: [_jsxs("span", { className: "sr-only", children: [label, ": "] }), _jsx("span", { children: displayValue !== null && displayValue !== void 0 ? displayValue : placeholder })] }), children: calendarContent }), showDescription ? (_jsx("span", { id: descriptionId, className: "sr-only", children: description })) : null, error ? (_jsx("span", { id: errorId, role: "alert", className: "sr-only", children: error })) : null] }));
|
|
170
170
|
}
|
|
171
|
-
return (_jsxs(Field, { className: className, "data-disabled": disabled ? "true" : undefined, "data-invalid": isInvalid ? "true" : undefined, children: [_jsx(FieldLabel, { htmlFor: inputId, className: cn(hideLabel && "sr-only", labelClassName), children: label }), _jsxs("div", { className: "relative", children: [_jsx(Popover, { open: open, onOpenChange: handleOpenChange, align: "start", title: popoverTitle, surface: popoverTitle ? "menu" : "panel", contentClassName: "w-auto p-0", trigger: _jsx("button", { ref: ref, type: "button", id: inputId, disabled: disabled, "aria-invalid": isInvalid ? "true" : undefined, "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || undefined, className: cn(inputControlClassName, "relative cursor-pointer pr-9 text-left", showClearButton && "pr-16", !displayValue && "text-muted-foreground", isInvalid && "border-destructive focus-visible:ring-destructive", triggerClassName), children: _jsx("span", { className: "block truncate", children: displayValue !== null && displayValue !== void 0 ? displayValue : placeholder }) }), children: calendarContent }), _jsxs("span", { "aria-hidden": showClearButton ? undefined : true, className: "pointer-events-none absolute inset-y-0 right-3 flex items-center gap-2 text-muted-foreground", children: [showClearButton ? (_jsx("button", { type: "button", "aria-label": resolvedClearLabel, onClick: handleClear, className: "pointer-events-auto inline-flex h-4 w-4 cursor-pointer items-center justify-center rounded-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:cursor-not-allowed", children: _jsx(XIcon, { size: 14, className: "flex items-center justify-center" }) })) : null, _jsx(CalendarIcon, { "aria-hidden": "true", className: "h-4 w-4 shrink-0", strokeWidth: 2 })] })] }), showDescription ? (_jsx(FieldDescription, { id: descriptionId, className: descriptionClassName, children: description })) : null, _jsx(FieldError, { id: errorId, className: errorClassName, children: error })] }));
|
|
171
|
+
return (_jsxs(Field, { className: className, "data-disabled": disabled ? "true" : undefined, "data-invalid": isInvalid ? "true" : undefined, children: [_jsx(FieldLabel, { htmlFor: inputId, className: cn(hideLabel && "sr-only", labelClassName), children: label }), _jsxs("div", { className: "relative", children: [_jsx(Popover, { open: open, onOpenChange: handleOpenChange, align: "start", title: popoverTitle, surface: popoverTitle ? "menu" : "panel", collisionPadding: 8, contentClassName: "max-h-[var(--radix-popover-content-available-height)] w-auto overflow-auto p-0 [&_[data-slot=popover-title]]:p-3", trigger: _jsx("button", { ref: ref, type: "button", id: inputId, disabled: disabled, "aria-invalid": isInvalid ? "true" : undefined, "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || undefined, className: cn(inputControlClassName, "relative cursor-pointer pr-9 text-left", showClearButton && "pr-16", !displayValue && "text-muted-foreground", isInvalid && "border-destructive focus-visible:ring-destructive", triggerClassName), children: _jsx("span", { className: "block truncate", children: displayValue !== null && displayValue !== void 0 ? displayValue : placeholder }) }), children: calendarContent }), _jsxs("span", { "aria-hidden": showClearButton ? undefined : true, className: "pointer-events-none absolute inset-y-0 right-3 flex items-center gap-2 text-muted-foreground", children: [showClearButton ? (_jsx("button", { type: "button", "aria-label": resolvedClearLabel, onClick: handleClear, className: "pointer-events-auto inline-flex h-4 w-4 cursor-pointer items-center justify-center rounded-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:cursor-not-allowed", children: _jsx(XIcon, { size: 14, className: "flex items-center justify-center" }) })) : null, _jsx(CalendarIcon, { "aria-hidden": "true", className: "h-4 w-4 shrink-0", strokeWidth: 2 })] })] }), showDescription ? (_jsx(FieldDescription, { id: descriptionId, className: descriptionClassName, children: description })) : null, _jsx(FieldError, { id: errorId, className: errorClassName, children: error })] }));
|
|
172
172
|
});
|
|
173
173
|
DateInput.displayName = "DateInput";
|
|
174
174
|
export { DateInput };
|
package/dist/dialog.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export interface DialogAction extends Omit<ButtonProps, "children"> {
|
|
|
9
9
|
}
|
|
10
10
|
type DialogRenderable = React.ReactNode | ((helpers: DialogRenderHelpers) => React.ReactNode);
|
|
11
11
|
export interface DialogProps {
|
|
12
|
+
variant?: "default" | "confirmation";
|
|
12
13
|
open?: boolean;
|
|
13
14
|
defaultOpen?: boolean;
|
|
14
15
|
onOpenChange?: (open: boolean) => void;
|
|
@@ -23,6 +24,8 @@ export interface DialogProps {
|
|
|
23
24
|
contentClassName?: string;
|
|
24
25
|
bodyClassName?: string;
|
|
25
26
|
hideCloseButton?: boolean;
|
|
27
|
+
/** Whether a pointer interaction outside the dialog closes it. */
|
|
28
|
+
closeOnOutsideClick?: boolean;
|
|
26
29
|
}
|
|
27
|
-
declare function Dialog({ open, defaultOpen, onOpenChange, modal, trigger, title, description, children, footer, primaryAction, secondaryAction, contentClassName, bodyClassName, hideCloseButton, }: DialogProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
declare function Dialog({ variant, open, defaultOpen, onOpenChange, modal, trigger, title, description, children, footer, primaryAction, secondaryAction, contentClassName, bodyClassName, hideCloseButton, closeOnOutsideClick, }: DialogProps): import("react/jsx-runtime").JSX.Element;
|
|
28
31
|
export { Dialog };
|
package/dist/dialog.js
CHANGED
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { Button } from "./button";
|
|
5
5
|
import { DialogDescription, DialogFooter, DialogHeader, DialogRoot, DialogSurface, DialogTitle, DialogTrigger, } from "./dialog-primitive";
|
|
6
|
+
import { CircleAlert } from "lucide-react";
|
|
6
7
|
import { cn } from "./lib/utils";
|
|
7
8
|
function useControllableOpen({ open, defaultOpen, onOpenChange, }) {
|
|
8
9
|
const [internalOpen, setInternalOpen] = React.useState(defaultOpen !== null && defaultOpen !== void 0 ? defaultOpen : false);
|
|
@@ -31,7 +32,7 @@ function renderDialogAction({ action, close, defaultVariant, }) {
|
|
|
31
32
|
}
|
|
32
33
|
}, children: label }));
|
|
33
34
|
}
|
|
34
|
-
function Dialog({ open, defaultOpen, onOpenChange, modal, trigger, title, description, children, footer, primaryAction, secondaryAction, contentClassName, bodyClassName, hideCloseButton, }) {
|
|
35
|
+
function Dialog({ variant = "default", open, defaultOpen, onOpenChange, modal, trigger, title, description, children, footer, primaryAction, secondaryAction, contentClassName, bodyClassName, hideCloseButton = false, closeOnOutsideClick = false, }) {
|
|
35
36
|
const [isOpen, setIsOpen] = useControllableOpen({
|
|
36
37
|
open,
|
|
37
38
|
defaultOpen,
|
|
@@ -43,7 +44,11 @@ function Dialog({ open, defaultOpen, onOpenChange, modal, trigger, title, descri
|
|
|
43
44
|
const body = resolveDialogRenderable(children, helpers);
|
|
44
45
|
const customFooter = resolveDialogRenderable(footer, helpers);
|
|
45
46
|
const hasFooter = Boolean(customFooter || primaryAction || secondaryAction);
|
|
46
|
-
return (_jsxs(DialogRoot, { open: isOpen, onOpenChange: setIsOpen, modal: modal, children: [trigger ? _jsx(DialogTrigger, { asChild: true, children: trigger }) : null, _jsxs(DialogSurface, {
|
|
47
|
+
return (_jsxs(DialogRoot, { open: isOpen, onOpenChange: setIsOpen, modal: modal, children: [trigger ? _jsx(DialogTrigger, { asChild: true, children: trigger }) : null, _jsxs(DialogSurface, { ...(!description ? { "aria-describedby": undefined } : {}), className: cn(variant === "confirmation" && "max-w-sm gap-0 overflow-hidden rounded-xl p-0", contentClassName), hideCloseButton: hideCloseButton || variant === "confirmation", onPointerDownOutside: (event) => {
|
|
48
|
+
if (!closeOnOutsideClick) {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
}
|
|
51
|
+
}, children: [_jsxs("div", { className: cn(variant === "confirmation" && "flex items-start gap-4 p-4"), children: [variant === "confirmation" ? _jsx("div", { className: "rounded-lg bg-muted p-2", children: _jsx(CircleAlert, { "aria-hidden": "true", className: "size-6" }) }) : null, _jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: title }), description ? _jsx(DialogDescription, { children: description }) : null] })] }), body ? _jsx("div", { className: cn("grid gap-4", bodyClassName), children: body }) : null, hasFooter ? (_jsx(DialogFooter, { className: variant === "confirmation" ? "border-t bg-muted/30 p-4" : undefined, children: customFooter !== null && customFooter !== void 0 ? customFooter : (_jsxs(_Fragment, { children: [secondaryAction
|
|
47
52
|
? renderDialogAction({
|
|
48
53
|
action: secondaryAction,
|
|
49
54
|
close: helpers.close,
|
package/dist/draggable-tabs.js
CHANGED
|
@@ -3,12 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, } from "@dnd-kit/core";
|
|
4
4
|
import { SortableContext, horizontalListSortingStrategy, sortableKeyboardCoordinates, useSortable, } from "@dnd-kit/sortable";
|
|
5
5
|
import { CSS } from "@dnd-kit/utilities";
|
|
6
|
+
import { GripVertical } from "lucide-react";
|
|
6
7
|
import { XIcon } from "./animated-icons/x";
|
|
7
8
|
import { Badge } from "./badge";
|
|
8
9
|
import { GuidanceTip } from "./guidance-tip";
|
|
9
10
|
import { cn } from "./lib/utils";
|
|
10
11
|
import { Tooltip } from "./tooltip";
|
|
11
|
-
function TabButton({ item, dragHandleProps, }) {
|
|
12
|
+
function TabButton({ item, dragHandleProps, showDivider = false, }) {
|
|
12
13
|
var _a, _b, _c;
|
|
13
14
|
const isDraggable = Boolean(dragHandleProps);
|
|
14
15
|
const labelClassName = item.labelClassName
|
|
@@ -16,17 +17,17 @@ function TabButton({ item, dragHandleProps, }) {
|
|
|
16
17
|
: item.active
|
|
17
18
|
? "text-foreground"
|
|
18
19
|
: "text-muted-foreground hover:text-foreground";
|
|
19
|
-
const content = (_jsxs("div", { className: cn("group flex items-center gap-1.5 border-b-
|
|
20
|
+
const content = (_jsxs("div", { className: cn("group/draggable-tab relative -mb-px flex items-center gap-1.5 border-b-[3px] px-2.5 transition-colors select-none", item.disabled
|
|
20
21
|
? "cursor-not-allowed opacity-50"
|
|
21
22
|
: isDraggable
|
|
22
23
|
? "cursor-grab active:cursor-grabbing"
|
|
23
24
|
: "cursor-pointer", item.active
|
|
24
25
|
? (_a = item.activeClassName) !== null && _a !== void 0 ? _a : "border-[hsl(var(--tab-indicator))] bg-transparent hover:bg-transparent"
|
|
25
|
-
: (_b = item.inactiveClassName) !== null && _b !== void 0 ? _b : "border-transparent hover:bg-[hsl(var(--tab-trigger-hover-background))]", item.className), ...dragHandleProps, children: [_jsxs("button", { type: "button", onClick: item.disabled ? undefined : item.onSelect, disabled: item.disabled, className: cn("flex cursor-pointer items-center gap-1.5 py-2 pr-1 text-sm font-medium whitespace-nowrap disabled:cursor-not-allowed", labelClassName), children: [item.badge ? (_jsx(Badge, { variant: item.badge.variant, bordered: item.badge.bordered, size: "icon", children: item.badge.label })) : null, item.leading, item.label, item.trailing] }), item.onClose ? (_jsx("button", { type: "button", onClick: (event) => {
|
|
26
|
+
: (_b = item.inactiveClassName) !== null && _b !== void 0 ? _b : "border-transparent hover:bg-[hsl(var(--tab-trigger-hover-background))]", item.className), ...dragHandleProps, children: [isDraggable ? (_jsx("span", { "data-slot": "draggable-tab-grip", "aria-hidden": "true", className: "pointer-events-none absolute left-0 top-1/2 z-10 inline-flex h-5 w-4 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity group-hover/draggable-tab:opacity-100 group-has-[:focus-visible]/draggable-tab:opacity-100", children: _jsx(GripVertical, { className: "h-3 w-3" }) })) : null, _jsxs("button", { type: "button", onClick: item.disabled ? undefined : item.onSelect, disabled: item.disabled, className: cn("flex cursor-pointer items-center gap-1.5 py-2 pr-1 text-sm font-medium whitespace-nowrap disabled:cursor-not-allowed", labelClassName), children: [item.badge ? (_jsx(Badge, { variant: item.badge.variant, bordered: item.badge.bordered, size: "icon", children: item.badge.label })) : null, item.leading, item.label, item.trailing] }), item.onClose ? (_jsx("button", { type: "button", onClick: (event) => {
|
|
26
27
|
var _a;
|
|
27
28
|
event.stopPropagation();
|
|
28
29
|
(_a = item.onClose) === null || _a === void 0 ? void 0 : _a.call(item);
|
|
29
|
-
}, className: cn("cursor-pointer rounded p-1 text-muted-foreground hover:text-foreground", item.closeButtonClassName), "aria-label": "Close tab", children: _jsx(XIcon, { size: 12 }) })) : null] }));
|
|
30
|
+
}, className: cn("cursor-pointer rounded p-1 text-muted-foreground hover:text-foreground", item.closeButtonClassName), "aria-label": "Close tab", children: _jsx(XIcon, { size: 12 }) })) : null, showDivider ? (_jsx("span", { "data-slot": "draggable-tab-divider", "aria-hidden": "true", className: "pointer-events-none absolute -right-0.5 top-1/2 h-4 w-px -translate-y-1/2 bg-[hsl(var(--layout-surface-border))]" })) : null] }));
|
|
30
31
|
if (item.guidance) {
|
|
31
32
|
return _jsx(GuidanceTip, { ...item.guidance, trigger: content });
|
|
32
33
|
}
|
|
@@ -35,13 +36,13 @@ function TabButton({ item, dragHandleProps, }) {
|
|
|
35
36
|
}
|
|
36
37
|
return (_jsx(Tooltip, { content: item.tooltip, side: (_c = item.tooltipSide) !== null && _c !== void 0 ? _c : "bottom", contentClassName: item.tooltipContentClassName, children: content }));
|
|
37
38
|
}
|
|
38
|
-
function SortableTab({ item }) {
|
|
39
|
-
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: item.id });
|
|
39
|
+
function SortableTab({ item, showDivider, }) {
|
|
40
|
+
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: item.id, disabled: item.disabled });
|
|
40
41
|
return (_jsx("div", { ref: setNodeRef, style: {
|
|
41
42
|
transform: CSS.Transform.toString(transform),
|
|
42
43
|
transition,
|
|
43
44
|
zIndex: isDragging ? 50 : undefined,
|
|
44
|
-
}, className: cn(isDragging && "opacity-50 shadow-lg"), children: _jsx(TabButton, { item: item, dragHandleProps: { ...attributes, ...listeners } }) }));
|
|
45
|
+
}, className: cn(isDragging && "opacity-50 shadow-lg"), children: _jsx(TabButton, { item: item, showDivider: showDivider, dragHandleProps: item.disabled ? undefined : { ...attributes, ...listeners } }) }));
|
|
45
46
|
}
|
|
46
47
|
function DraggableTabs({ staticTabs = [], tabs, onReorder, className, ...props }) {
|
|
47
48
|
const sensors = useSensors(useSensor(PointerSensor, {
|
|
@@ -61,6 +62,6 @@ function DraggableTabs({ staticTabs = [], tabs, onReorder, className, ...props }
|
|
|
61
62
|
onReorder(oldIndex, newIndex);
|
|
62
63
|
}
|
|
63
64
|
};
|
|
64
|
-
return (_jsxs("div", { "data-slot": "draggable-tabs", className: cn("flex items-end gap-1 border-b overflow-x-auto overflow-y-hidden bg-transparent", "border-[hsl(var(--layout-surface-border))]", className), ...props, children: [staticTabs.map((tab) => (_jsx(TabButton, { item: tab }, tab.id))), _jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: tabs.map((tab) => tab.id), strategy: horizontalListSortingStrategy, children: tabs.map((tab) => (_jsx(SortableTab, { item: tab }, tab.id))) }) })] }));
|
|
65
|
+
return (_jsxs("div", { "data-slot": "draggable-tabs", className: cn("flex items-end gap-1 border-b overflow-x-auto overflow-y-hidden bg-transparent", "border-[hsl(var(--layout-surface-border))]", className), ...props, children: [staticTabs.map((tab, index) => (_jsx(TabButton, { item: tab, showDivider: index < staticTabs.length - 1 || tabs.length > 0 }, tab.id))), _jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: tabs.map((tab) => tab.id), strategy: horizontalListSortingStrategy, children: tabs.map((tab, index) => (_jsx(SortableTab, { item: tab, showDivider: index < tabs.length - 1 }, tab.id))) }) })] }));
|
|
65
66
|
}
|
|
66
67
|
export { DraggableTabs };
|
package/dist/dropdown-button.js
CHANGED
|
@@ -8,6 +8,7 @@ import { cn } from "./lib/utils";
|
|
|
8
8
|
const splitButtonDividerClassNames = {
|
|
9
9
|
default: "before:bg-button-primary-foreground/30",
|
|
10
10
|
destructive: "before:bg-destructive-foreground/30",
|
|
11
|
+
warning: "before:bg-[hsl(var(--status-warning-foreground))]/30",
|
|
11
12
|
outline: "before:bg-[hsl(var(--button-outline-border))]",
|
|
12
13
|
secondary: "before:bg-secondary-foreground/20",
|
|
13
14
|
ghost: "before:bg-border",
|
package/dist/editable-table.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { Button } from "./button";
|
|
4
|
-
import {
|
|
4
|
+
import { TableAddRow } from "./table-add-row";
|
|
5
5
|
import { TrashIcon } from "./animated-icons/trash";
|
|
6
6
|
import { Checkbox } from "./checkbox";
|
|
7
7
|
import { EmptyState } from "./empty-state";
|
|
@@ -145,7 +145,7 @@ function EditableTable({ value, onChange, columns, isEditing = false, className,
|
|
|
145
145
|
insertRow: (nextRow, index = rowIndex + 1) => handleInsertRow(nextRow, index),
|
|
146
146
|
removeRow: () => handleDeleteRow(rowIndex),
|
|
147
147
|
})
|
|
148
|
-
: null, isEditing ? (_jsx(Button, { type: "button", variant: "ghost", size: "compactIcon", className: "text-muted-foreground hover:bg-destructive/10 hover:text-destructive focus-visible:text-destructive", onClick: () => handleDeleteRow(rowIndex), "aria-label": `Delete row ${rowIndex + 1}`, children: _jsx(TrashIcon, { size: 16 }) })) : null] }) })) : null] }, `row-${rowIndex}`)))) })] }) }), isEditing ? (
|
|
148
|
+
: null, isEditing ? (_jsx(Button, { type: "button", variant: "ghost", size: "compactIcon", className: "text-muted-foreground hover:bg-destructive/10 hover:text-destructive focus-visible:text-destructive", onClick: () => handleDeleteRow(rowIndex), "aria-label": `Delete row ${rowIndex + 1}`, children: _jsx(TrashIcon, { size: 16 }) })) : null] }) })) : null] }, `row-${rowIndex}`)))) })] }) }), isEditing ? (_jsx(TableAddRow, { onClick: handleAddRow, children: addRowLabel })) : null] }));
|
|
149
149
|
}
|
|
150
150
|
EditableTable.displayName = "EditableTable";
|
|
151
151
|
export { EditableTable };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/** Internal shared presentation for field length counters. */
|
|
3
|
+
export function FieldCounter({ id, count, limit, unit = "characters" }) {
|
|
4
|
+
return (_jsxs("div", { "data-slot": "field-counter", className: "flex items-start justify-between gap-3 text-sm text-muted-foreground", children: [_jsxs("span", { id: id, className: "sr-only", children: ["Maximum ", limit, " ", unit] }), _jsxs("span", { className: "ml-auto shrink-0 tabular-nums", "aria-live": "polite", "aria-atomic": "true", "aria-label": `${count} of ${limit} ${unit}`, children: [count, " / ", limit] })] }));
|
|
5
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,16 +7,24 @@ export { Alert, AlertAction, AlertConsent, alertVariants, } from "./alert";
|
|
|
7
7
|
export type { AlertActionProps, AlertConsentProps, AlertProps, } from "./alert";
|
|
8
8
|
export { AlertStack } from "./alert-stack";
|
|
9
9
|
export type { AlertStackProps } from "./alert-stack";
|
|
10
|
+
export { ActivityCard, ActivityCardActor, ActivityCardContent, } from "./activity-card";
|
|
11
|
+
export type { ActivityCardActorProps, ActivityCardContentProps, ActivityCardDensity, ActivityCardIconTone, ActivityCardProps, } from "./activity-card";
|
|
12
|
+
export { ChangelogActionPanel } from "./changelog-action-panel";
|
|
13
|
+
export type { ChangelogActionPanelProps } from "./changelog-action-panel";
|
|
10
14
|
export { Badge, badgeVariants } from "./badge";
|
|
11
15
|
export { Card, CardGrid, CardSplitGrid, CardList, CardListItem, } from "./card";
|
|
12
16
|
export type { CardGridProps, CardListItemProps, CardListProps, CardProps, CardSplitGridProps, } from "./card";
|
|
13
17
|
export type { BadgeProps } from "./badge";
|
|
14
|
-
export { MessageAttachmentRow, MessageItem, MessageNewDivider, MessageThread, formatMessageDate, } from "./message-item";
|
|
18
|
+
export { MessageAttachmentRow, MessageItem, MessageNewDivider, MessageThread, formatMessageCardTimestamp, formatMessageDate, } from "./message-item";
|
|
15
19
|
export type { MessageAttachmentRowProps, MessageItemAttachment, MessageItemData, MessageItemProps, MessageNewDividerProps, MessageThreadProps, } from "./message-item";
|
|
20
|
+
export { MessageActionPanel } from "./message-action-panel";
|
|
21
|
+
export type { MessageActionPanelProps } from "./message-action-panel";
|
|
16
22
|
export { formatNotificationTimestamp, NotificationItem, NotificationList, NotificationPopover, NotificationTrigger, } from "./notification";
|
|
17
23
|
export type { NotificationAction, NotificationFilter, NotificationIcon, NotificationItemData, NotificationItemProps, NotificationKind, NotificationListProps, NotificationPopoverProps, NotificationTimestamp, NotificationTriggerProps, NotificationTone, FormatNotificationTimestampOptions, } from "./notification";
|
|
18
24
|
export { RoutingTimeline } from "./routing-timeline";
|
|
19
25
|
export type { RoutingTimelineItem, RoutingTimelineItemKind, RoutingTimelineProps, } from "./routing-timeline";
|
|
26
|
+
export { RoutingActionPanel } from "./routing-action-panel";
|
|
27
|
+
export type { RoutingActionPanelProps } from "./routing-action-panel";
|
|
20
28
|
export { RichTextEditor, formatFileSize, replaceTemplateVariables, sanitizeRichTextHtml, } from "./rich-text-editor";
|
|
21
29
|
export type { AttachmentFile, RichTextEditorColor, RichTextEditorProps, RichTextEditorSendAction, RichTextEditorSendMetadata, RichTextEditorTemplate, TemplateContext, } from "./rich-text-editor";
|
|
22
30
|
export { Calendar, CalendarDayButton } from "./calendar";
|
|
@@ -30,6 +38,8 @@ export { DateInput } from "./date-input";
|
|
|
30
38
|
export type { DateInputProps, DateInputRangeProps, DateInputSingleProps, DateRangeInputValue, } from "./date-input";
|
|
31
39
|
export { CountBadge } from "./count-badge";
|
|
32
40
|
export type { CountBadgeProps } from "./count-badge";
|
|
41
|
+
export { StatusDot } from "./status-dot";
|
|
42
|
+
export type { StatusDotProps, StatusDotSize, StatusDotVariant, } from "./status-dot";
|
|
33
43
|
export { EmptyState } from "./empty-state";
|
|
34
44
|
export type { EmptyStateProps } from "./empty-state";
|
|
35
45
|
export { EditableTable } from "./editable-table";
|
|
@@ -90,6 +100,10 @@ export { PopoverMenuContent, PopoverMenuCheckboxItem, PopoverMenuHeader, Popover
|
|
|
90
100
|
export type { PopoverMenuContentProps, PopoverMenuCheckboxItemProps, PopoverMenuHeaderProps, PopoverMenuSectionProps, PopoverMenuItemProps, PopoverMenuDividerProps, PopoverMenuFooterActionProps, PopoverMenuFooterMetaProps, PopoverMenuFooterProps, PopoverMenuGroupProps, PopoverMenuGroupLabelProps, PopoverMenuSearchProps, PopoverMenuScrollAreaProps, PopoverMenuViewProps, } from "./popover-menu";
|
|
91
101
|
export { SearchInput } from "./search-input";
|
|
92
102
|
export type { SearchInputProps } from "./search-input";
|
|
103
|
+
export { CompoundSearchInput } from "./compound-search-input";
|
|
104
|
+
export type { CompoundSearchInputProps } from "./compound-search-input";
|
|
105
|
+
export { Autocomplete, AutocompleteOptions, AutocompletePopover, useAutocompleteController, } from "./autocomplete";
|
|
106
|
+
export type { AutocompleteController, AutocompleteControllerOptions, AutocompleteOption, AutocompleteOptionGroup, AutocompleteOptionRenderState, AutocompleteOptionsProps, AutocompletePopoverProps, AutocompleteProps, AutocompleteStateContent, } from "./autocomplete";
|
|
93
107
|
export { SectionNav } from "./section-nav";
|
|
94
108
|
export type { SectionNavItem, SectionNavProps } from "./section-nav";
|
|
95
109
|
export { GovtMasthead } from "./govt-masthead";
|
|
@@ -111,8 +125,8 @@ export type { TextareaProps } from "./textarea";
|
|
|
111
125
|
export { DraggableTabs, type DraggableTabBadge, type DraggableTabGuidance, type DraggableTabItem, type DraggableTabsProps, } from "./draggable-tabs";
|
|
112
126
|
export { Drawer, } from "./drawer";
|
|
113
127
|
export type { DrawerAction, DrawerProps, DrawerSide } from "./drawer";
|
|
114
|
-
export { DashboardContent, DashboardLayout, DashboardRightPanel, DashboardRightPanelBody, DashboardRightPanelHeader, DashboardRightPanelSection, DashboardRightPanelTabs, DashboardSidebar, DashboardSidebarProfile, DashboardSidebarProfilePopover, SidebarProvider, useSidebar, } from "./layout";
|
|
115
|
-
export type { DashboardContentProps, DashboardLayoutProps, DashboardRightPanelBodyProps, DashboardRightPanelHeaderProps, DashboardRightPanelMode, DashboardRightPanelProps, DashboardRightPanelSectionProps, DashboardRightPanelTabsProps, DashboardSidebarNavDropdownItem, DashboardSidebarNavGroup, DashboardSidebarNavItem, DashboardSidebarNavLinkItem, DashboardSidebarProfileProps, DashboardSidebarProfilePopoverProps, } from "./layout";
|
|
128
|
+
export { DashboardActionPanel, DashboardActionPanelEmptyState, DashboardContent, DashboardLayout, DashboardRightPanel, DashboardRightPanelBody, DashboardRightPanelHeader, DashboardRightPanelSection, DashboardRightPanelTabs, DashboardSidebar, DashboardSidebarProfile, DashboardSidebarProfilePopover, SidebarProvider, useSidebar, } from "./layout";
|
|
129
|
+
export type { DashboardActionPanelProps, DashboardActionPanelEmptyStateProps, DashboardContentProps, DashboardLayoutProps, DashboardRightPanelBodyProps, DashboardRightPanelHeaderProps, DashboardRightPanelMode, DashboardRightPanelProps, DashboardRightPanelSectionProps, DashboardRightPanelTabsProps, DashboardSidebarNavDropdownItem, DashboardSidebarNavGroup, DashboardSidebarNavItem, DashboardSidebarNavLinkItem, DashboardSidebarProfileProps, DashboardSidebarProfilePopoverProps, } from "./layout";
|
|
116
130
|
export { PageHeader } from "./page-header";
|
|
117
131
|
export { PageLayout, PageLayoutContext, PageLayoutControls, PageLayoutHeader, PageLayoutSection, PageLayoutStack, PageLayoutTitle, pageLayoutGapClassNames, pageLayoutStackGapClassNames, } from "./page-layout";
|
|
118
132
|
export type { PageLayoutGap, PageLayoutProps, PageLayoutStackGap, PageLayoutStackProps, PageLayoutTitleProps, } from "./page-layout";
|
|
@@ -134,7 +148,7 @@ export type { TableColumnVisibilityMenuProps } from "./table-column-visibility";
|
|
|
134
148
|
export { useTableSort } from "./use-table-sort";
|
|
135
149
|
export type { UseTableSortOptions, UseTableSortReturn, } from "./use-table-sort";
|
|
136
150
|
export { Table, TableRoot, TableContainer, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableRowHeader, TableCaption, TableRowSkeleton, TABLE_SKELETON_PRESETS, } from "./table";
|
|
137
|
-
export type { TableColumn, TableColumnWidths, TableProps, TableResizeMode, TableRowExpansionProps, TableRowTone, TableSortDirection, TableSortingProps, TableSkeletonConfig, TableRowSkeletonProps, } from "./table";
|
|
151
|
+
export type { TableColumn, TableColumnWidths, TableProps, TableResizeMode, TableRowExpansionProps, TableRowIndicatorProps, TableRowTone, TableSortDirection, TableSortingProps, TableSkeletonConfig, TableRowSkeletonProps, } from "./table";
|
|
138
152
|
export type { TableColumnFilter, TableColumnFilterOption, TableDateColumnFilter, TableDateRangeColumnFilter, TableOptionsColumnFilter, TableTextColumnFilter, } from "./table-column-filter";
|
|
139
153
|
export { Tabs, SubTabs, TabsRoot, TabWithDropdown, type TabsItem, type TabsItemLabel, type TabsItemLabelProps, type TabsProps, type SubTabsItem, type SubTabsProps, TabsList, TabsTrigger, TabsContent, type TabWithDropdownProps, useTabsContext, type TabDropdownSection, } from "./tabs";
|
|
140
154
|
export { Tooltip, TooltipRoot, TooltipTrigger, TooltipContent, TooltipProvider, type TooltipProps, } from "./tooltip";
|
|
@@ -153,3 +167,7 @@ export type { CollapsibleProps } from "./collapsible";
|
|
|
153
167
|
export { cn } from "./lib/utils";
|
|
154
168
|
export { parseDateTime, formatDateTime } from "./lib/date-utils";
|
|
155
169
|
export type { ParseDateTimeOptions } from "./lib/date-utils";
|
|
170
|
+
export { ChecklistAttachments, ChecklistPanel, ChecklistSection, ChecklistSelection, ChecklistQuestion } from "./checklist";
|
|
171
|
+
export type { ChecklistAttachmentsProps, ChecklistPanelProps, ChecklistSectionProps, ChecklistSelectionProps, ChecklistQuestionProps, ChecklistQuestionOption } from "./checklist";
|
|
172
|
+
export { TableAddRow, type TableAddRowProps } from "./table-add-row";
|
|
173
|
+
export { PopoverList, type PopoverListProps } from "./popover";
|
package/dist/index.js
CHANGED
|
@@ -3,11 +3,15 @@ export { AvatarProfilePopover, AvatarProfilePopoverContent, AvatarProfilePopover
|
|
|
3
3
|
export * from "./animated-icons";
|
|
4
4
|
export { Alert, AlertAction, AlertConsent, alertVariants, } from "./alert";
|
|
5
5
|
export { AlertStack } from "./alert-stack";
|
|
6
|
+
export { ActivityCard, ActivityCardActor, ActivityCardContent, } from "./activity-card";
|
|
7
|
+
export { ChangelogActionPanel } from "./changelog-action-panel";
|
|
6
8
|
export { Badge, badgeVariants } from "./badge";
|
|
7
9
|
export { Card, CardGrid, CardSplitGrid, CardList, CardListItem, } from "./card";
|
|
8
|
-
export { MessageAttachmentRow, MessageItem, MessageNewDivider, MessageThread, formatMessageDate, } from "./message-item";
|
|
10
|
+
export { MessageAttachmentRow, MessageItem, MessageNewDivider, MessageThread, formatMessageCardTimestamp, formatMessageDate, } from "./message-item";
|
|
11
|
+
export { MessageActionPanel } from "./message-action-panel";
|
|
9
12
|
export { formatNotificationTimestamp, NotificationItem, NotificationList, NotificationPopover, NotificationTrigger, } from "./notification";
|
|
10
13
|
export { RoutingTimeline } from "./routing-timeline";
|
|
14
|
+
export { RoutingActionPanel } from "./routing-action-panel";
|
|
11
15
|
export { RichTextEditor, formatFileSize, replaceTemplateVariables, sanitizeRichTextHtml, } from "./rich-text-editor";
|
|
12
16
|
export { Calendar, CalendarDayButton } from "./calendar";
|
|
13
17
|
export { Checkbox } from "./checkbox";
|
|
@@ -15,6 +19,7 @@ export { Switch } from "./switch";
|
|
|
15
19
|
export { ThemeSwitcher } from "./theme-switcher";
|
|
16
20
|
export { DateInput } from "./date-input";
|
|
17
21
|
export { CountBadge } from "./count-badge";
|
|
22
|
+
export { StatusDot } from "./status-dot";
|
|
18
23
|
export { EmptyState } from "./empty-state";
|
|
19
24
|
export { EditableTable } from "./editable-table";
|
|
20
25
|
export { EditButton } from "./edit-button";
|
|
@@ -46,6 +51,8 @@ export { useFileUpload } from "./use-file-upload";
|
|
|
46
51
|
export { Popover, PopoverTitle } from "./popover";
|
|
47
52
|
export { PopoverMenuContent, PopoverMenuCheckboxItem, PopoverMenuHeader, PopoverMenuSection, PopoverMenuItem, PopoverMenuDivider, PopoverMenuFooter, PopoverMenuFooterAction, PopoverMenuFooterMeta, PopoverMenuGroup, PopoverMenuGroupLabel, PopoverMenuSearch, PopoverMenuScrollArea, PopoverMenuView, } from "./popover-menu";
|
|
48
53
|
export { SearchInput } from "./search-input";
|
|
54
|
+
export { CompoundSearchInput } from "./compound-search-input";
|
|
55
|
+
export { Autocomplete, AutocompleteOptions, AutocompletePopover, useAutocompleteController, } from "./autocomplete";
|
|
49
56
|
export { SectionNav } from "./section-nav";
|
|
50
57
|
export { GovtMasthead } from "./govt-masthead";
|
|
51
58
|
export { GuidanceTip } from "./guidance-tip";
|
|
@@ -57,7 +64,7 @@ export { useViewportThreshold } from "./use-viewport-threshold";
|
|
|
57
64
|
export { Textarea } from "./textarea";
|
|
58
65
|
export { DraggableTabs, } from "./draggable-tabs";
|
|
59
66
|
export { Drawer, } from "./drawer";
|
|
60
|
-
export { DashboardContent, DashboardLayout, DashboardRightPanel, DashboardRightPanelBody, DashboardRightPanelHeader, DashboardRightPanelSection, DashboardRightPanelTabs, DashboardSidebar, DashboardSidebarProfile, DashboardSidebarProfilePopover, SidebarProvider, useSidebar, } from "./layout";
|
|
67
|
+
export { DashboardActionPanel, DashboardActionPanelEmptyState, DashboardContent, DashboardLayout, DashboardRightPanel, DashboardRightPanelBody, DashboardRightPanelHeader, DashboardRightPanelSection, DashboardRightPanelTabs, DashboardSidebar, DashboardSidebarProfile, DashboardSidebarProfilePopover, SidebarProvider, useSidebar, } from "./layout";
|
|
61
68
|
export { PageHeader } from "./page-header";
|
|
62
69
|
export { PageLayout, PageLayoutContext, PageLayoutControls, PageLayoutHeader, PageLayoutSection, PageLayoutStack, PageLayoutTitle, pageLayoutGapClassNames, pageLayoutStackGapClassNames, } from "./page-layout";
|
|
63
70
|
export { WorkspaceHeader } from "./workspace-header";
|
|
@@ -80,3 +87,6 @@ export { Spinner, PageLoader, FullPageLoader } from "./spinner";
|
|
|
80
87
|
export { Collapsible, CollapsibleSection } from "./collapsible";
|
|
81
88
|
export { cn } from "./lib/utils";
|
|
82
89
|
export { parseDateTime, formatDateTime } from "./lib/date-utils";
|
|
90
|
+
export { ChecklistAttachments, ChecklistPanel, ChecklistSection, ChecklistSelection, ChecklistQuestion } from "./checklist";
|
|
91
|
+
export { TableAddRow } from "./table-add-row";
|
|
92
|
+
export { PopoverList } from "./popover";
|
package/dist/input.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { InputControl } from "./input-control";
|
|
3
3
|
export interface InputProps extends Omit<React.ComponentProps<typeof InputControl>, "className"> {
|
|
4
|
+
/** Display a character counter when maxLength is set. */
|
|
5
|
+
showCount?: boolean;
|
|
4
6
|
label: React.ReactNode;
|
|
5
7
|
description?: React.ReactNode;
|
|
6
8
|
error?: React.ReactNode;
|
package/dist/input.js
CHANGED
|
@@ -2,10 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { Field, FieldDescription, FieldError, FieldLabel } from "./field";
|
|
4
4
|
import { InputControl } from "./input-control";
|
|
5
|
+
import { FieldCounter } from "./field-counter";
|
|
5
6
|
import { cn } from "./lib/utils";
|
|
6
|
-
const Input = React.forwardRef(({ label, description, error, invalid = false, hideLabel = false, className, inputClassName, labelClassName, descriptionClassName, errorClassName, id, disabled, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, required, ...props }, ref) => {
|
|
7
|
+
const Input = React.forwardRef(({ label, showCount = false, value, defaultValue, onChange, description, error, invalid = false, hideLabel = false, className, inputClassName, labelClassName, descriptionClassName, errorClassName, id, disabled, "aria-invalid": ariaInvalid, "aria-describedby": ariaDescribedBy, required, ...props }, ref) => {
|
|
8
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue !== null && defaultValue !== void 0 ? defaultValue : "");
|
|
9
|
+
const count = String(value !== null && value !== void 0 ? value : uncontrolledValue).length;
|
|
7
10
|
const generatedId = React.useId();
|
|
8
11
|
const inputId = id !== null && id !== void 0 ? id : `input-${generatedId}`;
|
|
12
|
+
const limitId = showCount && props.maxLength !== undefined ? `${inputId}-limit` : undefined;
|
|
9
13
|
const errorId = error ? `${inputId}-error` : undefined;
|
|
10
14
|
const showDescription = Boolean(description) && !error;
|
|
11
15
|
const descriptionId = showDescription ? `${inputId}-description` : undefined;
|
|
@@ -13,10 +17,14 @@ const Input = React.forwardRef(({ label, description, error, invalid = false, hi
|
|
|
13
17
|
ariaInvalid === true ||
|
|
14
18
|
ariaInvalid === "true" ||
|
|
15
19
|
Boolean(error);
|
|
16
|
-
const describedBy = [ariaDescribedBy, descriptionId, errorId]
|
|
20
|
+
const describedBy = [ariaDescribedBy, descriptionId, errorId, limitId]
|
|
17
21
|
.filter(Boolean)
|
|
18
22
|
.join(" ") || undefined;
|
|
19
|
-
return (_jsxs(Field, { className: className, "data-disabled": disabled ? "true" : undefined, "data-invalid": isInvalid ? "true" : undefined, children: [_jsx(FieldLabel, { htmlFor: inputId, required: required, className: cn(hideLabel && "sr-only", labelClassName), children: label }), _jsx(InputControl, { ref: ref, id: inputId, disabled: disabled, required: required, "aria-invalid": isInvalid ? "true" : undefined, "aria-describedby": describedBy, className: inputClassName, ...props
|
|
23
|
+
return (_jsxs(Field, { className: className, "data-disabled": disabled ? "true" : undefined, "data-invalid": isInvalid ? "true" : undefined, children: [_jsx(FieldLabel, { htmlFor: inputId, required: required, className: cn(hideLabel && "sr-only", labelClassName), children: label }), _jsx(InputControl, { ref: ref, id: inputId, disabled: disabled, required: required, "aria-invalid": isInvalid ? "true" : undefined, "aria-describedby": describedBy, className: inputClassName, ...props, value: value, defaultValue: defaultValue, onChange: (event) => {
|
|
24
|
+
if (value === undefined)
|
|
25
|
+
setUncontrolledValue(event.target.value);
|
|
26
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(event);
|
|
27
|
+
} }), showDescription ? (_jsx(FieldDescription, { id: descriptionId, className: descriptionClassName, children: description })) : null, limitId && _jsx(FieldCounter, { id: limitId, count: count, limit: props.maxLength }), _jsx(FieldError, { id: errorId, className: errorClassName, children: error })] }));
|
|
20
28
|
});
|
|
21
29
|
Input.displayName = "Input";
|
|
22
30
|
export { Input };
|