@godxjp/ui 23.2.1 → 23.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/app/timezones.js +2 -1
  2. package/dist/components/charts/chart-cartesian.js +2 -4
  3. package/dist/components/charts/chart-frame.js +2 -1
  4. package/dist/components/data-display/card.d.ts +87 -1
  5. package/dist/components/data-display/card.js +88 -15
  6. package/dist/components/data-display/index.d.ts +5 -1
  7. package/dist/components/data-display/index.js +5 -0
  8. package/dist/components/data-display/thought-chain.d.ts +42 -0
  9. package/dist/components/data-display/thought-chain.js +177 -0
  10. package/dist/components/data-display/welcome.d.ts +26 -0
  11. package/dist/components/data-display/welcome.js +37 -0
  12. package/dist/components/data-entry/attachments.d.ts +19 -0
  13. package/dist/components/data-entry/attachments.js +322 -0
  14. package/dist/components/data-entry/date-picker.js +12 -14
  15. package/dist/components/data-entry/index.d.ts +2 -0
  16. package/dist/components/data-entry/index.js +2 -0
  17. package/dist/components/data-entry/number-input.js +2 -1
  18. package/dist/components/feedback/dialog.d.ts +10 -7
  19. package/dist/components/feedback/dialog.js +40 -17
  20. package/dist/components/feedback/index.d.ts +3 -3
  21. package/dist/components/feedback/index.js +2 -0
  22. package/dist/components/feedback/skeleton.d.ts +11 -2
  23. package/dist/components/feedback/skeleton.js +8 -0
  24. package/dist/components/general/actions.d.ts +59 -0
  25. package/dist/components/general/actions.js +253 -0
  26. package/dist/components/general/activity.js +1 -0
  27. package/dist/components/general/button.js +2 -1
  28. package/dist/components/general/float-button.d.ts +41 -0
  29. package/dist/components/general/float-button.js +336 -0
  30. package/dist/components/general/index.d.ts +6 -2
  31. package/dist/components/general/index.js +12 -1
  32. package/dist/components/general/typography.d.ts +79 -4
  33. package/dist/components/general/typography.js +598 -54
  34. package/dist/components/layout/draggable-panel.d.ts +18 -0
  35. package/dist/components/layout/draggable-panel.js +189 -0
  36. package/dist/components/layout/error-surface.js +3 -2
  37. package/dist/components/layout/index.d.ts +2 -0
  38. package/dist/components/layout/index.js +2 -0
  39. package/dist/components/navigation/conversations.d.ts +39 -0
  40. package/dist/components/navigation/conversations.js +371 -0
  41. package/dist/components/navigation/index.d.ts +2 -0
  42. package/dist/components/navigation/index.js +2 -0
  43. package/dist/components/ui/card.js +1 -0
  44. package/dist/components/ui/toggle.js +2 -1
  45. package/dist/i18n/messages/en.json +53 -0
  46. package/dist/i18n/messages/ja.json +53 -0
  47. package/dist/i18n/messages/vi.json +53 -0
  48. package/dist/i18n/translate.js +3 -2
  49. package/dist/lib/datetime/picker-format.js +2 -1
  50. package/dist/lib/format.js +3 -2
  51. package/dist/lib/intl-cache.d.ts +32 -0
  52. package/dist/lib/intl-cache.js +29 -0
  53. package/dist/props/components/data-display.prop.d.ts +143 -1
  54. package/dist/props/components/data-entry.prop.d.ts +87 -0
  55. package/dist/props/components/feedback.prop.d.ts +53 -1
  56. package/dist/props/components/general.prop.d.ts +440 -3
  57. package/dist/props/components/index.d.ts +2 -2
  58. package/dist/props/components/layout.prop.d.ts +63 -1
  59. package/dist/props/components/navigation.prop.d.ts +150 -0
  60. package/dist/props/registry.d.ts +431 -0
  61. package/dist/props/registry.js +551 -0
  62. package/dist/props/vocabulary/index.d.ts +1 -1
  63. package/dist/props/vocabulary/interaction.prop.d.ts +113 -0
  64. package/dist/styles/alert-layout.css +22 -0
  65. package/dist/styles/card-layout.css +34 -0
  66. package/dist/styles/core.css +1 -0
  67. package/dist/styles/data-display-layout.css +236 -0
  68. package/dist/styles/float-button-layout.css +168 -0
  69. package/dist/styles/form-layout.css +11 -1
  70. package/dist/styles/index.css +1 -0
  71. package/dist/styles/layout.css +196 -0
  72. package/dist/styles/navigation-layout.css +139 -0
  73. package/dist/styles/text-layout.css +156 -0
  74. package/dist/tokens/axes.css +5 -0
  75. package/dist/tokens/base.css +7 -0
  76. package/dist/tokens/components/actions.css +14 -0
  77. package/dist/tokens/components/attachments.css +15 -0
  78. package/dist/tokens/components/conversations.css +28 -0
  79. package/dist/tokens/components/draggable-panel.css +25 -0
  80. package/dist/tokens/components/float-button.css +39 -0
  81. package/dist/tokens/components/text.css +13 -0
  82. package/dist/tokens/components/thought-chain.css +31 -0
  83. package/dist/tokens/components/welcome.css +19 -0
  84. package/dist/tokens/foundation.css +6 -4
  85. package/docs/DESIGN-AUTHORITY.md +133 -20
  86. package/docs/FRAME-COVERAGE-REPORT.md +5 -2
  87. package/docs/data-display/card/examples/tab-list.tsx +97 -0
  88. package/docs/data-display/thought-chain.tsx +176 -0
  89. package/docs/data-display/welcome.tsx +115 -0
  90. package/docs/data-entry/attachments.tsx +160 -0
  91. package/docs/feedback/dialog.tsx +50 -0
  92. package/docs/general/actions.tsx +175 -0
  93. package/docs/general/float-button.tsx +133 -0
  94. package/docs/general/typography.tsx +63 -1
  95. package/docs/layout/draggable-panel.tsx +127 -0
  96. package/docs/navigation/conversations.tsx +176 -0
  97. package/docs/roadmap/parity-audit-layout-navigation-general.md +17 -16
  98. package/package.json +20 -4
  99. package/scripts/_agent-setup.mjs +36 -5
  100. package/scripts/guinea-pig-skill.md +14 -0
  101. package/scripts/ui-audit.mjs +69 -9
