@arun-dev/headless 4.13.0 → 4.15.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/dist/avatar/index.cjs +218 -0
- package/dist/avatar/index.d.cts +52 -0
- package/dist/avatar/index.d.ts +52 -0
- package/dist/avatar/index.js +105 -0
- package/dist/chunk-36N5DD5K.js +78 -0
- package/dist/chunk-E4JBFRMM.js +11 -0
- package/dist/chunk-ETNICT5M.js +8 -0
- package/dist/combobox/index.cjs +3 -1
- package/dist/combobox/index.js +6 -6
- package/dist/menu/index.cjs +311 -19
- package/dist/menu/index.d.cts +144 -10
- package/dist/menu/index.d.ts +144 -10
- package/dist/menu/index.js +310 -22
- package/dist/rovingFocus-BZB3yicE.d.cts +11 -0
- package/dist/rovingFocus-BZB3yicE.d.ts +11 -0
- package/dist/tabs/index.d.cts +1 -10
- package/dist/tabs/index.d.ts +1 -10
- package/dist/toggle/index.cjs +232 -0
- package/dist/toggle/index.d.cts +26 -0
- package/dist/toggle/index.d.ts +26 -0
- package/dist/toggle/index.js +68 -0
- package/dist/toggle-group/index.cjs +292 -0
- package/dist/toggle-group/index.d.cts +31 -0
- package/dist/toggle-group/index.d.ts +31 -0
- package/dist/toggle-group/index.js +68 -0
- package/dist/toolbar/index.cjs +357 -0
- package/dist/toolbar/index.d.cts +89 -0
- package/dist/toolbar/index.d.ts +89 -0
- package/dist/toolbar/index.js +152 -0
- package/package.json +41 -1
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/toggle/index.ts
|
|
21
|
+
var toggle_exports = {};
|
|
22
|
+
__export(toggle_exports, {
|
|
23
|
+
Toggle: () => Toggle
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(toggle_exports);
|
|
26
|
+
|
|
27
|
+
// src/toggle/Toggle.tsx
|
|
28
|
+
var import_react5 = require("react");
|
|
29
|
+
|
|
30
|
+
// src/core/useRender.ts
|
|
31
|
+
var import_react = require("react");
|
|
32
|
+
|
|
33
|
+
// src/core/mergeProps.ts
|
|
34
|
+
function isEventHandler(key) {
|
|
35
|
+
return key.length > 2 && key.startsWith("on") && key[2] === key[2]?.toUpperCase();
|
|
36
|
+
}
|
|
37
|
+
function mergeRefs(...refs) {
|
|
38
|
+
return (node) => {
|
|
39
|
+
const cleanups = refs.map((ref) => {
|
|
40
|
+
if (typeof ref === "function") {
|
|
41
|
+
const result = ref(node);
|
|
42
|
+
return typeof result === "function" ? result : () => ref(null);
|
|
43
|
+
}
|
|
44
|
+
if (ref && typeof ref === "object") {
|
|
45
|
+
ref.current = node;
|
|
46
|
+
return () => {
|
|
47
|
+
ref.current = null;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return void 0;
|
|
51
|
+
});
|
|
52
|
+
return () => {
|
|
53
|
+
cleanups.forEach((cleanup) => {
|
|
54
|
+
if (typeof cleanup === "function") cleanup();
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function isSyntheticEvent(event) {
|
|
60
|
+
return typeof event === "object" && event !== null && "nativeEvent" in event;
|
|
61
|
+
}
|
|
62
|
+
function makeEventPreventable(event) {
|
|
63
|
+
if (Object.prototype.hasOwnProperty.call(event, "preventComponentHandler")) return;
|
|
64
|
+
const target = event;
|
|
65
|
+
target.preventComponentHandler = () => {
|
|
66
|
+
target.componentHandlerPrevented = true;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function isComponentHandlerPrevented(event) {
|
|
70
|
+
return typeof event === "object" && event !== null && event.componentHandlerPrevented === true;
|
|
71
|
+
}
|
|
72
|
+
function chainHandlers(earlier, value) {
|
|
73
|
+
return (...args) => {
|
|
74
|
+
const event = args[0];
|
|
75
|
+
if (isSyntheticEvent(event)) makeEventPreventable(event);
|
|
76
|
+
value(...args);
|
|
77
|
+
if (isComponentHandlerPrevented(event)) return;
|
|
78
|
+
earlier(...args);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function mergeProps(...objects) {
|
|
82
|
+
const merged = {};
|
|
83
|
+
for (const props of objects) {
|
|
84
|
+
if (!props) continue;
|
|
85
|
+
for (const key of Object.keys(props)) {
|
|
86
|
+
const value = props[key];
|
|
87
|
+
if (value === void 0) continue;
|
|
88
|
+
if (isEventHandler(key) && typeof value === "function") {
|
|
89
|
+
const earlier = merged[key];
|
|
90
|
+
merged[key] = typeof earlier === "function" ? chainHandlers(earlier, value) : value;
|
|
91
|
+
} else if (key === "className") {
|
|
92
|
+
merged.className = merged.className ? `${String(merged.className)} ${String(value)}` : value;
|
|
93
|
+
} else if (key === "style") {
|
|
94
|
+
merged.style = { ...merged.style, ...value };
|
|
95
|
+
} else if (key === "ref") {
|
|
96
|
+
merged.ref = merged.ref ? mergeRefs(merged.ref, value) : value;
|
|
97
|
+
} else {
|
|
98
|
+
merged[key] = value;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return merged;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/core/useRender.ts
|
|
106
|
+
function useRender({
|
|
107
|
+
render,
|
|
108
|
+
defaultTagName,
|
|
109
|
+
props,
|
|
110
|
+
consumerProps
|
|
111
|
+
}) {
|
|
112
|
+
const merged = mergeProps(props, consumerProps);
|
|
113
|
+
if ((0, import_react.isValidElement)(render)) {
|
|
114
|
+
return (0, import_react.cloneElement)(render, mergeProps(merged, render.props));
|
|
115
|
+
}
|
|
116
|
+
return (0, import_react.createElement)(defaultTagName, merged);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/core/useControlled.ts
|
|
120
|
+
var import_react2 = require("react");
|
|
121
|
+
function useControlled({
|
|
122
|
+
controlled,
|
|
123
|
+
default: defaultValue,
|
|
124
|
+
name = "Component",
|
|
125
|
+
state = "value"
|
|
126
|
+
}) {
|
|
127
|
+
const { current: isControlled } = (0, import_react2.useRef)(controlled !== void 0);
|
|
128
|
+
const [uncontrolled, setUncontrolled] = (0, import_react2.useState)(defaultValue);
|
|
129
|
+
const defaultRef = (0, import_react2.useRef)(defaultValue);
|
|
130
|
+
const value = isControlled ? controlled : uncontrolled;
|
|
131
|
+
if (process.env.NODE_ENV !== "production") {
|
|
132
|
+
if (isControlled !== (controlled !== void 0)) {
|
|
133
|
+
console.error(
|
|
134
|
+
`${name}: cannot switch between controlled and uncontrolled \`${state}\`. Decide which one this component is for the whole of its life.`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (!isControlled && defaultRef.current !== defaultValue) {
|
|
138
|
+
console.error(
|
|
139
|
+
`${name}: cannot change the default \`${state}\` after mount. It is only read once, so later changes are silently ignored.`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const setValue = (0, import_react2.useCallback)(
|
|
144
|
+
(next) => {
|
|
145
|
+
if (!isControlled) setUncontrolled(next);
|
|
146
|
+
},
|
|
147
|
+
[isControlled]
|
|
148
|
+
);
|
|
149
|
+
return [value, setValue];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/core/rovingGroup.ts
|
|
153
|
+
var import_react3 = require("react");
|
|
154
|
+
var RovingGroupContext = (0, import_react3.createContext)(null);
|
|
155
|
+
function useRovingGroupContext() {
|
|
156
|
+
return (0, import_react3.useContext)(RovingGroupContext);
|
|
157
|
+
}
|
|
158
|
+
function useRovingItem(ref, disabled, selected = false) {
|
|
159
|
+
const group = useRovingGroupContext();
|
|
160
|
+
const item = (0, import_react3.useMemo)(() => ({ ref, disabled, selected }), [ref, disabled, selected]);
|
|
161
|
+
const register = group?.register;
|
|
162
|
+
(0, import_react3.useLayoutEffect)(() => register?.(item), [register, item]);
|
|
163
|
+
if (!group) return { tabIndex: void 0, onFocus: void 0 };
|
|
164
|
+
return {
|
|
165
|
+
tabIndex: group.tabStop?.ref === ref ? 0 : -1,
|
|
166
|
+
onFocus() {
|
|
167
|
+
group.setTabStop(item);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// src/toggle-group/ToggleGroupContext.ts
|
|
173
|
+
var import_react4 = require("react");
|
|
174
|
+
var ToggleGroupContext = (0, import_react4.createContext)(null);
|
|
175
|
+
function useToggleGroupContext() {
|
|
176
|
+
return (0, import_react4.useContext)(ToggleGroupContext);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/toggle/Toggle.tsx
|
|
180
|
+
function Toggle({
|
|
181
|
+
pressed: pressedProp,
|
|
182
|
+
defaultPressed,
|
|
183
|
+
onPressedChange,
|
|
184
|
+
value,
|
|
185
|
+
disabled: disabledProp = false,
|
|
186
|
+
className,
|
|
187
|
+
children,
|
|
188
|
+
render,
|
|
189
|
+
...rest
|
|
190
|
+
}) {
|
|
191
|
+
const group = useToggleGroupContext();
|
|
192
|
+
const [ownPressed, setOwnPressed] = useControlled({
|
|
193
|
+
controlled: group ? void 0 : pressedProp,
|
|
194
|
+
default: defaultPressed ?? false,
|
|
195
|
+
name: "Toggle",
|
|
196
|
+
state: "pressed"
|
|
197
|
+
});
|
|
198
|
+
const pressed = group && value !== void 0 ? group.value.includes(value) : ownPressed;
|
|
199
|
+
const disabled = disabledProp || (group?.disabled ?? false);
|
|
200
|
+
const elementRef = (0, import_react5.useRef)(null);
|
|
201
|
+
const roving = useRovingItem(elementRef, disabled, pressed);
|
|
202
|
+
return useRender({
|
|
203
|
+
render,
|
|
204
|
+
defaultTagName: "button",
|
|
205
|
+
props: {
|
|
206
|
+
type: "button",
|
|
207
|
+
"aria-pressed": pressed,
|
|
208
|
+
disabled: disabled || void 0,
|
|
209
|
+
"data-pressed": pressed ? "" : void 0,
|
|
210
|
+
"data-disabled": disabled ? "" : void 0,
|
|
211
|
+
tabIndex: roving.tabIndex,
|
|
212
|
+
className,
|
|
213
|
+
children,
|
|
214
|
+
ref: elementRef,
|
|
215
|
+
onFocus: roving.onFocus,
|
|
216
|
+
onClick(event) {
|
|
217
|
+
if (disabled || event.defaultPrevented) return;
|
|
218
|
+
if (group && value !== void 0) {
|
|
219
|
+
group.toggle(value);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
setOwnPressed(!pressed);
|
|
223
|
+
onPressedChange?.(!pressed);
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
consumerProps: rest
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
230
|
+
0 && (module.exports = {
|
|
231
|
+
Toggle
|
|
232
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactElement, Ref, ComponentPropsWithRef } from 'react';
|
|
3
|
+
|
|
4
|
+
type ToggleOwnProps = {
|
|
5
|
+
/** Controlled state. Provide `onPressedChange` alongside it. Ignored inside a ToggleGroup. */
|
|
6
|
+
pressed?: boolean;
|
|
7
|
+
/** Initial state when uncontrolled. Read once, at mount. */
|
|
8
|
+
defaultPressed?: boolean;
|
|
9
|
+
onPressedChange?: (pressed: boolean) => void;
|
|
10
|
+
/** Its value in a ToggleGroup: pressed while the group's `value` holds it. */
|
|
11
|
+
value?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** Element to render instead of the default `<button>`. Props and ref are merged onto it. */
|
|
14
|
+
render?: ReactElement;
|
|
15
|
+
/** Ref to the rendered element. Merged with any ref on the `render` element. */
|
|
16
|
+
ref?: Ref<HTMLElement>;
|
|
17
|
+
};
|
|
18
|
+
type ToggleProps = ToggleOwnProps & Omit<ComponentPropsWithRef<'button'>, keyof ToggleOwnProps>;
|
|
19
|
+
/**
|
|
20
|
+
* A button that stays pressed: `<button aria-pressed>` (decision 17), as APG's toggle button.
|
|
21
|
+
* Inside a ToggleGroup its state is the group's, by `value`; inside a Toolbar or a ToggleGroup it
|
|
22
|
+
* is one of the arrow-key items. `data-pressed` while pressed.
|
|
23
|
+
*/
|
|
24
|
+
declare function Toggle({ pressed: pressedProp, defaultPressed, onPressedChange, value, disabled: disabledProp, className, children, render, ...rest }: ToggleProps): ReactElement<unknown, string | react.JSXElementConstructor<any>>;
|
|
25
|
+
|
|
26
|
+
export { Toggle, type ToggleProps };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactElement, Ref, ComponentPropsWithRef } from 'react';
|
|
3
|
+
|
|
4
|
+
type ToggleOwnProps = {
|
|
5
|
+
/** Controlled state. Provide `onPressedChange` alongside it. Ignored inside a ToggleGroup. */
|
|
6
|
+
pressed?: boolean;
|
|
7
|
+
/** Initial state when uncontrolled. Read once, at mount. */
|
|
8
|
+
defaultPressed?: boolean;
|
|
9
|
+
onPressedChange?: (pressed: boolean) => void;
|
|
10
|
+
/** Its value in a ToggleGroup: pressed while the group's `value` holds it. */
|
|
11
|
+
value?: string;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
/** Element to render instead of the default `<button>`. Props and ref are merged onto it. */
|
|
14
|
+
render?: ReactElement;
|
|
15
|
+
/** Ref to the rendered element. Merged with any ref on the `render` element. */
|
|
16
|
+
ref?: Ref<HTMLElement>;
|
|
17
|
+
};
|
|
18
|
+
type ToggleProps = ToggleOwnProps & Omit<ComponentPropsWithRef<'button'>, keyof ToggleOwnProps>;
|
|
19
|
+
/**
|
|
20
|
+
* A button that stays pressed: `<button aria-pressed>` (decision 17), as APG's toggle button.
|
|
21
|
+
* Inside a ToggleGroup its state is the group's, by `value`; inside a Toolbar or a ToggleGroup it
|
|
22
|
+
* is one of the arrow-key items. `data-pressed` while pressed.
|
|
23
|
+
*/
|
|
24
|
+
declare function Toggle({ pressed: pressedProp, defaultPressed, onPressedChange, value, disabled: disabledProp, className, children, render, ...rest }: ToggleProps): ReactElement<unknown, string | react.JSXElementConstructor<any>>;
|
|
25
|
+
|
|
26
|
+
export { Toggle, type ToggleProps };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useToggleGroupContext
|
|
3
|
+
} from "../chunk-E4JBFRMM.js";
|
|
4
|
+
import {
|
|
5
|
+
useRovingItem
|
|
6
|
+
} from "../chunk-36N5DD5K.js";
|
|
7
|
+
import "../chunk-2S4XG4VD.js";
|
|
8
|
+
import {
|
|
9
|
+
useControlled
|
|
10
|
+
} from "../chunk-UEIB3I3T.js";
|
|
11
|
+
import {
|
|
12
|
+
useRender
|
|
13
|
+
} from "../chunk-OQTWWZ4B.js";
|
|
14
|
+
|
|
15
|
+
// src/toggle/Toggle.tsx
|
|
16
|
+
import { useRef } from "react";
|
|
17
|
+
function Toggle({
|
|
18
|
+
pressed: pressedProp,
|
|
19
|
+
defaultPressed,
|
|
20
|
+
onPressedChange,
|
|
21
|
+
value,
|
|
22
|
+
disabled: disabledProp = false,
|
|
23
|
+
className,
|
|
24
|
+
children,
|
|
25
|
+
render,
|
|
26
|
+
...rest
|
|
27
|
+
}) {
|
|
28
|
+
const group = useToggleGroupContext();
|
|
29
|
+
const [ownPressed, setOwnPressed] = useControlled({
|
|
30
|
+
controlled: group ? void 0 : pressedProp,
|
|
31
|
+
default: defaultPressed ?? false,
|
|
32
|
+
name: "Toggle",
|
|
33
|
+
state: "pressed"
|
|
34
|
+
});
|
|
35
|
+
const pressed = group && value !== void 0 ? group.value.includes(value) : ownPressed;
|
|
36
|
+
const disabled = disabledProp || (group?.disabled ?? false);
|
|
37
|
+
const elementRef = useRef(null);
|
|
38
|
+
const roving = useRovingItem(elementRef, disabled, pressed);
|
|
39
|
+
return useRender({
|
|
40
|
+
render,
|
|
41
|
+
defaultTagName: "button",
|
|
42
|
+
props: {
|
|
43
|
+
type: "button",
|
|
44
|
+
"aria-pressed": pressed,
|
|
45
|
+
disabled: disabled || void 0,
|
|
46
|
+
"data-pressed": pressed ? "" : void 0,
|
|
47
|
+
"data-disabled": disabled ? "" : void 0,
|
|
48
|
+
tabIndex: roving.tabIndex,
|
|
49
|
+
className,
|
|
50
|
+
children,
|
|
51
|
+
ref: elementRef,
|
|
52
|
+
onFocus: roving.onFocus,
|
|
53
|
+
onClick(event) {
|
|
54
|
+
if (disabled || event.defaultPrevented) return;
|
|
55
|
+
if (group && value !== void 0) {
|
|
56
|
+
group.toggle(value);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
setOwnPressed(!pressed);
|
|
60
|
+
onPressedChange?.(!pressed);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
consumerProps: rest
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
Toggle
|
|
68
|
+
};
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/toggle-group/index.ts
|
|
21
|
+
var toggle_group_exports = {};
|
|
22
|
+
__export(toggle_group_exports, {
|
|
23
|
+
ToggleGroup: () => ToggleGroup
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(toggle_group_exports);
|
|
26
|
+
|
|
27
|
+
// src/toggle-group/ToggleGroup.tsx
|
|
28
|
+
var import_react5 = require("react");
|
|
29
|
+
|
|
30
|
+
// src/core/useRender.ts
|
|
31
|
+
var import_react = require("react");
|
|
32
|
+
|
|
33
|
+
// src/core/mergeProps.ts
|
|
34
|
+
function isEventHandler(key) {
|
|
35
|
+
return key.length > 2 && key.startsWith("on") && key[2] === key[2]?.toUpperCase();
|
|
36
|
+
}
|
|
37
|
+
function mergeRefs(...refs) {
|
|
38
|
+
return (node) => {
|
|
39
|
+
const cleanups = refs.map((ref) => {
|
|
40
|
+
if (typeof ref === "function") {
|
|
41
|
+
const result = ref(node);
|
|
42
|
+
return typeof result === "function" ? result : () => ref(null);
|
|
43
|
+
}
|
|
44
|
+
if (ref && typeof ref === "object") {
|
|
45
|
+
ref.current = node;
|
|
46
|
+
return () => {
|
|
47
|
+
ref.current = null;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return void 0;
|
|
51
|
+
});
|
|
52
|
+
return () => {
|
|
53
|
+
cleanups.forEach((cleanup) => {
|
|
54
|
+
if (typeof cleanup === "function") cleanup();
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function isSyntheticEvent(event) {
|
|
60
|
+
return typeof event === "object" && event !== null && "nativeEvent" in event;
|
|
61
|
+
}
|
|
62
|
+
function makeEventPreventable(event) {
|
|
63
|
+
if (Object.prototype.hasOwnProperty.call(event, "preventComponentHandler")) return;
|
|
64
|
+
const target = event;
|
|
65
|
+
target.preventComponentHandler = () => {
|
|
66
|
+
target.componentHandlerPrevented = true;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function isComponentHandlerPrevented(event) {
|
|
70
|
+
return typeof event === "object" && event !== null && event.componentHandlerPrevented === true;
|
|
71
|
+
}
|
|
72
|
+
function chainHandlers(earlier, value) {
|
|
73
|
+
return (...args) => {
|
|
74
|
+
const event = args[0];
|
|
75
|
+
if (isSyntheticEvent(event)) makeEventPreventable(event);
|
|
76
|
+
value(...args);
|
|
77
|
+
if (isComponentHandlerPrevented(event)) return;
|
|
78
|
+
earlier(...args);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function mergeProps(...objects) {
|
|
82
|
+
const merged = {};
|
|
83
|
+
for (const props of objects) {
|
|
84
|
+
if (!props) continue;
|
|
85
|
+
for (const key of Object.keys(props)) {
|
|
86
|
+
const value = props[key];
|
|
87
|
+
if (value === void 0) continue;
|
|
88
|
+
if (isEventHandler(key) && typeof value === "function") {
|
|
89
|
+
const earlier = merged[key];
|
|
90
|
+
merged[key] = typeof earlier === "function" ? chainHandlers(earlier, value) : value;
|
|
91
|
+
} else if (key === "className") {
|
|
92
|
+
merged.className = merged.className ? `${String(merged.className)} ${String(value)}` : value;
|
|
93
|
+
} else if (key === "style") {
|
|
94
|
+
merged.style = { ...merged.style, ...value };
|
|
95
|
+
} else if (key === "ref") {
|
|
96
|
+
merged.ref = merged.ref ? mergeRefs(merged.ref, value) : value;
|
|
97
|
+
} else {
|
|
98
|
+
merged[key] = value;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return merged;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/core/useRender.ts
|
|
106
|
+
function useRender({
|
|
107
|
+
render,
|
|
108
|
+
defaultTagName,
|
|
109
|
+
props,
|
|
110
|
+
consumerProps
|
|
111
|
+
}) {
|
|
112
|
+
const merged = mergeProps(props, consumerProps);
|
|
113
|
+
if ((0, import_react.isValidElement)(render)) {
|
|
114
|
+
return (0, import_react.cloneElement)(render, mergeProps(merged, render.props));
|
|
115
|
+
}
|
|
116
|
+
return (0, import_react.createElement)(defaultTagName, merged);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/core/useControlled.ts
|
|
120
|
+
var import_react2 = require("react");
|
|
121
|
+
function useControlled({
|
|
122
|
+
controlled,
|
|
123
|
+
default: defaultValue,
|
|
124
|
+
name = "Component",
|
|
125
|
+
state = "value"
|
|
126
|
+
}) {
|
|
127
|
+
const { current: isControlled } = (0, import_react2.useRef)(controlled !== void 0);
|
|
128
|
+
const [uncontrolled, setUncontrolled] = (0, import_react2.useState)(defaultValue);
|
|
129
|
+
const defaultRef = (0, import_react2.useRef)(defaultValue);
|
|
130
|
+
const value = isControlled ? controlled : uncontrolled;
|
|
131
|
+
if (process.env.NODE_ENV !== "production") {
|
|
132
|
+
if (isControlled !== (controlled !== void 0)) {
|
|
133
|
+
console.error(
|
|
134
|
+
`${name}: cannot switch between controlled and uncontrolled \`${state}\`. Decide which one this component is for the whole of its life.`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (!isControlled && defaultRef.current !== defaultValue) {
|
|
138
|
+
console.error(
|
|
139
|
+
`${name}: cannot change the default \`${state}\` after mount. It is only read once, so later changes are silently ignored.`
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const setValue = (0, import_react2.useCallback)(
|
|
144
|
+
(next) => {
|
|
145
|
+
if (!isControlled) setUncontrolled(next);
|
|
146
|
+
},
|
|
147
|
+
[isControlled]
|
|
148
|
+
);
|
|
149
|
+
return [value, setValue];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/core/rovingGroup.ts
|
|
153
|
+
var import_react3 = require("react");
|
|
154
|
+
|
|
155
|
+
// src/core/rovingFocus.ts
|
|
156
|
+
function byDocumentOrder(a, b) {
|
|
157
|
+
const x = a.ref.current;
|
|
158
|
+
const y = b.ref.current;
|
|
159
|
+
if (!x || !y) return 0;
|
|
160
|
+
return x.compareDocumentPosition(y) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
|
|
161
|
+
}
|
|
162
|
+
function rovingIndex(key, {
|
|
163
|
+
count,
|
|
164
|
+
current,
|
|
165
|
+
orientation,
|
|
166
|
+
rtl
|
|
167
|
+
}) {
|
|
168
|
+
if (count === 0) return null;
|
|
169
|
+
const [prevKey, nextKey] = orientation === "vertical" ? ["ArrowUp", "ArrowDown"] : rtl ? ["ArrowRight", "ArrowLeft"] : ["ArrowLeft", "ArrowRight"];
|
|
170
|
+
switch (key) {
|
|
171
|
+
case nextKey:
|
|
172
|
+
return current < 0 ? 0 : (current + 1) % count;
|
|
173
|
+
case prevKey:
|
|
174
|
+
return current < 0 ? count - 1 : (current - 1 + count) % count;
|
|
175
|
+
case "Home":
|
|
176
|
+
return 0;
|
|
177
|
+
case "End":
|
|
178
|
+
return count - 1;
|
|
179
|
+
default:
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// src/core/rovingGroup.ts
|
|
185
|
+
var RovingGroupContext = (0, import_react3.createContext)(null);
|
|
186
|
+
function useRovingGroupContext() {
|
|
187
|
+
return (0, import_react3.useContext)(RovingGroupContext);
|
|
188
|
+
}
|
|
189
|
+
function keyBelongsToField(event, orientation) {
|
|
190
|
+
const target = event.target;
|
|
191
|
+
if (!(target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement)) return false;
|
|
192
|
+
if (target instanceof HTMLInputElement && !/^(text|search|url|tel|email|password|number)$/.test(target.type)) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
const { key } = event;
|
|
196
|
+
const along = orientation === "horizontal" ? ["ArrowLeft", "ArrowRight", "Home", "End"] : [];
|
|
197
|
+
if (!along.includes(key)) return false;
|
|
198
|
+
const start = target.selectionStart ?? 0;
|
|
199
|
+
const end = target.selectionEnd ?? 0;
|
|
200
|
+
const atStart = start === 0 && end === 0;
|
|
201
|
+
const atEnd = start === target.value.length && end === target.value.length;
|
|
202
|
+
const rtl = getComputedStyle(target).direction === "rtl";
|
|
203
|
+
const towardStart = key === (rtl ? "ArrowRight" : "ArrowLeft") || key === "Home";
|
|
204
|
+
return towardStart ? !atStart : !atEnd;
|
|
205
|
+
}
|
|
206
|
+
function useRovingGroup({ orientation }) {
|
|
207
|
+
const [items, setItems] = (0, import_react3.useState)([]);
|
|
208
|
+
const register = (0, import_react3.useCallback)((item) => {
|
|
209
|
+
setItems((current) => [...current, item].sort(byDocumentOrder));
|
|
210
|
+
return () => setItems((current) => current.filter((i) => i !== item));
|
|
211
|
+
}, []);
|
|
212
|
+
const [chosen, setTabStop] = (0, import_react3.useState)(null);
|
|
213
|
+
const enabled = items.filter((item) => !item.disabled);
|
|
214
|
+
const tabStop = (
|
|
215
|
+
// Matched by element: an item re-registers when its props change.
|
|
216
|
+
chosen && enabled.find((item) => item.ref === chosen.ref) || enabled.find((item) => item.selected) || enabled[0] || null
|
|
217
|
+
);
|
|
218
|
+
const onKeyDown = (0, import_react3.useCallback)(
|
|
219
|
+
(event) => {
|
|
220
|
+
if (event.defaultPrevented || keyBelongsToField(event, orientation)) return;
|
|
221
|
+
const current = enabled.findIndex((item2) => item2.ref.current?.contains(event.target));
|
|
222
|
+
const rtl = getComputedStyle(event.currentTarget).direction === "rtl";
|
|
223
|
+
const next = rovingIndex(event.key, { count: enabled.length, current, orientation, rtl });
|
|
224
|
+
if (next === null) return;
|
|
225
|
+
const item = enabled[next];
|
|
226
|
+
if (!item) return;
|
|
227
|
+
event.preventDefault();
|
|
228
|
+
item.ref.current?.focus();
|
|
229
|
+
setTabStop(item);
|
|
230
|
+
},
|
|
231
|
+
[enabled, orientation]
|
|
232
|
+
);
|
|
233
|
+
const context = (0, import_react3.useMemo)(() => ({ tabStop, register, setTabStop }), [tabStop, register]);
|
|
234
|
+
return { context, onKeyDown };
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/toggle-group/ToggleGroupContext.ts
|
|
238
|
+
var import_react4 = require("react");
|
|
239
|
+
var ToggleGroupContext = (0, import_react4.createContext)(null);
|
|
240
|
+
|
|
241
|
+
// src/toggle-group/ToggleGroup.tsx
|
|
242
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
243
|
+
function ToggleGroup({
|
|
244
|
+
value: valueProp,
|
|
245
|
+
defaultValue,
|
|
246
|
+
onValueChange,
|
|
247
|
+
multiple = false,
|
|
248
|
+
disabled = false,
|
|
249
|
+
orientation = "horizontal",
|
|
250
|
+
className,
|
|
251
|
+
children,
|
|
252
|
+
render,
|
|
253
|
+
...rest
|
|
254
|
+
}) {
|
|
255
|
+
const [value, setValueState] = useControlled({
|
|
256
|
+
controlled: valueProp,
|
|
257
|
+
default: defaultValue ?? [],
|
|
258
|
+
name: "ToggleGroup",
|
|
259
|
+
state: "value"
|
|
260
|
+
});
|
|
261
|
+
const toggle = (0, import_react5.useCallback)(
|
|
262
|
+
(item) => {
|
|
263
|
+
const pressed = value.includes(item);
|
|
264
|
+
const next = multiple ? pressed ? value.filter((v) => v !== item) : [...value, item] : pressed ? [] : [item];
|
|
265
|
+
setValueState(next);
|
|
266
|
+
onValueChange?.(next);
|
|
267
|
+
},
|
|
268
|
+
[value, multiple, setValueState, onValueChange]
|
|
269
|
+
);
|
|
270
|
+
const outer = useRovingGroupContext();
|
|
271
|
+
const roving = useRovingGroup({ orientation });
|
|
272
|
+
const context = (0, import_react5.useMemo)(() => ({ value, disabled, toggle }), [value, disabled, toggle]);
|
|
273
|
+
const element = useRender({
|
|
274
|
+
render,
|
|
275
|
+
defaultTagName: "div",
|
|
276
|
+
props: {
|
|
277
|
+
role: "group",
|
|
278
|
+
"data-orientation": orientation,
|
|
279
|
+
"data-disabled": disabled ? "" : void 0,
|
|
280
|
+
className,
|
|
281
|
+
children,
|
|
282
|
+
// In a Toolbar, the Toolbar moves focus.
|
|
283
|
+
onKeyDown: outer ? void 0 : roving.onKeyDown
|
|
284
|
+
},
|
|
285
|
+
consumerProps: rest
|
|
286
|
+
});
|
|
287
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToggleGroupContext.Provider, { value: context, children: outer ? element : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RovingGroupContext.Provider, { value: roving.context, children: element }) });
|
|
288
|
+
}
|
|
289
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
290
|
+
0 && (module.exports = {
|
|
291
|
+
ToggleGroup
|
|
292
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactElement, Ref, ComponentPropsWithRef } from 'react';
|
|
3
|
+
import { O as Orientation } from '../rovingFocus-BZB3yicE.cjs';
|
|
4
|
+
|
|
5
|
+
type ToggleGroupOwnProps = {
|
|
6
|
+
/** Controlled: the pressed Toggles' values. Provide `onValueChange` alongside it. */
|
|
7
|
+
value?: readonly string[];
|
|
8
|
+
/** Initial value when uncontrolled. Read once, at mount. */
|
|
9
|
+
defaultValue?: readonly string[];
|
|
10
|
+
onValueChange?: (value: string[]) => void;
|
|
11
|
+
/** Lets more than one Toggle be pressed. Without it, pressing one releases the others. */
|
|
12
|
+
multiple?: boolean;
|
|
13
|
+
/** Disables every Toggle in it. */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
/** Which arrow keys move between the Toggles. */
|
|
16
|
+
orientation?: Orientation;
|
|
17
|
+
/** Element to render instead of the default `<div>`. Props and ref are merged onto it. */
|
|
18
|
+
render?: ReactElement;
|
|
19
|
+
/** Ref to the rendered element. Merged with any ref on the `render` element. */
|
|
20
|
+
ref?: Ref<HTMLElement>;
|
|
21
|
+
};
|
|
22
|
+
type ToggleGroupProps = ToggleGroupOwnProps & Omit<ComponentPropsWithRef<'div'>, keyof ToggleGroupOwnProps>;
|
|
23
|
+
/**
|
|
24
|
+
* Toggles that share one value (decision 17): `role="group"`, one Tab stop — the pressed Toggle,
|
|
25
|
+
* or the first — and the arrow keys between them. Pressing the pressed Toggle releases it, so the
|
|
26
|
+
* value may be empty. Inside a Toolbar its Toggles join the Toolbar's arrow keys instead. Name it
|
|
27
|
+
* with `aria-label`.
|
|
28
|
+
*/
|
|
29
|
+
declare function ToggleGroup({ value: valueProp, defaultValue, onValueChange, multiple, disabled, orientation, className, children, render, ...rest }: ToggleGroupProps): react.JSX.Element;
|
|
30
|
+
|
|
31
|
+
export { ToggleGroup, type ToggleGroupProps };
|