@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.
Files changed (76) hide show
  1. package/README.md +9 -0
  2. package/dist/activity-card.d.ts +31 -0
  3. package/dist/activity-card.js +65 -0
  4. package/dist/alert.d.ts +1 -1
  5. package/dist/autocomplete.d.ts +84 -0
  6. package/dist/autocomplete.js +267 -0
  7. package/dist/avatar.d.ts +3 -1
  8. package/dist/avatar.js +27 -10
  9. package/dist/badge.d.ts +1 -1
  10. package/dist/badge.js +1 -1
  11. package/dist/button.d.ts +2 -2
  12. package/dist/button.js +3 -1
  13. package/dist/calendar.js +1 -1
  14. package/dist/card.d.ts +1 -1
  15. package/dist/card.js +1 -1
  16. package/dist/changelog-action-panel.d.ts +17 -0
  17. package/dist/changelog-action-panel.js +14 -0
  18. package/dist/checklist.d.ts +63 -0
  19. package/dist/checklist.js +30 -0
  20. package/dist/compound-search-input.d.ts +10 -0
  21. package/dist/compound-search-input.js +19 -0
  22. package/dist/date-input.js +3 -3
  23. package/dist/dialog.d.ts +4 -1
  24. package/dist/dialog.js +7 -2
  25. package/dist/draggable-tabs.js +9 -8
  26. package/dist/dropdown-button.js +1 -0
  27. package/dist/editable-table.js +2 -2
  28. package/dist/field-counter.d.ts +7 -0
  29. package/dist/field-counter.js +5 -0
  30. package/dist/index.d.ts +22 -4
  31. package/dist/index.js +12 -2
  32. package/dist/input.d.ts +2 -0
  33. package/dist/input.js +11 -3
  34. package/dist/label-value-grid.js +6 -4
  35. package/dist/layout.d.ts +39 -6
  36. package/dist/layout.js +118 -42
  37. package/dist/lib/utils.js +1 -0
  38. package/dist/message-action-panel.d.ts +12 -0
  39. package/dist/message-action-panel.js +11 -0
  40. package/dist/message-item.d.ts +23 -3
  41. package/dist/message-item.js +115 -16
  42. package/dist/notification.d.ts +14 -3
  43. package/dist/notification.js +36 -7
  44. package/dist/page-section.d.ts +2 -1
  45. package/dist/page-section.js +2 -2
  46. package/dist/popover-menu.d.ts +4 -2
  47. package/dist/popover-menu.js +65 -5
  48. package/dist/popover.d.ts +10 -2
  49. package/dist/popover.js +7 -3
  50. package/dist/rich-text-editor.d.ts +2 -1
  51. package/dist/rich-text-editor.js +29 -6
  52. package/dist/routing-action-panel.d.ts +38 -0
  53. package/dist/routing-action-panel.js +19 -0
  54. package/dist/routing-timeline.d.ts +7 -2
  55. package/dist/routing-timeline.js +67 -29
  56. package/dist/search-input.d.ts +6 -0
  57. package/dist/search-input.js +6 -4
  58. package/dist/select-primitive.js +1 -1
  59. package/dist/select.d.ts +3 -1
  60. package/dist/select.js +9 -4
  61. package/dist/status-dot.d.ts +13 -0
  62. package/dist/status-dot.js +19 -0
  63. package/dist/styles.css +0 -19
  64. package/dist/table-add-row.d.ts +8 -0
  65. package/dist/table-add-row.js +7 -0
  66. package/dist/table-column-filter.js +7 -5
  67. package/dist/table.d.ts +9 -1
  68. package/dist/table.js +25 -11
  69. package/dist/tabs.d.ts +1 -1
  70. package/dist/tabs.js +6 -4
  71. package/dist/tailwind-preset.js +10 -0
  72. package/dist/textarea.d.ts +5 -0
  73. package/dist/textarea.js +18 -3
  74. package/dist/theme-switcher.d.ts +3 -1
  75. package/dist/theme-switcher.js +8 -2
  76. package/package.json +1 -1
package/README.md CHANGED
@@ -331,3 +331,12 @@ GitHub Actions builds Storybook with `npm run build-storybook` to verify that
331
331
  the stories compile. The Chromatic publishing step is temporarily commented
332
332
  out in `.github/workflows/ci.yml` and can be uncommented when snapshot
333
333
  publishing is needed again.
