@bysages/react 0.3.0 → 0.3.1

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 (55) hide show
  1. package/dist/{ai-response-jZy-0Tvv.mjs → ai-response-BfKTmtCt.mjs} +8 -4
  2. package/dist/components/ai/index.d.mts +2 -2
  3. package/dist/components/ai/index.mjs +25 -10
  4. package/dist/components/ai-attachments/index.mjs +3 -1
  5. package/dist/components/ai-prompt-input/index.d.mts +1 -1
  6. package/dist/components/ai-prompt-input/index.mjs +8 -4
  7. package/dist/components/ai-response/index.d.mts +4 -2
  8. package/dist/components/ai-response/index.mjs +1 -1
  9. package/dist/components/autocomplete/index.mjs +3 -1
  10. package/dist/components/banner/index.mjs +21 -17
  11. package/dist/components/breadcrumb/index.d.mts +3 -8
  12. package/dist/components/breadcrumb/index.mjs +11 -1
  13. package/dist/components/cascade-select/index.mjs +6 -2
  14. package/dist/components/command/index.mjs +9 -3
  15. package/dist/components/config-provider/index.d.mts +5 -2
  16. package/dist/components/config-provider/index.mjs +3 -2
  17. package/dist/components/data-view/index.mjs +4 -2
  18. package/dist/components/dynamic-input/index.mjs +3 -1
  19. package/dist/components/file-upload/index.d.mts +8 -1
  20. package/dist/components/file-upload/index.mjs +20 -1
  21. package/dist/components/float-button/index.mjs +3 -1
  22. package/dist/components/image/index.d.mts +7 -1
  23. package/dist/components/image/index.mjs +3 -1
  24. package/dist/components/image-viewer/index.d.mts +7 -1
  25. package/dist/components/image-viewer/index.mjs +8 -4
  26. package/dist/components/json-tree-view/index.d.mts +3 -3
  27. package/dist/components/json-tree-view/index.mjs +17 -4
  28. package/dist/components/layout/index.mjs +3 -1
  29. package/dist/components/list/index.d.mts +5 -4
  30. package/dist/components/list/index.mjs +10 -1
  31. package/dist/components/menubar/index.mjs +1 -0
  32. package/dist/components/order-list/index.mjs +8 -9
  33. package/dist/components/select/index.d.mts +1 -1
  34. package/dist/components/select/index.mjs +1 -1
  35. package/dist/components/spinner/index.mjs +3 -1
  36. package/dist/components/split-button/index.mjs +3 -1
  37. package/dist/components/steps/index.d.mts +5 -1
  38. package/dist/components/steps/index.mjs +10 -1
  39. package/dist/components/table/index.mjs +19 -15
  40. package/dist/components/terminal/index.mjs +5 -2
  41. package/dist/components/toc/index.d.mts +7 -1
  42. package/dist/components/toc/index.mjs +13 -1
  43. package/dist/components/transfer/index.mjs +6 -4
  44. package/dist/components/tree-select/index.mjs +4 -2
  45. package/dist/components/tree-view/index.d.mts +10 -1
  46. package/dist/components/tree-view/index.mjs +22 -1
  47. package/dist/components/virtual-list/index.mjs +1 -0
  48. package/dist/glyph-VI989p8H.mjs +14 -0
  49. package/dist/{index-CsfxYv6J.d.mts → index-Dn5mHf1g.d.mts} +6 -21
  50. package/dist/{index-DFN9F5Zt.d.mts → index-Iy8m0Qev.d.mts} +1 -1
  51. package/dist/index.d.mts +3 -3
  52. package/dist/index.mjs +5 -5
  53. package/dist/messages-1jJWtaYU.mjs +16 -0
  54. package/dist/{select-D1xiT1oJ.mjs → select-eAHutw56.mjs} +3 -1
  55. package/package.json +3 -3
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "./messages-1jJWtaYU.mjs";
1
2
  import { injectComponentStyle } from "@bysages/core";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  import { useEffect, useRef } from "react";
@@ -99,20 +100,23 @@ function wrapResponseTables(root) {
99
100
  }
100
101
  //#endregion
101
102
  //#region src/components/ai-response/index.tsx
