@edux-design/buttons 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +4 -0
- package/dist/index.d.mts +86 -4
- package/dist/index.d.ts +86 -4
- package/dist/index.js +296 -34
- package/dist/index.mjs +295 -33
- package/docs/toolbar.md +146 -0
- package/package.json +10 -17
- package/dist/chevron-EVM4GL6D.svg +0 -4
- package/dist/chunk-M47FNL4P.mjs +0 -10
- package/dist/elements/Button.js +0 -39
- package/dist/elements/Button.mjs +0 -6
- package/src/demo/Button.stories.jsx +0 -103
- package/src/demo/ButtonCompatibility.stories.jsx +0 -115
- package/src/demo/ButtonCounter.stories.jsx +0 -101
- package/src/demo/ButtonGroup.stories.jsx +0 -67
- package/src/elements/Button.a11y.test.jsx +0 -60
- package/src/elements/Button.jsx +0 -127
- package/src/elements/Button.test.jsx +0 -120
- package/src/elements/ButtonCounter.jsx +0 -356
- package/src/elements/ButtonCounter.test.jsx +0 -121
- package/src/elements/ButtonGroup.jsx +0 -404
- package/src/elements/ButtonGroup.test.jsx +0 -130
- package/src/elements/ButtonGroupItem.jsx +0 -8
- package/src/elements/IconButton.jsx +0 -115
- package/src/elements/IconButton.test.jsx +0 -62
- package/src/elements/MenuButton.jsx +0 -68
- package/src/elements/MenuButton.test.jsx +0 -40
- package/src/elements/testA11y.js +0 -14
- package/src/index.js +0 -6
- package/src/util/MenuButtonContext.jsx +0 -3
- package/tsconfig.json +0 -12
package/dist/index.js
CHANGED
|
@@ -34,7 +34,12 @@ __export(index_exports, {
|
|
|
34
34
|
ButtonGroup: () => ButtonGroup,
|
|
35
35
|
ButtonGroupItem: () => ButtonGroupItem,
|
|
36
36
|
IconButton: () => IconButton,
|
|
37
|
-
MenuButton: () => MenuButton
|
|
37
|
+
MenuButton: () => MenuButton,
|
|
38
|
+
Toolbar: () => Toolbar,
|
|
39
|
+
ToolbarButton: () => ToolbarButton,
|
|
40
|
+
ToolbarGroup: () => ToolbarGroup,
|
|
41
|
+
ToolbarSeparator: () => ToolbarSeparator,
|
|
42
|
+
ToolbarToggleButton: () => ToolbarToggleButton
|
|
38
43
|
});
|
|
39
44
|
module.exports = __toCommonJS(index_exports);
|
|
40
45
|
|
|
@@ -75,19 +80,19 @@ var IconButton = (0, import_react.forwardRef)(
|
|
|
75
80
|
}
|
|
76
81
|
}
|
|
77
82
|
const defaults = "flex justify-center items-center focus:shadow-focus focus-visible:shadow-focus outline-none transition-all duration-300 ease-in-out rounded-full cursor-pointer";
|
|
78
|
-
const
|
|
83
|
+
const sizes2 = {
|
|
79
84
|
small: "size-control-sm text-sm",
|
|
80
85
|
medium: "size-control-md text-base",
|
|
81
86
|
large: "size-control-lg text-lg"
|
|
82
87
|
};
|
|
83
88
|
const variants = {
|
|
84
|
-
primary: "border-2 border-border-primary-emphasis bg-bg-primary-base text-
|
|
89
|
+
primary: "border-2 border-border-primary-emphasis bg-bg-primary-base text-fg-invert hover:bg-border-focus hover:text-fg-focus hover:border-border-emphasis hover:shadow-md active:bg-border-focus active:bg-bg-focus-overlay active:text-fg-focus",
|
|
85
90
|
secondary: "border-2 border-border-primary-base bg-bg-base text-fg-primary-emphasis hover:shadow-md hover:bg-bg-primary-subtle active:bg-bg-primary-subtle-90",
|
|
86
91
|
bare: "bg-bg-base text-fg-primary-emphasis hover:bg-bg-minimal active:bg-bg-minimal-5",
|
|
87
92
|
danger: "bg-bg-danger-base border-2 border-border-danger-emphasis text-white hover:bg-bg-danger-base-5 active:bg-bg-danger-base-10",
|
|
88
93
|
disabled: "border-2 border-border-subtle bg-bg-inactive text-fg-inactive hover:no-underline cursor-not-allowed"
|
|
89
94
|
};
|
|
90
|
-
const STYLES = (0, import_utils.cx)(defaults,
|
|
95
|
+
const STYLES = (0, import_utils.cx)(defaults, sizes2[size], variants[variant], className);
|
|
91
96
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
92
97
|
"button",
|
|
93
98
|
{
|
|
@@ -145,21 +150,21 @@ var Button = (0, import_react2.forwardRef)(
|
|
|
145
150
|
}
|
|
146
151
|
const defaults = "flex justify-center items-center gap-8 focus:shadow-focus focus-visible:shadow-focus outline-none transition-all duration-300 ease-in-out cursor-pointer";
|
|
147
152
|
const fonts = "text-bold tracking-normal hover:underline hover:underline-offset-(--underline-offset-btn) active:underline active:underline-offset-(--underline-offset-btn)";
|
|
148
|
-
const
|
|
153
|
+
const sizes2 = {
|
|
149
154
|
small: "h-control-sm py-8 px-16 rounded-lg text-sm",
|
|
150
155
|
medium: "h-control-md py-8 px-16 rounded-lg text-base",
|
|
151
156
|
large: "h-control-lg py-8 px-16 rounded-lg text-lg"
|
|
152
157
|
};
|
|
153
158
|
const width = isStretched ? "w-full" : "w-fit-content";
|
|
154
159
|
const variants = {
|
|
155
|
-
primary: "border-2 border-border-primary-emphasis bg-bg-primary-base text-
|
|
160
|
+
primary: "border-2 border-border-primary-emphasis bg-bg-primary-base text-fg-invert hover:bg-border-focus hover:text-fg-focus hover:border-border-emphasis hover:shadow-md active:bg-border-focus active:bg-bg-focus-overlay active:text-fg-focus",
|
|
156
161
|
secondary: "border-2 border-border-primary-base bg-bg-base text-fg-primary-emphasis hover:shadow-md hover:bg-bg-primary-subtle active:bg-bg-primary-subtle-90",
|
|
157
162
|
bare: "bg-bg-base text-fg-primary-emphasis hover:bg-bg-minimal active:bg-bg-minimal-5",
|
|
158
163
|
dangerBare: "bg-bg-base text-fg-danger-emphasis hover:bg-bg-danger-subtle active:bg-bg-danger-subtle",
|
|
159
164
|
danger: "bg-bg-danger-base border-2 border-border-danger-emphasis text-white hover:bg-bg-danger-base-5 active:bg-bg-danger-base-10",
|
|
160
165
|
disabled: "border-2 border-border-subtle bg-bg-inactive text-fg-inactive hover:no-underline"
|
|
161
166
|
};
|
|
162
|
-
const STYLES = (0, import_utils2.cx)(defaults,
|
|
167
|
+
const STYLES = (0, import_utils2.cx)(defaults, sizes2[size], width, fonts, variants[variant]);
|
|
163
168
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
164
169
|
"button",
|
|
165
170
|
{
|
|
@@ -599,7 +604,7 @@ var ButtonCounter = (0, import_react6.forwardRef)(function ButtonCounter2({
|
|
|
599
604
|
(next) => {
|
|
600
605
|
const clamped = Math.min(max, Math.max(min, next));
|
|
601
606
|
if (!isControlled) setInternalValue(clamped);
|
|
602
|
-
onChange
|
|
607
|
+
onChange?.(clamped);
|
|
603
608
|
},
|
|
604
609
|
[isControlled, max, min, onChange]
|
|
605
610
|
);
|
|
@@ -632,15 +637,15 @@ var ButtonCounter = (0, import_react6.forwardRef)(function ButtonCounter2({
|
|
|
632
637
|
const CONTROL_SIZES = {
|
|
633
638
|
small: {
|
|
634
639
|
button: "size-control-sm text-sm",
|
|
635
|
-
display: "h-control-sm min-w-
|
|
640
|
+
display: "h-control-sm min-w-48 px-12 text-sm"
|
|
636
641
|
},
|
|
637
642
|
medium: {
|
|
638
643
|
button: "size-control-md text-base",
|
|
639
|
-
display: "h-control-md min-w-
|
|
644
|
+
display: "h-control-md min-w-56 px-12 text-base"
|
|
640
645
|
},
|
|
641
646
|
large: {
|
|
642
647
|
button: "size-control-lg text-lg",
|
|
643
|
-
display: "h-control-lg min-w-
|
|
648
|
+
display: "h-control-lg min-w-72 px-16 text-lg"
|
|
644
649
|
}
|
|
645
650
|
};
|
|
646
651
|
const defaultsButton = "flex justify-center items-center focus:shadow-focus focus-visible:shadow-focus outline-none transition-all duration-300 ease-in-out cursor-pointer";
|
|
@@ -648,8 +653,8 @@ var ButtonCounter = (0, import_react6.forwardRef)(function ButtonCounter2({
|
|
|
648
653
|
const width = isStretched ? "w-full" : "w-fit-content";
|
|
649
654
|
const variants = {
|
|
650
655
|
primary: {
|
|
651
|
-
button: "border-2 border-border-primary-emphasis bg-bg-primary-base text-
|
|
652
|
-
display: "border-y-2 border-x-2 border-border-primary-emphasis bg-bg-primary-base text-
|
|
656
|
+
button: "border-2 border-border-primary-emphasis bg-bg-primary-base text-fg-invert hover:bg-border-focus hover:text-fg-focus hover:border-border-emphasis hover:shadow-md active:bg-border-focus active:bg-bg-focus-overlay active:text-fg-focus",
|
|
657
|
+
display: "border-y-2 border-x-2 border-border-primary-emphasis bg-bg-primary-base text-fg-invert"
|
|
653
658
|
},
|
|
654
659
|
secondary: {
|
|
655
660
|
button: "border-2 border-border-primary-base bg-bg-base text-fg-primary-emphasis hover:shadow-md hover:bg-bg-primary-subtle active:bg-bg-primary-subtle-90",
|
|
@@ -699,8 +704,8 @@ var ButtonCounter = (0, import_react6.forwardRef)(function ButtonCounter2({
|
|
|
699
704
|
const effectiveDecrementIcon = decrementIcon ?? startIcon ?? "-";
|
|
700
705
|
const effectiveIncrementIcon = incrementIcon ?? endIcon ?? "+";
|
|
701
706
|
const generatedValueId = (0, import_react6.useId)();
|
|
702
|
-
const valueElementId =
|
|
703
|
-
const valueAriaLabel =
|
|
707
|
+
const valueElementId = inputProps?.id ?? generatedValueId;
|
|
708
|
+
const valueAriaLabel = inputProps?.["aria-label"] ?? ariaLabel ?? "Value";
|
|
704
709
|
const [draftValue, setDraftValue] = (0, import_react6.useState)(String(clampedValue));
|
|
705
710
|
const [isEditing, setIsEditing] = (0, import_react6.useState)(false);
|
|
706
711
|
const inputRef = (0, import_react6.useRef)(null);
|
|
@@ -733,18 +738,17 @@ var ButtonCounter = (0, import_react6.forwardRef)(function ButtonCounter2({
|
|
|
733
738
|
{
|
|
734
739
|
...decrementButtonProps,
|
|
735
740
|
type: "button",
|
|
736
|
-
"aria-label":
|
|
741
|
+
"aria-label": decrementButtonProps?.["aria-label"] ?? "Decrease",
|
|
737
742
|
"aria-controls": valueElementId,
|
|
738
743
|
"aria-disabled": decrementDisabled,
|
|
739
744
|
disabled: decrementDisabled,
|
|
740
745
|
className: (0, import_utils5.cx)(
|
|
741
746
|
leftButtonStyles,
|
|
742
747
|
decrementDisabled && variant !== "disabled" ? variants.disabled.button : null,
|
|
743
|
-
decrementButtonProps
|
|
748
|
+
decrementButtonProps?.className
|
|
744
749
|
),
|
|
745
750
|
onClick: (event) => {
|
|
746
|
-
|
|
747
|
-
(_a = decrementButtonProps == null ? void 0 : decrementButtonProps.onClick) == null ? void 0 : _a.call(decrementButtonProps, event);
|
|
751
|
+
decrementButtonProps?.onClick?.(event);
|
|
748
752
|
if (event.defaultPrevented) return;
|
|
749
753
|
commitValue(clampedValue - step);
|
|
750
754
|
},
|
|
@@ -763,34 +767,30 @@ var ButtonCounter = (0, import_react6.forwardRef)(function ButtonCounter2({
|
|
|
763
767
|
"aria-label": valueAriaLabel,
|
|
764
768
|
className: (0, import_utils5.cx)(
|
|
765
769
|
displayStyles,
|
|
766
|
-
"w-
|
|
770
|
+
"w-control-md text-center outline-none bg-transparent text-fg-base",
|
|
767
771
|
"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-inner-spin-button]:m-0",
|
|
768
772
|
"focus:shadow-focus focus-visible:shadow-focus focus:z-15 focus-within:z-15",
|
|
769
|
-
inputProps
|
|
773
|
+
inputProps?.className
|
|
770
774
|
),
|
|
771
775
|
value: draftValue,
|
|
772
776
|
onChange: (event) => {
|
|
773
|
-
|
|
774
|
-
(_a = inputProps == null ? void 0 : inputProps.onChange) == null ? void 0 : _a.call(inputProps, event);
|
|
777
|
+
inputProps?.onChange?.(event);
|
|
775
778
|
if (event.defaultPrevented) return;
|
|
776
779
|
setDraftValue(event.target.value);
|
|
777
780
|
},
|
|
778
781
|
onFocus: (event) => {
|
|
779
|
-
|
|
780
|
-
(_a = inputProps == null ? void 0 : inputProps.onFocus) == null ? void 0 : _a.call(inputProps, event);
|
|
782
|
+
inputProps?.onFocus?.(event);
|
|
781
783
|
if (event.defaultPrevented) return;
|
|
782
784
|
setIsEditing(true);
|
|
783
785
|
},
|
|
784
786
|
onBlur: (event) => {
|
|
785
|
-
|
|
786
|
-
(_a = inputProps == null ? void 0 : inputProps.onBlur) == null ? void 0 : _a.call(inputProps, event);
|
|
787
|
+
inputProps?.onBlur?.(event);
|
|
787
788
|
if (event.defaultPrevented) return;
|
|
788
789
|
setIsEditing(false);
|
|
789
790
|
commitDraft();
|
|
790
791
|
},
|
|
791
792
|
onKeyDown: (event) => {
|
|
792
|
-
|
|
793
|
-
(_a = inputProps == null ? void 0 : inputProps.onKeyDown) == null ? void 0 : _a.call(inputProps, event);
|
|
793
|
+
inputProps?.onKeyDown?.(event);
|
|
794
794
|
if (event.defaultPrevented) return;
|
|
795
795
|
if (event.key === "Enter") {
|
|
796
796
|
event.currentTarget.blur();
|
|
@@ -817,18 +817,17 @@ var ButtonCounter = (0, import_react6.forwardRef)(function ButtonCounter2({
|
|
|
817
817
|
{
|
|
818
818
|
...incrementButtonProps,
|
|
819
819
|
type: "button",
|
|
820
|
-
"aria-label":
|
|
820
|
+
"aria-label": incrementButtonProps?.["aria-label"] ?? "Increase",
|
|
821
821
|
"aria-controls": valueElementId,
|
|
822
822
|
"aria-disabled": incrementDisabled,
|
|
823
823
|
disabled: incrementDisabled,
|
|
824
824
|
className: (0, import_utils5.cx)(
|
|
825
825
|
rightButtonStyles,
|
|
826
826
|
incrementDisabled && variant !== "disabled" ? variants.disabled.button : null,
|
|
827
|
-
incrementButtonProps
|
|
827
|
+
incrementButtonProps?.className
|
|
828
828
|
),
|
|
829
829
|
onClick: (event) => {
|
|
830
|
-
|
|
831
|
-
(_a = incrementButtonProps == null ? void 0 : incrementButtonProps.onClick) == null ? void 0 : _a.call(incrementButtonProps, event);
|
|
830
|
+
incrementButtonProps?.onClick?.(event);
|
|
832
831
|
if (event.defaultPrevented) return;
|
|
833
832
|
commitValue(clampedValue + step);
|
|
834
833
|
},
|
|
@@ -839,6 +838,264 @@ var ButtonCounter = (0, import_react6.forwardRef)(function ButtonCounter2({
|
|
|
839
838
|
}
|
|
840
839
|
);
|
|
841
840
|
});
|
|
841
|
+
|
|
842
|
+
// src/elements/Toolbar.tsx
|
|
843
|
+
var import_react7 = require("react");
|
|
844
|
+
var import_utils6 = require("@edux-design/utils");
|
|
845
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
846
|
+
function toolbarButtons(root) {
|
|
847
|
+
return Array.from(
|
|
848
|
+
root.querySelectorAll("[data-edux-toolbar-button]")
|
|
849
|
+
).filter((button) => {
|
|
850
|
+
if (button.closest("[data-edux-toolbar]") !== root) return false;
|
|
851
|
+
if (button.disabled || button.getAttribute("aria-disabled") === "true")
|
|
852
|
+
return false;
|
|
853
|
+
for (let node = button; node; node = node.parentElement) {
|
|
854
|
+
if (node.hidden || node.hasAttribute("inert") || node.getAttribute("aria-hidden") === "true")
|
|
855
|
+
return false;
|
|
856
|
+
const styles = node.ownerDocument.defaultView?.getComputedStyle(node);
|
|
857
|
+
if (styles?.display === "none" || styles?.visibility === "hidden")
|
|
858
|
+
return false;
|
|
859
|
+
if (node === root) break;
|
|
860
|
+
}
|
|
861
|
+
return true;
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
var Toolbar = (0, import_react7.forwardRef)(
|
|
865
|
+
function Toolbar2({
|
|
866
|
+
keyboardNavigation = "native",
|
|
867
|
+
orientation = "horizontal",
|
|
868
|
+
loop = true,
|
|
869
|
+
className,
|
|
870
|
+
children,
|
|
871
|
+
onKeyDown,
|
|
872
|
+
onFocusCapture,
|
|
873
|
+
...props
|
|
874
|
+
}, forwardedRef) {
|
|
875
|
+
const rootRef = (0, import_react7.useRef)(null);
|
|
876
|
+
(0, import_react7.useImperativeHandle)(forwardedRef, () => rootRef.current);
|
|
877
|
+
const lastFocused = (0, import_react7.useRef)(null);
|
|
878
|
+
const originalTabIndexes = (0, import_react7.useRef)(
|
|
879
|
+
/* @__PURE__ */ new Map()
|
|
880
|
+
);
|
|
881
|
+
function syncTabStops() {
|
|
882
|
+
const root = rootRef.current;
|
|
883
|
+
if (!root || keyboardNavigation !== "roving") return;
|
|
884
|
+
const buttons = toolbarButtons(root);
|
|
885
|
+
const active = buttons.includes(lastFocused.current) ? lastFocused.current : buttons[0];
|
|
886
|
+
root.querySelectorAll("[data-edux-toolbar-button]").forEach((button) => {
|
|
887
|
+
const nextTabIndex = button === active ? 0 : -1;
|
|
888
|
+
if (button.closest("[data-edux-toolbar]") !== root) return;
|
|
889
|
+
if (!originalTabIndexes.current.has(button))
|
|
890
|
+
originalTabIndexes.current.set(
|
|
891
|
+
button,
|
|
892
|
+
button.getAttribute("tabindex")
|
|
893
|
+
);
|
|
894
|
+
if (button.tabIndex !== nextTabIndex) button.tabIndex = nextTabIndex;
|
|
895
|
+
});
|
|
896
|
+
lastFocused.current = active ?? null;
|
|
897
|
+
}
|
|
898
|
+
(0, import_react7.useEffect)(() => {
|
|
899
|
+
const root = rootRef.current;
|
|
900
|
+
if (!root || keyboardNavigation !== "roving") return;
|
|
901
|
+
syncTabStops();
|
|
902
|
+
const observer = typeof MutationObserver === "undefined" ? null : new MutationObserver(syncTabStops);
|
|
903
|
+
observer?.observe(root, {
|
|
904
|
+
subtree: true,
|
|
905
|
+
childList: true,
|
|
906
|
+
attributes: true,
|
|
907
|
+
attributeFilter: [
|
|
908
|
+
"disabled",
|
|
909
|
+
"aria-disabled",
|
|
910
|
+
"hidden",
|
|
911
|
+
"inert",
|
|
912
|
+
"aria-hidden",
|
|
913
|
+
"class",
|
|
914
|
+
"style",
|
|
915
|
+
"tabindex"
|
|
916
|
+
]
|
|
917
|
+
});
|
|
918
|
+
return () => {
|
|
919
|
+
observer?.disconnect();
|
|
920
|
+
originalTabIndexes.current.forEach((value, button) => {
|
|
921
|
+
if (value === null) button.removeAttribute("tabindex");
|
|
922
|
+
else button.setAttribute("tabindex", value);
|
|
923
|
+
});
|
|
924
|
+
originalTabIndexes.current.clear();
|
|
925
|
+
};
|
|
926
|
+
}, [keyboardNavigation]);
|
|
927
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
928
|
+
"div",
|
|
929
|
+
{
|
|
930
|
+
...props,
|
|
931
|
+
ref: rootRef,
|
|
932
|
+
role: "toolbar",
|
|
933
|
+
"aria-orientation": orientation,
|
|
934
|
+
"data-edux-toolbar": "",
|
|
935
|
+
className: (0, import_utils6.cx)(
|
|
936
|
+
"flex min-w-0 flex-wrap gap-8",
|
|
937
|
+
orientation === "vertical" ? "flex-col items-start" : "items-center",
|
|
938
|
+
className
|
|
939
|
+
),
|
|
940
|
+
onFocusCapture: (event) => {
|
|
941
|
+
onFocusCapture?.(event);
|
|
942
|
+
const target = event.target;
|
|
943
|
+
if (target instanceof HTMLButtonElement && target.closest("[data-edux-toolbar]") === event.currentTarget) {
|
|
944
|
+
if (toolbarButtons(event.currentTarget).includes(target))
|
|
945
|
+
lastFocused.current = target;
|
|
946
|
+
syncTabStops();
|
|
947
|
+
}
|
|
948
|
+
},
|
|
949
|
+
onKeyDown: (event) => {
|
|
950
|
+
onKeyDown?.(event);
|
|
951
|
+
if (keyboardNavigation !== "roving" || event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey)
|
|
952
|
+
return;
|
|
953
|
+
const root = event.currentTarget;
|
|
954
|
+
const target = event.target;
|
|
955
|
+
if (!(target instanceof HTMLButtonElement) || target.closest("[data-edux-toolbar]") !== root)
|
|
956
|
+
return;
|
|
957
|
+
const buttons = toolbarButtons(root);
|
|
958
|
+
const index = buttons.indexOf(target);
|
|
959
|
+
if (index === -1) return;
|
|
960
|
+
let next;
|
|
961
|
+
if (event.key === "Home") next = 0;
|
|
962
|
+
else if (event.key === "End") next = buttons.length - 1;
|
|
963
|
+
else {
|
|
964
|
+
const directionValue = root.ownerDocument.defaultView?.getComputedStyle(root).direction || root.closest("[dir]")?.getAttribute("dir");
|
|
965
|
+
const rtl = directionValue === "rtl";
|
|
966
|
+
const forward = orientation === "vertical" ? "ArrowDown" : rtl ? "ArrowLeft" : "ArrowRight";
|
|
967
|
+
const backward = orientation === "vertical" ? "ArrowUp" : rtl ? "ArrowRight" : "ArrowLeft";
|
|
968
|
+
if (event.key !== forward && event.key !== backward) return;
|
|
969
|
+
const direction = event.key === forward ? 1 : -1;
|
|
970
|
+
next = loop ? (index + direction + buttons.length) % buttons.length : Math.max(0, Math.min(buttons.length - 1, index + direction));
|
|
971
|
+
}
|
|
972
|
+
event.preventDefault();
|
|
973
|
+
buttons[next]?.focus();
|
|
974
|
+
},
|
|
975
|
+
children
|
|
976
|
+
}
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
);
|
|
980
|
+
var ToolbarGroup = (0, import_react7.forwardRef)(
|
|
981
|
+
function ToolbarGroup2({ orientation = "horizontal", className, ...props }, ref) {
|
|
982
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
983
|
+
"div",
|
|
984
|
+
{
|
|
985
|
+
...props,
|
|
986
|
+
ref,
|
|
987
|
+
role: "group",
|
|
988
|
+
className: (0, import_utils6.cx)(
|
|
989
|
+
"inline-flex gap-4",
|
|
990
|
+
orientation === "vertical" ? "flex-col" : "flex-wrap items-center",
|
|
991
|
+
className
|
|
992
|
+
)
|
|
993
|
+
}
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
);
|
|
997
|
+
var ToolbarSeparator = (0, import_react7.forwardRef)(function ToolbarSeparator2({ orientation = "vertical", className, ...props }, ref) {
|
|
998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
999
|
+
"div",
|
|
1000
|
+
{
|
|
1001
|
+
...props,
|
|
1002
|
+
ref,
|
|
1003
|
+
role: "separator",
|
|
1004
|
+
"aria-orientation": orientation,
|
|
1005
|
+
className: (0, import_utils6.cx)(
|
|
1006
|
+
"shrink-0 border-border-subtle",
|
|
1007
|
+
orientation === "vertical" ? "h-control-sm border-l" : "w-full border-t",
|
|
1008
|
+
className
|
|
1009
|
+
)
|
|
1010
|
+
}
|
|
1011
|
+
);
|
|
1012
|
+
});
|
|
1013
|
+
|
|
1014
|
+
// src/elements/ToolbarButton.tsx
|
|
1015
|
+
var import_react8 = require("react");
|
|
1016
|
+
var import_utils7 = require("@edux-design/utils");
|
|
1017
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1018
|
+
var sizes = {
|
|
1019
|
+
small: "h-control-sm min-w-control-sm text-sm",
|
|
1020
|
+
medium: "h-control-md min-w-control-md text-base",
|
|
1021
|
+
large: "h-control-lg min-w-control-lg text-lg"
|
|
1022
|
+
};
|
|
1023
|
+
var ToolbarButton = (0, import_react8.forwardRef)(
|
|
1024
|
+
function ToolbarButton2({
|
|
1025
|
+
active = false,
|
|
1026
|
+
size = "small",
|
|
1027
|
+
variant = "neutral",
|
|
1028
|
+
icon,
|
|
1029
|
+
iconOnly = false,
|
|
1030
|
+
children,
|
|
1031
|
+
className,
|
|
1032
|
+
type = "button",
|
|
1033
|
+
onClick,
|
|
1034
|
+
...props
|
|
1035
|
+
}, ref) {
|
|
1036
|
+
const pressed = active || props["aria-pressed"] === true || props["aria-pressed"] === "true" || props["aria-pressed"] === "mixed";
|
|
1037
|
+
const disabled = props.disabled || props["aria-disabled"] === true || props["aria-disabled"] === "true";
|
|
1038
|
+
const colours = {
|
|
1039
|
+
neutral: pressed ? "border-border-primary-base bg-bg-primary-subtle text-fg-primary-emphasis" : "border-transparent bg-transparent text-fg-base hover:bg-bg-minimal active:bg-bg-inactive",
|
|
1040
|
+
primary: pressed ? "border-border-primary-emphasis bg-bg-primary-subtle text-fg-primary-emphasis" : "border-transparent bg-transparent text-fg-primary-emphasis hover:bg-bg-primary-subtle active:bg-bg-primary-subtle-90",
|
|
1041
|
+
danger: pressed ? "border-border-danger-emphasis bg-bg-danger-subtle text-fg-danger-emphasis" : "border-transparent bg-transparent text-fg-danger-emphasis hover:bg-bg-danger-subtle active:bg-bg-danger-subtle"
|
|
1042
|
+
};
|
|
1043
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1044
|
+
"button",
|
|
1045
|
+
{
|
|
1046
|
+
"aria-pressed": active ? true : void 0,
|
|
1047
|
+
...props,
|
|
1048
|
+
ref,
|
|
1049
|
+
type,
|
|
1050
|
+
"data-edux-toolbar-button": "",
|
|
1051
|
+
"data-state": pressed ? "on" : "off",
|
|
1052
|
+
className: (0, import_utils7.cx)(
|
|
1053
|
+
"inline-flex shrink-0 items-center justify-center gap-8 whitespace-nowrap rounded-md border-2 font-semibold cursor-pointer outline-none transition-colors duration-150 motion-reduce:transition-none focus-visible:shadow-focus disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50",
|
|
1054
|
+
sizes[size],
|
|
1055
|
+
iconOnly ? "aspect-square p-0" : "px-8",
|
|
1056
|
+
disabled ? "border-border-subtle bg-bg-inactive text-fg-inactive" : colours[variant],
|
|
1057
|
+
className
|
|
1058
|
+
),
|
|
1059
|
+
onClick: (event) => {
|
|
1060
|
+
if (disabled) {
|
|
1061
|
+
event.preventDefault();
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
onClick?.(event);
|
|
1065
|
+
},
|
|
1066
|
+
children: [
|
|
1067
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1068
|
+
"span",
|
|
1069
|
+
{
|
|
1070
|
+
"aria-hidden": "true",
|
|
1071
|
+
className: "inline-flex shrink-0 items-center",
|
|
1072
|
+
children: icon
|
|
1073
|
+
}
|
|
1074
|
+
),
|
|
1075
|
+
children
|
|
1076
|
+
]
|
|
1077
|
+
}
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
);
|
|
1081
|
+
var ToolbarToggleButton = (0, import_react8.forwardRef)(function ToolbarToggleButton2({ pressed, defaultPressed = false, onPressedChange, onClick, ...props }, ref) {
|
|
1082
|
+
const [internalPressed, setInternalPressed] = (0, import_react8.useState)(defaultPressed);
|
|
1083
|
+
const isPressed = pressed ?? internalPressed;
|
|
1084
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1085
|
+
ToolbarButton,
|
|
1086
|
+
{
|
|
1087
|
+
...props,
|
|
1088
|
+
ref,
|
|
1089
|
+
"aria-pressed": isPressed,
|
|
1090
|
+
onClick: (event) => {
|
|
1091
|
+
onClick?.(event);
|
|
1092
|
+
if (event.defaultPrevented) return;
|
|
1093
|
+
if (pressed === void 0) setInternalPressed(!isPressed);
|
|
1094
|
+
onPressedChange?.(!isPressed, event);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
);
|
|
1098
|
+
});
|
|
842
1099
|
// Annotate the CommonJS export names for ESM import in node:
|
|
843
1100
|
0 && (module.exports = {
|
|
844
1101
|
Button,
|
|
@@ -846,5 +1103,10 @@ var ButtonCounter = (0, import_react6.forwardRef)(function ButtonCounter2({
|
|
|
846
1103
|
ButtonGroup,
|
|
847
1104
|
ButtonGroupItem,
|
|
848
1105
|
IconButton,
|
|
849
|
-
MenuButton
|
|
1106
|
+
MenuButton,
|
|
1107
|
+
Toolbar,
|
|
1108
|
+
ToolbarButton,
|
|
1109
|
+
ToolbarGroup,
|
|
1110
|
+
ToolbarSeparator,
|
|
1111
|
+
ToolbarToggleButton
|
|
850
1112
|
});
|