@nsaa/core 0.1.0-alpha.1 → 0.1.0-alpha.2
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/accordion/accordion.d.ts +7 -0
- package/dist/accordion/accordion.js +54 -0
- package/dist/accordion/index.d.ts +3 -0
- package/dist/alert/alert.d.ts +18 -0
- package/dist/alert/alert.js +53 -0
- package/dist/alert/index.d.ts +3 -0
- package/dist/alert-dialog/alert-dialog.d.ts +19 -0
- package/dist/alert-dialog/alert-dialog.js +100 -0
- package/dist/alert-dialog/index.d.ts +3 -0
- package/dist/avatar/avatar.d.ts +12 -0
- package/dist/avatar/avatar.js +50 -0
- package/dist/avatar/index.d.ts +3 -0
- package/dist/badge/badge.d.ts +8 -0
- package/dist/badge/badge.js +29 -0
- package/dist/badge/index.d.ts +3 -0
- package/dist/button/button.d.ts +25 -0
- package/dist/button/button.js +136 -0
- package/dist/button/index.d.ts +3 -0
- package/dist/calendar/calendar.d.ts +11 -0
- package/dist/calendar/calendar.js +131 -0
- package/dist/calendar/index.d.ts +3 -0
- package/dist/card/card.d.ts +12 -0
- package/dist/card/card.js +55 -0
- package/dist/card/index.d.ts +3 -0
- package/dist/checkbox/checkbox.d.ts +4 -0
- package/dist/checkbox/checkbox.js +35 -0
- package/dist/checkbox/index.d.ts +3 -0
- package/dist/collapsible/collapsible.d.ts +6 -0
- package/dist/collapsible/collapsible.js +24 -0
- package/dist/collapsible/index.d.ts +3 -0
- package/dist/combobox/combobox.d.ts +27 -0
- package/dist/combobox/combobox.js +226 -0
- package/dist/combobox/index.d.ts +3 -0
- package/dist/command/command.d.ts +20 -0
- package/dist/command/command.js +116 -0
- package/dist/command/index.d.ts +3 -0
- package/dist/context-menu/context-menu.d.ts +30 -0
- package/dist/context-menu/context-menu.js +173 -0
- package/dist/context-menu/index.d.ts +3 -0
- package/dist/dialog/dialog.d.ts +18 -0
- package/dist/dialog/dialog.js +106 -0
- package/dist/dialog/index.d.ts +3 -0
- package/dist/direction.d.ts +3 -0
- package/dist/direction.js +2 -0
- package/dist/drawer/drawer.d.ts +17 -0
- package/dist/drawer/drawer.js +136 -0
- package/dist/drawer/index.d.ts +3 -0
- package/dist/dropdown-menu/dropdown-menu.d.ts +30 -0
- package/dist/dropdown-menu/dropdown-menu.js +177 -0
- package/dist/dropdown-menu/index.d.ts +3 -0
- package/dist/empty/empty.d.ts +35 -0
- package/dist/empty/empty.js +93 -0
- package/dist/empty/index.d.ts +3 -0
- package/dist/field/field.d.ts +26 -0
- package/dist/field/field.js +109 -0
- package/dist/field/index.d.ts +3 -0
- package/dist/index.d.ts +89 -674
- package/dist/index.js +48 -3876
- package/dist/input/index.d.ts +3 -0
- package/dist/input/input.d.ts +4 -0
- package/dist/input/input.js +14 -0
- package/dist/input-group/index.d.ts +3 -0
- package/dist/input-group/input-group.d.ts +19 -0
- package/dist/input-group/input-group.js +78 -0
- package/dist/input-otp/index.d.ts +3 -0
- package/dist/input-otp/input-otp.d.ts +12 -0
- package/dist/input-otp/input-otp.js +73 -0
- package/dist/kbd/index.d.ts +3 -0
- package/dist/kbd/kbd.d.ts +5 -0
- package/dist/kbd/kbd.js +19 -0
- package/dist/label/index.d.ts +3 -0
- package/dist/label/label.d.ts +4 -0
- package/dist/label/label.js +13 -0
- package/dist/legacy/icon-button/icon-swap.js +58 -0
- package/dist/lib/cn.d.ts +3 -0
- package/dist/{cn-DxFBFdwT.js → lib/cn.js} +1 -1
- package/dist/lib/control-defaults.js +8 -0
- package/dist/lib/icon-swap.d.ts +15 -0
- package/dist/lib/icon-swap.js +26 -0
- package/dist/lib/input-modality.js +39 -0
- package/dist/lib/merge-refs.js +21 -0
- package/dist/lib/shortcut.js +50 -0
- package/dist/lib/track-input-modality.d.ts +2 -0
- package/dist/lib/track-input-modality.js +4 -0
- package/dist/lib/tv.js +7 -0
- package/dist/lib/use-press.js +48 -0
- package/dist/lib/user-action.js +13 -0
- package/dist/loaders/arc.d.ts +6 -0
- package/dist/loaders/arc.js +31 -0
- package/dist/loaders/atom.d.ts +5 -0
- package/dist/loaders/atom.js +70 -0
- package/dist/loaders/blocks.d.ts +8 -0
- package/dist/loaders/blocks.js +74 -0
- package/dist/loaders/bouncing-dots.d.ts +3 -0
- package/dist/loaders/bouncing-dots.js +45 -0
- package/dist/loaders/cap.d.ts +6 -0
- package/dist/loaders/cap.js +7 -0
- package/dist/loaders/cascade.d.ts +5 -0
- package/dist/loaders/cascade.js +50 -0
- package/dist/loaders/circular-dots.d.ts +3 -0
- package/dist/loaders/circular-dots.js +40 -0
- package/dist/loaders/classic-v2.d.ts +3 -0
- package/dist/loaders/classic-v2.js +41 -0
- package/dist/loaders/classic.d.ts +3 -0
- package/dist/loaders/classic.js +48 -0
- package/dist/loaders/clock.d.ts +5 -0
- package/dist/loaders/clock.js +31 -0
- package/dist/loaders/comet.d.ts +5 -0
- package/dist/loaders/comet.js +52 -0
- package/dist/loaders/compass.d.ts +3 -0
- package/dist/loaders/compass.js +39 -0
- package/dist/loaders/dual.d.ts +6 -0
- package/dist/loaders/dual.js +47 -0
- package/dist/loaders/easing.d.ts +6 -0
- package/dist/loaders/easing.js +34 -0
- package/dist/loaders/eclipse.d.ts +3 -0
- package/dist/loaders/eclipse.js +69 -0
- package/dist/loaders/fade.js +28 -0
- package/dist/loaders/flip.d.ts +3 -0
- package/dist/loaders/flip.js +41 -0
- package/dist/{frame-CK9IBOZB.js → loaders/frame.js} +2 -50
- package/dist/loaders/gather.d.ts +3 -0
- package/dist/loaders/gather.js +85 -0
- package/dist/loaders/leap.d.ts +3 -0
- package/dist/loaders/leap.js +67 -0
- package/dist/loaders/linear-dots.d.ts +3 -0
- package/dist/loaders/linear-dots.js +54 -0
- package/dist/loaders/loading.d.ts +3 -0
- package/dist/loaders/loading.js +64 -0
- package/dist/loaders/morph.d.ts +3 -0
- package/dist/loaders/morph.js +40 -0
- package/dist/loaders/motion.d.ts +35 -0
- package/dist/loaders/motion.js +51 -0
- package/dist/loaders/orbit.d.ts +5 -0
- package/dist/loaders/orbit.js +44 -0
- package/dist/loaders/pulse.d.ts +3 -0
- package/dist/loaders/pulse.js +52 -0
- package/dist/loaders/radar.d.ts +5 -0
- package/dist/loaders/radar.js +64 -0
- package/dist/loaders/ring.d.ts +6 -0
- package/dist/loaders/ring.js +38 -0
- package/dist/loaders/ripple.d.ts +8 -0
- package/dist/loaders/ripple.js +57 -0
- package/dist/loaders/slide.d.ts +3 -0
- package/dist/loaders/slide.js +74 -0
- package/dist/loaders/snake.d.ts +6 -0
- package/dist/loaders/snake.js +59 -0
- package/dist/loaders/spinners.d.ts +61 -0
- package/dist/loaders/spinners.js +63 -0
- package/dist/loaders/swirl.d.ts +3 -0
- package/dist/loaders/swirl.js +50 -0
- package/dist/loaders/text/shared.js +25 -0
- package/dist/loaders/text/text-loaders.d.ts +48 -0
- package/dist/loaders/text/text-loaders.js +723 -0
- package/dist/loaders/trace.d.ts +6 -0
- package/dist/loaders/trace.js +46 -0
- package/dist/loaders/types.d.ts +10 -0
- package/dist/loaders/wave.d.ts +8 -0
- package/dist/loaders/wave.js +59 -0
- package/dist/loaders-text.d.ts +2 -47
- package/dist/loaders-text.js +1 -743
- package/dist/loaders.d.ts +36 -132
- package/dist/loaders.js +35 -1096
- package/dist/native-select/index.d.ts +3 -0
- package/dist/native-select/native-select.d.ts +9 -0
- package/dist/native-select/native-select.js +44 -0
- package/dist/pagination/index.d.ts +3 -0
- package/dist/pagination/pagination.d.ts +18 -0
- package/dist/pagination/pagination.js +134 -0
- package/dist/popover/index.d.ts +3 -0
- package/dist/popover/popover.d.ts +10 -0
- package/dist/popover/popover.js +54 -0
- package/dist/radio-group/index.d.ts +3 -0
- package/dist/radio-group/radio-group.d.ts +6 -0
- package/dist/radio-group/radio-group.js +33 -0
- package/dist/select/index.d.ts +3 -0
- package/dist/select/select.d.ts +16 -0
- package/dist/select/select.js +148 -0
- package/dist/separator/index.d.ts +3 -0
- package/dist/separator/separator.d.ts +4 -0
- package/dist/separator/separator.js +15 -0
- package/dist/skeleton/index.d.ts +3 -0
- package/dist/skeleton/skeleton.d.ts +10 -0
- package/dist/skeleton/skeleton.js +24 -0
- package/dist/slider/index.d.ts +3 -0
- package/dist/slider/slider.d.ts +4 -0
- package/dist/slider/slider.js +39 -0
- package/dist/sound/sound-map.d.ts +70 -0
- package/dist/sound/sound-map.js +72 -0
- package/dist/sound/sound.d.ts +38 -0
- package/dist/sound/sound.js +136 -0
- package/dist/sound/uisfx.d.ts +37 -0
- package/dist/sound/uisfx.js +59 -0
- package/dist/sound-uisfx.d.ts +2 -37
- package/dist/sound-uisfx.js +1 -58
- package/dist/spinner/index.d.ts +5 -0
- package/dist/spinner/loader-provider.d.ts +16 -0
- package/dist/spinner/loader-provider.js +28 -0
- package/dist/spinner/registry.d.ts +9 -0
- package/dist/spinner/registry.js +15 -0
- package/dist/spinner/spinner.d.ts +26 -0
- package/dist/spinner/spinner.js +143 -0
- package/dist/switch/index.d.ts +3 -0
- package/dist/switch/switch.d.ts +6 -0
- package/dist/switch/switch.js +25 -0
- package/dist/table/index.d.ts +3 -0
- package/dist/table/table.d.ts +17 -0
- package/dist/table/table.js +66 -0
- package/dist/tabs/index.d.ts +3 -0
- package/dist/tabs/tabs.d.ts +11 -0
- package/dist/tabs/tabs.js +46 -0
- package/dist/textarea/index.d.ts +3 -0
- package/dist/textarea/textarea.d.ts +4 -0
- package/dist/textarea/textarea.js +12 -0
- package/dist/toast/index.d.ts +3 -0
- package/dist/toast/toast.d.ts +17 -0
- package/dist/toast/toast.js +211 -0
- package/dist/toggle-group/index.d.ts +3 -0
- package/dist/toggle-group/toggle-group.d.ts +64 -0
- package/dist/toggle-group/toggle-group.js +95 -0
- package/dist/tokens/dist/motion.d.ts +24 -0
- package/dist/{motion-NQq2BA78.js → tokens/dist/motion.js} +1 -1
- package/dist/toolbar/index.d.ts +3 -0
- package/dist/toolbar/overflow.d.ts +4 -0
- package/dist/toolbar/overflow.js +242 -0
- package/dist/toolbar/toolbar-item.d.ts +29 -0
- package/dist/toolbar/toolbar-item.js +71 -0
- package/dist/toolbar/toolbar.d.ts +73 -0
- package/dist/toolbar/toolbar.js +250 -0
- package/dist/tooltip/index.d.ts +3 -0
- package/dist/tooltip/tooltip.d.ts +7 -0
- package/dist/tooltip/tooltip.js +41 -0
- package/package.json +4 -3
- package/dist/registry-2PyPW9Xw.js +0 -390
- package/dist/registry-DjfWNw3R.d.ts +0 -18
- package/dist/sound-DiYNAnR_.d.ts +0 -61
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
|
|
2
|
+
import { OverflowPriority } from "../toolbar/overflow.js";
|
|
3
|
+
import { ToolbarItemProps } from "../toolbar/toolbar-item.js";
|
|
4
|
+
import { ComponentProps } from "react";
|
|
5
|
+
import { ToggleGroup } from "@base-ui/react/toggle-group";
|
|
6
|
+
export type ToggleGroupSize = "xs" | "sm" | "md" | "lg";
|
|
7
|
+
export type ToggleGroupVariant = "ghost" | "outline";
|
|
8
|
+
interface BaseProps extends Omit<ComponentProps<typeof ToggleGroup>, "value" | "defaultValue" | "onValueChange" | "multiple"> {
|
|
9
|
+
/** Names the group for screen readers. */
|
|
10
|
+
"aria-label": string;
|
|
11
|
+
/** `outline`: items joined in one bordered track. */
|
|
12
|
+
variant?: ToggleGroupVariant | undefined;
|
|
13
|
+
/** Inherits the Toolbar's size inside one; `md` otherwise. */
|
|
14
|
+
size?: ToggleGroupSize | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Inside an `overflow="menu"` Toolbar the group moves into the More menu as one unit: radio
|
|
17
|
+
* items (single) or checkbox items (multiple), so its state survives. `"never"` keeps it.
|
|
18
|
+
*/
|
|
19
|
+
overflowPriority?: OverflowPriority | undefined;
|
|
20
|
+
}
|
|
21
|
+
export interface ToggleGroupSingleProps extends BaseProps {
|
|
22
|
+
/** `"single"` (default): one item on at a time; `"multiple"`: any number. */
|
|
23
|
+
type?: "single" | undefined;
|
|
24
|
+
/** Single: the pressed item's value, or `null` for none. Controlled. */
|
|
25
|
+
value?: string | null | undefined;
|
|
26
|
+
/** Single: the item pressed at first (uncontrolled). */
|
|
27
|
+
defaultValue?: string | null | undefined;
|
|
28
|
+
/** Single: called with the new value, `null` when the last item is switched off. */
|
|
29
|
+
onValueChange?: ((value: string | null) => void) | undefined;
|
|
30
|
+
/** The pressed item can't be switched off (alignment, view switchers). */
|
|
31
|
+
required?: boolean | undefined;
|
|
32
|
+
}
|
|
33
|
+
export interface ToggleGroupMultipleProps extends BaseProps {
|
|
34
|
+
/** `"single"` (default): one item on at a time; `"multiple"`: any number. */
|
|
35
|
+
type: "multiple";
|
|
36
|
+
/** Multiple: the pressed items' values. Controlled. */
|
|
37
|
+
value?: string[] | undefined;
|
|
38
|
+
/** Multiple: the items pressed at first (uncontrolled). */
|
|
39
|
+
defaultValue?: string[] | undefined;
|
|
40
|
+
/** Multiple: called with the new array of pressed values. */
|
|
41
|
+
onValueChange?: ((value: string[]) => void) | undefined;
|
|
42
|
+
required?: never;
|
|
43
|
+
}
|
|
44
|
+
export type ToggleGroupProps = ToggleGroupSingleProps | ToggleGroupMultipleProps;
|
|
45
|
+
/**
|
|
46
|
+
* A set of toggles where one (`type="single"`) or several (`"multiple"`) can be on, on Base UI
|
|
47
|
+
* `ToggleGroup`. Inside a `Toolbar` its items join the toolbar's arrow-key navigation.
|
|
48
|
+
*/
|
|
49
|
+
declare function ToggleGroup$1(props: ToggleGroupProps): import("react").JSX.Element | null;
|
|
50
|
+
declare namespace ToggleGroup$1 {
|
|
51
|
+
var Item: typeof ToggleGroupItem;
|
|
52
|
+
}
|
|
53
|
+
export interface ToggleGroupItemProps extends Omit<ToolbarItemProps, "value" | "pressed" | "onPressedChange"> {
|
|
54
|
+
/** Identifies the item in the group's value. Required. */
|
|
55
|
+
value: string;
|
|
56
|
+
/** Display-only shortcut, shown in the tooltip. */
|
|
57
|
+
shortcut?: string | undefined;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* One toggle in a `ToggleGroup`: a ghost Button (#84), icon-only (with a tooltip) when it has
|
|
61
|
+
* only an `icon`, a text toggle otherwise. A shortcut shows in the tooltip for both.
|
|
62
|
+
*/
|
|
63
|
+
declare function ToggleGroupItem({ shortcut, tooltip, ...rest }: ToggleGroupItemProps): import("react").JSX.Element;
|
|
64
|
+
export { ToggleGroup$1 as ToggleGroup };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { ControlDefaultsContext, useControlDefaults } from "../lib/control-defaults.js";
|
|
4
|
+
import { DropdownMenuCheckboxItem, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem } from "../dropdown-menu/dropdown-menu.js";
|
|
5
|
+
import { tv } from "../lib/tv.js";
|
|
6
|
+
import { ToolbarItem } from "../toolbar/toolbar-item.js";
|
|
7
|
+
import { useOverflowUnit } from "../toolbar/overflow.js";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { Children, isValidElement, useState } from "react";
|
|
10
|
+
import { ToggleGroup } from "@base-ui/react/toggle-group";
|
|
11
|
+
// src/toggle-group/toggle-group.tsx
|
|
12
|
+
const groupStyles = tv({
|
|
13
|
+
base: ["inline-flex items-center data-[orientation=vertical]:flex-col", "data-[orientation=horizontal]:pointer-coarse:[&_button]:before:min-w-0 data-[orientation=vertical]:pointer-coarse:[&_button]:before:min-h-0"],
|
|
14
|
+
variants: { variant: {
|
|
15
|
+
ghost: "gap-0.5",
|
|
16
|
+
outline: "gap-0 rounded-control border border-border-default [&>*]:rounded-none [&>*:first-child]:rounded-s-control [&>*:last-child]:rounded-e-control [&>*+*]:border-s-border-default data-[orientation=vertical]:[&>*+*]:border-s-transparent data-[orientation=vertical]:[&>*+*]:border-t-border-default"
|
|
17
|
+
} },
|
|
18
|
+
defaultVariants: { variant: "ghost" }
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* A set of toggles where one (`type="single"`) or several (`"multiple"`) can be on, on Base UI
|
|
22
|
+
* `ToggleGroup`. Inside a `Toolbar` its items join the toolbar's arrow-key navigation.
|
|
23
|
+
*/
|
|
24
|
+
function ToggleGroup$1(props) {
|
|
25
|
+
const { type = "single", value: valueProp, defaultValue, onValueChange, required = false, variant = "ghost", size: sizeProp, overflowPriority, orientation: orientationProp, className, children, ...rest } = props;
|
|
26
|
+
const defaults = useControlDefaults();
|
|
27
|
+
const multiple = type === "multiple";
|
|
28
|
+
const toArray = (v) => Array.isArray(v) ? v : v === null || v === void 0 ? [] : [v];
|
|
29
|
+
const [inner, setInner] = useState(() => toArray(defaultValue));
|
|
30
|
+
const controlled = valueProp !== void 0;
|
|
31
|
+
const current = controlled ? toArray(valueProp) : inner;
|
|
32
|
+
const handleChange = (next) => {
|
|
33
|
+
if (!multiple && required && next.length === 0) return;
|
|
34
|
+
if (!controlled) setInner(next);
|
|
35
|
+
onValueChange?.(multiple ? next : next[0] ?? null);
|
|
36
|
+
};
|
|
37
|
+
const size = sizeProp ?? defaults.size ?? "md";
|
|
38
|
+
const orientation = orientationProp ?? defaults.orientation ?? "horizontal";
|
|
39
|
+
const items = Children.toArray(children).flatMap((child) => isValidElement(child) && child.type === ToggleGroupItem ? [child.props] : []);
|
|
40
|
+
const label = rest["aria-label"];
|
|
41
|
+
const menu = multiple ? /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [label && /* @__PURE__ */ jsx(DropdownMenuLabel, { children: label }), items.map((item) => /* @__PURE__ */ jsxs(DropdownMenuCheckboxItem, {
|
|
42
|
+
disabled: item.disabled,
|
|
43
|
+
checked: current.includes(item.value),
|
|
44
|
+
onCheckedChange: (on) => handleChange(on ? [...current, item.value] : current.filter((v) => v !== item.value)),
|
|
45
|
+
children: [item.icon, item["aria-label"] ?? item.children ?? item.value]
|
|
46
|
+
}, item.value))] }) : /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [label && /* @__PURE__ */ jsx(DropdownMenuLabel, { children: label }), /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
|
|
47
|
+
value: current[0] ?? null,
|
|
48
|
+
onValueChange: (next) => handleChange(next ? [next] : []),
|
|
49
|
+
children: items.map((item) => /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
|
|
50
|
+
value: item.value,
|
|
51
|
+
disabled: item.disabled,
|
|
52
|
+
children: [item.icon, item["aria-label"] ?? item.children ?? item.value]
|
|
53
|
+
}, item.value))
|
|
54
|
+
})] });
|
|
55
|
+
const { hidden, unitProps, placeholder } = useOverflowUnit({
|
|
56
|
+
kind: "group",
|
|
57
|
+
priority: overflowPriority,
|
|
58
|
+
menu
|
|
59
|
+
});
|
|
60
|
+
if (hidden) return placeholder;
|
|
61
|
+
return /* @__PURE__ */ jsx(ControlDefaultsContext.Provider, {
|
|
62
|
+
value: {
|
|
63
|
+
...defaults,
|
|
64
|
+
size,
|
|
65
|
+
iconTransition: defaults.iconTransition ?? "instant",
|
|
66
|
+
sound: defaults.sound ?? false
|
|
67
|
+
},
|
|
68
|
+
children: /* @__PURE__ */ jsx(ToggleGroup, {
|
|
69
|
+
"data-slot": "toggle-group",
|
|
70
|
+
"data-variant": variant,
|
|
71
|
+
"data-size": size,
|
|
72
|
+
multiple,
|
|
73
|
+
orientation,
|
|
74
|
+
value: current,
|
|
75
|
+
onValueChange: handleChange,
|
|
76
|
+
className: cn(groupStyles({ variant }), className),
|
|
77
|
+
...unitProps,
|
|
78
|
+
...rest,
|
|
79
|
+
children
|
|
80
|
+
})
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* One toggle in a `ToggleGroup`: a ghost Button (#84), icon-only (with a tooltip) when it has
|
|
85
|
+
* only an `icon`, a text toggle otherwise. A shortcut shows in the tooltip for both.
|
|
86
|
+
*/
|
|
87
|
+
function ToggleGroupItem({ shortcut, tooltip, ...rest }) {
|
|
88
|
+
return /* @__PURE__ */ jsx(ToolbarItem, {
|
|
89
|
+
...rest,
|
|
90
|
+
"data-slot": "toggle-group-item",
|
|
91
|
+
tooltip: tooltip ?? (shortcut ? { shortcut } : void 0)
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
ToggleGroup$1.Item = ToggleGroupItem;
|
|
95
|
+
export { ToggleGroup$1 as ToggleGroup };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
export declare const sound: {
|
|
3
|
+
readonly $note: "On by default (decision #30): plays only after a user action, never on load; quiet; one remembered global mute; silent under prefers-reduced-motion; apps can turn the default off. Cue values are UISFX 0.4.0 cue names (MIT code, CC0 audio), checked against its CUES export; feel is a UISFX pack name (decision #57).";
|
|
4
|
+
readonly enabled: true;
|
|
5
|
+
readonly volume: 0.35;
|
|
6
|
+
readonly feel: "zen";
|
|
7
|
+
readonly library: "uisfx";
|
|
8
|
+
readonly libraryVersion: "0.4.0";
|
|
9
|
+
readonly cue: {
|
|
10
|
+
readonly "input.press": "press";
|
|
11
|
+
readonly "input.toggle-on": "toggle-on";
|
|
12
|
+
readonly "input.toggle-off": "toggle-off";
|
|
13
|
+
readonly "selection.select": "select";
|
|
14
|
+
readonly "navigation.open": "open";
|
|
15
|
+
readonly "navigation.close": "close";
|
|
16
|
+
readonly "movement.snap": "snap";
|
|
17
|
+
readonly "movement.drop": "drop";
|
|
18
|
+
readonly "feedback.success": "success";
|
|
19
|
+
readonly "feedback.warning": "warning";
|
|
20
|
+
readonly "feedback.error": "error";
|
|
21
|
+
readonly "commerce.payment": "purchase";
|
|
22
|
+
readonly "progress.loop": "loading";
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
|
|
2
|
+
import { Toolbar, ToolbarButtonProps, ToolbarGroupProps, ToolbarInputProps, ToolbarLinkProps, ToolbarProps, ToolbarSize } from "./toolbar.js";
|
|
3
|
+
export { Toolbar, type ToolbarButtonProps, type ToolbarGroupProps, type ToolbarInputProps, type ToolbarLinkProps, type ToolbarProps, type ToolbarSize };
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuSeparator, DropdownMenuTrigger } from "../dropdown-menu/dropdown-menu.js";
|
|
3
|
+
import { ToolbarItem } from "./toolbar-item.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { Fragment as Fragment$1, createContext, useCallback, useContext, useId, useLayoutEffect, useRef, useSyncExternalStore } from "react";
|
|
6
|
+
import { Toolbar } from "@base-ui/react/toolbar";
|
|
7
|
+
// src/toolbar/overflow.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Units register here; the Toolbar measures them and decides which are hidden. Hidden units stay
|
|
10
|
+
* mounted (so a ToggleGroup keeps its state) but render nothing inline and show their `menu`
|
|
11
|
+
* form in the More menu instead.
|
|
12
|
+
*/
|
|
13
|
+
var OverflowStore = class {
|
|
14
|
+
units = /* @__PURE__ */ new Map();
|
|
15
|
+
hidden = /* @__PURE__ */ new Set();
|
|
16
|
+
listeners = /* @__PURE__ */ new Set();
|
|
17
|
+
version = 0;
|
|
18
|
+
moreWidth = 0;
|
|
19
|
+
subscribe = (listener) => {
|
|
20
|
+
this.listeners.add(listener);
|
|
21
|
+
return () => this.listeners.delete(listener);
|
|
22
|
+
};
|
|
23
|
+
getVersion = () => this.version;
|
|
24
|
+
isHidden = (id) => this.hidden.has(id);
|
|
25
|
+
emit() {
|
|
26
|
+
this.version++;
|
|
27
|
+
for (const listener of this.listeners) listener();
|
|
28
|
+
}
|
|
29
|
+
ensure(id) {
|
|
30
|
+
let unit = this.units.get(id);
|
|
31
|
+
if (!unit) {
|
|
32
|
+
unit = {
|
|
33
|
+
kind: "item",
|
|
34
|
+
priority: 0,
|
|
35
|
+
menu: null,
|
|
36
|
+
el: null,
|
|
37
|
+
width: 0,
|
|
38
|
+
rank: Number.MAX_SAFE_INTEGER
|
|
39
|
+
};
|
|
40
|
+
this.units.set(id, unit);
|
|
41
|
+
}
|
|
42
|
+
return unit;
|
|
43
|
+
}
|
|
44
|
+
upsert(id, patch) {
|
|
45
|
+
Object.assign(this.ensure(id), patch);
|
|
46
|
+
if (this.hidden.has(id)) this.emit();
|
|
47
|
+
}
|
|
48
|
+
remove(id) {
|
|
49
|
+
this.units.delete(id);
|
|
50
|
+
if (this.hidden.delete(id)) this.emit();
|
|
51
|
+
}
|
|
52
|
+
elementOf(id) {
|
|
53
|
+
return this.units.get(id)?.el ?? null;
|
|
54
|
+
}
|
|
55
|
+
setElement(id, el) {
|
|
56
|
+
this.ensure(id).el = el;
|
|
57
|
+
}
|
|
58
|
+
setMoreWidth(width) {
|
|
59
|
+
if (width > 0) this.moreWidth = width;
|
|
60
|
+
}
|
|
61
|
+
/** Hidden units' menu forms in toolbar order, for the More menu. */
|
|
62
|
+
hiddenMenus() {
|
|
63
|
+
return [...this.units.entries()].filter(([id, unit]) => this.hidden.has(id) && unit.kind !== "separator").sort(([, a], [, b]) => a.rank - b.rank).map(([id, unit]) => ({
|
|
64
|
+
id,
|
|
65
|
+
kind: unit.kind,
|
|
66
|
+
menu: unit.menu
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
/** Measures the toolbar and hides the fewest units (highest priority number first). */
|
|
70
|
+
layout(root) {
|
|
71
|
+
const parent = root.parentElement;
|
|
72
|
+
if (!parent) return;
|
|
73
|
+
const rootStyle = getComputedStyle(root);
|
|
74
|
+
const parentStyle = getComputedStyle(parent);
|
|
75
|
+
const px = (value) => Number.parseFloat(value) || 0;
|
|
76
|
+
const room = parent.clientWidth - px(parentStyle.paddingLeft) - px(parentStyle.paddingRight) - (root.offsetWidth - root.clientWidth) - px(rootStyle.paddingLeft) - px(rootStyle.paddingRight);
|
|
77
|
+
const gap = px(rootStyle.columnGap);
|
|
78
|
+
const unitEls = [...root.querySelectorAll("[data-overflow-unit]")];
|
|
79
|
+
for (const [id, unit] of this.units) {
|
|
80
|
+
if (!unit.el?.isConnected) continue;
|
|
81
|
+
unit.rank = unitEls.indexOf(unit.el);
|
|
82
|
+
if (!this.hidden.has(id)) unit.width = unit.el.getBoundingClientRect().width;
|
|
83
|
+
}
|
|
84
|
+
const more = this.moreWidth || Math.max(0, ...[...this.units.values()].map((u) => u.el?.getBoundingClientRect().height ?? 0));
|
|
85
|
+
const ordered = [...this.units.entries()].sort(([, a], [, b]) => a.rank - b.rank);
|
|
86
|
+
const needs = (hidden) => {
|
|
87
|
+
const shown = ordered.filter(([id]) => !hidden.has(id));
|
|
88
|
+
const items = shown.reduce((sum, [, u]) => sum + u.width, 0);
|
|
89
|
+
const slots = shown.length + (hidden.size > 0 ? 1 : 0);
|
|
90
|
+
return items + (hidden.size > 0 ? more : 0) + gap * Math.max(0, slots - 1);
|
|
91
|
+
};
|
|
92
|
+
const hidden = /* @__PURE__ */ new Set();
|
|
93
|
+
if (needs(hidden) > room) {
|
|
94
|
+
const candidates = ordered.filter(([, u]) => u.kind !== "separator" && u.priority !== "never").sort(([, a], [, b]) => {
|
|
95
|
+
const pa = a.priority;
|
|
96
|
+
return b.priority - pa || b.rank - a.rank;
|
|
97
|
+
});
|
|
98
|
+
for (const [id] of candidates) {
|
|
99
|
+
hidden.add(id);
|
|
100
|
+
hideOrphanSeparators(ordered, hidden);
|
|
101
|
+
if (needs(hidden) <= room) break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!(hidden.size === this.hidden.size && [...hidden].every((id) => this.hidden.has(id)))) {
|
|
105
|
+
const active = root.ownerDocument.activeElement;
|
|
106
|
+
this.refocus = [...hidden].some((id) => {
|
|
107
|
+
const el = this.units.get(id)?.el;
|
|
108
|
+
return !this.hidden.has(id) && el !== null && el !== void 0 && el.contains(active);
|
|
109
|
+
});
|
|
110
|
+
const more = this.moreEl;
|
|
111
|
+
const onMore = more?.isConnected && (more.contains(active) || more.getAttribute("aria-expanded") === "true" && active?.closest("[role=\"menu\"]")?.id === more.getAttribute("aria-controls"));
|
|
112
|
+
const returning = hidden.size === 0 && onMore ? ordered.find(([id]) => this.hidden.has(id) && this.units.get(id)?.kind !== "separator") : void 0;
|
|
113
|
+
this.focusOnReturn = returning?.[0] ?? null;
|
|
114
|
+
this.hidden = hidden;
|
|
115
|
+
this.emit();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
refocus = false;
|
|
119
|
+
focusOnReturn = null;
|
|
120
|
+
/** True once for the unit that should take focus when it renders again (see `layout`). */
|
|
121
|
+
takeFocusOnReturn(id) {
|
|
122
|
+
if (this.focusOnReturn !== id) return false;
|
|
123
|
+
this.focusOnReturn = null;
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
/** The More button, while it is shown. */
|
|
127
|
+
moreEl = null;
|
|
128
|
+
setMoreElement(el) {
|
|
129
|
+
this.moreEl = el;
|
|
130
|
+
}
|
|
131
|
+
/** True once after a layout hid the focused item; the More button then takes focus. */
|
|
132
|
+
takeRefocus() {
|
|
133
|
+
const refocus = this.refocus;
|
|
134
|
+
this.refocus = false;
|
|
135
|
+
return refocus;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
/** A separator hides when the unit on either side of it is hidden or missing. */
|
|
139
|
+
function hideOrphanSeparators(ordered, hidden) {
|
|
140
|
+
const items = (list) => list.filter(([, u]) => u.kind !== "separator");
|
|
141
|
+
ordered.forEach(([id, u], index) => {
|
|
142
|
+
if (u.kind !== "separator") return;
|
|
143
|
+
const before = items(ordered.slice(0, index)).at(-1);
|
|
144
|
+
const after = items(ordered.slice(index + 1))[0];
|
|
145
|
+
if (!before || !after || hidden.has(before[0]) || hidden.has(after[0])) hidden.add(id);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
const OverflowContext = createContext(null);
|
|
149
|
+
/**
|
|
150
|
+
* Registers a toolbar part for overflow. Returns `hidden` (render nothing inline) and the props
|
|
151
|
+
* for its element. Outside an `overflow="menu"` toolbar it does nothing.
|
|
152
|
+
*/
|
|
153
|
+
function useOverflowUnit({ kind, priority = 0, menu }) {
|
|
154
|
+
const store = useContext(OverflowContext);
|
|
155
|
+
const id = useId();
|
|
156
|
+
const hidden = useSyncExternalStore(store?.subscribe ?? noopSubscribe, () => store?.isHidden(id) ?? false, () => false);
|
|
157
|
+
useLayoutEffect(() => {
|
|
158
|
+
store?.upsert(id, {
|
|
159
|
+
kind,
|
|
160
|
+
priority,
|
|
161
|
+
menu
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
useLayoutEffect(() => store ? () => store.remove(id) : void 0, [store, id]);
|
|
165
|
+
const ref = useCallback((el) => store?.setElement(id, el), [store, id]);
|
|
166
|
+
const shown = store !== null && !hidden;
|
|
167
|
+
useLayoutEffect(() => {
|
|
168
|
+
if (!shown || !store?.takeFocusOnReturn(id)) return;
|
|
169
|
+
const el = store.elementOf(id);
|
|
170
|
+
(el?.matches("button, a[href]") ? el : el?.querySelector("button:not(:disabled), a[href]"))?.focus();
|
|
171
|
+
}, [
|
|
172
|
+
shown,
|
|
173
|
+
store,
|
|
174
|
+
id
|
|
175
|
+
]);
|
|
176
|
+
return {
|
|
177
|
+
hidden: store !== null && hidden,
|
|
178
|
+
unitProps: store ? {
|
|
179
|
+
ref,
|
|
180
|
+
"data-overflow-unit": ""
|
|
181
|
+
} : {},
|
|
182
|
+
/** Render this while hidden: it keeps the unit's place in the toolbar order. */
|
|
183
|
+
placeholder: store ? /* @__PURE__ */ jsx("span", {
|
|
184
|
+
hidden: true,
|
|
185
|
+
ref,
|
|
186
|
+
"data-overflow-unit": ""
|
|
187
|
+
}) : null
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
const noopSubscribe = () => () => {};
|
|
191
|
+
const Ellipsis = () => /* @__PURE__ */ jsxs("svg", {
|
|
192
|
+
viewBox: "0 0 16 16",
|
|
193
|
+
"aria-hidden": "true",
|
|
194
|
+
children: [
|
|
195
|
+
/* @__PURE__ */ jsx("circle", {
|
|
196
|
+
cx: "3.5",
|
|
197
|
+
cy: "8",
|
|
198
|
+
r: "1.25",
|
|
199
|
+
fill: "currentColor"
|
|
200
|
+
}),
|
|
201
|
+
/* @__PURE__ */ jsx("circle", {
|
|
202
|
+
cx: "8",
|
|
203
|
+
cy: "8",
|
|
204
|
+
r: "1.25",
|
|
205
|
+
fill: "currentColor"
|
|
206
|
+
}),
|
|
207
|
+
/* @__PURE__ */ jsx("circle", {
|
|
208
|
+
cx: "12.5",
|
|
209
|
+
cy: "8",
|
|
210
|
+
r: "1.25",
|
|
211
|
+
fill: "currentColor"
|
|
212
|
+
})
|
|
213
|
+
]
|
|
214
|
+
});
|
|
215
|
+
/** The trailing More button: shows the hidden units' menu forms, in toolbar order. */
|
|
216
|
+
function OverflowMore({ store, label }) {
|
|
217
|
+
const version = useSyncExternalStore(store.subscribe, store.getVersion, store.getVersion);
|
|
218
|
+
const menus = store.hiddenMenus();
|
|
219
|
+
const button = useRef(null);
|
|
220
|
+
const measure = useCallback((el) => {
|
|
221
|
+
button.current = el;
|
|
222
|
+
store.setMoreElement(el);
|
|
223
|
+
if (el) store.setMoreWidth(el.getBoundingClientRect().width);
|
|
224
|
+
}, [store]);
|
|
225
|
+
useLayoutEffect(() => {
|
|
226
|
+
if (version && store.takeRefocus()) button.current?.focus();
|
|
227
|
+
}, [store, version]);
|
|
228
|
+
if (menus.length === 0) return null;
|
|
229
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, { render: /* @__PURE__ */ jsx(Toolbar.Button, {
|
|
230
|
+
"data-slot": "toolbar-overflow",
|
|
231
|
+
ref: measure,
|
|
232
|
+
render: /* @__PURE__ */ jsx(ToolbarItem, {
|
|
233
|
+
icon: /* @__PURE__ */ jsx(Ellipsis, {}),
|
|
234
|
+
"aria-label": label
|
|
235
|
+
})
|
|
236
|
+
}) }), /* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
237
|
+
align: "end",
|
|
238
|
+
className: "w-auto",
|
|
239
|
+
children: menus.map(({ id, kind, menu }, index) => /* @__PURE__ */ jsxs(Fragment$1, { children: [index > 0 && (kind === "group" || menus[index - 1]?.kind === "group") && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}), menu] }, id))
|
|
240
|
+
})] });
|
|
241
|
+
}
|
|
242
|
+
export { OverflowContext, OverflowMore, OverflowStore, useOverflowUnit };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
import { ComponentPropsWithRef, ReactNode } from "react";
|
|
3
|
+
import { Toggle } from "@base-ui/react/toggle";
|
|
4
|
+
export type ToolbarItemSize = "xs" | "sm" | "md" | "lg";
|
|
5
|
+
/** `left` / `right` are logical: they follow the reading direction, so they mirror in RTL. */
|
|
6
|
+
export type ToolbarTooltipSide = "top" | "bottom" | "left" | "right";
|
|
7
|
+
export interface ToolbarItemTooltip {
|
|
8
|
+
/** Defaults to the `aria-label`. */
|
|
9
|
+
content?: ReactNode;
|
|
10
|
+
/** Display-only shortcut, e.g. `"mod+B"`. */
|
|
11
|
+
shortcut?: string | undefined;
|
|
12
|
+
side?: ToolbarTooltipSide | undefined;
|
|
13
|
+
}
|
|
14
|
+
export type PressedChangeDetails = Parameters<NonNullable<ComponentPropsWithRef<typeof Toggle>["onPressedChange"]>>[1];
|
|
15
|
+
export interface ToolbarItemProps extends Omit<ComponentPropsWithRef<"button">, "children" | "value" | "color"> {
|
|
16
|
+
/** Icon-only when there are no children; then `aria-label` is required. */
|
|
17
|
+
icon?: ReactNode;
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
/** Controlled toggle state (`aria-pressed`). */
|
|
20
|
+
pressed?: boolean | undefined;
|
|
21
|
+
/** Called when the toggle is pressed or released; makes the item a toggle. */
|
|
22
|
+
onPressedChange?: ((pressed: boolean, details: PressedChangeDetails) => void) | undefined;
|
|
23
|
+
/** Makes it a ToggleGroup item (Base UI `Toggle` reads the group's state). */
|
|
24
|
+
value?: string | undefined;
|
|
25
|
+
/** On by default for icon-only items (shows the `aria-label`); off for text items. */
|
|
26
|
+
tooltip?: boolean | ToolbarItemTooltip | undefined;
|
|
27
|
+
/** Defaults to the Toolbar's or ToggleGroup's size. */
|
|
28
|
+
size?: ToolbarItemSize | undefined;
|
|
29
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { useControlDefaults } from "../lib/control-defaults.js";
|
|
4
|
+
import { Button } from "../button/button.js";
|
|
5
|
+
import { Kbd } from "../kbd/kbd.js";
|
|
6
|
+
import { ariaShortcut, formatShortcut } from "../lib/shortcut.js";
|
|
7
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "../tooltip/tooltip.js";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { Toggle } from "@base-ui/react/toggle";
|
|
10
|
+
// src/toolbar/toolbar-item.tsx
|
|
11
|
+
const ICON_SIZE = {
|
|
12
|
+
xs: "icon-xs",
|
|
13
|
+
sm: "icon-sm",
|
|
14
|
+
md: "icon",
|
|
15
|
+
lg: "icon-lg"
|
|
16
|
+
};
|
|
17
|
+
const TEXT_SIZE = {
|
|
18
|
+
xs: "xs",
|
|
19
|
+
sm: "sm",
|
|
20
|
+
md: "default",
|
|
21
|
+
lg: "lg"
|
|
22
|
+
};
|
|
23
|
+
const SIDE = {
|
|
24
|
+
top: "top",
|
|
25
|
+
bottom: "bottom",
|
|
26
|
+
left: "inline-start",
|
|
27
|
+
right: "inline-end"
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* A ghost Button (#84) sized to its toolbar, as a toggle when it has `pressed`, `onPressedChange`
|
|
31
|
+
* or a `value`, with a tooltip for icon-only items. On-state: shadcn's toggle (`bg-muted`).
|
|
32
|
+
*/
|
|
33
|
+
function ToolbarItem({ icon, children, pressed, onPressedChange, value, tooltip, size: sizeProp, className, type, ...rest }) {
|
|
34
|
+
const defaults = useControlDefaults();
|
|
35
|
+
const size = sizeProp ?? defaults.size ?? "md";
|
|
36
|
+
const iconOnly = icon !== void 0 && (children === void 0 || children === null);
|
|
37
|
+
const toggle = pressed !== void 0 || onPressedChange !== void 0 || value !== void 0;
|
|
38
|
+
const label = rest["aria-label"];
|
|
39
|
+
const button = /* @__PURE__ */ jsx(Button, {
|
|
40
|
+
...rest,
|
|
41
|
+
type: type ?? "button",
|
|
42
|
+
variant: "ghost",
|
|
43
|
+
size: iconOnly ? ICON_SIZE[size] : TEXT_SIZE[size],
|
|
44
|
+
className: cn("data-pressed:bg-muted data-pressed:text-foreground", defaults.instantColors && "transition-none", className),
|
|
45
|
+
children: iconOnly ? icon : /* @__PURE__ */ jsxs(Fragment, { children: [icon !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
46
|
+
"data-icon": "inline-start",
|
|
47
|
+
"aria-hidden": "true",
|
|
48
|
+
className: "contents",
|
|
49
|
+
children: icon
|
|
50
|
+
}), children] })
|
|
51
|
+
});
|
|
52
|
+
let root = button;
|
|
53
|
+
if (toggle) root = /* @__PURE__ */ jsx(Toggle, {
|
|
54
|
+
disabled: rest.disabled,
|
|
55
|
+
value,
|
|
56
|
+
pressed,
|
|
57
|
+
onPressedChange,
|
|
58
|
+
render: button
|
|
59
|
+
});
|
|
60
|
+
const options = tooltip === false ? void 0 : tooltip === true ? {} : tooltip;
|
|
61
|
+
const content = options?.content ?? (iconOnly || options ? label?.trim() : void 0);
|
|
62
|
+
if ((iconOnly || tooltip !== void 0) && options && content) root = /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
63
|
+
render: root,
|
|
64
|
+
"aria-keyshortcuts": options.shortcut ? ariaShortcut(options.shortcut) : void 0
|
|
65
|
+
}), /* @__PURE__ */ jsxs(TooltipContent, {
|
|
66
|
+
side: SIDE[options.side ?? "top"],
|
|
67
|
+
children: [content, options.shortcut && /* @__PURE__ */ jsx(Kbd, { children: formatShortcut(options.shortcut) })]
|
|
68
|
+
})] });
|
|
69
|
+
return root;
|
|
70
|
+
}
|
|
71
|
+
export { ToolbarItem };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
import { Input } from "../input/input.js";
|
|
3
|
+
import { OverflowPriority } from "./overflow.js";
|
|
4
|
+
import { ToolbarItemProps } from "./toolbar-item.js";
|
|
5
|
+
import { ComponentProps, ReactNode } from "react";
|
|
6
|
+
import { Toolbar } from "@base-ui/react/toolbar";
|
|
7
|
+
export type ToolbarSize = "xs" | "sm" | "md" | "lg";
|
|
8
|
+
export interface ToolbarProps extends Omit<ComponentProps<typeof Toolbar.Root>, "className"> {
|
|
9
|
+
/** Names the toolbar for screen readers. */
|
|
10
|
+
"aria-label": string;
|
|
11
|
+
/** Passed to every item. Default `sm`. */
|
|
12
|
+
size?: ToolbarSize | undefined;
|
|
13
|
+
/** `floating`: a raised surface for selection and bubble toolbars. */
|
|
14
|
+
surface?: "none" | "floating" | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* What happens when items don't fit. `menu` (default): items move, highest `overflowPriority`
|
|
17
|
+
* first, into a trailing More menu (horizontal toolbars). `scroll`: one row that scrolls
|
|
18
|
+
* sideways with edge fades. `none`: items wrap.
|
|
19
|
+
*/
|
|
20
|
+
overflow?: "menu" | "scroll" | "none" | undefined;
|
|
21
|
+
/** Accessible name of the More button. Default "More". */
|
|
22
|
+
overflowLabel?: string | undefined;
|
|
23
|
+
/** Play sounds for the items (toolbars are silent by default). */
|
|
24
|
+
sound?: boolean | undefined;
|
|
25
|
+
/** Classes for the toolbar root. */
|
|
26
|
+
className?: string | undefined;
|
|
27
|
+
children?: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Groups related controls behind one Tab stop, with arrow keys, Home and End moving between items
|
|
31
|
+
* (Base UI `Toolbar`). Items get the toolbar's size, swap icons instantly, change colour without
|
|
32
|
+
* transitions and stay silent unless `sound` is set: a toolbar is high-frequency.
|
|
33
|
+
*/
|
|
34
|
+
declare function ToolbarRoot({ size, surface, overflow, overflowLabel, sound, orientation, className, children, onKeyDown, ref, ...props }: ToolbarProps): import("react").JSX.Element;
|
|
35
|
+
interface OverflowProps {
|
|
36
|
+
/** `"never"` keeps the item visible; higher numbers move into the More menu first. Default 0. */
|
|
37
|
+
overflowPriority?: OverflowPriority | undefined;
|
|
38
|
+
}
|
|
39
|
+
export type ToolbarButtonProps = OverflowProps & ToolbarItemProps;
|
|
40
|
+
/**
|
|
41
|
+
* A ghost Button (#84): icon-only (with a tooltip) when it has only an `icon`, labelled otherwise;
|
|
42
|
+
* a toggle with `pressed`. Disabled items stay focusable so people can discover them.
|
|
43
|
+
*/
|
|
44
|
+
declare function ToolbarButton({ disabled, overflowPriority, ...props }: ToolbarButtonProps): import("react").JSX.Element | null;
|
|
45
|
+
export interface ToolbarLinkProps extends ComponentProps<typeof Toolbar.Link>, OverflowProps {
|
|
46
|
+
className?: string | undefined;
|
|
47
|
+
}
|
|
48
|
+
/** A link styled like a ghost toolbar item. */
|
|
49
|
+
declare function ToolbarLink({ className, overflowPriority, ...props }: ToolbarLinkProps): import("react").JSX.Element | null;
|
|
50
|
+
export interface ToolbarGroupProps extends ComponentProps<typeof Toolbar.Group> {
|
|
51
|
+
/** Names the cluster (`role="group"`). */
|
|
52
|
+
"aria-label"?: string | undefined;
|
|
53
|
+
className?: string | undefined;
|
|
54
|
+
}
|
|
55
|
+
/** A labelled cluster of items. */
|
|
56
|
+
declare function ToolbarGroup({ className, ...props }: ToolbarGroupProps): import("react").JSX.Element;
|
|
57
|
+
/** 1 px `border-default`, 60% of the item height, perpendicular to the toolbar. */
|
|
58
|
+
declare function ToolbarSeparator({ className, ...props }: ComponentProps<typeof Toolbar.Separator>): import("react").JSX.Element | null;
|
|
59
|
+
export type ToolbarInputProps = ComponentProps<typeof Input>;
|
|
60
|
+
/**
|
|
61
|
+
* A text input in the toolbar (search, find, a URL). At most one, placed last: arrow keys move
|
|
62
|
+
* the caret inside it (Base UI). The base-nova Input (#84) without its resting border; never
|
|
63
|
+
* collapses.
|
|
64
|
+
*/
|
|
65
|
+
declare function ToolbarInput({ className, ...props }: ToolbarInputProps): import("react").JSX.Element;
|
|
66
|
+
declare const Toolbar$1: typeof ToolbarRoot & {
|
|
67
|
+
Button: typeof ToolbarButton;
|
|
68
|
+
Input: typeof ToolbarInput;
|
|
69
|
+
Link: typeof ToolbarLink;
|
|
70
|
+
Group: typeof ToolbarGroup;
|
|
71
|
+
Separator: typeof ToolbarSeparator;
|
|
72
|
+
};
|
|
73
|
+
export { Toolbar$1 as Toolbar };
|