334
+
335
+ ### Text length counters
336
+
337
+ Use `showCount` with `maxLength` on `Input`, `SearchInput`, `CompoundSearchInput`, or `Textarea` for a character counter. Use `maxWords` on `Textarea` for a word counter; it takes precedence if both limits are supplied. Counters appear below the field, aligned right, as `count / limit`. The unit is available to screen readers without repeating a visible maximum-length hint. Native character limits remain enforced; word limits report validation errors without truncating text.
338
+
339
+ ```tsx
340
+ const [reference, setReference] = React.useState("");
341
+ <Input label="Reference" value={reference} onChange={(event) => setReference(event.target.value)} maxLength={50} showCount />
342
+ ```
@@ -0,0 +1,31 @@
1
+ import * as React from "react";
2
+ export type ActivityCardDensity = "default" | "compact";
3
+ export type ActivityCardIconTone = "accent" | "destructive" | "info" | "muted" | "success" | "warning";
4
+ export interface ActivityCardProps extends Omit<React.HTMLAttributes<HTMLElement>, "title"> {
5
+ as?: "article" | "div" | "a" | "button";
6
+ density?: ActivityCardDensity;
7
+ icon?: React.ReactNode;
8
+ iconTone?: ActivityCardIconTone;
9
+ title: React.ReactNode;
10
+ titleLines?: 1 | 2;
11
+ meta?: React.ReactNode;
12
+ /** Optional supporting content rendered inside the card header. */
13
+ headerContent?: React.ReactNode;
14
+ trailing?: React.ReactNode;
15
+ href?: string;
16
+ type?: "button" | "submit" | "reset";
17
+ "data-slot"?: string;
18
+ }
19
+ export interface ActivityCardContentProps extends React.HTMLAttributes<HTMLDivElement> {
20
+ density?: ActivityCardDensity;
21
+ }
22
+ export interface ActivityCardActorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
23
+ actor: React.ReactNode;
24
+ label?: React.ReactNode;
25
+ avatarSrc?: string | null;
26
+ avatarFallback?: React.ReactNode;
27
+ }
28
+ declare const ActivityCard: React.ForwardRefExoticComponent<ActivityCardProps & React.RefAttributes<HTMLElement>>;
29
+ declare const ActivityCardContent: React.ForwardRefExoticComponent<ActivityCardContentProps & React.RefAttributes<HTMLDivElement>>;
30
+ declare const ActivityCardActor: React.ForwardRefExoticComponent<ActivityCardActorProps & React.RefAttributes<HTMLDivElement>>;
31
+ export { ActivityCard, ActivityCardActor, ActivityCardContent };
@@ -0,0 +1,65 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { AvatarProfile } from "./avatar";
4
+ import { cn } from "./lib/utils";
5
+ import { Typography } from "./typography";
6
+ const activityCardIconToneClasses = {
7
+ accent: "border-status-accent-foreground/20 bg-status-accent text-status-accent-foreground",
8
+ destructive: "border-status-destructive-foreground/20 bg-status-destructive text-status-destructive-foreground",
9
+ info: "border-status-info-foreground/20 bg-status-info text-status-info-foreground",
10
+ muted: "border-border bg-muted text-muted-foreground",
11
+ success: "border-status-success-foreground/20 bg-status-success text-status-success-foreground",
12
+ warning: "border-status-warning-foreground/20 bg-status-warning text-status-warning-foreground",
13
+ };
14
+ const activityCardTitleLineClasses = {
15
+ 1: "truncate",
16
+ 2: "line-clamp-2",
17
+ };
18
+ function getActivityActorText(value) {
19
+ if (value === null || value === undefined || typeof value === "boolean") {
20
+ return "";
21
+ }
22
+ if (typeof value === "string" || typeof value === "number") {
23
+ return String(value);
24
+ }
25
+ if (Array.isArray(value)) {
26
+ return value.map(getActivityActorText).join(" ").trim();
27
+ }
28
+ if (React.isValidElement(value)) {
29
+ return getActivityActorText(value.props.children);
30
+ }
31
+ return "";
32
+ }
33
+ function getActivityActorInitials(value) {
34
+ return getActivityActorText(value)
35
+ .split(/\s+/)
36
+ .filter(Boolean)
37
+ .slice(0, 2)
38
+ .map((part) => part.charAt(0).toUpperCase())
39
+ .join("");
40
+ }
41
+ const ActivityCard = React.forwardRef(({ as = "article", density = "default", icon, iconTone, title, titleLines = 2, meta, headerContent, trailing, href, type, className, children, "data-slot": dataSlot, ...props }, ref) => {
42
+ const Comp = as;
43
+ return (_jsxs(Comp, { ref: ref, "data-slot": dataSlot !== null && dataSlot !== void 0 ? dataSlot : "activity-card", "data-activity-card": "", "data-density": density, href: as === "a" ? href : undefined, type: as === "button" ? (type !== null && type !== void 0 ? type : "button") : undefined, className: cn("min-w-0 overflow-hidden rounded-surface border border-border bg-card text-card-foreground shadow-sm", className), ...props, children: [_jsxs("header", { "data-slot": "activity-card-header", className: cn("flex items-center", density === "compact"
44
+ ? "min-h-[var(--space-12)] p-[var(--space-3)]"
45
+ : "min-h-[80px] p-[16px]"), children: [icon ? (_jsx("span", { "data-slot": "activity-card-icon", "aria-hidden": "true", className: cn("flex shrink-0 items-center justify-center", iconTone
46
+ ? cn("rounded-control border", density === "compact" ? "size-7" : "size-8", activityCardIconToneClasses[iconTone])
47
+ : cn("text-foreground", density === "compact" ? "size-4" : "size-[24px]")), children: icon })) : null, _jsxs("div", { className: cn("min-w-0 flex-1", icon &&
48
+ (density === "compact"
49
+ ? "pl-[var(--space-3)]"
50
+ : "pl-[16px]"), trailing &&
51
+ (density === "compact"
52
+ ? "pr-[var(--space-3)]"
53
+ : "pr-[32px]")), children: [_jsx(Typography, { as: "h3", variant: "label", className: cn("font-semibold", activityCardTitleLineClasses[titleLines]), children: title }), meta ? (_jsx(Typography, { as: "div", variant: "caption", className: "font-medium text-instructional", children: meta })) : null, headerContent ? (_jsx("div", { "data-slot": "activity-card-header-content", className: "mt-[var(--space-2)]", children: headerContent })) : null] }), trailing ? (_jsx("div", { "data-slot": "activity-card-trailing", className: "max-w-full shrink-0", children: trailing })) : null] }), children] }));
54
+ });
55
+ ActivityCard.displayName = "ActivityCard";
56
+ const ActivityCardContent = React.forwardRef(({ density = "default", className, ...props }, ref) => (_jsx("div", { ref: ref, "data-slot": "activity-card-content", "data-density": density, className: cn("border-t border-border", density === "compact"
57
+ ? "space-y-[var(--space-3)] px-[var(--space-4)] py-[var(--space-3)]"
58
+ : "space-y-[24px] px-[32px] pb-[24px] pt-[16px]", className), ...props })));
59
+ ActivityCardContent.displayName = "ActivityCardContent";
60
+ const ActivityCardActor = React.forwardRef(({ actor, label = "By", avatarSrc, avatarFallback, className, ...props }, ref) => {
61
+ const actorText = getActivityActorText(actor);
62
+ return (_jsx("div", { ref: ref, "data-slot": "activity-card-actor", className: cn("min-w-0 text-left", className), ...props, children: _jsx(AvatarProfile, { size: "xs", src: avatarSrc, alt: actorText, fallback: avatarFallback !== null && avatarFallback !== void 0 ? avatarFallback : (getActivityActorInitials(actor) || "?"), name: _jsxs(_Fragment, { children: [label, " ", actor] }), wrapName: true, nameClassName: "font-semibold" }) }));
63
+ });
64
+ ActivityCardActor.displayName = "ActivityCardActor";
65
+ export { ActivityCard, ActivityCardActor, ActivityCardContent };
package/dist/alert.d.ts CHANGED
@@ -3,7 +3,7 @@ import { type VariantProps } from "class-variance-authority";
3
3
  import { type ButtonProps } from "./button";