@@ -1,5 +1,6 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { ImageIcon } from "lucide-react";
3
+ import { ResponsiveGrid } from "../layout/responsive-grid.js";
3
4
  import { cn } from "../../lib/utils.js";
4
5
  import { tableCellPaddingClass, tableRowHeightClass } from "../../lib/control-styles.js";
5
6
  function measureStyle(width) {
@@ -169,6 +170,12 @@ function SkeletonRows({ rows = 6, columns = 4, className }) {
169
170
  j
170
171
  )) }, i)) });
171
172
  }
173
+ function SkeletonForm({ columns = 1, fields = 6, active, className }) {
174
+ return /* @__PURE__ */ jsx("div", { className: cn("ui-skeleton-form", className), "aria-busy": "true", children: /* @__PURE__ */ jsx(ResponsiveGrid, { columns, children: Array.from({ length: fields }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-form-field", children: [
175
+ /* @__PURE__ */ jsx(Skeleton, { active, className: "ui-skeleton-form-label" }),
176
+ /* @__PURE__ */ jsx(Skeleton, { active, className: "ui-skeleton-form-control" })
177
+ ] }, i)) }) });
178
+ }
172
179
  function SkeletonTable({ rows = 8, columns = 5 }) {
173
180
  return /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-table", "aria-busy": "true", children: [
174
181
  /* @__PURE__ */ jsx("div", { className: cn("ui-skeleton-table-head", tableCellPaddingClass, tableRowHeightClass), children: Array.from({ length: columns }).map((_, j) => /* @__PURE__ */ jsx(Skeleton, { className: cn("ui-skeleton-caption", j === 0 ? "w-1/5" : "flex-1") }, j)) }),
@@ -205,6 +212,7 @@ export {
205
212
  SkeletonAvatar,
206
213
  SkeletonButton,
207
214
  SkeletonDetail,
215
+ SkeletonForm,
208
216
  SkeletonImage,
209
217
  SkeletonInput,
210
218
  SkeletonNode,
@@ -0,0 +1,59 @@
1
+ import * as React from "react";
2
+ import type { ActionsCopyProp, ActionsFeedbackProp, ActionsItemProp, ActionsProp } from "../../props/components/general.prop.js";
3
+ export type { ActionsProp, ActionsProp as ActionsProps, ActionsItemsProp, ActionsItemProp, ActionsItemProp as ActionsItemProps, ActionsCopyProp, ActionsCopyProp as ActionsCopyProps, ActionsFeedbackProp, ActionsFeedbackProp as ActionsFeedbackProps, ActionsVariantProp, ActionsStatusProp, ActionsFeedbackValueProp, } from "../../props/components/general.prop.js";
4
+ /**
5
+ * Actions — the strip of actions under an assistant message (Ant Design X `Actions`).
6
+ *
7
+ * ## What Ant X ships, measured
8
+ *
9
+ * `@ant-design/x@2.9.0`, `es/actions/Item.js`: each action is
10
+ * `<div className="…-item" onClick>` wrapping `<div className="…-icon">{item.icon}</div>`, with
11
+ * the label supplied only as a `Tooltip` title. Three consequences, all of them defects rather
12
+ * than choices: the strip cannot be reached by keyboard at all, the actions have no accessible
13
+ * name, and on a touch device — where `useMobile()` drops the Tooltip entirely — they have no
14
+ * visible name either.
15
+ *
16
+ * ## What this port does about it, while keeping the API
17
+ *
18
+ * `items`, `onClick({ item, key, keyPath, domEvent })`, `onItemClick` winning over `onClick`,
19
+ * `danger`, `subItems`, `actionRender`, `variant`, `fadeIn` / `fadeInLeft` — all Ant's, with Ant's
20
+ * semantics. What changes is what they render onto: a real `Button` per action carrying `label` as
21
+ * its accessible name AND its tooltip, inside a WAI-ARIA APG **Toolbar** — one tab stop for the
22
+ * whole strip, the logical arrows moving between the actions, `Home` / `End` at its ends. That is
23
+ * the same trade `Conversations` makes and for the same reason: a strip of eight actions under
24
+ * every message would otherwise be eight tab stops between the reader and the next message.
25
+ */
26
+ export declare const Actions: React.ForwardRefExoticComponent<ActionsProp & React.RefAttributes<HTMLDivElement>>;
27
+ /**
28
+ * ActionsItem — one status-aware action (Ant Design X `Actions.Item`).
29
+ *
30
+ * It is a NAMED export rather than `Actions.Item`, because this library has no compound-static
31
+ * convention: `CardHeader`, `TabsList` and `DropdownMenuItem` are all separate exports, and one
32
+ * component attaching statics would be the only one of its kind.
33
+ *
34
+ * The status table is Ant's, from `es/actions/ActionsItem.js`: `loading` and `error` bring their
35
+ * own glyph, `running` takes `runningIcon`, anything else takes `defaultIcon`. What is added is
36
+ * that the status is ANNOUNCED — `aria-busy` while loading, and the state in the accessible name —
37
+ * because a glyph swap is a colour-and-shape-only signal (WCAG 1.4.1).
38
+ */
39
+ export declare const ActionsItem: React.ForwardRefExoticComponent<ActionsItemProp & React.RefAttributes<HTMLButtonElement>>;
40
+ /**
41
+ * ActionsCopy — copy the message to the clipboard (Ant Design X `Actions.Copy`).
42
+ *
43
+ * Ant X hands this to antd's `Typography copyable`, which swaps the glyph to a tick for 3s. The
44
+ * tick is reproduced at the same 3s, and the change is also SPOKEN through a polite status region:
45
+ * a glyph that only changes shape tells a screen-reader user nothing about whether the copy
46
+ * worked, which is the one thing this control exists to report.
47
+ */
48
+ export declare const ActionsCopy: React.ForwardRefExoticComponent<ActionsCopyProp & React.RefAttributes<HTMLButtonElement>>;
49
+ /**
50
+ * ActionsFeedback — the like / dislike pair (Ant Design X `Actions.Feedback`).
51
+ *
52
+ * `value` / `onChange` and the clear-on-second-click behaviour are Ant's, byte for byte. ONE
53
+ * rendering difference, and it is deliberate: Ant hides the opposite button once an opinion is
54
+ * recorded (`[default, like].includes(value) && likeNode`), so a reader who mis-clicked "dislike"
55
+ * finds no "like" button on the screen at all and has to guess that clicking dislike again brings
56
+ * it back. Both buttons stay here, and the recorded opinion is carried by `aria-pressed` — the APG
57
+ * toggle-button pattern, which states the value instead of removing its alternative.
58
+ */
59
+ export declare const ActionsFeedback: React.ForwardRefExoticComponent<ActionsFeedbackProp & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,253 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Check, Copy, MoreHorizontal, ThumbsDown, ThumbsUp, TriangleAlert } from "lucide-react";
5
+ import { useTranslation } from "../../i18n/use-translation.js";
6
+ import { cn } from "../../lib/utils.js";
7
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../feedback/tooltip.js";
8
+ import {
9
+ DropdownMenu,
10
+ DropdownMenuContent,
11
+ DropdownMenuItem,
12
+ DropdownMenuTrigger
13
+ } from "../navigation/dropdown-menu.js";
14
+ import { Button } from "./button.js";
15
+ import { VisuallyHidden } from "./visually-hidden.js";
16
+ function isRtl(element) {
17
+ return element?.closest("[dir]")?.getAttribute("dir")?.toLowerCase() === "rtl";
18
+ }
19
+ function LabelledIconButton({
20
+ label,
21
+ children,
22
+ ...props
23
+ }) {
24
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
25
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { type: "button", size: "icon-sm", variant: "ghost", "aria-label": label, ...props, children }) }),
26
+ /* @__PURE__ */ jsx(TooltipContent, { children: label })
27
+ ] });
28
+ }
29
+ const Actions = React.forwardRef(
30
+ ({ items, onClick, variant = "borderless", fadeIn, fadeInLeft, label, id, className, ...rest }, ref) => {
31
+ const { t } = useTranslation();
32
+ const nodes = React.useRef(/* @__PURE__ */ new Map());
33
+ const [focusKey, setFocusKey] = React.useState(null);
34
+ const navKeys = items.filter((item) => !item.actionRender).map((item) => item.key);
35
+ const tabStop = focusKey && navKeys.includes(focusKey) ? focusKey : navKeys[0];
36
+ const moveTo = (key) => {
37
+ if (!key) return;
38
+ setFocusKey(key);
39
+ nodes.current.get(key)?.focus();
40
+ };
41
+ const handleKeyDown = (key) => (event) => {
42
+ const rtl = isRtl(event.currentTarget);
43
+ const forward = rtl ? "ArrowLeft" : "ArrowRight";
44
+ const backward = rtl ? "ArrowRight" : "ArrowLeft";
45
+ const index = navKeys.indexOf(key);
46
+ if (event.key === forward) {
47
+ event.preventDefault();
48
+ moveTo(navKeys[(index + 1) % navKeys.length]);
49
+ } else if (event.key === backward) {
50
+ event.preventDefault();
51
+ moveTo(navKeys[(index - 1 + navKeys.length) % navKeys.length]);
52
+ } else if (event.key === "Home") {
53
+ event.preventDefault();
54
+ moveTo(navKeys[0]);
55
+ } else if (event.key === "End") {
56
+ event.preventDefault();
57
+ moveTo(navKeys[navKeys.length - 1]);
58
+ }
59
+ };
60
+ const dispatch = (item, keyPath, domEvent) => {
61
+ if (item.onItemClick) {
62
+ item.onItemClick(item);
63
+ return;
64
+ }
65
+ onClick?.({ item, key: keyPath[0], keyPath, domEvent });
66
+ };
67
+ return /* @__PURE__ */ jsx(
68
+ "div",
69
+ {
70
+ ref,
71
+ id,
72
+ role: "toolbar",
73
+ "aria-label": label ?? t("general.actions.label"),
74
+ "aria-orientation": "horizontal",
75
+ "data-slot": "actions",
76
+ "data-variant": variant,
77
+ "data-fade-in": fadeIn || fadeInLeft ? "" : void 0,
78
+ "data-fade-in-inline": fadeInLeft ? "" : void 0,
79
+ className: cn("ui-actions", className),
80
+ ...rest,
81
+ children: items.map((item) => {
82
+ if (item.actionRender) {
83
+ return /* @__PURE__ */ jsx(React.Fragment, { children: typeof item.actionRender === "function" ? item.actionRender(item) : item.actionRender }, item.key);
84
+ }
85
+ const name = item.label ?? item.key;
86
+ const shared = {
87
+ ref: (node) => {
88
+ if (node) nodes.current.set(item.key, node);
89
+ else nodes.current.delete(item.key);
90
+ },
91
+ tabIndex: tabStop === item.key ? 0 : -1,
92
+ onFocus: () => setFocusKey(item.key),
93
+ onKeyDown: handleKeyDown(item.key),
94
+ variant: item.danger ? "destructive" : "ghost"
95
+ };
96
+ if (item.subItems && item.subItems.length > 0) {
97
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
98
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { type: "button", size: "icon-sm", "aria-label": name, ...shared, children: item.icon ?? /* @__PURE__ */ jsx(MoreHorizontal, { "aria-hidden": "true" }) }) }),
99
+ /* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", children: item.subItems.map((sub) => /* @__PURE__ */ jsxs(
100
+ DropdownMenuItem,
101
+ {
102
+ variant: sub.danger ? "destructive" : void 0,
103
+ onSelect: (event) => dispatch(
104
+ sub,
105
+ [sub.key, item.key],
106
+ event
107
+ ),
108
+ children: [
109
+ sub.icon,
110
+ sub.label ?? sub.key
111
+ ]
112
+ },
113
+ sub.key
114
+ )) })
115
+ ] }, item.key);
116
+ }
117
+ return /* @__PURE__ */ jsx(
118
+ LabelledIconButton,
119
+ {
120
+ label: name,
121
+ onClick: (event) => dispatch(item, [item.key], event),
122
+ ...shared,
123
+ children: item.icon
124
+ },
125
+ item.key
126
+ );
127
+ })
128
+ }
129
+ );
130
+ }
131
+ );
132
+ Actions.displayName = "Actions";
133
+ const ActionsItem = React.forwardRef(
134
+ ({ status = "default", defaultIcon, runningIcon, label, id, className, ...rest }, ref) => {
135
+ const { t } = useTranslation();
136
+ const base = label ?? t("general.actions.label");
137
+ const name = status === "default" ? base : `${base} \xB7 ${t(`general.actions.status.${status}`)}`;
138
+ const glyph = status === "loading" ? null : status === "error" ? /* @__PURE__ */ jsx(TriangleAlert, { "aria-hidden": "true" }) : status === "running" ? runningIcon ?? defaultIcon : defaultIcon;
139
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
140
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
141
+ Button,
142
+ {
143
+ ref,
144
+ id,
145
+ type: "button",
146
+ size: "icon-sm",
147
+ variant: "ghost",
148
+ "data-slot": "actions-item",
149
+ "data-status": status,
150
+ "aria-label": name,
151
+ "aria-busy": status === "loading" || void 0,
152
+ loading: status === "loading",
153
+ className: cn("ui-actions-item", className),
154
+ ...rest,
155
+ children: glyph
156
+ }
157
+ ) }),
158
+ /* @__PURE__ */ jsx(TooltipContent, { children: name })
159
+ ] });
160
+ }
161
+ );
162
+ ActionsItem.displayName = "ActionsItem";
163
+ const ActionsCopy = React.forwardRef(
164
+ ({ text = "", icon, label, onCopy, id, className, ...rest }, ref) => {
165
+ const { t } = useTranslation();
166
+ const [copied, setCopied] = React.useState(false);
167
+ const timer = React.useRef(void 0);
168
+ React.useEffect(() => () => clearTimeout(timer.current), []);
169
+ const name = label ?? t("general.actions.copy");
170
+ const run = async () => {
171
+ try {
172
+ await navigator.clipboard?.writeText(text);
173
+ } catch {
174
+ return;
175
+ }
176
+ onCopy?.(text);
177
+ setCopied(true);
178
+ clearTimeout(timer.current);
179
+ timer.current = setTimeout(() => setCopied(false), 3e3);
180
+ };
181
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
182
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
183
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
184
+ Button,
185
+ {
186
+ ref,
187
+ id,
188
+ type: "button",
189
+ size: "icon-sm",
190
+ variant: "ghost",
191
+ "data-slot": "actions-copy",
192
+ "data-copied": copied ? "" : void 0,
193
+ "aria-label": name,
194
+ className: cn("ui-actions-copy", className),
195
+ onClick: run,
196
+ ...rest,
197
+ children: copied ? /* @__PURE__ */ jsx(Check, { "aria-hidden": "true" }) : icon ?? /* @__PURE__ */ jsx(Copy, { "aria-hidden": "true" })
198
+ }
199
+ ) }),
200
+ /* @__PURE__ */ jsx(TooltipContent, { children: name })
201
+ ] }),
202
+ /* @__PURE__ */ jsx(VisuallyHidden, { role: "status", "aria-live": "polite", children: copied ? t("general.actions.copied") : "" })
203
+ ] });
204
+ }
205
+ );
206
+ ActionsCopy.displayName = "ActionsCopy";
207
+ const ActionsFeedback = React.forwardRef(
208
+ ({ value = "default", onChange, label, likeLabel, dislikeLabel, id, className, ...rest }, ref) => {
209
+ const { t } = useTranslation();
210
+ const toggle = (next) => onChange?.(value === next ? "default" : next);
211
+ return /* @__PURE__ */ jsxs(
212
+ "div",
213
+ {
214
+ ref,
215
+ id,
216
+ role: "group",
217
+ "aria-label": label ?? t("general.actions.feedback"),
218
+ "data-slot": "actions-feedback",
219
+ className: cn("ui-actions-feedback", className),
220
+ ...rest,
221
+ children: [
222
+ /* @__PURE__ */ jsx(
223
+ LabelledIconButton,
224
+ {
225
+ label: likeLabel ?? t("general.actions.like"),
226
+ "aria-pressed": value === "like",
227
+ "data-pressed": value === "like" ? "" : void 0,
228
+ onClick: () => toggle("like"),
229
+ children: /* @__PURE__ */ jsx(ThumbsUp, { "aria-hidden": "true" })
230
+ }
231
+ ),
232
+ /* @__PURE__ */ jsx(
233
+ LabelledIconButton,
234
+ {
235
+ label: dislikeLabel ?? t("general.actions.dislike"),
236
+ "aria-pressed": value === "dislike",
237
+ "data-pressed": value === "dislike" ? "" : void 0,
238
+ onClick: () => toggle("dislike"),
239
+ children: /* @__PURE__ */ jsx(ThumbsDown, { "aria-hidden": "true" })
240
+ }
241
+ )
242
+ ]
243
+ }
244
+ );
245
+ }
246
+ );
247
+ ActionsFeedback.displayName = "ActionsFeedback";
248
+ export {
249
+ Actions,
250
+ ActionsCopy,
251
+ ActionsFeedback,
252
+ ActionsItem
253
+ };
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
3
  import * as React from "react";