102
- function Response({ content, highlighter, copyLabel = "Copy code", copiedLabel = "Copied", ...rest }) {
103
+ function Response({ content, highlighter, copyLabel, copiedLabel, ...rest }) {
103
104
  injectComponentStyle("ai");
105
+ const messages = useComponentMessages();
106
+ const resolvedCopyLabel = copyLabel ?? messages.ai.copyCode;
107
+ const resolvedCopiedLabel = copiedLabel ?? messages.ai.copied;
104
108
  const root = useRef(null);
105
109
  useEffect(() => {
106
110
  const host = root.current;
107
- if (host) decorateCodeCopy(host, copyLabel);
111
+ if (host) decorateCodeCopy(host, resolvedCopyLabel);
108
112
  if (host) wrapResponseTables(host);
109
113
  }, [
110
114
  content,
111
115
  highlighter,
112
- copyLabel
116
+ resolvedCopyLabel
113
117
  ]);
114
118
  const onClick = (event) => {
115
- clickCodeCopy(event.nativeEvent, copyLabel, copiedLabel);
119
+ clickCodeCopy(event.nativeEvent, resolvedCopyLabel, resolvedCopiedLabel);
116
120
  };
117
121
  return /* @__PURE__ */ jsx("div", {
118
122
  ...rest,
@@ -1,2 +1,2 @@
1
- import { a as AiLoader, c as ReasoningUIPart, d as StepStartUIPart, f as TextUIPart, h as UIMessagePart, i as AiConversation, l as SourceDocumentUIPart, m as UIMessage, n as AiActions, o as DataUIPart, p as ToolUIPart, r as AiContent, s as FileUIPart, t as Ai, u as SourceUrlUIPart } from "../../index-CsfxYv6J.mjs";
2
- export { Ai, AiActions, AiContent, AiConversation, AiLoader, type DataUIPart, type FileUIPart, type ReasoningUIPart, type SourceDocumentUIPart, type SourceUrlUIPart, type StepStartUIPart, type TextUIPart, type ToolUIPart, type UIMessage, type UIMessagePart };
1
+ import { a as FileUIPart, c as SourceUrlUIPart, d as ToolUIPart, f as UIMessage, i as DataUIPart, l as StepStartUIPart, n as AiActions, o as ReasoningUIPart, p as UIMessagePart, r as AiContent, s as SourceDocumentUIPart, t as Ai, u as TextUIPart } from "../../index-Dn5mHf1g.mjs";
2
+ export { Ai, AiActions, AiContent, type DataUIPart, type FileUIPart, type ReasoningUIPart, type SourceDocumentUIPart, type SourceUrlUIPart, type StepStartUIPart, type TextUIPart, type ToolUIPart, type UIMessage, type UIMessagePart };
@@ -1,8 +1,9 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { Action } from "../ai-action/index.mjs";
2
3
  import { AiMessage as Message } from "../ai-message/index.mjs";
3
4
  import { AiPromptInput as PromptInput } from "../ai-prompt-input/index.mjs";
4
5
  import { AiReasoning as Reasoning } from "../ai-reasoning/index.mjs";
5
- import { t as Response } from "../../ai-response-jZy-0Tvv.mjs";
6
+ import { t as Response } from "../../ai-response-BfKTmtCt.mjs";
6
7
  import { AiSource as Source, AiSources as Sources } from "../ai-source/index.mjs";
7
8
  import { AiSuggestion as Suggestion } from "../ai-suggestion/index.mjs";
8
9
  import { AiTool as Tool } from "../ai-tool/index.mjs";
@@ -29,20 +30,34 @@ function part(name, tag, extra = {}) {
29
30
  }
30
31
  /** The log itself: the column every stroke lands in, a landmark to
31
32
  * screen readers. */
32
- const AiConversation = part("Conversation", "div", {
33
- role: "log",
34
- "aria-label": "Conversation"
35
- });
33
+ function AiConversation({ children, ...rest }) {
34
+ const messages = useComponentMessages();
35
+ return /* @__PURE__ */ jsx("div", {
36
+ ...rest,
37
+ role: "log",
38
+ "aria-label": rest["aria-label"] ?? messages.ai.conversation,
39
+ "data-scope": "ai",
40
+ "data-part": "conversation",
41
+ children
42
+ });
43
+ }
36
44
  /** The bubble's inner measure — content that belongs to neither side
37
45
  * specifically. */
38
46
  const AiContent = part("Content", "div");
39
47
  /** The quiet row under a message — copy, retry, feedback. */
40
48
  const AiActions = part("Actions", "div");
41
49
  /** The while-it-works whisper for the in-flight turns. */
42
- const AiLoader = part("Loader", "span", {
43
- role: "status",
44
- "aria-label": "Loading"
45
- });
50
+ function AiLoader({ children, ...rest }) {
51
+ const messages = useComponentMessages();
52
+ return /* @__PURE__ */ jsx("span", {
53
+ ...rest,
54
+ role: "status",
55
+ "aria-label": rest["aria-label"] ?? messages.ai.loading,
56
+ "data-scope": "ai",
57
+ "data-part": "loader",
58
+ children
59
+ });
60
+ }
46
61
  /** The whole family under one handle — `Ai.Conversation`,
47
62
  * `Ai.Message`, and the rest, exactly as before the split. */
48
63
  const Ai = Object.assign(AiConversation, {
@@ -62,4 +77,4 @@ const Ai = Object.assign(AiConversation, {
62
77
  });
63
78
  injectComponentStyle("ai");
64
79
  //#endregion
65
- export { Ai, AiActions, AiContent, AiConversation, AiLoader };
80
+ export { Ai, AiActions, AiContent };
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages, t as formatMessage } from "../../messages-1jJWtaYU.mjs";
1
2
  import { injectComponentStyle } from "@bysages/core";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
4
  //#region src/components/ai-attachments/index.tsx
@@ -74,6 +75,7 @@ const humanSize = (bytes) => {
74
75
  };
75
76
  function Attachment({ name, size, status = "ready", onRemove, ...rest }) {
76
77
  injectComponentStyle("ai");
78
+ const messages = useComponentMessages();
77
79
  return /* @__PURE__ */ jsxs("span", {
78
80
  ...rest,
79
81
  "data-scope": "ai",
@@ -86,7 +88,7 @@ function Attachment({ name, size, status = "ready", onRemove, ...rest }) {
86
88
  /* @__PURE__ */ jsx("button", {
87
89
  type: "button",
88
90
  "data-remove": "",
89
- "aria-label": `Remove ${name}`,
91
+ "aria-label": formatMessage(messages.ai.removeAttachment, { name }),
90
92
  onClick: () => onRemove?.(),
91
93
  children: removeGlyph
92
94
  })
@@ -42,6 +42,6 @@ export interface PromptInputProps extends Omit<HTMLAttributes<HTMLFormElement>,
42
42
  footer?: ReactNode;
43
43
  footerEnd?: ReactNode;
44
44
  }
45
- export declare function PromptInput({ value, onValueChange, onSubmit, onStop, placeholder, disabled, busy, mentions, header, leading, trailing, footer, footerEnd, ...rest }: PromptInputProps): import("react").JSX.Element;
45
+ export declare function PromptInput({ value, onValueChange, onSubmit, onStop, placeholder, "aria-label": ariaLabel, disabled, busy, mentions, header, leading, trailing, footer, footerEnd, ...rest }: PromptInputProps): import("react").JSX.Element;
46
46
  //#endregion
47
47
  export { PromptInput as AiPromptInput };
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { Button } from "../button/index.mjs";
2
3
  import { Field } from "../field/index.mjs";
3
4
  import { n as MentionsVessel, r as useMentions } from "../../mentions-DMIBCBOd.mjs";
@@ -39,9 +40,11 @@ function row(part, content) {
39
40
  children: content
40
41
  });
41
42
  }
42
- function PromptInput({ value, onValueChange, onSubmit, onStop, placeholder = "Send a message", disabled = false, busy = false, mentions, header, leading, trailing, footer, footerEnd, ...rest }) {
43
+ function PromptInput({ value, onValueChange, onSubmit, onStop, placeholder, "aria-label": ariaLabel, disabled = false, busy = false, mentions, header, leading, trailing, footer, footerEnd, ...rest }) {
43
44
  injectComponentStyle("ai");
44
45
  const fieldRef = useRef(null);
46
+ const messages = useComponentMessages();
47
+ const placeholderText = placeholder ?? messages.ai.conversation;
45
48
  const mentionState = useMentions(() => ({
46
49
  items: mentions?.items ?? [],
47
50
  trigger: mentions?.trigger
@@ -61,7 +64,7 @@ function PromptInput({ value, onValueChange, onSubmit, onStop, placeholder = "Se
61
64
  size: "sm",
62
65
  square: true,
63
66
  type: "button",
64
- "aria-label": "Stop",
67
+ "aria-label": messages.ai.stop,
65
68
  disabled,
66
69
  onClick: () => onStop?.(),
67
70
  children: stopGlyph
@@ -70,7 +73,7 @@ function PromptInput({ value, onValueChange, onSubmit, onStop, placeholder = "Se
70
73
  size: "sm",
71
74
  square: true,
72
75
  type: "submit",
73
- "aria-label": "Send",
76
+ "aria-label": messages.ai.send,
74
77
  disabled: disabled || !value.trim(),
75
78
  children: arrowUpGlyph
76
79
  });
@@ -95,7 +98,8 @@ function PromptInput({ value, onValueChange, onSubmit, onStop, placeholder = "Se
95
98
  autoresize: true,
96
99
  rows: 1,
97
100
  value,
98
- placeholder,
101
+ placeholder: placeholderText,
102
+ "aria-label": ariaLabel ?? messages.ai.conversation,
99
103
  disabled,
100
104
  onChange: (event) => {
101
105
  onValueChange?.(event.target.value);
@@ -12,9 +12,11 @@ export interface ResponseProps extends HTMLAttributes<HTMLDivElement> {
12
12
  /** Optional code-highlighting function re-inking fenced blocks; the
13
13
  * component stays agnostic about which engine provides it. */
14
14
  highlighter?: (code: string, lang?: string) => string;
15
- /** The copy stamp's accessible name before the copy lands. */
15
+ /** The copy stamp's accessible name before the copy lands; leave
16
+ * unset for the resolved default. */
16
17
  copyLabel?: string;
17
- /** The copy stamp's accessible name once the text has landed. */
18
+ /** The copy stamp's accessible name once the text has landed; leave
19
+ * unset for the resolved default. */
18
20
  copiedLabel?: string;
19
21
  }
20
22
  export declare function Response({ content, highlighter, copyLabel, copiedLabel, ...rest }: ResponseProps): import("react").JSX.Element;
@@ -1,2 +1,2 @@
1
- import { t as Response } from "../../ai-response-jZy-0Tvv.mjs";
1
+ import { t as Response } from "../../ai-response-BfKTmtCt.mjs";
2
2
  export { Response as AiResponse, Response };
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { injectComponentStyle } from "@bysages/core";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
4
  import { Portal } from "@ark-ui/react/portal";
@@ -6,6 +7,7 @@ import { Combobox } from "@ark-ui/react/combobox";
6
7
  //#region src/components/autocomplete/index.tsx
7
8
  function AutoComplete({ value = "", items = [], placeholder, filter, size = "md", onValueChange, ...rest }) {
8
9
  injectComponentStyle("combobox");
10
+ const messages = useComponentMessages();
9
11
  const { collection, filter: filterItems } = useListCollection({
10
12
  initialItems: items,
11
13
  filter: (item, input) => filter ? filter(item, input) : item.toLowerCase().includes(input.toLowerCase())
@@ -25,7 +27,7 @@ function AutoComplete({ value = "", items = [], placeholder, filter, size = "md"
25
27
  onValueChange?.(details.inputValue);
26
28
  },
27
29
  positioning: { sameWidth: true },
28
- children: [/* @__PURE__ */ jsx(Combobox.Control, { children: /* @__PURE__ */ jsx(Combobox.Input, { placeholder }) }), /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Combobox.Positioner, { children: /* @__PURE__ */ jsxs(Combobox.Content, { children: [/* @__PURE__ */ jsx(Combobox.Empty, { children: "No matches" }), collection.items.map((item) => /* @__PURE__ */ jsx(Combobox.Item, {
30
+ children: [/* @__PURE__ */ jsx(Combobox.Control, { children: /* @__PURE__ */ jsx(Combobox.Input, { placeholder }) }), /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Combobox.Positioner, { children: /* @__PURE__ */ jsxs(Combobox.Content, { children: [/* @__PURE__ */ jsx(Combobox.Empty, { children: messages.command.noMatches }), collection.items.map((item) => /* @__PURE__ */ jsx(Combobox.Item, {
29
31
  item,
30
32
  children: /* @__PURE__ */ jsx(Combobox.ItemText, { children: item })
31
33
  }, item))] }) }) })]
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { injectComponentStyle } from "@bysages/core";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  //#region src/components/banner/index.tsx
@@ -31,24 +32,27 @@ const Description = part("Description", "p");
31
32
  const Actions = part("Actions", "div");
32
33
  /** The quiet close: a plain square-cut button; dismissal stays the
33
34
  * consumer's state. */
34
- const Close = (rest) => /* @__PURE__ */ jsx("button", {
35
- ...rest,
36
- type: rest.type ?? "button",
37
- "aria-label": rest["aria-label"] ?? "Dismiss",
38
- "data-scope": "banner",
39
- "data-part": "close",
40
- children: /* @__PURE__ */ jsx("svg", {
41
- viewBox: "0 0 16 16",
42
- fill: "none",
43
- "aria-hidden": true,
44
- children: /* @__PURE__ */ jsx("path", {
45
- d: "M4 4l8 8M12 4l-8 8",
46
- stroke: "currentColor",
47
- strokeWidth: 1.5,
48
- strokeLinecap: "round"
35
+ const Close = (rest) => {
36
+ const messages = useComponentMessages();
37
+ return /* @__PURE__ */ jsx("button", {
38
+ ...rest,
39
+ type: rest.type ?? "button",
40
+ "aria-label": rest["aria-label"] ?? messages.banner.dismiss,
41
+ "data-scope": "banner",
42
+ "data-part": "close",
43
+ children: /* @__PURE__ */ jsx("svg", {
44
+ viewBox: "0 0 16 16",
45
+ fill: "none",
46
+ "aria-hidden": true,
47
+ children: /* @__PURE__ */ jsx("path", {
48
+ d: "M4 4l8 8M12 4l-8 8",
49
+ stroke: "currentColor",
50
+ strokeWidth: 1.5,
51
+ strokeLinecap: "round"
52
+ })
49
53
  })
50
- })
51
- });
54
+ });
55
+ };
52
56
  const Banner = Object.assign(Root, {
53
57
  Root,
54
58
  Icon,
@@ -1,13 +1,8 @@
1
1
  import { AnchorHTMLAttributes, HTMLAttributes } from "react";
2
2
  //#region src/components/breadcrumb/index.d.ts
3
- export declare const Breadcrumb: {
4
- ({ children, ...rest }: HTMLAttributes<HTMLElement>): import("react").JSX.Element;
5
- displayName: string;
6
- } & {
7
- Root: {
8
- ({ children, ...rest }: HTMLAttributes<HTMLElement>): import("react").JSX.Element;
9
- displayName: string;
10
- };
3
+ declare function Root({ children, ...rest }: HTMLAttributes<HTMLElement>): import("react").JSX.Element;
4
+ export declare const Breadcrumb: typeof Root & {
5
+ Root: typeof Root;
11
6
  List: {
12
7
  ({ children, ...rest }: HTMLAttributes<HTMLElement>): import("react").JSX.Element;
13
8
  displayName: string;
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { injectComponentStyle } from "@bysages/core";
2
3
  import { jsx } from "react/jsx-runtime";
3
4
  //#region src/components/breadcrumb/index.tsx
@@ -16,7 +17,16 @@ function part(name, tag, extra = {}, fallback) {
16
17
  Component.displayName = "Breadcrumb" + name;
17
18
  return Component;
18
19
  }
19
- const Root = part("Root", "nav", { "aria-label": "Breadcrumb" });
20
+ function Root({ children, ...rest }) {
21
+ const messages = useComponentMessages();
22
+ return /* @__PURE__ */ jsx("nav", {
23
+ ...rest,
24
+ "aria-label": rest["aria-label"] ?? messages.breadcrumb.label,
25
+ "data-scope": "breadcrumb",
26
+ "data-part": "root",
27
+ children
28
+ });
29
+ }
20
30
  const List = part("List", "ol");
21
31
  const Item = part("Item", "li");
22
32
  const Link = part("Link", "a");
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { t as Input } from "../../input-2oezH-dY.mjs";
2
3
  import { injectComponentStyle } from "@bysages/core";
3
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -40,6 +41,7 @@ const checkGlyph = /* @__PURE__ */ jsx("svg", {
40
41
  });
41
42
  function CascadeSelect({ value, data, placeholder = "Select…", highlightTrigger, filterable = false, multiple = false, disabled = false, size = "md", onValueChange, ...rest }) {
42
43
  injectComponentStyle("cascade-select");
44
+ const messages = useComponentMessages();
43
45
  const id = useId();
44
46
  const locale = useLocaleContext();
45
47
  const env = useEnvironmentContext();
@@ -176,6 +178,7 @@ function CascadeSelect({ value, data, placeholder = "Select…", highlightTrigge
176
178
  ...api.getControlProps(),
177
179
  children: /* @__PURE__ */ jsxs("button", {
178
180
  ...api.getTriggerProps(),
181
+ "aria-labelledby": id + ":value-text",
179
182
  onClick: (event) => {
180
183
  api.getTriggerProps().onClick?.(event);
181
184
  setQuery("");
@@ -183,6 +186,7 @@ function CascadeSelect({ value, data, placeholder = "Select…", highlightTrigge
183
186
  disabled: disabled || void 0,
184
187
  children: [/* @__PURE__ */ jsx("span", {
185
188
  ...api.getValueTextProps(),
189
+ id: id + ":value-text",
186
190
  children: display || placeholder
187
191
  }), /* @__PURE__ */ jsx("span", {
188
192
  ...api.getIndicatorProps(),
@@ -201,8 +205,8 @@ function CascadeSelect({ value, data, placeholder = "Select…", highlightTrigge
201
205
  size: "sm",
202
206
  value: query,
203
207
  onValueChange: setQuery,
204
- placeholder: "Filter…",
205
- "aria-label": "Filter options"
208
+ placeholder: messages.select.filter,
209
+ "aria-label": messages.select.filter
206
210
  })
207
211
  }) : null, /* @__PURE__ */ jsx("div", {
208
212
  "data-scope": "cascade-select",
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { injectComponentStyle } from "@bysages/core";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
4
  import { useEffect, useState } from "react";
@@ -6,9 +7,12 @@ import { useListCollection } from "@ark-ui/react/collection";
6
7
  import { Combobox } from "@ark-ui/react/combobox";
7
8
  import { Dialog } from "@ark-ui/react/dialog";
8
9
  //#region src/components/command/index.tsx
9
- function Command({ items = [], placeholder, open, autoFilter = true, inputValue, emptyText = "No matching commands", onSelect, onOpenChange, onInputValueChange }) {
10
+ function Command({ items = [], placeholder, open, autoFilter = true, inputValue, emptyText, onSelect, onOpenChange, onInputValueChange }) {
10
11
  injectComponentStyle("command");
11
12
  injectComponentStyle("dialog");
13
+ const messages = useComponentMessages();
14
+ const resolvedPlaceholder = placeholder ?? messages.command.search;
15
+ const resolvedEmptyText = emptyText ?? messages.command.noMatches;
12
16
  const [internalOpen, setInternalOpen] = useState(false);
13
17
  const [listOpen, setListOpen] = useState(true);
14
18
  const [fieldText, setFieldText] = useState("");
@@ -74,6 +78,7 @@ function Command({ items = [], placeholder, open, autoFilter = true, inputValue,
74
78
  children: /* @__PURE__ */ jsx("div", {
75
79
  "data-scope": "command",
76
80
  "data-part": "content",
81
+ "aria-label": messages.command.palette,
77
82
  children: /* @__PURE__ */ jsxs(Combobox.Root, {
78
83
  collection,
79
84
  inputValue,
@@ -96,7 +101,8 @@ function Command({ items = [], placeholder, open, autoFilter = true, inputValue,
96
101
  asChild: true,
97
102
  children: /* @__PURE__ */ jsx("input", {
98
103
  type: "text",
99
- placeholder,
104
+ placeholder: resolvedPlaceholder,
105
+ "aria-label": resolvedPlaceholder,
100
106
  "data-scope": "command",
101
107
  "data-part": "input"
102
108
  })
@@ -122,7 +128,7 @@ function Command({ items = [], placeholder, open, autoFilter = true, inputValue,
122
128
  }, group)), groups.size === 0 ? /* @__PURE__ */ jsx("div", {
123
129
  "data-scope": "command",
124
130
  "data-part": "empty",
125
- children: emptyText
131
+ children: resolvedEmptyText
126
132
  }) : null]
127
133
  })
128
134
  })]
@@ -1,4 +1,4 @@
1
- import { ThemeScene } from "@bysages/core";
1
+ import { ComponentMessagesOverride, ThemeScene } from "@bysages/core";
2
2
  import { HTMLAttributes, ReactNode } from "react";
3
3
  //#region src/components/config-provider/index.d.ts
4
4
  /** The four density tiers the token layer's `[data-density]` selectors
@@ -22,6 +22,8 @@ export interface ConfigContext {
22
22
  dir?: "ltr" | "rtl";
23
23
  /** BCP-47 locale, landing as the native `lang` attribute. */
24
24
  locale?: string;
25
+ /** Partial leaf overrides for wrapper-owned runtime copy. */
26
+ messages?: ComponentMessagesOverride;
25
27
  }
26
28
  /** The nearest provider's snapshot, or an empty one when no provider
27
29
  * wraps the caller — the hook the date and format families will consume
@@ -33,6 +35,7 @@ export interface ConfigProviderProps extends HTMLAttributes<HTMLDivElement> {
33
35
  accent?: string;
34
36
  dir?: "ltr" | "rtl";
35
37
  locale?: string;
38
+ messages?: ComponentMessagesOverride;
36
39
  children?: ReactNode;
37
40
  }
38
41
  /**
@@ -42,5 +45,5 @@ export interface ConfigProviderProps extends HTMLAttributes<HTMLDivElement> {
42
45
  * descendants through `useConfig`, so interactive behavior (formatting,
43
46
  * messages) and visual theming stay one decision.
44
47
  */
45
- export declare function ConfigProvider({ density, scene, accent, dir, locale, children, ...rest }: ConfigProviderProps): import("react").JSX.Element;
48
+ export declare function ConfigProvider({ density, scene, accent, dir, locale, messages, children, ...rest }: ConfigProviderProps): import("react").JSX.Element;
46
49
  //#endregion
@@ -15,14 +15,15 @@ function useConfig() {
15
15
  * descendants through `useConfig`, so interactive behavior (formatting,
16
16
  * messages) and visual theming stay one decision.
17
17
  */
18
- function ConfigProvider({ density, scene, accent, dir, locale, children, ...rest }) {
18
+ function ConfigProvider({ density, scene, accent, dir, locale, messages, children, ...rest }) {
19
19
  return /* @__PURE__ */ jsx(ConfigContextImpl.Provider, {
20
20
  value: {
21
21
  density,
22
22
  scene,
23
23
  accent,
24
24
  dir,
25
- locale
25
+ locale,
26
+ messages
26
27
  },
27
28
  children: /* @__PURE__ */ jsx("div", {
28
29
  ...rest,
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { Pagination } from "../pagination/index.mjs";
2
3
  import { injectComponentStyle } from "@bysages/core";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -10,6 +11,7 @@ import { useState } from "react";
10
11
  function DataView({ items, layout = "list", pageSize, renderItem, header, ...rest }) {
11
12
  injectComponentStyle("data-view");
12
13
  const [page, setPage] = useState(1);
14
+ const messages = useComponentMessages();
13
15
  const pageCount = pageSize ? Math.max(1, Math.ceil(items.length / pageSize)) : 1;
14
16
  const visible = pageSize ? items.slice((page - 1) * pageSize, page * pageSize) : items;
15
17
  return /* @__PURE__ */ jsxs("div", {
@@ -39,7 +41,7 @@ function DataView({ items, layout = "list", pageSize, renderItem, header, ...res
39
41
  onPageChange: (details) => setPage(details.page),
40
42
  children: [
41
43
  /* @__PURE__ */ jsx(Pagination.PrevTrigger, {
42
- "aria-label": "Previous page",
44
+ "aria-label": messages.pagination.previous,
43
45
  children: "‹"
44
46
  }),
45
47
  /* @__PURE__ */ jsx(Pagination.Context, { children: (pagination) => pagination.pages.map((entry, index) => entry.type === "ellipsis" ? /* @__PURE__ */ jsx(Pagination.Ellipsis, {
@@ -51,7 +53,7 @@ function DataView({ items, layout = "list", pageSize, renderItem, header, ...res
51
53
  children: entry.value
52
54
  }, entry.value)) }),
53
55
  /* @__PURE__ */ jsx(Pagination.NextTrigger, {
54
- "aria-label": "Next page",
56
+ "aria-label": messages.pagination.next,
55
57
  children: "›"
56
58
  })
57
59
  ]
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { Button } from "../button/index.mjs";
2
3
  import { t as Input } from "../../input-2oezH-dY.mjs";
3
4
  import { injectComponentStyle } from "@bysages/core";
@@ -13,6 +14,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
13
14
  */
14
15
  function DynamicInput({ value, min = 0, max, placeholder, addLabel = "Add entry", disabled = false, invalid = false, size = "md", onValueChange, children: _children, ...rest }) {
15
16
  injectComponentStyle("dynamic-input");
17
+ const messages = useComponentMessages();
16
18
  const values = value ?? [""];
17
19
  const update = (index, next) => {
18
20
  const rows = values.slice();
@@ -47,7 +49,7 @@ function DynamicInput({ value, min = 0, max, placeholder, addLabel = "Add entry"
47
49
  square: true,
48
50
  size,
49
51
  disabled: disabled || !canRemove,
50
- "aria-label": `Remove entry ${index + 1}`,
52
+ "aria-label": messages.dynamicEntry.remove,
51
53
  onClick: () => remove(index),
52
54
  children: crossIcon()
53
55
  })]
@@ -6,13 +6,20 @@ type FileUploadRootProps = ComponentProps<typeof FileUpload$1.Root> & {
6
6
  size?: "sm" | "md" | "lg";
7
7
  };
8
8
  declare function FileUploadRoot({ size, ...rest }: FileUploadRootProps): import("react").JSX.Element;
9
+ /** The inner trigger repeats the click binding the dropzone already
10
+ * owns, and no flavor of taming a nested button survives the audit —
11
+ * assistive tech can still land on it. So the visual cue is a plain
12
+ * span wearing the trigger props; the dropzone stays the one real
13
+ * control, keyboard included. */
14
+ declare function FileUploadTrigger(props: ComponentProps<typeof FileUpload$1.Trigger>): import("react").JSX.Element;
9
15
  /** Ark's FileUpload, dressed in the paper-and-ink system: a dashed
10
16
  * dropzone that floods with subtle light on drag-over, and accepted files
11
17
  * as loose hairline slips. The API is Ark's own — Root, Label, Trigger,
12
18
  * Dropzone, HiddenInput, ItemGroup, Item, ItemName, ItemSizeText,
13
19
  * ItemPreview, ItemPreviewImage, ItemDeleteTrigger, ClearTrigger,
14
20
  * Context. */
15
- export declare const FileUpload: Omit<typeof FileUpload$1, "Root"> & {
21
+ export declare const FileUpload: Omit<typeof FileUpload$1, "Root" | "Trigger"> & {
16
22
  Root: typeof FileUploadRoot;
23
+ Trigger: typeof FileUploadTrigger;
17
24
  };
18
25
  //#endregion
@@ -8,6 +8,24 @@ function FileUploadRoot({ size = "md", ...rest }) {
8
8
  "data-size": size
9
9
  });
10
10
  }
11
+ /** The inner trigger repeats the click binding the dropzone already
12
+ * owns, and no flavor of taming a nested button survives the audit —
13
+ * assistive tech can still land on it. So the visual cue is a plain
14
+ * span wearing the trigger props; the dropzone stays the one real
15
+ * control, keyboard included. */
16
+ function FileUploadTrigger(props) {
17
+ const { children, ...rest } = props;
18
+ return /* @__PURE__ */ jsx(FileUpload$1.Trigger, {
19
+ asChild: true,
20
+ ...rest,
21
+ children: /* @__PURE__ */ jsx("span", {
22
+ "data-scope": "file-upload",
23
+ "data-part": "trigger",
24
+ "aria-hidden": "true",
25
+ children
26
+ })
27
+ });
28
+ }
11
29
  /** Ark's FileUpload, dressed in the paper-and-ink system: a dashed
12
30
  * dropzone that floods with subtle light on drag-over, and accepted files
13
31
  * as loose hairline slips. The API is Ark's own — Root, Label, Trigger,
@@ -16,7 +34,8 @@ function FileUploadRoot({ size = "md", ...rest }) {
16
34
  * Context. */
17
35
  const FileUpload = {
18
36
  ...FileUpload$1,
19
- Root: FileUploadRoot
37
+ Root: FileUploadRoot,
38
+ Trigger: FileUploadTrigger
20
39
  };
21
40
  injectComponentStyle("file-upload");
22
41
  //#endregion
@@ -1,3 +1,4 @@
1
+ import { n as useComponentMessages } from "../../messages-1jJWtaYU.mjs";
1
2
  import { Button } from "../button/index.mjs";
2
3
  import { injectComponentStyle } from "@bysages/core";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -46,12 +47,13 @@ const STEP_DOWN = {
46
47
  };
47
48
  function Trigger({ label, children }) {
48
49
  const context = useContext(FLOAT_BUTTON_CONTEXT);
50
+ const messages = useComponentMessages();
49
51
  return /* @__PURE__ */ jsx(Button, {
50
52
  variant: "solid",
51
53
  square: true,
52
54
  size: context?.size ?? "lg",
53
55
  onClick: () => context?.toggle(),
54
- "aria-label": label || "Actions",
56
+ "aria-label": label || messages.floatButton.actions,
55
57
  "aria-expanded": context ? context.open : false,
56
58
  children
57
59
  });
@@ -10,8 +10,14 @@ export interface ImageProps extends Omit<HTMLAttributes<HTMLElement>, "onError"
10
10
  alt?: string;
11
11
  fit?: "cover" | "contain" | "fill" | "none";
12
12
  loading?: "lazy" | "eager";
13
+ /** Intrinsic rendered width, reserved on the image to avoid layout
14
+ * shift while the source loads. */
15
+ width?: number | string;
16
+ /** Intrinsic rendered height, reserved on the image to avoid layout
17
+ * shift while the source loads. */
18
+ height?: number | string;
13
19
  /** Shown in place of the picture when the source breaks. */
14
20
  fallback?: ReactNode;
15
21
  }
16
- export declare function Image({ src, alt, fit, loading, fallback, ...rest }: ImageProps): import("react").JSX.Element;
22
+ export declare function Image({ src, alt, fit, loading, width, height, fallback, ...rest }: ImageProps): import("react").JSX.Element;
17
23
  //#endregion
@@ -27,7 +27,7 @@ function placeholderGlyph() {
27
27
  ]
28
28
  });
29
29
  }
30
- function Image({ src, alt = "", fit = "cover", loading = "lazy", fallback, ...rest }) {
30
+ function Image({ src, alt = "", fit = "cover", loading = "lazy", width, height, fallback, ...rest }) {
31
31
  injectComponentStyle("image");
32
32
  const [state, setState] = useState("loading");
33
33
  useEffect(() => setState("loading"), [src]);
@@ -44,6 +44,8 @@ function Image({ src, alt = "", fit = "cover", loading = "lazy", fallback, ...re
44
44
  alt,
45
45
  loading,
46
46
  decoding: "async",
47
+ width,
48
+ height,
47
49
  onLoad: () => setState("loaded"),
48
50
  onError: () => setState("error")
49
51
  }), state === "error" ? /* @__PURE__ */ jsx("div", {
@@ -11,8 +11,14 @@ export interface ImageViewerProps {
11
11
  alt?: string;
12
12
  open?: boolean;
13
13
  zoomable?: boolean;
14
+ /** Intrinsic rendered width, reserved on the image to avoid layout
15
+ * shift while the source loads. */
16
+ width?: number | string;
17
+ /** Intrinsic rendered height, reserved on the image to avoid layout
18
+ * shift while the source loads. */
19
+ height?: number | string;
14
20
  /** Reports the viewer's next state. */
15
21
  onOpenChange?: (open: boolean) => void;
16
22
  }
17
- export declare function ImageViewer({ src, alt, open, zoomable, onOpenChange }: ImageViewerProps): import("react").JSX.Element;
23
+ export declare function ImageViewer({ src, alt, open, zoomable, width, height, onOpenChange }: ImageViewerProps): import("react").JSX.Element;
18
24
  //#endregion