4
4
  import { type CheckboxProps } from "./checkbox";
5
5
  declare const alertVariants: (props?: ({
6
- variant?: "destructive" | "info" | "success" | "warning" | null | undefined;
6
+ variant?: "warning" | "destructive" | "info" | "success" | null | undefined;
7
7
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
8
  export interface AlertProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title">, VariantProps<typeof alertVariants> {
9
9
  title?: React.ReactNode;
@@ -0,0 +1,84 @@
1
+ import * as React from "react";
2
+ import { type EmptyStateProps } from "./empty-state";
3
+ import { type PopoverProps } from "./popover";
4
+ import { type PopoverMenuScrollAreaProps } from "./popover-menu";
5
+ import { type SearchInputProps } from "./search-input";
6
+ export interface AutocompleteControllerOptions {
7
+ listboxId: string;
8
+ onDismiss: () => void;
9
+ onSelect: (index: number) => void;
10
+ open: boolean;
11
+ optionCount: number;
12
+ isOptionDisabled?: (index: number) => boolean;
13
+ }
14
+ export interface AutocompleteController {
15
+ activeIndex: number;
16
+ getInputProps: () => {
17
+ "aria-activedescendant": string | undefined;
18
+ "aria-autocomplete": "list";
19
+ "aria-controls": string | undefined;
20
+ "aria-expanded": boolean;
21
+ "aria-haspopup": "listbox";
22
+ role: "combobox";
23
+ };
24
+ getOptionProps: (index: number) => Pick<React.ButtonHTMLAttributes<HTMLButtonElement>, "aria-selected" | "disabled" | "id" | "onClick" | "onMouseEnter" | "role" | "tabIndex">;
25
+ handleInputKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => boolean;
26
+ resetActiveIndex: () => void;
27
+ }
28
+ declare function useAutocompleteController({ listboxId, onDismiss, onSelect, open, optionCount, isOptionDisabled, }: AutocompleteControllerOptions): AutocompleteController;
29
+ export interface AutocompletePopoverProps extends Omit<PopoverProps, "surface"> {
30
+ }
31
+ /** Menu popover that preserves focus in its autocomplete input. */
32
+ declare function AutocompletePopover({ contentClassName, onCloseAutoFocus, onMouseDown, onOpenAutoFocus, ...props }: AutocompletePopoverProps): import("react/jsx-runtime").JSX.Element;
33
+ export interface AutocompleteOptionsProps extends PopoverMenuScrollAreaProps {
34
+ }
35
+ /** Scrollable option area that also works inside a modal dialog. */
36
+ declare function AutocompleteOptions({ className, onWheel, ...props }: AutocompleteOptionsProps): import("react/jsx-runtime").JSX.Element;
37
+ export interface AutocompleteOption {
38
+ value: string;
39
+ label: string;
40
+ description?: React.ReactNode;
41
+ disabled?: boolean;
42
+ }
43
+ export interface AutocompleteOptionGroup {
44
+ id: string;
45
+ label?: React.ReactNode;
46
+ options: readonly AutocompleteOption[];
47
+ }
48
+ export interface AutocompleteOptionRenderState {
49
+ active: boolean;
50
+ query: string;
51
+ }
52
+ export interface AutocompleteStateContent extends Pick<EmptyStateProps, "description" | "icon" | "message"> {
53
+ }
54
+ interface AutocompleteBaseProps extends Omit<SearchInputProps, "onKeyDown" | "onSearch" | "onValueChange" | "searchOnChange" | "searchOnEnter" | "value"> {
55
+ value: string;
56
+ onValueChange: (value: string) => void;
57
+ onOptionSelect: (option: AutocompleteOption) => void;
58
+ /** Minimum trimmed query length required before the menu can open. */
59
+ minLength?: number;
60
+ loading?: boolean;
61
+ open?: boolean;
62
+ defaultOpen?: boolean;
63
+ onOpenChange?: (open: boolean) => void;
64
+ /** Filters supplied options by label in the browser. Keep false for remote or fuzzy search results. */
65
+ filterOptions?: boolean;
66
+ emptyState?: AutocompleteStateContent;
67
+ loadingState?: AutocompleteStateContent;
68
+ renderOption?: (option: AutocompleteOption, state: AutocompleteOptionRenderState) => React.ReactNode;
69
+ listboxLabel?: string;
70
+ contentClassName?: string;
71
+ optionClassName?: string;
72
+ maxHeight?: string;
73
+ onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;
74
+ }
75
+ type AutocompleteOptionSource = {
76
+ options: readonly AutocompleteOption[];
77
+ groups?: never;
78
+ } | {
79
+ options?: never;
80
+ groups: readonly AutocompleteOptionGroup[];
81
+ };
82
+ export type AutocompleteProps = AutocompleteBaseProps & AutocompleteOptionSource;
83
+ declare function Autocomplete({ value, onValueChange, onOptionSelect, options, groups, minLength, loading, open, defaultOpen, onOpenChange, filterOptions, emptyState, loadingState, renderOption, listboxLabel, contentClassName, optionClassName, maxHeight, onKeyDown, label, hideLabel, disabled, id, onFocus, ...inputProps }: AutocompleteProps): import("react/jsx-runtime").JSX.Element;
84
+ export { Autocomplete, AutocompleteOptions, AutocompletePopover, useAutocompleteController, };
@@ -0,0 +1,267 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { LoaderPinwheelIcon, SearchIcon } from "./animated-icons";
5
+ import { EmptyState } from "./empty-state";
6
+ import { cn } from "./lib/utils";
7
+ import { Popover } from "./popover";
8
+ import { PopoverMenuDivider, PopoverMenuGroup, PopoverMenuGroupLabel, PopoverMenuItem, PopoverMenuScrollArea, } from "./popover-menu";
9
+ import { SearchInput } from "./search-input";
10
+ import { Typography } from "./typography";
11
+ import { SearchHighlight } from "./use-search-highlight";
12
+ function getNextEnabledOptionIndex({ currentIndex, direction, isOptionDisabled, optionCount, }) {
13
+ if (optionCount <= 0) {
14
+ return -1;
15
+ }
16
+ const startIndex = direction === "previous" && currentIndex < 0 ? 0 : currentIndex;
17
+ const offset = direction === "previous" ? -1 : 1;
18
+ for (let step = 1; step <= optionCount; step += 1) {
19
+ const index = (startIndex + offset * step + optionCount * 2) % optionCount;
20
+ if (!isOptionDisabled(index)) {
21
+ return index;
22
+ }
23
+ }
24
+ return -1;
25
+ }
26
+ /**
27
+ * Shared active-descendant navigation for autocomplete inputs whose focus must
28
+ * remain in the search field. Prefer `Autocomplete` unless the result rows need
29
+ * a custom composition.
30
+ */
31
+ const autocompleteOptionIsEnabled = () => false;
32
+ function useAutocompleteController({ listboxId, onDismiss, onSelect, open, optionCount, isOptionDisabled = autocompleteOptionIsEnabled, }) {
33
+ const [activeIndex, setActiveIndex] = React.useState(-1);
34
+ React.useEffect(() => {
35
+ if (!open ||
36
+ activeIndex >= optionCount ||
37
+ (activeIndex >= 0 && isOptionDisabled(activeIndex))) {
38
+ setActiveIndex(-1);
39
+ }
40
+ }, [activeIndex, isOptionDisabled, open, optionCount]);
41
+ React.useEffect(() => {
42
+ var _a, _b;
43
+ if (!open || activeIndex < 0) {
44
+ return;
45
+ }
46
+ (_b = (_a = document
47
+ .getElementById(`${listboxId}-option-${activeIndex}`)) === null || _a === void 0 ? void 0 : _a.scrollIntoView) === null || _b === void 0 ? void 0 : _b.call(_a, { block: "nearest" });
48
+ }, [activeIndex, listboxId, open]);
49
+ const resetActiveIndex = React.useCallback(() => setActiveIndex(-1), []);
50
+ const handleInputKeyDown = React.useCallback((event) => {
51
+ if (event.nativeEvent.isComposing || !open) {
52
+ return false;
53
+ }
54
+ let direction;
55
+ if (event.key === "ArrowDown")
56
+ direction = "next";
57
+ if (event.key === "ArrowUp")
58
+ direction = "previous";
59
+ if (direction && optionCount > 0) {
60
+ event.preventDefault();
61
+ setActiveIndex((currentIndex) => getNextEnabledOptionIndex({
62
+ currentIndex,
63
+ direction,
64
+ isOptionDisabled,
65
+ optionCount,
66
+ }));
67
+ return true;
68
+ }
69
+ if (event.key === "Enter" && activeIndex >= 0) {
70
+ event.preventDefault();
71
+ onSelect(activeIndex);
72
+ setActiveIndex(-1);
73
+ return true;
74
+ }
75
+ if (event.key === "Escape") {
76
+ event.preventDefault();
77
+ event.stopPropagation();
78
+ setActiveIndex(-1);
79
+ onDismiss();
80
+ return true;
81
+ }
82
+ return false;
83
+ }, [activeIndex, isOptionDisabled, onDismiss, onSelect, open, optionCount]);
84
+ const getInputProps = React.useCallback(() => ({
85
+ "aria-activedescendant": open && activeIndex >= 0 && activeIndex < optionCount
86
+ ? `${listboxId}-option-${activeIndex}`
87
+ : undefined,
88
+ "aria-autocomplete": "list",
89
+ "aria-controls": open ? listboxId : undefined,
90
+ "aria-expanded": open,
91
+ "aria-haspopup": "listbox",
92
+ role: "combobox",
93
+ }), [activeIndex, listboxId, open, optionCount]);
94
+ const getOptionProps = React.useCallback((index) => {
95
+ const disabled = isOptionDisabled(index);
96
+ return {
97
+ id: `${listboxId}-option-${index}`,
98
+ role: "option",
99
+ tabIndex: -1,
100
+ "aria-selected": activeIndex === index,
101
+ disabled,
102
+ onMouseEnter: () => {
103
+ if (!disabled)
104
+ setActiveIndex(index);
105
+ },
106
+ onClick: () => {
107
+ if (disabled)
108
+ return;
109
+ onSelect(index);
110
+ setActiveIndex(-1);
111
+ },
112
+ };
113
+ }, [activeIndex, isOptionDisabled, listboxId, onSelect]);
114
+ return {
115
+ activeIndex,
116
+ getInputProps,
117
+ getOptionProps,
118
+ handleInputKeyDown,
119
+ resetActiveIndex,
120
+ };
121
+ }
122
+ /** Menu popover that preserves focus in its autocomplete input. */
123
+ function AutocompletePopover({ contentClassName, onCloseAutoFocus, onMouseDown, onOpenAutoFocus, ...props }) {
124
+ return (_jsx(Popover, { ...props, surface: "menu", contentClassName: cn("[&_[data-slot=popover-menu-item]]:min-h-8 [&_[data-slot=popover-menu-item]]:px-1.5 [&_[data-slot=popover-menu-item]]:py-1.5", contentClassName), onMouseDown: (event) => {
125
+ onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(event);
126
+ if (!event.defaultPrevented)
127
+ event.preventDefault();
128
+ }, onOpenAutoFocus: (event) => {
129
+ onOpenAutoFocus === null || onOpenAutoFocus === void 0 ? void 0 : onOpenAutoFocus(event);
130
+ if (!event.defaultPrevented)
131
+ event.preventDefault();
132
+ }, onCloseAutoFocus: (event) => {
133
+ onCloseAutoFocus === null || onCloseAutoFocus === void 0 ? void 0 : onCloseAutoFocus(event);
134
+ if (!event.defaultPrevented)
135
+ event.preventDefault();
136
+ } }));
137
+ }
138
+ /** Scrollable option area that also works inside a modal dialog. */
139
+ function AutocompleteOptions({ className, onWheel, ...props }) {
140
+ const handleWheel = (event) => {
141
+ onWheel === null || onWheel === void 0 ? void 0 : onWheel(event);
142
+ if (event.defaultPrevented)
143
+ return;
144
+ const optionList = event.currentTarget;
145
+ const maxScrollTop = optionList.scrollHeight - optionList.clientHeight;
146
+ if (maxScrollTop <= 0)
147
+ return;
148
+ const deltaMultiplier = event.deltaMode === WheelEvent.DOM_DELTA_LINE
149
+ ? 16
150
+ : event.deltaMode === WheelEvent.DOM_DELTA_PAGE
151
+ ? optionList.clientHeight
152
+ : 1;
153
+ const nextScrollTop = Math.min(maxScrollTop, Math.max(0, optionList.scrollTop + event.deltaY * deltaMultiplier));
154
+ if (nextScrollTop === optionList.scrollTop)
155
+ return;
156
+ optionList.scrollTop = nextScrollTop;
157
+ event.preventDefault();
158
+ event.stopPropagation();
159
+ };
160
+ return (_jsx(PopoverMenuScrollArea, { ...props, "data-slot": "autocomplete-options", className: cn("min-h-0 touch-pan-y space-y-0 overscroll-contain", className), onWheel: handleWheel }));
161
+ }
162
+ const defaultEmptyState = {
163
+ icon: SearchIcon,
164
+ message: "No matches found",
165
+ description: "Try a different search term.",
166
+ };
167
+ function AutocompleteLoadingIcon({ className }) {
168
+ return _jsx(LoaderPinwheelIcon, { className: cn("animate-spin", className) });
169
+ }
170
+ const defaultLoadingState = {
171
+ icon: AutocompleteLoadingIcon,
172
+ message: "Finding matching options",
173
+ description: "Search results will appear here.",
174
+ };
175
+ function Autocomplete({ value, onValueChange, onOptionSelect, options, groups, minLength = 0, loading = false, open, defaultOpen = false, onOpenChange, filterOptions = false, emptyState = defaultEmptyState, loadingState = defaultLoadingState, renderOption, listboxLabel, contentClassName, optionClassName, maxHeight, onKeyDown, label = "Search", hideLabel = false, disabled, id, onFocus, ...inputProps }) {
176
+ const inputRef = React.useRef(null);
177
+ const generatedId = React.useId().replace(/:/g, "");
178
+ const inputId = id !== null && id !== void 0 ? id : `autocomplete-${generatedId}`;
179
+ const listboxId = `${inputId}-listbox`;
180
+ const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
181
+ const isControlled = open !== undefined;
182
+ const requestedOpen = isControlled ? open : internalOpen;
183
+ const meetsMinimumLength = value.trim().length >= minLength;
184
+ const canOpen = !disabled && meetsMinimumLength;
185
+ const currentOpen = Boolean(requestedOpen && canOpen);
186
+ const requestOpen = React.useCallback((nextOpen) => {
187
+ const resolvedOpen = Boolean(nextOpen && canOpen);
188
+ if (!isControlled)
189
+ setInternalOpen(resolvedOpen);
190
+ onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(resolvedOpen);
191
+ }, [canOpen, isControlled, onOpenChange]);
192
+ React.useEffect(() => {
193
+ if (requestedOpen && !canOpen)
194
+ requestOpen(false);
195
+ }, [canOpen, requestOpen, requestedOpen]);
196
+ const sourceGroups = React.useMemo(() => groups !== null && groups !== void 0 ? groups : [
197
+ {
198
+ id: "options",
199
+ options: options !== null && options !== void 0 ? options : [],
200
+ },
201
+ ], [groups, options]);
202
+ const visibleGroups = React.useMemo(() => {
203
+ if (!filterOptions)
204
+ return sourceGroups;
205
+ const normalizedQuery = value.trim().toLocaleLowerCase();
206
+ return sourceGroups
207
+ .map((group) => ({
208
+ ...group,
209
+ options: group.options.filter((option) => option.label.toLocaleLowerCase().includes(normalizedQuery)),
210
+ }))
211
+ .filter((group) => group.options.length > 0);
212
+ }, [filterOptions, sourceGroups, value]);
213
+ const visibleOptions = React.useMemo(() => visibleGroups.flatMap((group) => group.options), [visibleGroups]);
214
+ const visibleOptionIdentity = visibleOptions
215
+ .map((option) => option.value)
216
+ .join("\u0000");
217
+ const isOptionDisabled = React.useCallback((index) => { var _a; return Boolean((_a = visibleOptions[index]) === null || _a === void 0 ? void 0 : _a.disabled); }, [visibleOptions]);
218
+ const selectOption = React.useCallback((index) => {
219
+ const option = visibleOptions[index];
220
+ if (!option || option.disabled)
221
+ return;
222
+ onOptionSelect(option);
223
+ requestOpen(false);
224
+ }, [onOptionSelect, requestOpen, visibleOptions]);
225
+ const controller = useAutocompleteController({
226
+ listboxId,
227
+ onDismiss: () => requestOpen(false),
228
+ onSelect: selectOption,
229
+ open: currentOpen,
230
+ optionCount: visibleOptions.length,
231
+ isOptionDisabled,
232
+ });
233
+ React.useEffect(() => {
234
+ controller.resetActiveIndex();
235
+ }, [controller.resetActiveIndex, value, visibleOptionIdentity]);
236
+ const handleValueChange = React.useCallback((nextValue) => {
237
+ onValueChange(nextValue);
238
+ const nextCanOpen = !disabled && nextValue.trim().length >= minLength;
239
+ if (!isControlled)
240
+ setInternalOpen(nextCanOpen);
241
+ onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(nextCanOpen);
242
+ }, [disabled, isControlled, minLength, onOpenChange, onValueChange]);
243
+ const handleKeyDown = React.useCallback((event) => {
244
+ onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
245
+ if (!event.defaultPrevented)
246
+ controller.handleInputKeyDown(event);
247
+ }, [controller, onKeyDown]);
248
+ const resolvedListboxLabel = listboxLabel !== null && listboxLabel !== void 0 ? listboxLabel : (typeof label === "string" ? `${label} options` : "Autocomplete options");
249
+ let optionIndex = -1;
250
+ return (_jsx(AutocompletePopover, { open: currentOpen, onOpenChange: requestOpen, virtualAnchorRef: inputRef, align: "start", contentClassName: cn("flex max-h-[var(--radix-popover-content-available-height)] w-[var(--radix-popover-trigger-width)] flex-col", contentClassName), id: listboxId, role: "listbox", "aria-label": resolvedListboxLabel, "aria-busy": loading || undefined, trigger: _jsx("div", { "data-slot": "autocomplete", className: "w-full", onClick: (event) => {
251
+ if (currentOpen)
252
+ event.preventDefault();
253
+ }, children: _jsx(SearchInput, { ref: inputRef, ...inputProps, ...controller.getInputProps(), id: inputId, label: label, hideLabel: hideLabel, value: value, onValueChange: handleValueChange, onFocus: (event) => {
254
+ onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
255
+ if (!event.defaultPrevented && canOpen)
256
+ requestOpen(true);
257
+ }, onKeyDown: handleKeyDown, disabled: disabled, searchOnChange: false, searchOnEnter: false }) }), children: _jsx(AutocompleteOptions, { maxHeight: maxHeight, children: loading ? (_jsx(EmptyState, { ...loadingState, className: "min-h-40", role: "status" })) : visibleOptions.length === 0 ? (_jsx(EmptyState, { ...emptyState, className: "min-h-40", role: "status" })) : (visibleGroups.map((group, groupIndex) => {
258
+ const groupLabelId = `${listboxId}-group-${group.id}`;
259
+ return (_jsxs(React.Fragment, { children: [_jsxs(PopoverMenuGroup, { role: group.label ? "group" : undefined, "aria-labelledby": group.label ? groupLabelId : undefined, className: "space-y-0", children: [group.label ? (_jsx(PopoverMenuGroupLabel, { id: groupLabelId, children: group.label })) : null, group.options.map((option) => {
260
+ optionIndex += 1;
261
+ const currentIndex = optionIndex;
262
+ const active = controller.activeIndex === currentIndex;
263
+ return (_jsx(PopoverMenuItem, { type: "button", className: optionClassName, ...controller.getOptionProps(currentIndex), children: renderOption ? (renderOption(option, { active, query: value })) : (_jsxs("span", { className: "min-w-0 flex-1", children: [_jsx(Typography, { as: "span", variant: "bodySm", className: "block truncate", children: _jsx(SearchHighlight, { text: option.label, query: value }) }), option.description ? (_jsx(Typography, { as: "span", variant: "caption", className: "mt-0.5 block", children: option.description })) : null] })) }, option.value));
264
+ })] }), groupIndex < visibleGroups.length - 1 ? (_jsx(PopoverMenuDivider, { "data-slot": "autocomplete-group-separator" })) : null] }, group.id));
265
+ })) }) }));
266
+ }
267
+ export { Autocomplete, AutocompleteOptions, AutocompletePopover, useAutocompleteController, };
package/dist/avatar.d.ts CHANGED
@@ -22,6 +22,8 @@ interface AvatarProfileProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
22
22
  name?: React.ReactNode;
23
23
  nameAs?: React.ElementType;
24
24
  nameTrailing?: React.ReactNode;
25
+ wrapName?: boolean;
26
+ wrapInfo?: boolean;
25
27
  role?: React.ReactNode;
26
28
  rolePlacement?: "above" | "below";
27
29
  topInfo?: React.ReactNode;
@@ -38,7 +40,7 @@ interface AvatarProfileProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
38
40
  avatarOverlay?: React.ReactNode;
39
41
  }
40
42
  declare function Avatar({ src, alt, fallback, size, loading, className, imageClassName, fallbackClassName, ...props }: AvatarProps): import("react/jsx-runtime").JSX.Element;
41
- declare function AvatarProfile({ src, alt, fallback, size, loading, name, nameAs: NameElement, nameTrailing, role, rolePlacement, topInfo, bottomInfo, className, avatarClassName, imageClassName, fallbackClassName, contentClassName, nameRowClassName, nameClassName, roleClassName, topInfoClassName, bottomInfoClassName, avatarOverlay, ...props }: AvatarProfileProps): import("react/jsx-runtime").JSX.Element;
43
+ declare function AvatarProfile({ src, alt, fallback, size, loading, name, nameAs: NameElement, nameTrailing, wrapName, wrapInfo, role, rolePlacement, topInfo, bottomInfo, className, avatarClassName, imageClassName, fallbackClassName, contentClassName, nameRowClassName, nameClassName, roleClassName, topInfoClassName, bottomInfoClassName, avatarOverlay, ...props }: AvatarProfileProps): import("react/jsx-runtime").JSX.Element;
42
44
  export { Avatar, AvatarProfile, AvatarRoot, AvatarImage, AvatarFallback };
43
45
  export type AvatarRootProps = React.ComponentPropsWithoutRef<typeof AvatarRoot>;
44
46
  export type { AvatarProps, AvatarProfileProps };
package/dist/avatar.js CHANGED
@@ -21,9 +21,19 @@ const avatarProfileGapClasses = {
21
21
  md: "gap-2.5",
22
22
  };
23
23
  const avatarProfileNameClasses = {
24
- xs: "text-xs leading-4",
25
- sm: "text-sm leading-5",
26
- md: "text-sm leading-5",
24
+ xs: "text-xs",
25
+ sm: "text-sm",
26
+ md: "text-sm",
27
+ };
28
+ const avatarProfileNameCompactLeadingClasses = {
29
+ xs: "leading-4",
30
+ sm: "leading-5",
31
+ md: "leading-5",
32
+ };
33
+ const avatarProfileContentMinHeightClasses = {
34
+ xs: "min-h-[24px]",
35
+ sm: "min-h-[32px]",
36
+ md: "min-h-[40px]",
27
37
  };
28
38
  const avatarProfileInfoClasses = {
29
39
  xs: "text-[11px] leading-3",
@@ -80,27 +90,34 @@ function Avatar({ src, alt = "", fallback, size = "sm", loading = false, classNa
80
90
  "--avatar-fallback-background": fallbackTone.background,
81
91
  "--avatar-fallback-foreground": fallbackTone.foreground,
82
92
  };
83
- return (_jsxs(AvatarRoot, { className: cn(avatarSizeClasses[size], className), ...props, children: [src ? (_jsx(AvatarImage, { src: src, alt: alt, className: imageClassName })) : null, _jsx(AvatarFallback, { style: fallbackStyle, className: cn("bg-[hsl(var(--avatar-fallback-background))] font-medium text-[hsl(var(--avatar-fallback-foreground))]", fallbackClassName), children: fallback })] }));
93
+ return (_jsxs(AvatarRoot, { "data-slot": "avatar", className: cn(avatarSizeClasses[size], className), ...props, children: [src ? (_jsx(AvatarImage, { src: src, alt: alt, className: imageClassName })) : null, _jsx(AvatarFallback, { style: fallbackStyle, className: cn("bg-[hsl(var(--avatar-fallback-background))] font-medium text-[hsl(var(--avatar-fallback-foreground))]", fallbackClassName), children: fallback })] }));
84
94
  }
85
- function AvatarProfile({ src, alt = "", fallback, size = "sm", loading = false, name, nameAs: NameElement = "span", nameTrailing, role, rolePlacement = "below", topInfo, bottomInfo, className, avatarClassName, imageClassName, fallbackClassName, contentClassName, nameRowClassName, nameClassName, roleClassName, topInfoClassName, bottomInfoClassName, avatarOverlay, ...props }) {
95
+ function AvatarProfile({ src, alt = "", fallback, size = "sm", loading = false, name, nameAs: NameElement = "span", nameTrailing, wrapName = false, wrapInfo = false, role, rolePlacement = "below", topInfo, bottomInfo, className, avatarClassName, imageClassName, fallbackClassName, contentClassName, nameRowClassName, nameClassName, roleClassName, topInfoClassName, bottomInfoClassName, avatarOverlay, ...props }) {
86
96
  const resolvedTop = topInfo !== null && topInfo !== void 0 ? topInfo : (rolePlacement === "above" ? role : undefined);
87
97
  const resolvedBottom = bottomInfo !== null && bottomInfo !== void 0 ? bottomInfo : (rolePlacement === "below" ? role : undefined);
88
98
  const hasSupportingInfo = (resolvedTop !== undefined && resolvedTop !== null) ||
89
99
  (resolvedBottom !== undefined && resolvedBottom !== null);
90
- const alignmentClassName = hasSupportingInfo ? "items-start" : "items-center";
100
+ const alignmentClassName = hasSupportingInfo || wrapName ? "items-start" : "items-center";
91
101
  const avatarOffsetClassName = hasSupportingInfo ? "mt-0.5" : undefined;
102
+ const wrappedNameContentClassName = wrapName && !hasSupportingInfo
103
+ ? cn(avatarProfileContentMinHeightClasses[size], "justify-center")
104
+ : undefined;
92
105
  if (loading) {
93
- return (_jsxs("div", { className: cn("flex min-w-0 max-w-full", alignmentClassName, avatarProfileGapClasses[size], className), "aria-busy": "true", ...props, children: [_jsx(Skeleton, { className: cn("shrink-0 rounded-full", avatarSizeClasses[size], avatarOffsetClassName, avatarClassName) }), _jsxs("div", { className: cn("flex min-w-0 flex-1 flex-col", avatarProfileContentGapClass, contentClassName), children: [resolvedTop !== undefined ? (_jsx(Skeleton, { className: "h-3 w-20" })) : null, _jsx(Skeleton, { className: "h-4 w-32" }), resolvedBottom !== undefined ? (_jsx(Skeleton, { className: "h-3 w-20" })) : null] })] }));
106
+ return (_jsxs("div", { className: cn("flex min-w-0 max-w-full", alignmentClassName, avatarProfileGapClasses[size], className), "aria-busy": "true", ...props, children: [_jsx(Skeleton, { className: cn("shrink-0 rounded-full", avatarSizeClasses[size], avatarOffsetClassName, avatarClassName) }), _jsxs("div", { className: cn("flex min-w-0 flex-1 flex-col", avatarProfileContentGapClass, wrappedNameContentClassName, contentClassName), children: [resolvedTop !== undefined ? (_jsx(Skeleton, { className: "h-3 w-20" })) : null, _jsx(Skeleton, { className: "h-4 w-32" }), resolvedBottom !== undefined ? (_jsx(Skeleton, { className: "h-3 w-20" })) : null] })] }));
94
107
  }
95
108
  const hasMeta = name !== undefined ||
96
109
  nameTrailing !== undefined ||
97
110
  resolvedTop !== undefined ||
98
111
  resolvedBottom !== undefined;
99
- const infoBaseClass = cn("min-w-0 truncate text-muted-foreground", avatarProfileInfoClasses[size]);
112
+ const infoBaseClass = cn("min-w-0", wrapInfo
113
+ ? "whitespace-normal break-words [overflow-wrap:anywhere]"
114
+ : "truncate", "text-muted-foreground", avatarProfileInfoClasses[size]);
100
115
  const topNode = resolvedTop !== undefined && resolvedTop !== null ? (_jsx("span", { className: cn(infoBaseClass, topInfo !== undefined ? topInfoClassName : roleClassName), children: resolvedTop })) : null;
101
116
  const bottomNode = resolvedBottom !== undefined && resolvedBottom !== null ? (_jsx("span", { className: cn(infoBaseClass, bottomInfo !== undefined ? bottomInfoClassName : roleClassName), children: resolvedBottom })) : null;
102
- const nameTextNode = name !== undefined && name !== null ? (_jsx(NameElement, { className: cn("min-w-0 truncate font-medium text-foreground", avatarProfileNameClasses[size], nameClassName), children: name })) : null;
117
+ const nameTextNode = name !== undefined && name !== null ? (_jsx(NameElement, { className: cn("min-w-0 font-medium text-foreground", wrapName
118
+ ? "whitespace-normal break-words [overflow-wrap:anywhere]"
119
+ : "truncate", avatarProfileNameClasses[size], wrapName ? undefined : avatarProfileNameCompactLeadingClasses[size], nameClassName), children: name })) : null;
103
120
  const nameNode = nameTrailing !== undefined && nameTrailing !== null ? (_jsxs("div", { className: cn("flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1", nameRowClassName), children: [nameTextNode, nameTrailing] })) : (nameTextNode);
104
- return (_jsxs("div", { className: cn("flex min-w-0 max-w-full", alignmentClassName, avatarProfileGapClasses[size], className), ...props, children: [_jsxs("div", { className: "relative shrink-0", children: [_jsx(Avatar, { src: src, alt: alt, fallback: fallback, size: size, className: cn(avatarOffsetClassName, avatarClassName), imageClassName: imageClassName, fallbackClassName: fallbackClassName }), avatarOverlay] }), hasMeta ? (_jsxs("div", { className: cn("flex min-w-0 flex-1 flex-col", avatarProfileContentGapClass, contentClassName), children: [topNode, nameNode, bottomNode] })) : null] }));
121
+ return (_jsxs("div", { className: cn("flex min-w-0 max-w-full", alignmentClassName, avatarProfileGapClasses[size], className), ...props, children: [_jsxs("div", { className: "relative shrink-0", children: [_jsx(Avatar, { src: src, alt: alt, fallback: fallback, size: size, className: cn(avatarOffsetClassName, avatarClassName), imageClassName: imageClassName, fallbackClassName: fallbackClassName }), avatarOverlay] }), hasMeta ? (_jsxs("div", { className: cn("flex min-w-0 flex-1 flex-col", avatarProfileContentGapClass, wrappedNameContentClassName, contentClassName), children: [topNode, nameNode, bottomNode] })) : null] }));
105
122
  }
106
123
  export { Avatar, AvatarProfile, AvatarRoot, AvatarImage, AvatarFallback };
package/dist/badge.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { type VariantProps } from "class-variance-authority";
3
3
  declare const badgeVariants: (props?: ({
4
- variant?: "accent" | "muted" | "destructive" | "outline" | "secondary" | "info" | "success" | "warning" | null | undefined;
4
+ variant?: "accent" | "muted" | "warning" | "destructive" | "outline" | "secondary" | "info" | "success" | null | undefined;
5
5
  size?: "default" | "icon" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  /**
package/dist/badge.js CHANGED
@@ -3,7 +3,7 @@ import * as React from "react";
3
3
  import { cva } from "class-variance-authority";
4
4
  import { cn } from "./lib/utils";
5
5
  import { Typography } from "./typography";
6
- const badgeVariants = cva("inline-flex items-center justify-center text-center rounded-md border transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 truncate", {
6
+ const badgeVariants = cva("inline-flex items-center justify-center text-center rounded-md border transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 truncate [&>span]:text-[10px] [&_svg]:size-3 [&_svg]:shrink-0", {
7
7
  variants: {
8
8
  variant: {
9
9
  secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
package/dist/button.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as React from "react";
2
2
  import { type VariantProps } from "class-variance-authority";
3
3
  declare const buttonVariants: (props?: ({
4
- variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
5
- size?: "default" | "sm" | "compact" | "icon" | "compactIcon" | null | undefined;
4
+ variant?: "link" | "default" | "warning" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
5
+ size?: "default" | "sm" | "compact" | "comfortable" | "icon" | "compactIcon" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
8
8
  /**
package/dist/button.js CHANGED
@@ -7,6 +7,7 @@ const buttonVariants = cva("inline-flex cursor-pointer items-center justify-cent
7
7
  variants: {
8
8
  variant: {
9
9
  default: "bg-button-primary text-button-primary-foreground hover:bg-button-primary-hover",
10
+ warning: "border border-[hsl(var(--status-warning-foreground))]/30 bg-[hsl(var(--status-warning))] text-[hsl(var(--status-warning-foreground))] hover:bg-[hsl(var(--status-warning))]/80 focus-visible:ring-[hsl(var(--status-warning-foreground))]",
10
11
  destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
11
12
  outline: "border border-[hsl(var(--button-outline-border))] bg-[hsl(var(--button-outline-background))] text-foreground hover:bg-[hsl(var(--button-outline-hover-background))] hover:text-accent-foreground",
12
13
  secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
@@ -16,6 +17,7 @@ const buttonVariants = cva("inline-flex cursor-pointer items-center justify-cent
16
17
  size: {
17
18
  sm: "h-8 px-2.5 text-sm",
18
19
  compact: "h-8 gap-1 px-2 text-sm",
20
+ comfortable: "h-[46px] px-[12px] py-[11px] text-[16px] [&_svg]:h-[24px] [&_svg]:min-h-[24px] [&_svg]:w-[24px] [&_svg]:min-w-[24px]",
19
21
  default: "h-control px-3 py-1.5",
20
22
  icon: "h-control w-control",
21
23
  compactIcon: "h-8 w-8",
@@ -145,7 +147,7 @@ const Button = React.forwardRef(({ className, variant, size, asChild = false, lo
145
147
  stopAnimatedIcons();
146
148
  onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
147
149
  };
148
- return (_jsx(Comp, { className: cn(buttonVariants({ variant, size, className })), ref: ref, "aria-busy": loading || undefined, "aria-disabled": isDisabled || undefined, "data-loading": loading ? "" : undefined, "data-disabled": isDisabled ? "" : undefined, onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onFocus: handleFocus, onBlur: handleBlur, tabIndex: isDisabled && asChild ? -1 : tabIndex, disabled: !asChild ? isDisabled : undefined, ...props, children: content }));
150
+ return (_jsx(Comp, { "data-slot": "button", className: cn(buttonVariants({ variant, size, className })), ref: ref, "aria-busy": loading || undefined, "aria-disabled": isDisabled || undefined, "data-loading": loading ? "" : undefined, "data-disabled": isDisabled ? "" : undefined, onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onFocus: handleFocus, onBlur: handleBlur, tabIndex: isDisabled && asChild ? -1 : tabIndex, disabled: !asChild ? isDisabled : undefined, ...props, children: content }));
149
151
  });
150
152
  Button.displayName = "Button";
151
153
  export { Button, buttonVariants };
package/dist/calendar.js CHANGED
@@ -25,7 +25,7 @@ function Calendar({ className, classNames, showOutsideDays = true, fixedWeeks =
25
25
  ...formatters,
26
26
  }, classNames: {
27
27
  root: cn("w-fit", defaultClassNames.root),
28
- months: cn("relative flex flex-col gap-4 md:flex-row", defaultClassNames.months),
28
+ months: cn("relative flex flex-col gap-4 sm:flex-row", defaultClassNames.months),
29
29
  month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
30
30
  nav: cn("absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1", defaultClassNames.nav),
31
31
  button_previous: cn(buttonVariants({ variant: buttonVariant }), "h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50", defaultClassNames.button_previous),