@edux-design/buttons 0.0.2 → 0.0.4
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 +15 -0
- package/README.md +110 -0
- package/dist/index.d.mts +159 -0
- package/dist/index.d.ts +159 -0
- package/dist/index.js +425 -26
- package/dist/index.mjs +429 -25
- package/package.json +6 -4
- package/src/demo/Button.stories.jsx +84 -0
- package/src/demo/ButtonGroup.stories.jsx +67 -0
- package/src/elements/Button.jsx +35 -3
- package/src/elements/ButtonGroup.jsx +387 -0
- package/src/elements/ButtonGroup.test.jsx +69 -0
- package/src/elements/ButtonGroupItem.jsx +8 -0
- package/src/elements/IconButton.jsx +104 -0
- package/src/elements/MenuButton.jsx +25 -1
- package/src/index.js +3 -0
- package/tsconfig.json +12 -0
package/dist/index.js
CHANGED
|
@@ -30,14 +30,76 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
32
|
Button: () => Button,
|
|
33
|
+
ButtonGroup: () => ButtonGroup,
|
|
34
|
+
ButtonGroupItem: () => ButtonGroupItem,
|
|
35
|
+
IconButton: () => IconButton,
|
|
33
36
|
MenuButton: () => MenuButton
|
|
34
37
|
});
|
|
35
38
|
module.exports = __toCommonJS(index_exports);
|
|
36
39
|
|
|
37
|
-
// src/elements/
|
|
40
|
+
// src/elements/IconButton.jsx
|
|
38
41
|
var import_react = __toESM(require("react"));
|
|
39
42
|
var import_utils = require("@edux-design/utils");
|
|
40
|
-
var
|
|
43
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
44
|
+
var IconButton = (0, import_react.forwardRef)(
|
|
45
|
+
({
|
|
46
|
+
icon,
|
|
47
|
+
size = "medium",
|
|
48
|
+
isSecondary,
|
|
49
|
+
isDanger,
|
|
50
|
+
isBare,
|
|
51
|
+
disabled,
|
|
52
|
+
className,
|
|
53
|
+
...props
|
|
54
|
+
}, ref) => {
|
|
55
|
+
let variant = "primary";
|
|
56
|
+
if (isBare) variant = "bare";
|
|
57
|
+
if (isSecondary) variant = "secondary";
|
|
58
|
+
if (isDanger) variant = "danger";
|
|
59
|
+
if (disabled) variant = "disabled";
|
|
60
|
+
if (process.env.NODE_ENV !== "production") {
|
|
61
|
+
const count = [isSecondary, isDanger, isBare].filter(Boolean).length;
|
|
62
|
+
if (count > 1) {
|
|
63
|
+
console.warn(
|
|
64
|
+
"[IconButton]: Multiple variant props passed. Using the highest priority only."
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
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";
|
|
69
|
+
const sizes = {
|
|
70
|
+
small: "h-[36px] w-[36px] text-sm",
|
|
71
|
+
medium: "h-[44px] w-[44px] text-base",
|
|
72
|
+
large: "h-[56px] w-[56px] text-lg"
|
|
73
|
+
};
|
|
74
|
+
const variants = {
|
|
75
|
+
primary: "border-2 border-border-primary-emphasis bg-bg-primary-base text-white hover:bg-border-focus hover:text-fg-base hover:border-border-emphasis hover:shadow-md active:bg-border-focus active:bg-bg-focus-overlay active:text-fg-base",
|
|
76
|
+
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",
|
|
77
|
+
bare: "bg-bg-base text-fg-primary-emphasis hover:bg-bg-minimal active:bg-bg-minimal-5",
|
|
78
|
+
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",
|
|
79
|
+
disabled: "border-2 border-border-subtle bg-bg-inactive text-fg-inactive hover:no-underline cursor-not-allowed"
|
|
80
|
+
};
|
|
81
|
+
const STYLES = (0, import_utils.cx)(defaults, sizes[size], variants[variant], className);
|
|
82
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
83
|
+
"button",
|
|
84
|
+
{
|
|
85
|
+
role: "button",
|
|
86
|
+
type: "button",
|
|
87
|
+
"aria-disabled": disabled,
|
|
88
|
+
disabled,
|
|
89
|
+
className: STYLES,
|
|
90
|
+
ref,
|
|
91
|
+
...props,
|
|
92
|
+
children: icon
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// src/elements/Button.jsx
|
|
99
|
+
var import_react2 = __toESM(require("react"));
|
|
100
|
+
var import_utils2 = require("@edux-design/utils");
|
|
101
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
102
|
+
var Button = (0, import_react2.forwardRef)(
|
|
41
103
|
({
|
|
42
104
|
children,
|
|
43
105
|
size = "medium",
|
|
@@ -77,8 +139,8 @@ var Button = (0, import_react.forwardRef)(
|
|
|
77
139
|
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",
|
|
78
140
|
disabled: "border-2 border-border-subtle bg-bg-inactive text-fg-inactive hover:no-underline"
|
|
79
141
|
};
|
|
80
|
-
const STYLES = (0,
|
|
81
|
-
return /* @__PURE__ */
|
|
142
|
+
const STYLES = (0, import_utils2.cx)(defaults, sizes[size], width, fonts, variants[variant]);
|
|
143
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
82
144
|
"button",
|
|
83
145
|
{
|
|
84
146
|
role: "button",
|
|
@@ -87,22 +149,22 @@ var Button = (0, import_react.forwardRef)(
|
|
|
87
149
|
disabled,
|
|
88
150
|
className: STYLES,
|
|
89
151
|
ref,
|
|
90
|
-
...props
|
|
91
|
-
|
|
92
|
-
|
|
152
|
+
...props,
|
|
153
|
+
children
|
|
154
|
+
}
|
|
93
155
|
);
|
|
94
156
|
}
|
|
95
157
|
);
|
|
96
158
|
|
|
97
159
|
// src/elements/MenuButton.jsx
|
|
98
|
-
var
|
|
160
|
+
var import_react4 = __toESM(require("react"));
|
|
99
161
|
|
|
100
162
|
// src/util/MenuButtonContext.jsx
|
|
101
|
-
var
|
|
102
|
-
var MenuButtonContext = (0,
|
|
163
|
+
var import_react3 = __toESM(require("react"));
|
|
164
|
+
var MenuButtonContext = (0, import_react3.createContext)();
|
|
103
165
|
|
|
104
166
|
// src/elements/MenuButton.jsx
|
|
105
|
-
var
|
|
167
|
+
var import_utils3 = require("@edux-design/utils");
|
|
106
168
|
|
|
107
169
|
// ../icons/dist/index.mjs
|
|
108
170
|
var __create2 = Object.create;
|
|
@@ -1759,19 +1821,19 @@ var require_react_jsx_runtime_development = __commonJS({
|
|
|
1759
1821
|
function validateChildKeys(node) {
|
|
1760
1822
|
"object" === typeof node && null !== node && node.$$typeof === REACT_ELEMENT_TYPE && node._store && (node._store.validated = 1);
|
|
1761
1823
|
}
|
|
1762
|
-
var
|
|
1763
|
-
var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals =
|
|
1824
|
+
var React7 = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler");
|
|
1825
|
+
var REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React7.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
|
|
1764
1826
|
return null;
|
|
1765
1827
|
};
|
|
1766
|
-
|
|
1828
|
+
React7 = {
|
|
1767
1829
|
react_stack_bottom_frame: function(callStackForError) {
|
|
1768
1830
|
return callStackForError();
|
|
1769
1831
|
}
|
|
1770
1832
|
};
|
|
1771
1833
|
var specialPropKeyWarningShown;
|
|
1772
1834
|
var didWarnAboutElementRef = {};
|
|
1773
|
-
var unknownOwnerDebugStack =
|
|
1774
|
-
|
|
1835
|
+
var unknownOwnerDebugStack = React7.react_stack_bottom_frame.bind(
|
|
1836
|
+
React7,
|
|
1775
1837
|
UnknownOwner
|
|
1776
1838
|
)();
|
|
1777
1839
|
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
|
|
@@ -1815,10 +1877,13 @@ var require_jsx_runtime = __commonJS({
|
|
|
1815
1877
|
}
|
|
1816
1878
|
}
|
|
1817
1879
|
});
|
|
1818
|
-
var import_jsx_runtime = __toESM2(require_jsx_runtime());
|
|
1819
|
-
var import_jsx_runtime2 = __toESM2(require_jsx_runtime());
|
|
1820
1880
|
var import_jsx_runtime3 = __toESM2(require_jsx_runtime());
|
|
1821
|
-
var
|
|
1881
|
+
var import_jsx_runtime22 = __toESM2(require_jsx_runtime());
|
|
1882
|
+
var import_jsx_runtime32 = __toESM2(require_jsx_runtime());
|
|
1883
|
+
var import_jsx_runtime4 = __toESM2(require_jsx_runtime());
|
|
1884
|
+
var import_jsx_runtime5 = __toESM2(require_jsx_runtime());
|
|
1885
|
+
var import_jsx_runtime6 = __toESM2(require_jsx_runtime());
|
|
1886
|
+
var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1822
1887
|
"svg",
|
|
1823
1888
|
{
|
|
1824
1889
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -1827,7 +1892,7 @@ var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
|
1827
1892
|
fill: "none",
|
|
1828
1893
|
viewBox: "0 0 24 24",
|
|
1829
1894
|
...props,
|
|
1830
|
-
children: /* @__PURE__ */ (0,
|
|
1895
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1831
1896
|
"path",
|
|
1832
1897
|
{
|
|
1833
1898
|
fill: "currentColor",
|
|
@@ -1839,9 +1904,6 @@ var SvgChevron = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
|
1839
1904
|
}
|
|
1840
1905
|
);
|
|
1841
1906
|
var Chevron_default = SvgChevron;
|
|
1842
|
-
var import_jsx_runtime4 = __toESM2(require_jsx_runtime());
|
|
1843
|
-
var import_jsx_runtime5 = __toESM2(require_jsx_runtime());
|
|
1844
|
-
var import_jsx_runtime6 = __toESM2(require_jsx_runtime());
|
|
1845
1907
|
var import_jsx_runtime7 = __toESM2(require_jsx_runtime());
|
|
1846
1908
|
var import_jsx_runtime8 = __toESM2(require_jsx_runtime());
|
|
1847
1909
|
var import_jsx_runtime9 = __toESM2(require_jsx_runtime());
|
|
@@ -1857,7 +1919,7 @@ var import_jsx_runtime18 = __toESM2(require_jsx_runtime());
|
|
|
1857
1919
|
var import_jsx_runtime19 = __toESM2(require_jsx_runtime());
|
|
1858
1920
|
var import_jsx_runtime20 = __toESM2(require_jsx_runtime());
|
|
1859
1921
|
var import_jsx_runtime21 = __toESM2(require_jsx_runtime());
|
|
1860
|
-
var
|
|
1922
|
+
var import_jsx_runtime222 = __toESM2(require_jsx_runtime());
|
|
1861
1923
|
var import_jsx_runtime23 = __toESM2(require_jsx_runtime());
|
|
1862
1924
|
var import_jsx_runtime24 = __toESM2(require_jsx_runtime());
|
|
1863
1925
|
var import_jsx_runtime25 = __toESM2(require_jsx_runtime());
|
|
@@ -1866,21 +1928,358 @@ var import_jsx_runtime27 = __toESM2(require_jsx_runtime());
|
|
|
1866
1928
|
var import_jsx_runtime28 = __toESM2(require_jsx_runtime());
|
|
1867
1929
|
var import_jsx_runtime29 = __toESM2(require_jsx_runtime());
|
|
1868
1930
|
var import_jsx_runtime30 = __toESM2(require_jsx_runtime());
|
|
1931
|
+
var import_jsx_runtime31 = __toESM2(require_jsx_runtime());
|
|
1932
|
+
var import_jsx_runtime322 = __toESM2(require_jsx_runtime());
|
|
1933
|
+
var import_jsx_runtime33 = __toESM2(require_jsx_runtime());
|
|
1934
|
+
var import_jsx_runtime34 = __toESM2(require_jsx_runtime());
|
|
1935
|
+
var import_jsx_runtime35 = __toESM2(require_jsx_runtime());
|
|
1936
|
+
var import_jsx_runtime36 = __toESM2(require_jsx_runtime());
|
|
1937
|
+
var import_jsx_runtime37 = __toESM2(require_jsx_runtime());
|
|
1938
|
+
var import_jsx_runtime38 = __toESM2(require_jsx_runtime());
|
|
1939
|
+
var import_jsx_runtime39 = __toESM2(require_jsx_runtime());
|
|
1940
|
+
var import_jsx_runtime40 = __toESM2(require_jsx_runtime());
|
|
1941
|
+
var import_jsx_runtime41 = __toESM2(require_jsx_runtime());
|
|
1942
|
+
var import_jsx_runtime42 = __toESM2(require_jsx_runtime());
|
|
1943
|
+
var import_jsx_runtime43 = __toESM2(require_jsx_runtime());
|
|
1944
|
+
var import_jsx_runtime44 = __toESM2(require_jsx_runtime());
|
|
1945
|
+
var import_jsx_runtime45 = __toESM2(require_jsx_runtime());
|
|
1946
|
+
var import_jsx_runtime46 = __toESM2(require_jsx_runtime());
|
|
1947
|
+
var import_jsx_runtime47 = __toESM2(require_jsx_runtime());
|
|
1948
|
+
var import_jsx_runtime48 = __toESM2(require_jsx_runtime());
|
|
1949
|
+
var import_jsx_runtime49 = __toESM2(require_jsx_runtime());
|
|
1950
|
+
var import_jsx_runtime50 = __toESM2(require_jsx_runtime());
|
|
1951
|
+
var import_jsx_runtime51 = __toESM2(require_jsx_runtime());
|
|
1952
|
+
var import_jsx_runtime52 = __toESM2(require_jsx_runtime());
|
|
1953
|
+
var import_jsx_runtime53 = __toESM2(require_jsx_runtime());
|
|
1954
|
+
var import_jsx_runtime54 = __toESM2(require_jsx_runtime());
|
|
1955
|
+
var import_jsx_runtime55 = __toESM2(require_jsx_runtime());
|
|
1869
1956
|
|
|
1870
1957
|
// src/elements/MenuButton.jsx
|
|
1958
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
1871
1959
|
function MenuButton({ children, size }) {
|
|
1872
|
-
const SPLIT_BUTTON_STYLES = (0,
|
|
1960
|
+
const SPLIT_BUTTON_STYLES = (0, import_utils3.cx)(
|
|
1873
1961
|
"w-[36px] border-l-[1px] border-l-black flex flex-row justify-center items-center",
|
|
1874
1962
|
{
|
|
1875
1963
|
"h-[32px]": size === "small",
|
|
1876
1964
|
"h-[40px] py-2": size === "medium" || size === void 0
|
|
1877
1965
|
}
|
|
1878
1966
|
);
|
|
1879
|
-
return /* @__PURE__ */
|
|
1967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(MenuButtonContext.Provider, { value: true, children: [
|
|
1968
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: SPLIT_BUTTON_STYLES, children }),
|
|
1969
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Chevron_default, {})
|
|
1970
|
+
] });
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
// src/elements/ButtonGroup.jsx
|
|
1974
|
+
var import_react5 = __toESM(require("react"));
|
|
1975
|
+
var import_utils4 = require("@edux-design/utils");
|
|
1976
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
1977
|
+
var SIZE_STYLES = {
|
|
1978
|
+
small: {
|
|
1979
|
+
button: "text-xs px-12 py-6 rounded-md "
|
|
1980
|
+
},
|
|
1981
|
+
medium: {
|
|
1982
|
+
button: "text-sm px-12 py-6 rounded-md "
|
|
1983
|
+
},
|
|
1984
|
+
large: {
|
|
1985
|
+
button: "text-base px-12 py-6 rounded-md"
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
var isBrowser = typeof window !== "undefined";
|
|
1989
|
+
var useIsomorphicLayoutEffect = isBrowser ? import_react5.useLayoutEffect : import_react5.useEffect;
|
|
1990
|
+
var ButtonGroup = (0, import_react5.forwardRef)(function ButtonGroup2({
|
|
1991
|
+
value,
|
|
1992
|
+
defaultValue,
|
|
1993
|
+
onChange,
|
|
1994
|
+
size = "medium",
|
|
1995
|
+
isStretched = false,
|
|
1996
|
+
className,
|
|
1997
|
+
children,
|
|
1998
|
+
...rest
|
|
1999
|
+
}, forwardedRef) {
|
|
2000
|
+
const normalizedOptions = (0, import_react5.useMemo)(() => {
|
|
2001
|
+
const childItems = (0, import_utils4.filterChildrenByDisplayName)(children, "ButtonGroupItem");
|
|
2002
|
+
return childItems.map((child, index) => {
|
|
2003
|
+
const props = child.props || {};
|
|
2004
|
+
const hasValue = props.value !== void 0;
|
|
2005
|
+
const safeValue = hasValue && props.value !== null ? props.value : index;
|
|
2006
|
+
return {
|
|
2007
|
+
...props,
|
|
2008
|
+
label: props.label ?? props.children ?? `Option ${index + 1}`,
|
|
2009
|
+
value: safeValue
|
|
2010
|
+
};
|
|
2011
|
+
});
|
|
2012
|
+
}, [children]);
|
|
2013
|
+
const sizeStyles = SIZE_STYLES[size] ?? SIZE_STYLES.medium;
|
|
2014
|
+
const initialValue = value ?? defaultValue ?? (normalizedOptions.length ? normalizedOptions[0].value : void 0);
|
|
2015
|
+
const [internalValue, setInternalValue] = (0, import_react5.useState)(initialValue);
|
|
2016
|
+
const isControlled = value !== void 0;
|
|
2017
|
+
const selectedValue = isControlled ? value : internalValue;
|
|
2018
|
+
(0, import_react5.useEffect)(() => {
|
|
2019
|
+
if (!isControlled && defaultValue !== void 0) {
|
|
2020
|
+
setInternalValue(defaultValue);
|
|
2021
|
+
}
|
|
2022
|
+
}, [defaultValue, isControlled]);
|
|
2023
|
+
(0, import_react5.useEffect)(() => {
|
|
2024
|
+
if (isControlled) return;
|
|
2025
|
+
if (normalizedOptions.length && !normalizedOptions.some((option) => option.value === internalValue)) {
|
|
2026
|
+
setInternalValue(normalizedOptions[0].value);
|
|
2027
|
+
}
|
|
2028
|
+
}, [internalValue, isControlled, normalizedOptions]);
|
|
2029
|
+
const buttonRefs = (0, import_react5.useRef)(/* @__PURE__ */ new Map());
|
|
2030
|
+
const containerRef = (0, import_react5.useRef)(null);
|
|
2031
|
+
const indicatorRef = (0, import_react5.useRef)({ width: 0, height: 0, x: 0, y: 0 });
|
|
2032
|
+
const [indicator, setIndicator] = (0, import_react5.useState)({
|
|
2033
|
+
width: 0,
|
|
2034
|
+
height: 0,
|
|
2035
|
+
x: 0,
|
|
2036
|
+
y: 0
|
|
2037
|
+
});
|
|
2038
|
+
const setContainerRef = (0, import_react5.useCallback)(
|
|
2039
|
+
(node) => {
|
|
2040
|
+
containerRef.current = node;
|
|
2041
|
+
if (typeof forwardedRef === "function") {
|
|
2042
|
+
forwardedRef(node);
|
|
2043
|
+
} else if (forwardedRef) {
|
|
2044
|
+
forwardedRef.current = node;
|
|
2045
|
+
}
|
|
2046
|
+
},
|
|
2047
|
+
[forwardedRef]
|
|
2048
|
+
);
|
|
2049
|
+
const registerButtonRef = (0, import_react5.useCallback)((optionValue) => {
|
|
2050
|
+
return (node) => {
|
|
2051
|
+
if (!buttonRefs.current) return;
|
|
2052
|
+
if (node) {
|
|
2053
|
+
buttonRefs.current.set(optionValue, node);
|
|
2054
|
+
} else {
|
|
2055
|
+
buttonRefs.current.delete(optionValue);
|
|
2056
|
+
}
|
|
2057
|
+
};
|
|
2058
|
+
}, []);
|
|
2059
|
+
const updateIndicator = (0, import_react5.useCallback)(() => {
|
|
2060
|
+
const container = containerRef.current;
|
|
2061
|
+
const target = buttonRefs.current.get(selectedValue);
|
|
2062
|
+
if (!container || !target) {
|
|
2063
|
+
if (indicatorRef.current.width !== 0) {
|
|
2064
|
+
indicatorRef.current = { width: 0, height: 0, x: 0, y: 0 };
|
|
2065
|
+
setIndicator(indicatorRef.current);
|
|
2066
|
+
}
|
|
2067
|
+
return;
|
|
2068
|
+
}
|
|
2069
|
+
const containerRect = container.getBoundingClientRect();
|
|
2070
|
+
const targetRect = target.getBoundingClientRect();
|
|
2071
|
+
const next = {
|
|
2072
|
+
width: targetRect.width,
|
|
2073
|
+
height: targetRect.height,
|
|
2074
|
+
x: targetRect.left - containerRect.left,
|
|
2075
|
+
y: targetRect.top - containerRect.top
|
|
2076
|
+
};
|
|
2077
|
+
const prev = indicatorRef.current;
|
|
2078
|
+
if (prev.width !== next.width || prev.height !== next.height || prev.x !== next.x || prev.y !== next.y) {
|
|
2079
|
+
indicatorRef.current = next;
|
|
2080
|
+
setIndicator(next);
|
|
2081
|
+
}
|
|
2082
|
+
}, [selectedValue]);
|
|
2083
|
+
useIsomorphicLayoutEffect(() => {
|
|
2084
|
+
updateIndicator();
|
|
2085
|
+
}, [updateIndicator, normalizedOptions.length, size]);
|
|
2086
|
+
(0, import_react5.useEffect)(() => {
|
|
2087
|
+
if (!isBrowser) return;
|
|
2088
|
+
const handleResize = () => updateIndicator();
|
|
2089
|
+
window.addEventListener("resize", handleResize);
|
|
2090
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
2091
|
+
}, [updateIndicator]);
|
|
2092
|
+
(0, import_react5.useEffect)(() => {
|
|
2093
|
+
if (!isBrowser) return;
|
|
2094
|
+
const node = containerRef.current;
|
|
2095
|
+
if (!node || typeof ResizeObserver === "undefined") return;
|
|
2096
|
+
const observer = new ResizeObserver(() => {
|
|
2097
|
+
updateIndicator();
|
|
2098
|
+
});
|
|
2099
|
+
observer.observe(node);
|
|
2100
|
+
return () => observer.disconnect();
|
|
2101
|
+
}, [updateIndicator]);
|
|
2102
|
+
const focusOption = (0, import_react5.useCallback)((option) => {
|
|
2103
|
+
const node = buttonRefs.current.get(option.value);
|
|
2104
|
+
if (node) {
|
|
2105
|
+
node.focus();
|
|
2106
|
+
}
|
|
2107
|
+
}, []);
|
|
2108
|
+
const handleSelect = (0, import_react5.useCallback)(
|
|
2109
|
+
(option) => {
|
|
2110
|
+
if (option.disabled || option.value === selectedValue) {
|
|
2111
|
+
return;
|
|
2112
|
+
}
|
|
2113
|
+
if (!isControlled) {
|
|
2114
|
+
setInternalValue(option.value);
|
|
2115
|
+
}
|
|
2116
|
+
if (typeof onChange === "function") {
|
|
2117
|
+
onChange(option.value, option);
|
|
2118
|
+
}
|
|
2119
|
+
},
|
|
2120
|
+
[isControlled, onChange, selectedValue]
|
|
2121
|
+
);
|
|
2122
|
+
const getNextEnabledIndex = (0, import_react5.useCallback)(
|
|
2123
|
+
(startIndex, direction) => {
|
|
2124
|
+
if (!normalizedOptions.length) return -1;
|
|
2125
|
+
let nextIndex = startIndex;
|
|
2126
|
+
for (let i = 0; i < normalizedOptions.length; i += 1) {
|
|
2127
|
+
nextIndex = (nextIndex + direction + normalizedOptions.length) % normalizedOptions.length;
|
|
2128
|
+
if (!normalizedOptions[nextIndex].disabled) {
|
|
2129
|
+
return nextIndex;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
return startIndex;
|
|
2133
|
+
},
|
|
2134
|
+
[normalizedOptions]
|
|
2135
|
+
);
|
|
2136
|
+
const findFirstEnabledIndex = (0, import_react5.useCallback)(() => {
|
|
2137
|
+
return normalizedOptions.findIndex((option) => !option.disabled);
|
|
2138
|
+
}, [normalizedOptions]);
|
|
2139
|
+
const findLastEnabledIndex = (0, import_react5.useCallback)(() => {
|
|
2140
|
+
for (let i = normalizedOptions.length - 1; i >= 0; i -= 1) {
|
|
2141
|
+
if (!normalizedOptions[i].disabled) {
|
|
2142
|
+
return i;
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
return -1;
|
|
2146
|
+
}, [normalizedOptions]);
|
|
2147
|
+
const indicatorVisible = indicator.width > 0 && indicator.height > 0;
|
|
2148
|
+
const rootClasses = (0, import_utils4.cx)(
|
|
2149
|
+
"inline-flex h-[44px] rounded-lg border-2 border-border-subtle bg-bg-base/90 p-2 shadow-inner",
|
|
2150
|
+
isStretched ? "w-full" : "w-auto",
|
|
2151
|
+
className
|
|
2152
|
+
);
|
|
2153
|
+
const trackClasses = (0, import_utils4.cx)(
|
|
2154
|
+
"relative isolate flex w-full items-center gap-8",
|
|
2155
|
+
!isStretched && "w-auto"
|
|
2156
|
+
);
|
|
2157
|
+
const buttonBaseClasses = (0, import_utils4.cx)(
|
|
2158
|
+
"relative z-10 h-[36px] inline-flex items-center justify-center gap-2 whitespace-nowrap font-semibold tracking-tight transition-colors duration-200 ease-out focus-visible:outline-none focus-visible:shadow-focus motion-reduce:duration-0",
|
|
2159
|
+
sizeStyles.button,
|
|
2160
|
+
isStretched ? "flex-1" : "w-auto"
|
|
2161
|
+
);
|
|
2162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
2163
|
+
"div",
|
|
2164
|
+
{
|
|
2165
|
+
...rest,
|
|
2166
|
+
ref: setContainerRef,
|
|
2167
|
+
role: "radiogroup",
|
|
2168
|
+
className: rootClasses,
|
|
2169
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: trackClasses, children: [
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
2171
|
+
"span",
|
|
2172
|
+
{
|
|
2173
|
+
"aria-hidden": "true",
|
|
2174
|
+
className: (0, import_utils4.cx)(
|
|
2175
|
+
"pointer-events-none h-[44px] absolute rounded-md border-2 border-border-primary-emphasis bg-bg-base shadow-[0_8px_20px_rgb(22_92_131/0.18)] transition-[transform,width,height] duration-300 ease-out motion-reduce:duration-0",
|
|
2176
|
+
!indicatorVisible && "opacity-0"
|
|
2177
|
+
),
|
|
2178
|
+
style: {
|
|
2179
|
+
width: indicator.width || void 0,
|
|
2180
|
+
height: indicator.height || void 0,
|
|
2181
|
+
transform: `translate(${indicator.x - 4}px`
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
),
|
|
2185
|
+
normalizedOptions.map((option, index) => {
|
|
2186
|
+
const isActive = option.value === selectedValue;
|
|
2187
|
+
const handleKeyDown = (event) => {
|
|
2188
|
+
if (option.disabled) return;
|
|
2189
|
+
if (event.key === "ArrowRight" || event.key === "ArrowDown") {
|
|
2190
|
+
event.preventDefault();
|
|
2191
|
+
const nextIndex = getNextEnabledIndex(index, 1);
|
|
2192
|
+
const nextOption = normalizedOptions[nextIndex];
|
|
2193
|
+
if (nextOption && nextOption !== option) {
|
|
2194
|
+
focusOption(nextOption);
|
|
2195
|
+
handleSelect(nextOption);
|
|
2196
|
+
}
|
|
2197
|
+
} else if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
|
|
2198
|
+
event.preventDefault();
|
|
2199
|
+
const prevIndex = getNextEnabledIndex(index, -1);
|
|
2200
|
+
const prevOption = normalizedOptions[prevIndex];
|
|
2201
|
+
if (prevOption && prevOption !== option) {
|
|
2202
|
+
focusOption(prevOption);
|
|
2203
|
+
handleSelect(prevOption);
|
|
2204
|
+
}
|
|
2205
|
+
} else if (event.key === "Home") {
|
|
2206
|
+
event.preventDefault();
|
|
2207
|
+
const firstIndex = findFirstEnabledIndex();
|
|
2208
|
+
const firstOption = firstIndex >= 0 ? normalizedOptions[firstIndex] : void 0;
|
|
2209
|
+
if (firstOption && firstOption !== option) {
|
|
2210
|
+
focusOption(firstOption);
|
|
2211
|
+
handleSelect(firstOption);
|
|
2212
|
+
}
|
|
2213
|
+
} else if (event.key === "End") {
|
|
2214
|
+
event.preventDefault();
|
|
2215
|
+
const lastIndex = findLastEnabledIndex();
|
|
2216
|
+
const lastOption = lastIndex >= 0 ? normalizedOptions[lastIndex] : void 0;
|
|
2217
|
+
if (lastOption && lastOption !== option) {
|
|
2218
|
+
focusOption(lastOption);
|
|
2219
|
+
handleSelect(lastOption);
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
};
|
|
2223
|
+
const buttonClasses = (0, import_utils4.cx)(
|
|
2224
|
+
buttonBaseClasses,
|
|
2225
|
+
option.disabled ? "cursor-not-allowed text-fg-inactive opacity-60" : "cursor-pointer text-fg-subtle hover:text-fg-base",
|
|
2226
|
+
isActive && "text-fg-primary-emphasis",
|
|
2227
|
+
!isActive && "hover:bg-bg-minimal-5 active:bg-bg-inactive"
|
|
2228
|
+
);
|
|
2229
|
+
const hasStartAdornment = option.startAdornment !== void 0 && option.startAdornment !== null;
|
|
2230
|
+
const hasendIcon = option.endIcon !== void 0 && option.endIcon !== null;
|
|
2231
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
2232
|
+
"button",
|
|
2233
|
+
{
|
|
2234
|
+
ref: registerButtonRef(option.value),
|
|
2235
|
+
type: "button",
|
|
2236
|
+
role: "radio",
|
|
2237
|
+
"aria-checked": isActive,
|
|
2238
|
+
disabled: option.disabled,
|
|
2239
|
+
className: buttonClasses,
|
|
2240
|
+
onClick: () => handleSelect(option),
|
|
2241
|
+
onKeyDown: handleKeyDown,
|
|
2242
|
+
"data-state": isActive ? "active" : "inactive",
|
|
2243
|
+
children: [
|
|
2244
|
+
hasStartAdornment && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
2245
|
+
"span",
|
|
2246
|
+
{
|
|
2247
|
+
"aria-hidden": "true",
|
|
2248
|
+
className: "flex items-center text-current",
|
|
2249
|
+
children: option.startAdornment
|
|
2250
|
+
}
|
|
2251
|
+
),
|
|
2252
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "flex items-center gap-1 leading-none text-current", children: option.label ?? `Option ${index + 1}` }),
|
|
2253
|
+
hasendIcon && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
2254
|
+
"span",
|
|
2255
|
+
{
|
|
2256
|
+
"aria-hidden": "true",
|
|
2257
|
+
className: "flex items-center text-current",
|
|
2258
|
+
children: option.endIcon
|
|
2259
|
+
}
|
|
2260
|
+
)
|
|
2261
|
+
]
|
|
2262
|
+
},
|
|
2263
|
+
String(option.value)
|
|
2264
|
+
);
|
|
2265
|
+
})
|
|
2266
|
+
] })
|
|
2267
|
+
}
|
|
2268
|
+
);
|
|
2269
|
+
});
|
|
2270
|
+
|
|
2271
|
+
// src/elements/ButtonGroupItem.jsx
|
|
2272
|
+
var import_react6 = __toESM(require("react"));
|
|
2273
|
+
function ButtonGroupItem(_props) {
|
|
2274
|
+
return null;
|
|
1880
2275
|
}
|
|
2276
|
+
ButtonGroupItem.displayName = "ButtonGroupItem";
|
|
1881
2277
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1882
2278
|
0 && (module.exports = {
|
|
1883
2279
|
Button,
|
|
2280
|
+
ButtonGroup,
|
|
2281
|
+
ButtonGroupItem,
|
|
2282
|
+
IconButton,
|
|
1884
2283
|
MenuButton
|
|
1885
2284
|
});
|
|
1886
2285
|
/*! Bundled license information:
|