3
4
  import { cn } from "../../lib/utils.js";
@@ -6,6 +6,7 @@ import { cva } from "class-variance-authority";
6
6
  import { Loader2 } from "lucide-react";
7
7
  import { cn } from "../../lib/utils.js";
8
8
  import { useTranslation } from "../../i18n/use-translation.js";
9
+ import { numberFormat } from "../../lib/intl-cache.js";
9
10
  const buttonVariants = cva("ui-button", {
10
11
  variants: {
11
12
  variant: {
@@ -78,7 +79,7 @@ const Button = React.forwardRef(
78
79
  loadingText ?? children
79
80
  ] }) : children;
80
81
  const showCount = !asChild && count != null && (count !== 0 || showZero);
81
- const countLabel = showCount && count != null && count > overflowCount ? `${new Intl.NumberFormat(locale).format(overflowCount)}+` : count != null ? new Intl.NumberFormat(locale).format(count) : "";
82
+ const countLabel = showCount && count != null && count > overflowCount ? `${numberFormat(locale).format(overflowCount)}+` : count != null ? numberFormat(locale).format(count) : "";
82
83
  const countNode = showCount ? /* @__PURE__ */ jsx("span", { "data-slot": "button-count", className: "ui-button-count", children: countLabel }) : null;
83
84
  return /* @__PURE__ */ jsx(
84
85
  Comp,
@@ -0,0 +1,41 @@
1
+ import * as React from "react";
2
+ import type { FloatButtonBackTopProp, FloatButtonGroupProp, FloatButtonShapeProp, FloatButtonTooltipProp, FloatButtonTypeProp } from "../../props/components/general.prop.js";
3
+ export type { FloatButtonBackTopProp, FloatButtonBackTopProp as FloatButtonBackTopProps, FloatButtonBadgeProp, FloatButtonGroupProp, FloatButtonGroupProp as FloatButtonGroupProps, FloatButtonPlacementProp, FloatButtonProp, FloatButtonProp as FloatButtonProps, FloatButtonShapeProp, FloatButtonTooltipProp, FloatButtonTriggerProp, FloatButtonTypeProp, } from "../../props/components/general.prop.js";
4
+ /**
5
+ * FloatButton.Group — a stack of corner actions, optionally behind one trigger.
6
+ *
7
+ * Two modes, and `trigger` is the switch, exactly as in antd: WITHOUT it every child is visible and
8
+ * no trigger is drawn; WITH it the children collapse behind a trigger that opens them on click or
9
+ * on hover.
10
+ */
11
+ declare function FloatButtonGroup({ children, trigger, open, onOpenChange, closeIcon, placement, shape, type, icon, disabled, className, onClick, ...rest }: FloatButtonGroupProp): React.JSX.Element;
12
+ /**
13
+ * FloatButton.BackTop — the corner action that returns a scroll container to the top.
14
+ *
15
+ * `target` is antd's, and it is the answer to the objection that a document-bound BackTop competes
16
+ * with a shell that owns its own scroll: pass `() => element` and this watches that element, not
17
+ * the document. Under `prefers-reduced-motion` the scroll is instant rather than tweened
18
+ * (WCAG 2.3.3), which is antd's behaviour too.
19
+ */
20
+ declare function FloatButtonBackTop({ visibilityHeight, target, duration, showProgress, onClick, icon, tooltip, className, ...rest }: FloatButtonBackTopProp): React.JSX.Element | null;
21
+ /**
22
+ * The compound, exactly as antd exports it: one name, two sub-parts on it. A consumer porting a
23
+ * screen writes `<FloatButton.Group>` / `<FloatButton.BackTop>` unchanged.
24
+ */
25
+ export declare const FloatButton: React.ForwardRefExoticComponent<Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "color" | "content" | "type"> & {
26
+ icon?: import("../../props/index.js").ChildrenProp;
27
+ description?: import("../../props/index.js").DescriptionProp;
28
+ content?: import("../../props/index.js").ChildrenProp;
29
+ type?: FloatButtonTypeProp;
30
+ shape?: FloatButtonShapeProp;
31
+ tooltip?: import("../../props/index.js").ChildrenProp | FloatButtonTooltipProp;
32
+ href?: string;
33
+ target?: React.HTMLAttributeAnchorTarget;
34
+ badge?: import("./float-button.js").FloatButtonBadgeProp;
35
+ disabled?: import("../../props/index.js").DisabledProp;
36
+ htmlType?: "button" | "submit" | "reset";
37
+ className?: import("../../props/index.js").ClassNameProp;
38
+ } & React.RefAttributes<HTMLElement>> & {
39
+ Group: typeof FloatButtonGroup;
40
+ BackTop: typeof FloatButtonBackTop;
41
+ };