@godxjp/ui 19.5.0 → 20.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/components/data-display/card.d.ts +2 -2
  2. package/dist/components/data-display/collapsible.d.ts +23 -4
  3. package/dist/components/data-display/collapsible.js +119 -4
  4. package/dist/components/data-display/index.d.ts +3 -1
  5. package/dist/components/data-display/index.js +2 -0
  6. package/dist/components/data-display/legend.d.ts +15 -0
  7. package/dist/components/data-display/legend.js +11 -0
  8. package/dist/components/data-display/list-row.js +1 -1
  9. package/dist/components/data-display/popover.d.ts +58 -5
  10. package/dist/components/data-display/popover.js +206 -27
  11. package/dist/components/data-display/progress.d.ts +50 -2
  12. package/dist/components/data-display/progress.js +57 -9
  13. package/dist/components/data-entry/calendar.d.ts +1 -1
  14. package/dist/components/data-entry/calendar.js +67 -32
  15. package/dist/components/data-entry/checkbox.d.ts +19 -6
  16. package/dist/components/data-entry/checkbox.js +55 -16
  17. package/dist/components/data-entry/choice-option.d.ts +1 -1
  18. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  19. package/dist/components/data-entry/field.js +0 -1
  20. package/dist/components/data-entry/form.js +1 -1
  21. package/dist/components/data-entry/label.d.ts +3 -2
  22. package/dist/components/data-entry/label.js +23 -10
  23. package/dist/components/data-entry/month-picker.d.ts +1 -1
  24. package/dist/components/data-entry/month-range-picker.d.ts +1 -1
  25. package/dist/components/data-entry/transfer.js +16 -6
  26. package/dist/components/data-entry/tree-select-strategy.d.ts +1 -1
  27. package/dist/components/data-entry/tree-select.js +29 -12
  28. package/dist/components/data-entry/tree-utils.d.ts +1 -1
  29. package/dist/components/data-entry/upload.js +7 -2
  30. package/dist/components/feedback/dialog.d.ts +105 -38
  31. package/dist/components/feedback/dialog.js +272 -194
  32. package/dist/components/feedback/overlay-close-focus.d.ts +31 -0
  33. package/dist/components/feedback/overlay-close-focus.js +31 -0
  34. package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
  35. package/dist/components/feedback/sheet.d.ts +53 -11
  36. package/dist/components/feedback/sheet.js +150 -81
  37. package/dist/components/feedback/tooltip.d.ts +51 -7
  38. package/dist/components/feedback/tooltip.js +107 -25
  39. package/dist/components/general/button.js +2 -2
  40. package/dist/components/general/logo.d.ts +17 -0
  41. package/dist/components/general/logo.js +22 -16
  42. package/dist/components/general/typography.d.ts +7 -1
  43. package/dist/components/general/typography.js +20 -5
  44. package/dist/components/layout/app-shell.d.ts +1 -1
  45. package/dist/components/layout/app-shell.js +52 -8
  46. package/dist/components/layout/aspect-ratio.js +0 -1
  47. package/dist/components/layout/auth-divider.js +0 -1
  48. package/dist/components/layout/flex.d.ts +1 -1
  49. package/dist/components/layout/flex.js +19 -2
  50. package/dist/components/layout/nav-surface.d.ts +26 -0
  51. package/dist/components/layout/nav-surface.js +17 -0
  52. package/dist/components/layout/org-switcher.d.ts +5 -1
  53. package/dist/components/layout/org-switcher.js +5 -3
  54. package/dist/components/layout/separator.js +0 -1
  55. package/dist/components/layout/sidebar.js +4 -1
  56. package/dist/components/layout/split-pane.d.ts +14 -1
  57. package/dist/components/layout/split-pane.js +26 -13
  58. package/dist/components/layout/topbar-item.js +1 -2
  59. package/dist/components/navigation/app-setting-picker.js +21 -2
  60. package/dist/components/navigation/app-setting-toggle.d.ts +16 -0
  61. package/dist/components/navigation/app-setting-toggle.js +96 -0
  62. package/dist/components/navigation/dropdown-menu.d.ts +199 -18
  63. package/dist/components/navigation/dropdown-menu.js +344 -117
  64. package/dist/components/navigation/index.d.ts +2 -0
  65. package/dist/components/navigation/index.js +2 -0
  66. package/dist/components/navigation/pagination-utils.d.ts +2 -1
  67. package/dist/components/navigation/tabs.d.ts +47 -6
  68. package/dist/components/navigation/tabs.js +152 -90
  69. package/dist/components/ui/accordion.d.ts +50 -5
  70. package/dist/components/ui/accordion.js +239 -33
  71. package/dist/components/ui/aspect-ratio.d.ts +23 -2
  72. package/dist/components/ui/aspect-ratio.js +15 -13
  73. package/dist/components/ui/avatar.d.ts +29 -4
  74. package/dist/components/ui/avatar.js +111 -25
  75. package/dist/components/ui/hover-card.d.ts +42 -4
  76. package/dist/components/ui/hover-card.js +183 -27
  77. package/dist/components/ui/label.js +0 -1
  78. package/dist/components/ui/segmented.d.ts +3 -3
  79. package/dist/components/ui/separator.d.ts +8 -2
  80. package/dist/components/ui/separator.js +17 -9
  81. package/dist/components/ui/toggle-group.d.ts +50 -5
  82. package/dist/components/ui/toggle-group.js +79 -20
  83. package/dist/components/ui/toggle.d.ts +31 -5
  84. package/dist/components/ui/toggle.js +42 -3
  85. package/dist/i18n/messages/en.json +8 -0
  86. package/dist/i18n/messages/ja.json +8 -0
  87. package/dist/i18n/messages/vi.json +8 -0
  88. package/dist/lib/control-styles.d.ts +1 -1
  89. package/dist/lib/control-styles.js +1 -1
  90. package/dist/lib/slot.d.ts +32 -0
  91. package/dist/lib/slot.js +22 -0
  92. package/dist/lib/variants.d.ts +22 -3
  93. package/dist/lib/variants.js +56 -1
  94. package/dist/props/components/app.prop.d.ts +25 -1
  95. package/dist/props/components/data-display.prop.d.ts +17 -0
  96. package/dist/props/components/data-entry.prop.d.ts +32 -4
  97. package/dist/props/components/general.prop.d.ts +31 -1
  98. package/dist/props/components/index.d.ts +1 -1
  99. package/dist/props/components/layout.prop.d.ts +118 -5
  100. package/dist/props/components/navigation.prop.d.ts +1 -1
  101. package/dist/props/registry.d.ts +22 -2
  102. package/dist/props/registry.js +33 -2
  103. package/dist/props/vocabulary/content.prop.d.ts +1 -1
  104. package/dist/props/vocabulary/index.d.ts +2 -2
  105. package/dist/props/vocabulary/interaction.prop.d.ts +17 -1
  106. package/dist/props/vocabulary/layout.prop.d.ts +57 -1
  107. package/dist/styles/control.css +142 -1
  108. package/dist/styles/core.css +5 -2
  109. package/dist/styles/data-display-layout.css +72 -0
  110. package/dist/styles/focus-ring.css +13 -1
  111. package/dist/styles/index.css +5 -2
  112. package/dist/styles/layout.css +106 -0
  113. package/dist/styles/shell-layout.css +140 -8
  114. package/dist/styles/text-layout.css +16 -4
  115. package/dist/tokens/base.css +2 -1
  116. package/dist/tokens/components/data-display.css +11 -0
  117. package/dist/tokens/components/shell.css +3 -1
  118. package/dist/tokens/components/text.css +7 -0
  119. package/dist/tokens/foundation.css +2 -0
  120. package/docs/COMPONENTS.md +9 -3
  121. package/docs/DESIGN-AUTHORITY.md +96 -71
  122. package/docs/FRAME-COVERAGE-REPORT.md +5 -3
  123. package/docs/README.md +14 -14
  124. package/docs/WHAT-BELONGS-HERE.md +179 -0
  125. package/docs/data-display/legend.tsx +145 -0
  126. package/docs/data-display/progress.tsx +32 -0
  127. package/docs/data-entry/segmented.tsx +1 -1
  128. package/docs/data-entry/select.tsx +2 -2
  129. package/docs/feedback/sheet.tsx +1 -1
  130. package/docs/general/typography.tsx +84 -1
  131. package/docs/layout/app-shell-arrangements.tsx +225 -0
  132. package/docs/layout/aspect-ratio.tsx +1 -1
  133. package/docs/navigation/app-setting-picker.tsx +26 -1
  134. package/docs/navigation/app-setting-toggle.tsx +111 -0
  135. package/package.json +11 -8
  136. package/scripts/_agent-setup.mjs +165 -3
  137. package/scripts/consumer-rule.md +98 -0
  138. package/scripts/guinea-pig-skill.md +322 -0
  139. package/scripts/init-guinea-pig.mjs +62 -0
  140. package/scripts/postinstall.mjs +13 -2
  141. package/scripts/ui-audit.mjs +115 -14
  142. /package/dist/tokens/{antd.generated.css → derived.css} +0 -0
