@bysages/react 0.1.1 → 0.2.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.
- package/dist/index.d.mts +69 -23
- package/dist/index.mjs +346 -108
- package/package.json +9 -8
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Accordion as Accordion$1 } from "@ark-ui/react/accordion";
|
|
2
|
-
import { AnchorHTMLAttributes, ButtonHTMLAttributes, CSSProperties, HTMLAttributes, InputHTMLAttributes, ReactNode, Ref, TextareaHTMLAttributes } from "react";
|
|
2
|
+
import { AnchorHTMLAttributes, ButtonHTMLAttributes, CSSProperties, ComponentProps, HTMLAttributes, InputHTMLAttributes, ReactNode, Ref, TextareaHTMLAttributes } from "react";
|
|
3
3
|
import { Field as Field$1 } from "@ark-ui/react/field";
|
|
4
4
|
import { Popover as Popover$1 } from "@ark-ui/react/popover";
|
|
5
5
|
import { Collapsible as Collapsible$1 } from "@ark-ui/react/collapsible";
|
|
@@ -278,8 +278,12 @@ export interface ResponseProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
278
278
|
/** Optional code-highlighting function re-inking fenced blocks; the
|
|
279
279
|
* component stays agnostic about which engine provides it. */
|
|
280
280
|
highlighter?: (code: string, lang?: string) => string;
|
|
281
|
+
/** The copy stamp's accessible name before the copy lands. */
|
|
282
|
+
copyLabel?: string;
|
|
283
|
+
/** The copy stamp's accessible name once the text has landed. */
|
|
284
|
+
copiedLabel?: string;
|
|
281
285
|
}
|
|
282
|
-
declare function Response$1({ content, highlighter, ...rest }: ResponseProps): import("react").JSX.Element;
|
|
286
|
+
declare function Response$1({ content, highlighter, copyLabel, copiedLabel, ...rest }: ResponseProps): import("react").JSX.Element;
|
|
283
287
|
//#endregion
|
|
284
288
|
//#region src/components/ai-source/index.d.ts
|
|
285
289
|
/** One place the ink came from; href and the rest ride the anchor. */
|
|
@@ -326,7 +330,7 @@ export interface ToolProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
326
330
|
}
|
|
327
331
|
export declare function Tool({ name, label, status, input, output, ...rest }: ToolProps): import("react").JSX.Element;
|
|
328
332
|
//#endregion
|
|
329
|
-
//#region ../../node_modules/.pnpm/@ai-sdk+provider@4.0.
|
|
333
|
+
//#region ../../node_modules/.pnpm/@ai-sdk+provider@4.0.17/node_modules/@ai-sdk/provider/dist/index.d.ts
|
|
330
334
|
/**
|
|
331
335
|
* Audio format configuration shared by provider V4 model specifications.
|
|
332
336
|
*/
|
|
@@ -406,7 +410,7 @@ type SharedV4Headers = Record<string, string>;
|
|
|
406
410
|
* A JSON value can be a string, number, boolean, object, array, or null.
|
|
407
411
|
* JSON values can be serialized and deserialized by the JSON.stringify and JSON.parse methods.
|
|
408
412
|
*/
|
|
409
|
-
type JSONValue = null | string | number | boolean | JSONObject |
|
|
413
|
+
type JSONValue = null | string | number | boolean | Readonly<JSONObject> | readonly JSONValue[];
|
|
410
414
|
type JSONObject = {
|
|
411
415
|
[key: string]: JSONValue | undefined;
|
|
412
416
|
};
|
|
@@ -9853,7 +9857,7 @@ interface $ZodConfig {
|
|
|
9853
9857
|
declare const globalConfig: $ZodConfig;
|
|
9854
9858
|
declare function config(newConfig?: Partial<$ZodConfig>): $ZodConfig;
|
|
9855
9859
|
//#endregion
|
|
9856
|
-
//#region ../../node_modules/.pnpm/@ai-sdk+provider-utils@5.0.
|
|
9860
|
+
//#region ../../node_modules/.pnpm/@ai-sdk+provider-utils@5.0.45_zod@4.6.5/node_modules/@ai-sdk/provider-utils/dist/index.d.ts
|
|
9857
9861
|
/**
|
|
9858
9862
|
* A value that can be provided either as a single item, an array of items,
|
|
9859
9863
|
* or be left undefined.
|
|
@@ -10814,6 +10818,13 @@ type ToolOutputProperties<INPUT, OUTPUT, CONTEXT extends Context | unknown | nev
|
|
|
10814
10818
|
* Common properties shared by all tool kinds.
|
|
10815
10819
|
*/
|
|
10816
10820
|
type BaseTool<INPUT extends JSONValue | unknown | never = any, OUTPUT extends JSONValue | unknown | never = any, CONTEXT extends Context | unknown | never = any> = {
|
|
10821
|
+
/**
|
|
10822
|
+
* Defer exposing this tool until it is discovered by `toolSearch`.
|
|
10823
|
+
* Supports direct calls and local callers that announce tools in conversation
|
|
10824
|
+
* messages (code mode with `toolDiscovery: 'conversation'`). Discovered tools
|
|
10825
|
+
* become available on the next model step.
|
|
10826
|
+
*/
|
|
10827
|
+
deferLoading?: boolean;
|
|
10817
10828
|
/**
|
|
10818
10829
|
* An optional title of the tool.
|
|
10819
10830
|
*
|
|
@@ -11070,7 +11081,7 @@ type Normalize<OBJECT> = { [KEY in keyof OBJECT]: OBJECT[KEY]; };
|
|
|
11070
11081
|
*/
|
|
11071
11082
|
type InferToolSetContext<TOOLS extends ToolSet> = Normalize<RequiredToolSetContext<TOOLS> & OptionalToolSetContext<TOOLS>>;
|
|
11072
11083
|
//#endregion
|
|
11073
|
-
//#region ../../node_modules/.pnpm/ai@7.0.
|
|
11084
|
+
//#region ../../node_modules/.pnpm/ai@7.0.107_zod@4.6.5/node_modules/ai/dist/index.d.ts
|
|
11074
11085
|
/**
|
|
11075
11086
|
* Embedding.
|
|
11076
11087
|
*/
|
|
@@ -12559,6 +12570,10 @@ type UIToolInvocation<TOOL extends UITool | Tool$1> = {
|
|
|
12559
12570
|
} | {
|
|
12560
12571
|
state: 'output-error';
|
|
12561
12572
|
input: asUITool<TOOL>['input'] | undefined;
|
|
12573
|
+
/**
|
|
12574
|
+
* @deprecated Use `input` instead. This field will be removed in the next
|
|
12575
|
+
* major version.
|
|
12576
|
+
*/
|
|
12562
12577
|
rawInput?: unknown;
|
|
12563
12578
|
output?: never;
|
|
12564
12579
|
errorText: string;
|
|
@@ -13430,6 +13445,7 @@ declare global {
|
|
|
13430
13445
|
* String model ids are resolved to the default provider and model id.
|
|
13431
13446
|
*
|
|
13432
13447
|
* If not set, the default provider is the Vercel AI gateway provider.
|
|
13448
|
+
* Experimental evaluation requires an explicitly configured evaluation-capable provider.
|
|
13433
13449
|
*
|
|
13434
13450
|
* @see https://ai-sdk.dev/docs/ai-sdk-core/provider-management#global-provider-configuration
|
|
13435
13451
|
*/
|
|
@@ -13562,10 +13578,22 @@ export interface AutoCompleteProps extends Omit<HTMLAttributes<HTMLDivElement>,
|
|
|
13562
13578
|
export declare function AutoComplete({ value, items, placeholder, filter, onValueChange, ...rest }: AutoCompleteProps): import("react").JSX.Element;
|
|
13563
13579
|
//#endregion
|
|
13564
13580
|
//#region src/components/avatar/index.d.ts
|
|
13565
|
-
/**
|
|
13566
|
-
* inset paper that holds initials until the image loads over them.
|
|
13567
|
-
*
|
|
13568
|
-
|
|
13581
|
+
/** Avatar, dressed in the paper-and-ink system: a circular seal on
|
|
13582
|
+
* inset paper that holds initials until the image loads over them.
|
|
13583
|
+
* `size` picks a control-height rung for the seal — the core styles
|
|
13584
|
+
* re-point `--bs-avatar-size` per rung, and scenes can still retune the
|
|
13585
|
+
* variable directly. */
|
|
13586
|
+
export type AvatarSize = "sm" | "md" | "lg";
|
|
13587
|
+
export interface AvatarProps extends ComponentProps<typeof Avatar$1.Root> {
|
|
13588
|
+
/** Seal diameter: the small, medium, or large control rung. The
|
|
13589
|
+
* default (large) stands as tall as the biggest control so an avatar
|
|
13590
|
+
* rides a row without stretching it. */
|
|
13591
|
+
size?: AvatarSize;
|
|
13592
|
+
}
|
|
13593
|
+
declare function AvatarRoot({ size, ...rest }: AvatarProps): import("react").JSX.Element;
|
|
13594
|
+
export declare const Avatar: typeof Avatar$1 & {
|
|
13595
|
+
Root: typeof AvatarRoot;
|
|
13596
|
+
};
|
|
13569
13597
|
//#endregion
|
|
13570
13598
|
//#region src/components/avatar-group/index.d.ts
|
|
13571
13599
|
/** Avatars overlapping one row, each rimmed in the ground so the pile
|
|
@@ -13580,20 +13608,26 @@ export interface BackTopProps extends HTMLAttributes<HTMLButtonElement> {
|
|
|
13580
13608
|
threshold?: number;
|
|
13581
13609
|
/** The accessible name; the control is icon-only by default. */
|
|
13582
13610
|
label?: string;
|
|
13611
|
+
/** Ride a scrolling element of your own instead of the page: the
|
|
13612
|
+
* control moors inside that element's corner and watches its
|
|
13613
|
+
* scrollTop. The host supplies the positioning context. */
|
|
13614
|
+
scrollEl?: () => HTMLElement | null;
|
|
13583
13615
|
}
|
|
13584
13616
|
/**
|
|
13585
13617
|
* A way home: after the page has scrolled past `threshold`, a small
|
|
13586
13618
|
* floating control rises at the page's corner and returns the reader to
|
|
13587
13619
|
* the top. The scroll itself stays native — `window.scrollTo` defers to
|
|
13588
13620
|
* the stylesheet's `scroll-behavior: smooth`, which reduced motion turns
|
|
13589
|
-
* back into an instant jump
|
|
13590
|
-
*
|
|
13621
|
+
* back into an instant jump (a moored control asks the media query
|
|
13622
|
+
* directly, since a scroller of its own has no stylesheet to defer to).
|
|
13623
|
+
* The button stays mounted either way so the entrance is a transition,
|
|
13624
|
+
* never a pop.
|
|
13591
13625
|
*
|
|
13592
13626
|
* The control itself is the shared `Button` (outline, square) — the
|
|
13593
13627
|
* paper, hairline and halo are its; this family owns only the floating
|
|
13594
13628
|
* and the entrance.
|
|
13595
13629
|
*/
|
|
13596
|
-
export declare function BackTop({ threshold, label, ...rest }: BackTopProps): import("react").JSX.Element;
|
|
13630
|
+
export declare function BackTop({ threshold, label, scrollEl, ...rest }: BackTopProps): import("react").JSX.Element;
|
|
13597
13631
|
//#endregion
|
|
13598
13632
|
//#region src/components/badge/index.d.ts
|
|
13599
13633
|
/** A small seal of state. Ink is the neutral tone; the four semantic
|
|
@@ -13778,18 +13812,21 @@ export interface CascadeSelectNode {
|
|
|
13778
13812
|
* dissolves open beside it, until a leaf click settles the whole path.
|
|
13779
13813
|
* `value` is the selected path (or paths, when `multiple`) — the joined
|
|
13780
13814
|
* labels ride the trigger. `highlightTrigger: "hover"` turns the
|
|
13781
|
-
* classic cascading menu: pointing is enough to unfold.
|
|
13815
|
+
* classic cascading menu: pointing is enough to unfold. `filterable`
|
|
13816
|
+
* swaps the corridor for a flat list of matching paths while a query
|
|
13817
|
+
* runs — each hit still reads as its full route.
|
|
13782
13818
|
*/
|
|
13783
13819
|
export interface CascadeSelectProps extends HTMLAttributes<HTMLDivElement> {
|
|
13784
13820
|
value?: string[][];
|
|
13785
13821
|
data: CascadeSelectNode[];
|
|
13786
13822
|
placeholder?: string;
|
|
13787
13823
|
highlightTrigger?: "click" | "hover";
|
|
13824
|
+
filterable?: boolean;
|
|
13788
13825
|
multiple?: boolean;
|
|
13789
13826
|
disabled?: boolean;
|
|
13790
13827
|
onValueChange?: (value: string[][]) => void;
|
|
13791
13828
|
}
|
|
13792
|
-
export declare function CascadeSelect({ value, data, placeholder, highlightTrigger, multiple, disabled, onValueChange, ...rest }: CascadeSelectProps): import("react").JSX.Element;
|
|
13829
|
+
export declare function CascadeSelect({ value, data, placeholder, highlightTrigger, filterable, multiple, disabled, onValueChange, ...rest }: CascadeSelectProps): import("react").JSX.Element;
|
|
13793
13830
|
//#endregion
|
|
13794
13831
|
//#region src/components/carousel/index.d.ts
|
|
13795
13832
|
/** Ark's Carousel, dressed in the paper-and-ink system: slides ride in one
|
|
@@ -13816,6 +13853,7 @@ export interface CheckboxGroupProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
13816
13853
|
value?: string[];
|
|
13817
13854
|
options: CheckboxOption[];
|
|
13818
13855
|
layout?: "vertical" | "horizontal";
|
|
13856
|
+
invalid?: boolean;
|
|
13819
13857
|
disabled?: boolean;
|
|
13820
13858
|
onValueChange?: (value: string[]) => void;
|
|
13821
13859
|
}
|
|
@@ -13823,9 +13861,11 @@ export interface CheckboxGroupProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
13823
13861
|
* One question, many answers: a labelled stack (or row) of the seal-cut
|
|
13824
13862
|
* checkboxes bound to a single array. Toggling a box adds or removes its
|
|
13825
13863
|
* value; the group itself is semantics (`role="group"`), the boxes stay
|
|
13826
|
-
* the machine-driven originals.
|
|
13864
|
+
* the machine-driven originals. Inside a `Field.Root` the group picks up
|
|
13865
|
+
* the field context, so the invalid and disabled states a Form routes to
|
|
13866
|
+
* its name dress every box at once.
|
|
13827
13867
|
*/
|
|
13828
|
-
export declare function CheckboxGroup({ value, options, layout, disabled, onValueChange, ...rest }: CheckboxGroupProps): import("react").JSX.Element;
|
|
13868
|
+
export declare function CheckboxGroup({ value, options, layout, invalid, disabled, onValueChange, ...rest }: CheckboxGroupProps): import("react").JSX.Element;
|
|
13829
13869
|
//#endregion
|
|
13830
13870
|
//#region src/components/chip/index.d.ts
|
|
13831
13871
|
/** A counting coin: the numeric value, capped at `max` with an ellipsis
|
|
@@ -14411,10 +14451,9 @@ export interface LayoutContextValue {
|
|
|
14411
14451
|
}
|
|
14412
14452
|
/**
|
|
14413
14453
|
* The application skeleton: Root, Header, Sider, Content, Footer —
|
|
14414
|
-
* the admin arrangement
|
|
14415
|
-
*
|
|
14416
|
-
*
|
|
14417
|
-
* edge the rail stands on.
|
|
14454
|
+
* the admin arrangement dressed in the paper-and-ink surfaces. The
|
|
14455
|
+
* root is a full-height grid; a declared `sider` turns the columns
|
|
14456
|
+
* around to meet whichever edge the rail stands on.
|
|
14418
14457
|
*/
|
|
14419
14458
|
declare function Root$1({ sider, children, ...rest }: LayoutRootProps): import("react").JSX.Element;
|
|
14420
14459
|
export interface LayoutSiderProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
@@ -14946,6 +14985,11 @@ export interface DataTableProps {
|
|
|
14946
14985
|
sortable?: boolean;
|
|
14947
14986
|
/** Render a global-filter toolbar and per-column filter inputs. */
|
|
14948
14987
|
filterable?: boolean;
|
|
14988
|
+
/** Keep the built-in toolbar row above the table (default true when
|
|
14989
|
+
* `filterable`). Turn it off to host the global filter in your own
|
|
14990
|
+
* toolbar — the feature stays registered and the instance methods
|
|
14991
|
+
* keep working. */
|
|
14992
|
+
showToolbar?: boolean;
|
|
14949
14993
|
/** Enable tree expansion over `subRows`; the first column hosts the
|
|
14950
14994
|
* expander and depth indent. */
|
|
14951
14995
|
tree?: boolean;
|
|
@@ -15134,16 +15178,18 @@ export interface TreeSelectNode {
|
|
|
15134
15178
|
* A tree behind a field: the control reads like an input, the vessel
|
|
15135
15179
|
* below walks the hierarchy, and one leaf click closes the deal. Single
|
|
15136
15180
|
* selection — the chosen label rides on the control, its value rides in
|
|
15137
|
-
* `value`.
|
|
15181
|
+
* `value`. `filterable` puts a filter line at the top of the vessel;
|
|
15182
|
+
* matches keep their ancestors and the branches fan open.
|
|
15138
15183
|
*/
|
|
15139
15184
|
export interface TreeSelectProps extends HTMLAttributes<HTMLDivElement> {
|
|
15140
15185
|
value?: string;
|
|
15141
15186
|
data: TreeSelectNode[];
|
|
15142
15187
|
placeholder?: string;
|
|
15188
|
+
filterable?: boolean;
|
|
15143
15189
|
disabled?: boolean;
|
|
15144
15190
|
onValueChange?: (value: string) => void;
|
|
15145
15191
|
}
|
|
15146
|
-
export declare function TreeSelect({ value, data, placeholder, disabled, onValueChange, ...rest }: TreeSelectProps): import("react").JSX.Element;
|
|
15192
|
+
export declare function TreeSelect({ value, data, placeholder, filterable, disabled, onValueChange, ...rest }: TreeSelectProps): import("react").JSX.Element;
|
|
15147
15193
|
//#endregion
|
|
15148
15194
|
//#region src/components/tree-view/index.d.ts
|
|
15149
15195
|
/** Ark's TreeView, dressed in the paper-and-ink system: quiet rows where
|
package/dist/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import { Combobox as Combobox$1 } from "@ark-ui/react/combobox";
|
|
|
13
13
|
import { Avatar as Avatar$1 } from "@ark-ui/react/avatar";
|
|
14
14
|
import { DatePicker as DatePicker$1 } from "@ark-ui/react/date-picker";
|
|
15
15
|
import { useEnvironmentContext } from "@ark-ui/react/environment";
|
|
16
|
-
import { useLocaleContext } from "@ark-ui/react/locale";
|
|
16
|
+
import { useFilter, useLocaleContext } from "@ark-ui/react/locale";
|
|
17
17
|
import * as cascade from "@zag-js/cascade-select";
|
|
18
18
|
import { normalizeProps, useMachine } from "@zag-js/react";
|
|
19
19
|
import { Carousel as Carousel$1 } from "@ark-ui/react/carousel";
|
|
@@ -51,7 +51,7 @@ import { RadioGroup as RadioGroup$1 } from "@ark-ui/react/radio-group";
|
|
|
51
51
|
import { RatingGroup as RatingGroup$1 } from "@ark-ui/react/rating-group";
|
|
52
52
|
import { ScrollArea as ScrollArea$1 } from "@ark-ui/react/scroll-area";
|
|
53
53
|
import { SegmentGroup as SegmentGroup$1 } from "@ark-ui/react/segment-group";
|
|
54
|
-
import { Select as Select$1 } from "@ark-ui/react/select";
|
|
54
|
+
import { Select as Select$1, createListCollection } from "@ark-ui/react/select";
|
|
55
55
|
import { SignaturePad as SignaturePad$1 } from "@ark-ui/react/signature-pad";
|
|
56
56
|
import { Slider as Slider$1 } from "@ark-ui/react/slider";
|
|
57
57
|
import { Splitter as Splitter$1 } from "@ark-ui/react/splitter";
|
|
@@ -487,12 +487,83 @@ function Reasoning({ label = "Thinking", children, ...rest }) {
|
|
|
487
487
|
}
|
|
488
488
|
injectComponentStyle("ai");
|
|
489
489
|
//#endregion
|
|
490
|
+
//#region src/components/ai-response/code-copy.ts
|
|
491
|
+
/** The two glyphs a copy affordance needs: the stamp and its
|
|
492
|
+
* confirmation. Inline SVG keeps the enhancement framework-agnostic —
|
|
493
|
+
* it lives beside the renderer's generated code HTML. */
|
|
494
|
+
const COPY_CODE_ICON = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>`;
|
|
495
|
+
const COPIED_CODE_ICON = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>`;
|
|
496
|
+
/** How long the confirmation stays before the stamp returns. */
|
|
497
|
+
const REVERT_MS = 1500;
|
|
498
|
+
/** Make sure every fenced block under `host` carries its copy stamp.
|
|
499
|
+
* The stamp anchors to a wrapper outside the scrolling `pre` — inside,
|
|
500
|
+
* it would fix to the overflow area and travel out of view with the
|
|
501
|
+
* code. The renderer rebuilds the markdown as one HTML string on every
|
|
502
|
+
* stream tick, so this stays idempotent and cheap enough to re-run
|
|
503
|
+
* after each patch. */
|
|
504
|
+
function decorateCodeCopy(host, copyLabel) {
|
|
505
|
+
for (const pre of host.querySelectorAll("pre")) {
|
|
506
|
+
let body = pre.parentElement;
|
|
507
|
+
if (!body || body.getAttribute("data-part") !== "code-body") {
|
|
508
|
+
body = document.createElement("div");
|
|
509
|
+
body.setAttribute("data-scope", "ai");
|
|
510
|
+
body.setAttribute("data-part", "code-body");
|
|
511
|
+
pre.replaceWith(body);
|
|
512
|
+
body.appendChild(pre);
|
|
513
|
+
}
|
|
514
|
+
let button = body.querySelector("[data-part=\"code-copy\"]");
|
|
515
|
+
if (!button) {
|
|
516
|
+
button = document.createElement("button");
|
|
517
|
+
button.type = "button";
|
|
518
|
+
button.setAttribute("data-scope", "ai");
|
|
519
|
+
button.setAttribute("data-part", "code-copy");
|
|
520
|
+
button.innerHTML = COPY_CODE_ICON;
|
|
521
|
+
body.appendChild(button);
|
|
522
|
+
}
|
|
523
|
+
button.title = copyLabel;
|
|
524
|
+
button.setAttribute("aria-label", copyLabel);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
/** The one delegated click for the whole response: copy the block's
|
|
528
|
+
* text and confirm in place, then return the stamp after a beat. */
|
|
529
|
+
async function clickCodeCopy(event, copyLabel, copiedLabel) {
|
|
530
|
+
const button = event.target?.closest("[data-part=\"code-copy\"]");
|
|
531
|
+
const pre = button?.closest("[data-part=\"code-body\"]")?.querySelector("pre");
|
|
532
|
+
if (!button || !pre) return;
|
|
533
|
+
await navigator.clipboard.writeText(pre.textContent ?? "");
|
|
534
|
+
button.innerHTML = COPIED_CODE_ICON;
|
|
535
|
+
button.setAttribute("data-state", "copied");
|
|
536
|
+
button.title = copiedLabel;
|
|
537
|
+
button.setAttribute("aria-label", copiedLabel);
|
|
538
|
+
setTimeout(() => {
|
|
539
|
+
if (!button.isConnected) return;
|
|
540
|
+
button.innerHTML = COPY_CODE_ICON;
|
|
541
|
+
button.removeAttribute("data-state");
|
|
542
|
+
button.title = copyLabel;
|
|
543
|
+
button.setAttribute("aria-label", copyLabel);
|
|
544
|
+
}, REVERT_MS);
|
|
545
|
+
}
|
|
546
|
+
//#endregion
|
|
490
547
|
//#region src/components/ai-response/index.tsx
|
|
491
|
-
function Response({ content, highlighter, ...rest }) {
|
|
548
|
+
function Response({ content, highlighter, copyLabel = "Copy code", copiedLabel = "Copied", ...rest }) {
|
|
549
|
+
const root = useRef(null);
|
|
550
|
+
useEffect(() => {
|
|
551
|
+
const host = root.current;
|
|
552
|
+
if (host) decorateCodeCopy(host, copyLabel);
|
|
553
|
+
}, [
|
|
554
|
+
content,
|
|
555
|
+
highlighter,
|
|
556
|
+
copyLabel
|
|
557
|
+
]);
|
|
558
|
+
const onClick = (event) => {
|
|
559
|
+
clickCodeCopy(event.nativeEvent, copyLabel, copiedLabel);
|
|
560
|
+
};
|
|
492
561
|
return /* @__PURE__ */ jsx("div", {
|
|
493
562
|
...rest,
|
|
563
|
+
ref: root,
|
|
494
564
|
"data-scope": "ai",
|
|
495
565
|
"data-part": "response",
|
|
566
|
+
onClick,
|
|
496
567
|
dangerouslySetInnerHTML: { __html: renderHtml(content, highlighter ? { highlighter } : void 0) }
|
|
497
568
|
});
|
|
498
569
|
}
|
|
@@ -849,10 +920,13 @@ function AutoComplete({ value = "", items = [], placeholder, filter, onValueChan
|
|
|
849
920
|
injectComponentStyle("combobox");
|
|
850
921
|
//#endregion
|
|
851
922
|
//#region src/components/avatar/index.tsx
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
923
|
+
function AvatarRoot({ size, ...rest }) {
|
|
924
|
+
return /* @__PURE__ */ jsx(Avatar$1.Root, {
|
|
925
|
+
...rest,
|
|
926
|
+
"data-size": size
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
const Avatar = Object.assign({}, Avatar$1, { Root: AvatarRoot });
|
|
856
930
|
injectComponentStyle("avatar");
|
|
857
931
|
//#endregion
|
|
858
932
|
//#region src/components/avatar-group/index.tsx
|
|
@@ -887,26 +961,46 @@ function chevronUp() {
|
|
|
887
961
|
* floating control rises at the page's corner and returns the reader to
|
|
888
962
|
* the top. The scroll itself stays native — `window.scrollTo` defers to
|
|
889
963
|
* the stylesheet's `scroll-behavior: smooth`, which reduced motion turns
|
|
890
|
-
* back into an instant jump
|
|
891
|
-
*
|
|
964
|
+
* back into an instant jump (a moored control asks the media query
|
|
965
|
+
* directly, since a scroller of its own has no stylesheet to defer to).
|
|
966
|
+
* The button stays mounted either way so the entrance is a transition,
|
|
967
|
+
* never a pop.
|
|
892
968
|
*
|
|
893
969
|
* The control itself is the shared `Button` (outline, square) — the
|
|
894
970
|
* paper, hairline and halo are its; this family owns only the floating
|
|
895
971
|
* and the entrance.
|
|
896
972
|
*/
|
|
897
|
-
function BackTop({ threshold = 400, label = "Back to top", ...rest }) {
|
|
973
|
+
function BackTop({ threshold = 400, label = "Back to top", scrollEl, ...rest }) {
|
|
898
974
|
const [visible, setVisible] = useState(false);
|
|
899
975
|
useEffect(() => {
|
|
900
976
|
if (typeof window === "undefined") return;
|
|
901
|
-
const
|
|
977
|
+
const el = scrollEl?.() ?? null;
|
|
978
|
+
const onScroll = () => setVisible((el ? el.scrollTop : window.scrollY) > threshold);
|
|
902
979
|
onScroll();
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
980
|
+
if (el) el.addEventListener("scroll", onScroll, { passive: true });
|
|
981
|
+
else window.addEventListener("scroll", onScroll, { passive: true });
|
|
982
|
+
return () => {
|
|
983
|
+
if (el) el.removeEventListener("scroll", onScroll);
|
|
984
|
+
else window.removeEventListener("scroll", onScroll);
|
|
985
|
+
};
|
|
986
|
+
}, [threshold, scrollEl]);
|
|
987
|
+
const toTop = () => {
|
|
988
|
+
const el = scrollEl?.();
|
|
989
|
+
if (!el) {
|
|
990
|
+
window.scrollTo({ top: 0 });
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
994
|
+
el.scrollTo({
|
|
995
|
+
top: 0,
|
|
996
|
+
behavior: reduce ? "auto" : "smooth"
|
|
997
|
+
});
|
|
998
|
+
};
|
|
906
999
|
return /* @__PURE__ */ jsx("div", {
|
|
907
1000
|
"data-scope": "back-top",
|
|
908
1001
|
"data-part": "root",
|
|
909
1002
|
"data-state": visible ? "shown" : "hidden",
|
|
1003
|
+
...scrollEl ? { "data-container": "" } : {},
|
|
910
1004
|
children: /* @__PURE__ */ jsx(Button, {
|
|
911
1005
|
...rest,
|
|
912
1006
|
variant: "outline",
|
|
@@ -916,7 +1010,7 @@ function BackTop({ threshold = 400, label = "Back to top", ...rest }) {
|
|
|
916
1010
|
"aria-label": label,
|
|
917
1011
|
"aria-hidden": visible ? void 0 : "true",
|
|
918
1012
|
tabIndex: visible ? 0 : -1,
|
|
919
|
-
onClick:
|
|
1013
|
+
onClick: toTop,
|
|
920
1014
|
children: rest.children ?? chevronUp()
|
|
921
1015
|
})
|
|
922
1016
|
});
|
|
@@ -1181,6 +1275,23 @@ const Card = Object.assign(Root$9, {
|
|
|
1181
1275
|
});
|
|
1182
1276
|
injectComponentStyle("card");
|
|
1183
1277
|
//#endregion
|
|
1278
|
+
//#region src/components/input/index.tsx
|
|
1279
|
+
function Input({ value, size = "md", invalid = false, onValueChange, ...rest }) {
|
|
1280
|
+
const field = useFieldContext();
|
|
1281
|
+
const fieldProps = field?.getInputProps() ?? {};
|
|
1282
|
+
return /* @__PURE__ */ jsx("input", {
|
|
1283
|
+
...fieldProps,
|
|
1284
|
+
...rest,
|
|
1285
|
+
...value !== void 0 ? { value } : {},
|
|
1286
|
+
"data-scope": "input",
|
|
1287
|
+
"data-part": "root",
|
|
1288
|
+
"data-size": size,
|
|
1289
|
+
"data-invalid": invalid || field?.invalid ? "" : void 0,
|
|
1290
|
+
onChange: (event) => onValueChange?.(event.target.value)
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
injectComponentStyle("input");
|
|
1294
|
+
//#endregion
|
|
1184
1295
|
//#region src/components/cascade-select/index.tsx
|
|
1185
1296
|
const chevronDown$2 = /* @__PURE__ */ jsx("svg", {
|
|
1186
1297
|
viewBox: "0 0 24 24",
|
|
@@ -1212,7 +1323,7 @@ const checkGlyph$2 = /* @__PURE__ */ jsx("svg", {
|
|
|
1212
1323
|
"aria-hidden": "true",
|
|
1213
1324
|
children: /* @__PURE__ */ jsx("path", { d: "m5 12.5 5 5L19 7" })
|
|
1214
1325
|
});
|
|
1215
|
-
function CascadeSelect({ value, data, placeholder = "Select…", highlightTrigger, multiple = false, disabled = false, onValueChange, ...rest }) {
|
|
1326
|
+
function CascadeSelect({ value, data, placeholder = "Select…", highlightTrigger, filterable = false, multiple = false, disabled = false, onValueChange, ...rest }) {
|
|
1216
1327
|
const id = useId();
|
|
1217
1328
|
const locale = useLocaleContext();
|
|
1218
1329
|
const env = useEnvironmentContext();
|
|
@@ -1240,6 +1351,47 @@ function CascadeSelect({ value, data, placeholder = "Select…", highlightTrigge
|
|
|
1240
1351
|
}
|
|
1241
1352
|
});
|
|
1242
1353
|
const api = cascade.connect(service, normalizeProps);
|
|
1354
|
+
const [query, setQuery] = useState("");
|
|
1355
|
+
const filterFns = useFilter({ sensitivity: "base" });
|
|
1356
|
+
const filtering = filterable && query.trim().length > 0;
|
|
1357
|
+
/** The corridor's answer to a query: every leaf whose route matches —
|
|
1358
|
+
* the query may land on any hop, and the whole route still shows. */
|
|
1359
|
+
const matchPaths = useMemo(() => {
|
|
1360
|
+
if (!filtering) return [];
|
|
1361
|
+
const q = query.trim();
|
|
1362
|
+
const hits = [];
|
|
1363
|
+
const walk = (nodes, path, labels, matched) => {
|
|
1364
|
+
for (const node of nodes ?? []) {
|
|
1365
|
+
const hit = matched || filterFns.contains(node.label, q);
|
|
1366
|
+
const nextPath = [...path, node.value];
|
|
1367
|
+
const nextLabels = [...labels, node.label];
|
|
1368
|
+
if (node.children?.length) walk(node.children, nextPath, nextLabels, hit);
|
|
1369
|
+
else if (hit) hits.push({
|
|
1370
|
+
path: nextPath,
|
|
1371
|
+
labels: nextLabels
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1374
|
+
};
|
|
1375
|
+
walk(data, [], [], false);
|
|
1376
|
+
return hits;
|
|
1377
|
+
}, [
|
|
1378
|
+
filtering,
|
|
1379
|
+
query,
|
|
1380
|
+
filterFns,
|
|
1381
|
+
data
|
|
1382
|
+
]);
|
|
1383
|
+
const isSelected = (path) => (value ?? []).some((p) => p.join("/") === path.join("/"));
|
|
1384
|
+
function pickMatch(path) {
|
|
1385
|
+
if (multiple) {
|
|
1386
|
+
const current = value ?? [];
|
|
1387
|
+
const key = path.join("/");
|
|
1388
|
+
const next = current.some((p) => p.join("/") === key) ? current.filter((p) => p.join("/") !== key) : [...current, path];
|
|
1389
|
+
api.setValue(next);
|
|
1390
|
+
} else {
|
|
1391
|
+
api.selectValue(path);
|
|
1392
|
+
api.setOpen(false);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1243
1395
|
/** The machine's `valueAsString` only updates through its select
|
|
1244
1396
|
* event, so an externally-set `value` would render the placeholder
|
|
1245
1397
|
* forever — resolve the labels from the data instead. */
|
|
@@ -1305,6 +1457,10 @@ function CascadeSelect({ value, data, placeholder = "Select…", highlightTrigge
|
|
|
1305
1457
|
...api.getControlProps(),
|
|
1306
1458
|
children: /* @__PURE__ */ jsxs("button", {
|
|
1307
1459
|
...api.getTriggerProps(),
|
|
1460
|
+
onClick: (event) => {
|
|
1461
|
+
api.getTriggerProps().onClick?.(event);
|
|
1462
|
+
setQuery("");
|
|
1463
|
+
},
|
|
1308
1464
|
disabled: disabled || void 0,
|
|
1309
1465
|
children: [/* @__PURE__ */ jsx("span", {
|
|
1310
1466
|
...api.getValueTextProps(),
|
|
@@ -1316,9 +1472,27 @@ function CascadeSelect({ value, data, placeholder = "Select…", highlightTrigge
|
|
|
1316
1472
|
})
|
|
1317
1473
|
}), /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx("div", {
|
|
1318
1474
|
...api.getPositionerProps(),
|
|
1319
|
-
children: /* @__PURE__ */
|
|
1475
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1320
1476
|
...api.getContentProps(),
|
|
1321
|
-
children:
|
|
1477
|
+
children: [filterable ? /* @__PURE__ */ jsx("div", {
|
|
1478
|
+
"data-part": "search",
|
|
1479
|
+
children: /* @__PURE__ */ jsx(Input, {
|
|
1480
|
+
size: "sm",
|
|
1481
|
+
value: query,
|
|
1482
|
+
onValueChange: setQuery,
|
|
1483
|
+
placeholder: "Filter…",
|
|
1484
|
+
"aria-label": "Filter options"
|
|
1485
|
+
})
|
|
1486
|
+
}) : null, filtering ? matchPaths.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
1487
|
+
"data-part": "empty",
|
|
1488
|
+
children: "Nothing matches"
|
|
1489
|
+
}) : matchPaths.map((hit) => /* @__PURE__ */ jsx("button", {
|
|
1490
|
+
type: "button",
|
|
1491
|
+
"data-part": "match",
|
|
1492
|
+
"data-selected": isSelected(hit.path) || void 0,
|
|
1493
|
+
onClick: () => pickMatch(hit.path),
|
|
1494
|
+
children: hit.labels.join(" / ")
|
|
1495
|
+
}, hit.path.join("/"))) : renderColumn(collection.rootNode, [], [])]
|
|
1322
1496
|
})
|
|
1323
1497
|
}) })]
|
|
1324
1498
|
});
|
|
@@ -1357,10 +1531,15 @@ const checkGlyph$1 = /* @__PURE__ */ jsx("svg", {
|
|
|
1357
1531
|
* One question, many answers: a labelled stack (or row) of the seal-cut
|
|
1358
1532
|
* checkboxes bound to a single array. Toggling a box adds or removes its
|
|
1359
1533
|
* value; the group itself is semantics (`role="group"`), the boxes stay
|
|
1360
|
-
* the machine-driven originals.
|
|
1534
|
+
* the machine-driven originals. Inside a `Field.Root` the group picks up
|
|
1535
|
+
* the field context, so the invalid and disabled states a Form routes to
|
|
1536
|
+
* its name dress every box at once.
|
|
1361
1537
|
*/
|
|
1362
|
-
function CheckboxGroup({ value = [], options, layout = "vertical", disabled = false, onValueChange, ...rest }) {
|
|
1538
|
+
function CheckboxGroup({ value = [], options, layout = "vertical", invalid = false, disabled = false, onValueChange, ...rest }) {
|
|
1539
|
+
const field = useFieldContext();
|
|
1363
1540
|
const selected = new Set(value);
|
|
1541
|
+
const isInvalid = invalid || field?.invalid === true;
|
|
1542
|
+
const isDisabled = disabled || field?.disabled === true;
|
|
1364
1543
|
function toggle(option) {
|
|
1365
1544
|
const next = new Set(selected);
|
|
1366
1545
|
if (next.has(option)) next.delete(option);
|
|
@@ -1373,9 +1552,11 @@ function CheckboxGroup({ value = [], options, layout = "vertical", disabled = fa
|
|
|
1373
1552
|
"data-scope": "checkbox-group",
|
|
1374
1553
|
"data-part": "root",
|
|
1375
1554
|
"data-layout": layout,
|
|
1555
|
+
"data-invalid": isInvalid ? "" : void 0,
|
|
1376
1556
|
children: options.map((option) => /* @__PURE__ */ jsxs(Checkbox$1.Root, {
|
|
1377
1557
|
checked: selected.has(option.value),
|
|
1378
|
-
|
|
1558
|
+
invalid: isInvalid,
|
|
1559
|
+
disabled: isDisabled || option.disabled === true,
|
|
1379
1560
|
onCheckedChange: () => toggle(option.value),
|
|
1380
1561
|
children: [
|
|
1381
1562
|
/* @__PURE__ */ jsx(Checkbox$1.Control, { children: /* @__PURE__ */ jsx(Checkbox$1.Indicator, { children: checkGlyph$1 }) }),
|
|
@@ -1716,23 +1897,6 @@ injectComponentStyle("dialog");
|
|
|
1716
1897
|
const Drawer = Drawer$1;
|
|
1717
1898
|
injectComponentStyle("drawer");
|
|
1718
1899
|
//#endregion
|
|
1719
|
-
//#region src/components/input/index.tsx
|
|
1720
|
-
function Input({ value, size = "md", invalid = false, onValueChange, ...rest }) {
|
|
1721
|
-
const field = useFieldContext();
|
|
1722
|
-
const fieldProps = field?.getInputProps() ?? {};
|
|
1723
|
-
return /* @__PURE__ */ jsx("input", {
|
|
1724
|
-
...fieldProps,
|
|
1725
|
-
...rest,
|
|
1726
|
-
...value !== void 0 ? { value } : {},
|
|
1727
|
-
"data-scope": "input",
|
|
1728
|
-
"data-part": "root",
|
|
1729
|
-
"data-size": size,
|
|
1730
|
-
"data-invalid": invalid || field?.invalid ? "" : void 0,
|
|
1731
|
-
onChange: (event) => onValueChange?.(event.target.value)
|
|
1732
|
-
});
|
|
1733
|
-
}
|
|
1734
|
-
injectComponentStyle("input");
|
|
1735
|
-
//#endregion
|
|
1736
1900
|
//#region src/components/dynamic-input/index.tsx
|
|
1737
1901
|
/**
|
|
1738
1902
|
* A column of entry rows: one Input per line, each with a quiet remove
|
|
@@ -2383,10 +2547,9 @@ injectComponentStyle("kbd");
|
|
|
2383
2547
|
const LAYOUT_CONTEXT = createContext(null);
|
|
2384
2548
|
/**
|
|
2385
2549
|
* The application skeleton: Root, Header, Sider, Content, Footer —
|
|
2386
|
-
* the admin arrangement
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2389
|
-
* edge the rail stands on.
|
|
2550
|
+
* the admin arrangement dressed in the paper-and-ink surfaces. The
|
|
2551
|
+
* root is a full-height grid; a declared `sider` turns the columns
|
|
2552
|
+
* around to meet whichever edge the rail stands on.
|
|
2390
2553
|
*/
|
|
2391
2554
|
function Root$5({ sider, children, ...rest }) {
|
|
2392
2555
|
return /* @__PURE__ */ jsx(LAYOUT_CONTEXT.Provider, {
|
|
@@ -3203,6 +3366,36 @@ const TagsInput = TagsInput$1;
|
|
|
3203
3366
|
injectComponentStyle("tags-input");
|
|
3204
3367
|
//#endregion
|
|
3205
3368
|
//#region src/components/table/index.tsx
|
|
3369
|
+
/** The pagination bar's arrows — thin chevrons for the row of seals. */
|
|
3370
|
+
function pageGlyph(direction) {
|
|
3371
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
3372
|
+
viewBox: "0 0 24 24",
|
|
3373
|
+
width: 14,
|
|
3374
|
+
height: 14,
|
|
3375
|
+
fill: "none",
|
|
3376
|
+
stroke: "currentColor",
|
|
3377
|
+
strokeWidth: 2,
|
|
3378
|
+
strokeLinecap: "round",
|
|
3379
|
+
strokeLinejoin: "round",
|
|
3380
|
+
"aria-hidden": "true",
|
|
3381
|
+
children: /* @__PURE__ */ jsx("path", { d: direction === "start" ? "m15 18-6-6 6-6" : "m9 18 6-6-6-6" })
|
|
3382
|
+
});
|
|
3383
|
+
}
|
|
3384
|
+
/** The page-size select's pointing chevron. */
|
|
3385
|
+
function chevronDownGlyph() {
|
|
3386
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
3387
|
+
viewBox: "0 0 24 24",
|
|
3388
|
+
width: 14,
|
|
3389
|
+
height: 14,
|
|
3390
|
+
fill: "none",
|
|
3391
|
+
stroke: "currentColor",
|
|
3392
|
+
strokeWidth: 2.5,
|
|
3393
|
+
strokeLinecap: "round",
|
|
3394
|
+
strokeLinejoin: "round",
|
|
3395
|
+
"aria-hidden": "true",
|
|
3396
|
+
children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
|
|
3397
|
+
});
|
|
3398
|
+
}
|
|
3206
3399
|
const SELECT_COL_ID = "__select";
|
|
3207
3400
|
const SELECT_COL_WIDTH = 48;
|
|
3208
3401
|
/** The list holding `id` and the index inside it, or null when absent. */
|
|
@@ -3282,7 +3475,7 @@ function SelectBox(props) {
|
|
|
3282
3475
|
}
|
|
3283
3476
|
function DataTable(rawProps) {
|
|
3284
3477
|
const props = rawProps;
|
|
3285
|
-
const { selectable = false, sortable = true, filterable = false, tree = false, virtual: virtualProp = false, rowHeight = 40, paginated = false, pageSize = 10, pageSizeOptions = [
|
|
3478
|
+
const { selectable = false, sortable = true, filterable = false, showToolbar = true, tree = false, virtual: virtualProp = false, rowHeight = 40, paginated = false, pageSize = 10, pageSizeOptions = [
|
|
3286
3479
|
10,
|
|
3287
3480
|
20,
|
|
3288
3481
|
50
|
|
@@ -3377,21 +3570,24 @@ function DataTable(rawProps) {
|
|
|
3377
3570
|
const rows = table.getRowModel().rows;
|
|
3378
3571
|
/** The declared row height is the density-scale baseline; the live
|
|
3379
3572
|
* scale comes off the document so the virtual window matches what CSS
|
|
3380
|
-
* actually renders.
|
|
3381
|
-
|
|
3573
|
+
* actually renders. It is read once and re-read only when the density
|
|
3574
|
+
* or scene attribute moves — estimateSize runs on every scroll frame. */
|
|
3575
|
+
let densityScale = 1;
|
|
3576
|
+
const readDensityScale = () => {
|
|
3382
3577
|
const value = Number(getComputedStyle(document.documentElement).getPropertyValue("--bs-density-scale"));
|
|
3383
|
-
|
|
3578
|
+
densityScale = Number.isFinite(value) && value > 0 ? value : 1;
|
|
3384
3579
|
};
|
|
3385
3580
|
const virtualizer = useVirtualizer({
|
|
3386
3581
|
count: rows.length,
|
|
3387
3582
|
getScrollElement: () => viewport.current,
|
|
3388
|
-
estimateSize: () => rowHeight * densityScale
|
|
3583
|
+
estimateSize: () => rowHeight * densityScale,
|
|
3389
3584
|
getItemKey: (index) => rows[index]?.id ?? index,
|
|
3390
3585
|
overscan: 8
|
|
3391
3586
|
});
|
|
3392
3587
|
const [, rerender] = useReducer((count) => count + 1, 0);
|
|
3393
3588
|
useEffect(() => {
|
|
3394
3589
|
if (!virtual) return;
|
|
3590
|
+
readDensityScale();
|
|
3395
3591
|
const observer = new MutationObserver(rerender);
|
|
3396
3592
|
observer.observe(document.documentElement, {
|
|
3397
3593
|
attributes: true,
|
|
@@ -3650,7 +3846,7 @@ function DataTable(rawProps) {
|
|
|
3650
3846
|
onDragLeave: canDrag ? onColDragLeave : void 0,
|
|
3651
3847
|
onDrop: canDrag ? (e) => onColDrop(column, e) : void 0,
|
|
3652
3848
|
onDragEnd: canDrag ? onColDragEnd : void 0,
|
|
3653
|
-
children: [header.isPlaceholder ? null : /* @__PURE__ */ jsx(FlexRender, { header }), canFilter ? /* @__PURE__ */ jsx("input", {
|
|
3849
|
+
children: [header.isPlaceholder || header.column.columnDef.header === "" ? null : /* @__PURE__ */ jsx(FlexRender, { header }), canFilter ? /* @__PURE__ */ jsx("input", {
|
|
3654
3850
|
type: "text",
|
|
3655
3851
|
"data-scope": "table",
|
|
3656
3852
|
"data-part": "header-filter",
|
|
@@ -3757,55 +3953,53 @@ function DataTable(rawProps) {
|
|
|
3757
3953
|
const paginationBar = paginated ? (() => {
|
|
3758
3954
|
const pagination = table.atoms.pagination.get();
|
|
3759
3955
|
const rowCount = table.getRowCount();
|
|
3760
|
-
const
|
|
3956
|
+
const sizeItems = createListCollection({ items: pageSizeOptions.map((size) => ({
|
|
3957
|
+
label: `${size} / page`,
|
|
3958
|
+
value: String(size)
|
|
3959
|
+
})) });
|
|
3960
|
+
const pageSize = /* @__PURE__ */ jsxs(Select.Root, {
|
|
3961
|
+
collection: sizeItems,
|
|
3962
|
+
value: [String(pagination.pageSize)],
|
|
3963
|
+
onValueChange: (details) => table.setPageSize(Number(details.value[0])),
|
|
3964
|
+
positioning: { placement: "top-start" },
|
|
3965
|
+
children: [/* @__PURE__ */ jsx(Select.Control, { children: /* @__PURE__ */ jsxs(Select.Trigger, {
|
|
3966
|
+
"aria-label": "Rows per page",
|
|
3967
|
+
children: [/* @__PURE__ */ jsx(Select.ValueText, {}), /* @__PURE__ */ jsx(Select.Indicator, { children: chevronDownGlyph() })]
|
|
3968
|
+
}) }), /* @__PURE__ */ jsx(Select.Positioner, { children: /* @__PURE__ */ jsx(Select.Content, { children: sizeItems.items.map((item) => /* @__PURE__ */ jsxs(Select.Item, {
|
|
3969
|
+
item,
|
|
3970
|
+
children: [/* @__PURE__ */ jsx(Select.ItemText, { children: item.label }), /* @__PURE__ */ jsx(Select.ItemIndicator, { children: "✓" })]
|
|
3971
|
+
}, item.value)) }) })]
|
|
3972
|
+
});
|
|
3973
|
+
const pager = /* @__PURE__ */ jsxs(Pagination.Root, {
|
|
3974
|
+
count: rowCount,
|
|
3975
|
+
pageSize: pagination.pageSize,
|
|
3976
|
+
page: pagination.pageIndex + 1,
|
|
3977
|
+
onPageChange: (details) => table.setPageIndex(details.page - 1),
|
|
3978
|
+
children: [
|
|
3979
|
+
/* @__PURE__ */ jsx(Pagination.PrevTrigger, { children: pageGlyph("start") }),
|
|
3980
|
+
/* @__PURE__ */ jsx(Pagination.Context, { children: (scope) => scope.pages.map((page, index) => page.type === "ellipsis" ? /* @__PURE__ */ jsx(Pagination.Ellipsis, { index }, `e${index}`) : /* @__PURE__ */ jsx(Pagination.Item, {
|
|
3981
|
+
type: "page",
|
|
3982
|
+
value: page.value,
|
|
3983
|
+
children: String(page.value)
|
|
3984
|
+
}, page.value)) }),
|
|
3985
|
+
/* @__PURE__ */ jsx(Pagination.NextTrigger, { children: pageGlyph("end") })
|
|
3986
|
+
]
|
|
3987
|
+
});
|
|
3761
3988
|
return /* @__PURE__ */ jsxs("div", {
|
|
3762
3989
|
"data-scope": "table",
|
|
3763
3990
|
"data-part": "pagination",
|
|
3764
|
-
children: [
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
/* @__PURE__ */ jsx("button", {
|
|
3774
|
-
type: "button",
|
|
3775
|
-
"data-scope": "table",
|
|
3776
|
-
"data-part": "page-button",
|
|
3777
|
-
disabled: !table.getCanNextPage(),
|
|
3778
|
-
onClick: () => table.nextPage(),
|
|
3779
|
-
children: "Next"
|
|
3780
|
-
}),
|
|
3781
|
-
/* @__PURE__ */ jsx("select", {
|
|
3782
|
-
"data-scope": "table",
|
|
3783
|
-
"data-part": "page-size",
|
|
3784
|
-
"aria-label": "Rows per page",
|
|
3785
|
-
value: pagination.pageSize,
|
|
3786
|
-
onChange: (e) => table.setPageSize(Number(e.target.value)),
|
|
3787
|
-
children: pageSizeOptions.map((size) => /* @__PURE__ */ jsxs("option", {
|
|
3788
|
-
value: size,
|
|
3789
|
-
children: [size, " / page"]
|
|
3790
|
-
}, size))
|
|
3791
|
-
}),
|
|
3792
|
-
/* @__PURE__ */ jsxs("span", {
|
|
3793
|
-
"data-scope": "table",
|
|
3794
|
-
"data-part": "page-status",
|
|
3795
|
-
children: [
|
|
3796
|
-
"Page ",
|
|
3797
|
-
pagination.pageIndex + 1,
|
|
3798
|
-
" of ",
|
|
3799
|
-
pageCount,
|
|
3800
|
-
" · ",
|
|
3801
|
-
rowCount,
|
|
3802
|
-
" rows"
|
|
3803
|
-
]
|
|
3804
|
-
})
|
|
3805
|
-
]
|
|
3991
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
3992
|
+
"data-scope": "table",
|
|
3993
|
+
"data-part": "page-status",
|
|
3994
|
+
children: [rowCount, " rows"]
|
|
3995
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3996
|
+
"data-scope": "table",
|
|
3997
|
+
"data-part": "page-nav",
|
|
3998
|
+
children: [pageSize, pager]
|
|
3999
|
+
})]
|
|
3806
4000
|
});
|
|
3807
4001
|
})() : null;
|
|
3808
|
-
const toolbar = filterable ? /* @__PURE__ */ jsx("div", {
|
|
4002
|
+
const toolbar = filterable && showToolbar ? /* @__PURE__ */ jsx("div", {
|
|
3809
4003
|
"data-scope": "table",
|
|
3810
4004
|
"data-part": "toolbar",
|
|
3811
4005
|
children: /* @__PURE__ */ jsx("input", {
|
|
@@ -4162,9 +4356,11 @@ function TreeSelectRow({ node, indexPath }) {
|
|
|
4162
4356
|
})
|
|
4163
4357
|
});
|
|
4164
4358
|
}
|
|
4165
|
-
function TreeSelect({ value, data, placeholder = "Select…", disabled = false, onValueChange, ...rest }) {
|
|
4359
|
+
function TreeSelect({ value, data, placeholder = "Select…", filterable = false, disabled = false, onValueChange, ...rest }) {
|
|
4166
4360
|
const [open, setOpen] = useState(false);
|
|
4167
|
-
const
|
|
4361
|
+
const [query, setQuery] = useState("");
|
|
4362
|
+
const filterFns = useFilter({ sensitivity: "base" });
|
|
4363
|
+
const collection = useMemo(() => createTreeCollection$1({
|
|
4168
4364
|
nodeToValue: (node) => node.value,
|
|
4169
4365
|
nodeToString: (node) => node.label,
|
|
4170
4366
|
rootNode: {
|
|
@@ -4172,8 +4368,29 @@ function TreeSelect({ value, data, placeholder = "Select…", disabled = false,
|
|
|
4172
4368
|
label: "",
|
|
4173
4369
|
children: data
|
|
4174
4370
|
}
|
|
4175
|
-
});
|
|
4371
|
+
}), [data]);
|
|
4372
|
+
const filtering = filterable && query.trim().length > 0;
|
|
4373
|
+
/** The collection pruned to the matches — each hit keeping its
|
|
4374
|
+
* ancestors, so a deep match still reads inside its hierarchy. */
|
|
4375
|
+
const visibleCollection = useMemo(() => filtering ? collection.filter((node) => filterFns.contains(node.label, query.trim())) : collection, [
|
|
4376
|
+
filtering,
|
|
4377
|
+
collection,
|
|
4378
|
+
filterFns,
|
|
4379
|
+
query
|
|
4380
|
+
]);
|
|
4176
4381
|
const firstLevel = data.map((node) => node.value);
|
|
4382
|
+
const expandedWhileFiltering = useMemo(() => {
|
|
4383
|
+
if (!filtering) return void 0;
|
|
4384
|
+
const values = [];
|
|
4385
|
+
const walk = (nodes) => {
|
|
4386
|
+
for (const node of nodes) if (node.children?.length) {
|
|
4387
|
+
values.push(node.value);
|
|
4388
|
+
walk(node.children);
|
|
4389
|
+
}
|
|
4390
|
+
};
|
|
4391
|
+
walk(visibleCollection.rootNode.children ?? []);
|
|
4392
|
+
return values;
|
|
4393
|
+
}, [filtering, visibleCollection]);
|
|
4177
4394
|
let found;
|
|
4178
4395
|
const walk = (nodes) => {
|
|
4179
4396
|
for (const node of nodes ?? []) {
|
|
@@ -4192,7 +4409,10 @@ function TreeSelect({ value, data, placeholder = "Select…", disabled = false,
|
|
|
4192
4409
|
return /* @__PURE__ */ jsxs(Popover$1.Root, {
|
|
4193
4410
|
...rest,
|
|
4194
4411
|
open,
|
|
4195
|
-
onOpenChange: (details) =>
|
|
4412
|
+
onOpenChange: (details) => {
|
|
4413
|
+
setOpen(details.open);
|
|
4414
|
+
if (!details.open) setQuery("");
|
|
4415
|
+
},
|
|
4196
4416
|
positioning: {
|
|
4197
4417
|
sameWidth: true,
|
|
4198
4418
|
placement: "bottom-start"
|
|
@@ -4209,20 +4429,38 @@ function TreeSelect({ value, data, placeholder = "Select…", disabled = false,
|
|
|
4209
4429
|
disabled,
|
|
4210
4430
|
children: [label ?? placeholder, chevronDown]
|
|
4211
4431
|
})
|
|
4212
|
-
}), /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Popover$1.Positioner, { children: /* @__PURE__ */
|
|
4432
|
+
}), /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Popover$1.Positioner, { children: /* @__PURE__ */ jsxs(Popover$1.Content, {
|
|
4213
4433
|
"data-scope": "tree-select",
|
|
4214
4434
|
"data-part": "content",
|
|
4215
|
-
children: /* @__PURE__ */ jsx(
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
}
|
|
4225
|
-
})
|
|
4435
|
+
children: [filterable ? /* @__PURE__ */ jsx("div", {
|
|
4436
|
+
"data-scope": "tree-select",
|
|
4437
|
+
"data-part": "search",
|
|
4438
|
+
children: /* @__PURE__ */ jsx(Input, {
|
|
4439
|
+
size: "sm",
|
|
4440
|
+
value: query,
|
|
4441
|
+
onValueChange: setQuery,
|
|
4442
|
+
placeholder: "Filter…",
|
|
4443
|
+
"aria-label": "Filter options"
|
|
4444
|
+
})
|
|
4445
|
+
}) : null, /* @__PURE__ */ jsx("div", {
|
|
4446
|
+
"data-scope": "tree-select",
|
|
4447
|
+
"data-part": "body",
|
|
4448
|
+
children: (visibleCollection.rootNode.children ?? []).length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
4449
|
+
"data-scope": "tree-select",
|
|
4450
|
+
"data-part": "empty",
|
|
4451
|
+
children: "Nothing matches"
|
|
4452
|
+
}) : /* @__PURE__ */ jsx(TreeView$1.Root, {
|
|
4453
|
+
collection: visibleCollection,
|
|
4454
|
+
selectionMode: "single",
|
|
4455
|
+
selectedValue: value ? [value] : [],
|
|
4456
|
+
...filtering ? { expandedValue: expandedWhileFiltering } : { defaultExpandedValue: firstLevel },
|
|
4457
|
+
onSelectionChange: pick,
|
|
4458
|
+
children: /* @__PURE__ */ jsx(TreeView$1.Tree, { children: visibleCollection.rootNode.children?.map((node, index) => /* @__PURE__ */ jsx(TreeSelectRow, {
|
|
4459
|
+
node,
|
|
4460
|
+
indexPath: [index]
|
|
4461
|
+
}, node.value)) })
|
|
4462
|
+
})
|
|
4463
|
+
})]
|
|
4226
4464
|
}) }) })]
|
|
4227
4465
|
});
|
|
4228
4466
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bysages/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "By Sages Elements components for React — styled by the paper-and-ink design tokens",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessible",
|
|
@@ -41,23 +41,24 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@ark-ui/react": "5.39.
|
|
44
|
+
"@ark-ui/react": "5.39.2",
|
|
45
45
|
"@tanstack/markdown": "0.0.15",
|
|
46
46
|
"@tanstack/react-table": "9.2.4",
|
|
47
|
-
"@tanstack/react-virtual": "3.14.
|
|
48
|
-
"@zag-js/cascade-select": "1.
|
|
49
|
-
"@zag-js/react": "1.
|
|
50
|
-
"@bysages/core": "0.
|
|
47
|
+
"@tanstack/react-virtual": "3.14.13",
|
|
48
|
+
"@zag-js/cascade-select": "1.44.0",
|
|
49
|
+
"@zag-js/react": "1.44.0",
|
|
50
|
+
"@bysages/core": "0.2.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@storybook/addon-a11y": "10.6.0",
|
|
54
54
|
"@storybook/react-vite": "10.6.0",
|
|
55
55
|
"@types/react": "19.3.0",
|
|
56
56
|
"@types/react-dom": "19.3.0",
|
|
57
|
-
"ai": "7.0.
|
|
57
|
+
"ai": "7.0.107",
|
|
58
58
|
"react": "19.3.0",
|
|
59
59
|
"react-dom": "19.3.0",
|
|
60
|
-
"storybook": "10.6.0"
|
|
60
|
+
"storybook": "10.6.0",
|
|
61
|
+
"zod": "4.6.5"
|
|
61
62
|
},
|
|
62
63
|
"peerDependencies": {
|
|
63
64
|
"react": ">=18",
|