@@ -1,138 +1,361 @@
1
1
  "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
4
+ import {
5
+ Header,
6
+ Menu,
7
+ MenuItem,
8
+ MenuSection,
9
+ MenuTrigger,
10
+ OverlayTriggerStateContext,
11
+ Popover,
12
+ Pressable,
13
+ Separator,
14
+ SubmenuTrigger
15
+ } from "react-aria-components";
5
16
  import { Check, ChevronRight } from "lucide-react";
6
17
  import { cn } from "../../lib/utils.js";
7
- import { useInertHiddenBackground } from "../general/inert-background.js";
8
- function DropdownMenu(props) {
9
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
18
+ import { Slot } from "../../lib/slot.js";
19
+ function borrowedTag(children, asChild) {
20
+ return asChild ? React.Children.only(children) : null;
10
21
  }
11
- function DropdownMenuTrigger(props) {
12
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
22
+ function renderItemTag(tag, domProps, content) {
23
+ if (!tag) {
24
+ return /* @__PURE__ */ jsx("div", { ...domProps, children: content });
25
+ }
26
+ return /* @__PURE__ */ jsx(Slot, { ...domProps, children: React.cloneElement(tag, void 0, content) });
27
+ }
28
+ function radixItemState(state) {
29
+ return {
30
+ "data-highlighted": state.isFocused ? "" : void 0,
31
+ "data-disabled": state.isDisabled ? "" : void 0,
32
+ "data-state": state.hasSubmenu ? state.isOpen ? "open" : "closed" : state.selectionMode === "none" ? void 0 : state.isSelected ? "checked" : "unchecked"
33
+ };
34
+ }
35
+ function radixSurfaceState(state) {
36
+ return {
37
+ "data-state": state.isExiting ? "closed" : "open",
38
+ "data-side": state.placement && state.placement !== "center" ? state.placement : void 0
39
+ };
13
40
  }
14
- function DropdownMenuPortal(props) {
15
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
41
+ function toPlacement(side, align) {
42
+ const resolvedSide = side ?? "bottom";
43
+ if (!align || align === "center") return resolvedSide;
44
+ return `${resolvedSide} ${align}`;
16
45
  }
17
- function DropdownMenuGroup(props) {
18
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
46
+ function selectEvent(name) {
47
+ return typeof CustomEvent === "function" ? new CustomEvent(name, { bubbles: false, cancelable: true }) : { defaultPrevented: false, preventDefault() {
48
+ } };
19
49
  }
20
- function DropdownMenuRadioGroup(props) {
21
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.RadioGroup, { "data-slot": "dropdown-menu-radio-group", ...props });
50
+ const DropdownMenuModalContext = React.createContext({ modal: true });
51
+ function DropdownMenu({
52
+ children,
53
+ open,
54
+ defaultOpen,
55
+ onOpenChange,
56
+ modal = true,
57
+ dir
58
+ }) {
59
+ void dir;
60
+ const options = React.useMemo(() => ({ modal }), [modal]);
61
+ return /* @__PURE__ */ jsx(DropdownMenuModalContext.Provider, { value: options, children: /* @__PURE__ */ jsx(MenuTrigger, { isOpen: open, defaultOpen, onOpenChange, children }) });
62
+ }
63
+ function DropdownMenuTrigger({ asChild, children, ...props }) {
64
+ const state = React.useContext(OverlayTriggerStateContext);
65
+ const dataState = state?.isOpen ? "open" : "closed";
66
+ if (asChild && React.isValidElement(children)) {
67
+ return /* @__PURE__ */ jsx(Pressable, { children: React.cloneElement(children, {
68
+ "data-slot": "dropdown-menu-trigger",
69
+ "data-state": dataState
70
+ }) });
71
+ }
72
+ return /* @__PURE__ */ jsx(Pressable, { children: /* @__PURE__ */ jsx("button", { type: "button", "data-slot": "dropdown-menu-trigger", "data-state": dataState, ...props, children }) });
73
+ }
74
+ function DropdownMenuPortal({ children }) {
75
+ return /* @__PURE__ */ jsx(Fragment, { children });
76
+ }
77
+ function DropdownMenuGroup({ children, className }) {
78
+ return /* @__PURE__ */ jsx(MenuSection, { "data-slot": "dropdown-menu-group", className, children });
79
+ }
80
+ function DropdownMenuRadioGroup({
81
+ children,
82
+ className,
83
+ value,
84
+ onValueChange
85
+ }) {
86
+ return /* @__PURE__ */ jsx(
87
+ MenuSection,
88
+ {
89
+ "data-slot": "dropdown-menu-radio-group",
90
+ className,
91
+ selectionMode: "single",
92
+ disallowEmptySelection: true,
93
+ selectedKeys: value == null ? [] : [value],
94
+ onSelectionChange: (keys) => {
95
+ if (keys === "all") return;
96
+ const [first] = [...keys];
97
+ if (first != null) onValueChange?.(String(first));
98
+ },
99
+ children
100
+ }
101
+ );
22
102
  }
23
- function DropdownMenuSub(props) {
24
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
103
+ function DropdownMenuSub({ children }) {
104
+ const parts = React.Children.toArray(children).filter(React.isValidElement);
105
+ return /* @__PURE__ */ jsx(SubmenuTrigger, { children: parts });
25
106
  }
26
- const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
27
- const contentRef = useInertHiddenBackground(ref);
107
+ function DropdownMenuContent({
108
+ children,
109
+ className,
110
+ side,
111
+ align,
112
+ sideOffset = 4,
113
+ alignOffset,
114
+ avoidCollisions,
115
+ collisionPadding,
116
+ loop,
117
+ hideWhenDetached,
118
+ sticky,
119
+ forceMount
120
+ }) {
121
+ void hideWhenDetached;
122
+ void sticky;
123
+ void forceMount;
124
+ const { modal } = React.useContext(DropdownMenuModalContext);
28
125
  return /* @__PURE__ */ jsx(DropdownMenuPortal, { children: /* @__PURE__ */ jsx(
29
- DropdownMenuPrimitive.Content,
126
+ Popover,
30
127
  {
31
- ref: contentRef,
32
128
  "data-slot": "dropdown-menu-content",
33
- sideOffset,
129
+ isNonModal: !modal,
130
+ placement: toPlacement(side, align),
131
+ offset: sideOffset,
132
+ crossOffset: alignOffset,
133
+ shouldFlip: avoidCollisions,
134
+ containerPadding: collisionPadding,
34
135
  className: cn(
35
- "ui-dropdown-menu-content data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 origin-[var(--radix-dropdown-menu-content-transform-origin)]",
136
+ "ui-dropdown-menu-content data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 origin-[var(--trigger-anchor-point)]",
36
137
  className
37
138
  ),
38
- ...props
139
+ render: (props, state) => (
140
+ // `role={undefined}`: một menu không phải một dialog — xem radixSurfaceState.
141
+ /* @__PURE__ */ jsx("div", { ...props, role: void 0, ...radixSurfaceState(state) })
142
+ ),
143
+ children: /* @__PURE__ */ jsx(Menu, { shouldFocusWrap: loop, children })
39
144
  }
40
145
  ) });
41
- });
42
- DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
43
- const DropdownMenuItem = React.forwardRef(({ className, inset, variant = "default", ...props }, ref) => /* @__PURE__ */ jsx(
44
- DropdownMenuPrimitive.Item,
45
- {
46
- ref,
47
- "data-slot": "dropdown-menu-item",
48
- "data-inset": inset,
49
- "data-variant": variant,
50
- className: cn(
51
- "ui-dropdown-menu-item [&_svg:not([class*='text-'])]:text-muted-foreground",
52
- className
53
- ),
54
- ...props
55
- }
56
- ));
57
- DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
58
- const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
59
- DropdownMenuPrimitive.Label,
60
- {
61
- ref,
62
- "data-slot": "dropdown-menu-label",
63
- "data-inset": inset,
64
- className: cn("ui-dropdown-menu-label", className),
65
- ...props
66
- }
67
- ));
68
- DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
69
- const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
70
- DropdownMenuPrimitive.Separator,
71
- {
72
- ref,
73
- "data-slot": "dropdown-menu-separator",
74
- className: cn("ui-dropdown-menu-separator", className),
75
- ...props
76
- }
77
- ));
78
- DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
79
- const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
80
- DropdownMenuPrimitive.CheckboxItem,
81
- {
82
- ref,
83
- "data-slot": "dropdown-menu-checkbox-item",
84
- className: cn("ui-dropdown-menu-checkbox-item", className),
85
- checked,
86
- ...props,
87
- children: [
88
- /* @__PURE__ */ jsx("span", { className: "ui-dropdown-menu-indicator-slot", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "ui-dropdown-menu-check", "aria-hidden": "true" }) }) }),
146
+ }
147
+ function DropdownMenuItem({
148
+ children,
149
+ className,
150
+ inset,
151
+ variant = "default",
152
+ disabled,
153
+ onSelect,
154
+ textValue,
155
+ asChild
156
+ }) {
157
+ const tag = borrowedTag(children, asChild);
158
+ return /* @__PURE__ */ jsx(
159
+ MenuItem,
160
+ {
161
+ isDisabled: disabled,
162
+ textValue,
163
+ onAction: onSelect ? () => onSelect(selectEvent("dropdownmenu.itemSelect")) : void 0,
164
+ className: cn(
165
+ "ui-dropdown-menu-item [&_svg:not([class*='text-'])]:text-muted-foreground",
166
+ className
167
+ ),
168
+ render: (props, state) => {
169
+ const { children: content, ...rest } = props;
170
+ return renderItemTag(
171
+ tag,
172
+ {
173
+ ...rest,
174
+ "data-slot": "dropdown-menu-item",
175
+ "data-inset": inset,
176
+ "data-variant": variant,
177
+ ...radixItemState(state)
178
+ },
179
+ content
180
+ );
181
+ },
182
+ children: tag ? tag.props.children : children
183
+ }
184
+ );
185
+ }
186
+ function DropdownMenuLabel({ children, className, inset, asChild }) {
187
+ return /* @__PURE__ */ jsx(
188
+ Header,
189
+ {
190
+ "data-slot": "dropdown-menu-label",
191
+ "data-inset": inset,
192
+ className: cn("ui-dropdown-menu-label", className),
193
+ render: asChild ? (props) => /* @__PURE__ */ jsx(
194
+ Slot,
195
+ {
196
+ ...props
197
+ }
198
+ ) : void 0,
89
199
  children
90
- ]
91
- }
92
- ));
93
- DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
94
- const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
95
- DropdownMenuPrimitive.RadioItem,
96
- {
97
- ref,
98
- "data-slot": "dropdown-menu-radio-item",
99
- className: cn("ui-dropdown-menu-radio-item", className),
100
- ...props,
101
- children
102
- }
103
- ));
104
- DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
105
- const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
106
- DropdownMenuPrimitive.SubTrigger,
107
- {
108
- ref,
109
- "data-slot": "dropdown-menu-sub-trigger",
110
- "data-inset": inset,
111
- className: cn(
112
- "ui-dropdown-menu-sub-trigger [&_svg:not([class*='text-'])]:text-muted-foreground",
113
- className
114
- ),
115
- ...props,
116
- children: [
117
- children,
118
- /* @__PURE__ */ jsx(ChevronRight, { className: "ui-dropdown-menu-sub-trigger-icon", "aria-hidden": "true" })
119
- ]
120
- }
121
- ));
122
- DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
123
- const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
124
- DropdownMenuPrimitive.SubContent,
125
- {
126
- ref,
127
- "data-slot": "dropdown-menu-sub-content",
128
- className: cn(
129
- "ui-dropdown-menu-sub-content data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 origin-[var(--radix-dropdown-menu-content-transform-origin)]",
130
- className
131
- ),
132
- ...props
133
- }
134
- ));
135
- DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
200
+ }
201
+ );
202
+ }
203
+ function DropdownMenuSeparator({ className }) {
204
+ return /* @__PURE__ */ jsx(
205
+ Separator,
206
+ {
207
+ "data-slot": "dropdown-menu-separator",
208
+ className: cn("ui-dropdown-menu-separator", className)
209
+ }
210
+ );
211
+ }
212
+ const CHECKBOX_KEY = "checked-item";
213
+ function DropdownMenuCheckboxItem({
214
+ children,
215
+ className,
216
+ checked,
217
+ onCheckedChange,
218
+ disabled,
219
+ textValue,
220
+ asChild
221
+ }) {
222
+ const tag = borrowedTag(children, asChild);
223
+ return /* @__PURE__ */ jsx(
224
+ MenuSection,
225
+ {
226
+ selectionMode: "multiple",
227
+ shouldCloseOnSelect: true,
228
+ selectedKeys: checked ? [CHECKBOX_KEY] : [],
229
+ onSelectionChange: (keys) => {
230
+ onCheckedChange?.(keys === "all" ? true : keys.has(CHECKBOX_KEY));
231
+ },
232
+ children: /* @__PURE__ */ jsx(
233
+ MenuItem,
234
+ {
235
+ id: CHECKBOX_KEY,
236
+ isDisabled: disabled,
237
+ textValue,
238
+ className: cn("ui-dropdown-menu-checkbox-item", className),
239
+ render: (props, state) => {
240
+ const { children: content, ...rest } = props;
241
+ return renderItemTag(
242
+ tag,
243
+ { ...rest, "data-slot": "dropdown-menu-checkbox-item", ...radixItemState(state) },
244
+ /* @__PURE__ */ jsxs(Fragment, { children: [
245
+ /* @__PURE__ */ jsx("span", { className: "ui-dropdown-menu-indicator-slot", children: state.isSelected ? /* @__PURE__ */ jsx(Check, { className: "ui-dropdown-menu-check", "aria-hidden": "true" }) : null }),
246
+ content
247
+ ] })
248
+ );
249
+ },
250
+ children: tag ? tag.props.children : children
251
+ }
252
+ )
253
+ }
254
+ );
255
+ }
256
+ function DropdownMenuRadioItem({
257
+ children,
258
+ className,
259
+ value,
260
+ disabled,
261
+ textValue,
262
+ asChild
263
+ }) {
264
+ const tag = borrowedTag(children, asChild);
265
+ return /* @__PURE__ */ jsx(
266
+ MenuItem,
267
+ {
268
+ id: value,
269
+ isDisabled: disabled,
270
+ textValue,
271
+ className: cn("ui-dropdown-menu-radio-item", className),
272
+ render: (props, state) => {
273
+ const { children: content, ...rest } = props;
274
+ return renderItemTag(
275
+ tag,
276
+ { ...rest, "data-slot": "dropdown-menu-radio-item", ...radixItemState(state) },
277
+ content
278
+ );
279
+ },
280
+ children: tag ? tag.props.children : children
281
+ }
282
+ );
283
+ }
284
+ function DropdownMenuSubTrigger({
285
+ children,
286
+ className,
287
+ inset,
288
+ disabled,
289
+ textValue,
290
+ asChild
291
+ }) {
292
+ const tag = borrowedTag(children, asChild);
293
+ return /* @__PURE__ */ jsx(
294
+ MenuItem,
295
+ {
296
+ isDisabled: disabled,
297
+ textValue,
298
+ className: cn(
299
+ "ui-dropdown-menu-sub-trigger [&_svg:not([class*='text-'])]:text-muted-foreground",
300
+ className
301
+ ),
302
+ render: (props, state) => {
303
+ const { children: content, ...rest } = props;
304
+ return renderItemTag(
305
+ tag,
306
+ {
307
+ ...rest,
308
+ "data-slot": "dropdown-menu-sub-trigger",
309
+ "data-inset": inset,
310
+ ...radixItemState(state)
311
+ },
312
+ /* @__PURE__ */ jsxs(Fragment, { children: [
313
+ content,
314
+ /* @__PURE__ */ jsx(ChevronRight, { className: "ui-dropdown-menu-sub-trigger-icon", "aria-hidden": "true" })
315
+ ] })
316
+ );
317
+ },
318
+ children: tag ? tag.props.children : children
319
+ }
320
+ );
321
+ }
322
+ function DropdownMenuSubContent({
323
+ children,
324
+ className,
325
+ align,
326
+ alignOffset,
327
+ sideOffset,
328
+ avoidCollisions,
329
+ collisionPadding,
330
+ loop,
331
+ forceMount,
332
+ hideWhenDetached,
333
+ sticky
334
+ }) {
335
+ void forceMount;
336
+ void hideWhenDetached;
337
+ void sticky;
338
+ return /* @__PURE__ */ jsx(
339
+ Popover,
340
+ {
341
+ "data-slot": "dropdown-menu-sub-content",
342
+ placement: align ? toPlacement("right", align) : void 0,
343
+ offset: sideOffset,
344
+ crossOffset: alignOffset,
345
+ shouldFlip: avoidCollisions,
346
+ containerPadding: collisionPadding,
347
+ className: cn(
348
+ "ui-dropdown-menu-sub-content data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 origin-[var(--trigger-anchor-point)]",
349
+ className
350
+ ),
351
+ render: (props, state) => (
352
+ // `role={undefined}`: một menu không phải một dialog — xem radixSurfaceState.
353
+ /* @__PURE__ */ jsx("div", { ...props, role: void 0, ...radixSurfaceState(state) })
354
+ ),
355
+ children: /* @__PURE__ */ jsx(Menu, { shouldFocusWrap: loop, children })
356
+ }
357
+ );
358
+ }
136
359
  const DropdownMenuShortcut = ({
137
360
  className,
138
361
  ...props
@@ -159,5 +382,9 @@ export {
159
382
  DropdownMenuSub,
160
383
  DropdownMenuSubContent,
161
384
  DropdownMenuSubTrigger,
162
- DropdownMenuTrigger
385
+ DropdownMenuTrigger,
386
+ radixItemState,
387
+ radixSurfaceState,
388
+ selectEvent,
389
+ toPlacement
163
390
  };
@@ -8,5 +8,7 @@ export { FilterBar, FilterBarGroup, Toolbar, ToolbarGroup } from "./filter-bar.j
8
8
  export type { FilterBarChipProp, FilterBarChipProps, FilterBarFilterProp, FilterBarFilterProps, FilterBarGroupProp, FilterBarGroupProps, FilterBarOverflowProp, FilterBarProp, FilterBarProps, FilterBarSearchProp, FilterBarSearchProps, ToolbarGroupProps, ToolbarProps, } from "./filter-bar.js";
9
9
  export { AppSettingPicker } from "./app-setting-picker.js";
10
10
  export type { AppSettingPickerProp, AppSettingPickerProps, AppSettingKind, } from "./app-setting-picker.js";
11
+ export { AppSettingToggle } from "./app-setting-toggle.js";
12
+ export type { AppSettingToggleProp, AppSettingToggleProps, AppSettingToggleKind, } from "./app-setting-toggle.js";
11
13
  export type { BreadcrumbItemProp as BreadcrumbItem } from "../../props/vocabulary/navigation.prop.js";
12
14
  export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from "./dropdown-menu.js";
@@ -53,6 +53,7 @@ import {
53
53
  import { Steps } from "./steps.js";
54
54
  import { FilterBar, FilterBarGroup, Toolbar, ToolbarGroup } from "./filter-bar.js";
55
55
  import { AppSettingPicker } from "./app-setting-picker.js";
56
+ import { AppSettingToggle } from "./app-setting-toggle.js";
56
57
  import {
57
58
  DropdownMenu,
58
59
  DropdownMenuCheckboxItem,
@@ -72,6 +73,7 @@ import {
72
73
  } from "./dropdown-menu.js";
73
74
  export {
74
75
  AppSettingPicker,
76
+ AppSettingToggle,
75
77
  ContextMenu,
76
78
  ContextMenuCheckboxItem,
77
79
  ContextMenuContent,
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Build visible page numbers with ellipsis — Ant Design / MUI pagination style. The item count is
2
+ * Build visible page numbers with ellipsis — the conventional enterprise / MUI pagination style.
3
+ * The item count is
3
4
  * CONSTANT wherever the current page sits.
4
5
  */
5
6
  export declare function buildPageRange(current: number, totalPages: number, siblingCount?: number, boundaryCount?: number): (number | "ellipsis")[];
@@ -1,20 +1,61 @@
1
1
  import * as React from "react";
2
- import * as TabsPrimitive from "@radix-ui/react-tabs";
3
2
  export type TabsItem = {
4
3
  value: string;
5
4
  label: React.ReactNode;
6
5
  content: React.ReactNode;
7
6
  disabled?: boolean;
8
7
  };
9
- export type TabsProps = React.ComponentProps<typeof TabsPrimitive.Root> & {
8
+ export type TabsOrientation = "vertical" | "horizontal";
9
+ /**
10
+ * The repo's Radix-era vocabulary, kept VERBATIM. React Aria spells the same four things
11
+ * `selectedKey` / `defaultSelectedKey` / `onSelectionChange` / `keyboardActivation`; the
12
+ * translation lives inside this file so no consumer ever has to learn RAC's names.
13
+ *
14
+ * `activationMode` is the one that MUST NOT be dropped. `.ai/rules/settings.md` in the consumer
15
+ * requires `orientation="vertical"` + `activationMode="manual"` for the settings rail, because
16
+ * every item there is a URL — automatic activation would load four pages while the reader is only
17
+ * arrowing past them.
18
+ */
19
+ export type TabsProps = Omit<React.ComponentPropsWithoutRef<"div">, "defaultValue" | "dir"> & {
20
+ /** Controlled selected tab — RAC `selectedKey`. */
21
+ value?: string;
22
+ /** Uncontrolled initial selection — RAC `defaultSelectedKey`. */
23
+ defaultValue?: string;
24
+ /** Fired with the NEW selected value — RAC `onSelectionChange`. */
25
+ onValueChange?: (value: string) => void;
26
+ orientation?: TabsOrientation;
27
+ /**
28
+ * DOM attribute only. Under Radix this also steered RTL arrow keys; React Aria reads the
29
+ * direction from the locale, so an RTL app must set it through `I18nProvider`.
30
+ */
31
+ dir?: "ltr" | "rtl";
32
+ /** `"manual"` = arrow keys move focus without selecting — RAC `keyboardActivation`. */
33
+ activationMode?: "manual" | "automatic";
10
34
  items?: TabsItem[];
11
35
  variant?: "default" | "line" | "card";
12
36
  listClassName?: string;
13
37
  contentClassName?: string;
14
38
  };
15
- export declare function Tabs({ className, orientation, items, value, defaultValue, variant, listClassName, contentClassName, ...props }: TabsProps): React.JSX.Element;
16
- export declare const TabsList: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsListProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
39
+ export declare function Tabs({ className, orientation, items, value, defaultValue, onValueChange, activationMode, dir, variant, listClassName, contentClassName, children, ...props }: TabsProps): React.JSX.Element;
40
+ export declare const TabsList: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
17
41
  variant?: "default" | "line";
42
+ /**
43
+ * ACCEPTED AND IGNORED. Radix's `RovingFocusGroup` took a `loop` switch; React Aria's tab list
44
+ * always wraps at the ends and exposes no equivalent knob. The prop stays so no consumer's build
45
+ * breaks. No test records this: the claim worth pinning would have been "both libraries wrap
46
+ * by default", and once Radix is gone there is no second library left to compare against.
47
+ */
48
+ loop?: boolean;
49
+ } & React.RefAttributes<HTMLDivElement>>;
50
+ export declare const TabsTrigger: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "value"> & {
51
+ /** The tab's key — RAC `id` (its DOM `id` stays RAC-generated, exactly as Radix generated one). */
52
+ value: string;
53
+ /** RAC `isDisabled`; ALSO written to the button so `disabled:` utilities keep matching. */
54
+ disabled?: boolean;
55
+ } & React.RefAttributes<HTMLButtonElement>>;
56
+ export declare const TabsContent: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "value"> & {
57
+ /** The panel's key — must match a `TabsTrigger value`. RAC `id`. */
58
+ value: string;
59
+ /** Keep the panel mounted while another tab is selected — RAC `shouldForceMount`. */
60
+ forceMount?: true;
18
61
  } & React.RefAttributes<HTMLDivElement>>;
19
- export declare const TabsTrigger: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
20
- export declare const TabsContent: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;