@arun-dev/headless 4.12.0 → 4.14.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/combobox/index.js +4 -4
- package/dist/menu/index.js +4 -4
- 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/toast/index.cjs +376 -0
- package/dist/toast/index.d.cts +141 -0
- package/dist/toast/index.d.ts +141 -0
- package/dist/toast/index.js +262 -0
- 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 +51 -1
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export,
|
|
3
|
+
useRender
|
|
4
|
+
} from "../chunk-OQTWWZ4B.js";
|
|
5
|
+
|
|
6
|
+
// src/toast/index.parts.ts
|
|
7
|
+
var index_parts_exports = {};
|
|
8
|
+
__export(index_parts_exports, {
|
|
9
|
+
Action: () => ToastAction,
|
|
10
|
+
Close: () => ToastClose,
|
|
11
|
+
Description: () => ToastDescription,
|
|
12
|
+
Provider: () => ToastProvider,
|
|
13
|
+
Root: () => ToastRoot,
|
|
14
|
+
Title: () => ToastTitle,
|
|
15
|
+
Viewport: () => ToastViewport
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// src/toast/ToastProvider.tsx
|
|
19
|
+
import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
20
|
+
|
|
21
|
+
// src/toast/ToastContext.ts
|
|
22
|
+
import { createContext, useContext } from "react";
|
|
23
|
+
var ToastContext = createContext(null);
|
|
24
|
+
function useToastContext(part) {
|
|
25
|
+
const context = useContext(ToastContext);
|
|
26
|
+
if (context === null) {
|
|
27
|
+
throw new Error(`${part} must be used inside <Toast.Provider>.`);
|
|
28
|
+
}
|
|
29
|
+
return context;
|
|
30
|
+
}
|
|
31
|
+
function useToastManager() {
|
|
32
|
+
const { toasts, add, update, close } = useToastContext("useToastManager()");
|
|
33
|
+
return { toasts, add, update, close };
|
|
34
|
+
}
|
|
35
|
+
var ToastRootContext = createContext(null);
|
|
36
|
+
function useToastRootContext(part) {
|
|
37
|
+
const toast = useContext(ToastRootContext);
|
|
38
|
+
if (toast === null) {
|
|
39
|
+
throw new Error(`<Toast.${part}> must be rendered inside <Toast.Root>.`);
|
|
40
|
+
}
|
|
41
|
+
return toast;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/toast/ToastProvider.tsx
|
|
45
|
+
import { jsx } from "react/jsx-runtime";
|
|
46
|
+
function ToastProvider({ limit = 3, timeout = 5e3, children }) {
|
|
47
|
+
const [all, setAll] = useState([]);
|
|
48
|
+
const prefix = useId();
|
|
49
|
+
const counter = useRef(0);
|
|
50
|
+
const closedRef = useRef(/* @__PURE__ */ new Set());
|
|
51
|
+
const add = useCallback(
|
|
52
|
+
(options) => {
|
|
53
|
+
const id = options.id ?? `${prefix}-${++counter.current}`;
|
|
54
|
+
const toast = {
|
|
55
|
+
...options,
|
|
56
|
+
id,
|
|
57
|
+
timeout: options.timeout ?? timeout,
|
|
58
|
+
priority: options.priority ?? "low"
|
|
59
|
+
};
|
|
60
|
+
closedRef.current.delete(id);
|
|
61
|
+
setAll((current) => [...current.filter((t) => t.id !== id), toast]);
|
|
62
|
+
return id;
|
|
63
|
+
},
|
|
64
|
+
[prefix, timeout]
|
|
65
|
+
);
|
|
66
|
+
const update = useCallback((id, patch) => {
|
|
67
|
+
setAll(
|
|
68
|
+
(current) => current.map((t) => t.id === id ? { ...t, ...patch, id } : t)
|
|
69
|
+
);
|
|
70
|
+
}, []);
|
|
71
|
+
const close = useCallback((id) => {
|
|
72
|
+
setAll((current) => {
|
|
73
|
+
const toast = current.find((t) => t.id === id);
|
|
74
|
+
if (toast && !closedRef.current.has(id)) {
|
|
75
|
+
closedRef.current.add(id);
|
|
76
|
+
queueMicrotask(() => toast.onClose?.());
|
|
77
|
+
}
|
|
78
|
+
return current.filter((t) => t.id !== id);
|
|
79
|
+
});
|
|
80
|
+
}, []);
|
|
81
|
+
const [pointerInside, setPointerInside] = useState(false);
|
|
82
|
+
const [focusInside, setFocusInside] = useState(false);
|
|
83
|
+
const [pageHidden, setPageHidden] = useState(false);
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
const onVisibility = () => setPageHidden(document.visibilityState === "hidden");
|
|
86
|
+
onVisibility();
|
|
87
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
88
|
+
return () => document.removeEventListener("visibilitychange", onVisibility);
|
|
89
|
+
}, []);
|
|
90
|
+
const viewportRef = useRef(null);
|
|
91
|
+
const toasts = useMemo(() => all.slice(-limit), [all, limit]);
|
|
92
|
+
const context = useMemo(
|
|
93
|
+
() => ({
|
|
94
|
+
toasts,
|
|
95
|
+
add,
|
|
96
|
+
update,
|
|
97
|
+
close,
|
|
98
|
+
paused: pointerInside || focusInside || pageHidden,
|
|
99
|
+
setPointerInside,
|
|
100
|
+
setFocusInside,
|
|
101
|
+
viewportRef
|
|
102
|
+
}),
|
|
103
|
+
[toasts, add, update, close, pointerInside, focusInside, pageHidden]
|
|
104
|
+
);
|
|
105
|
+
return /* @__PURE__ */ jsx(ToastContext.Provider, { value: context, children });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/toast/ToastViewport.tsx
|
|
109
|
+
import { useLayoutEffect, useRef as useRef2 } from "react";
|
|
110
|
+
function ToastViewport({ className, children, render, ...rest }) {
|
|
111
|
+
const { toasts, viewportRef, setPointerInside, setFocusInside } = useToastContext("<Toast.Viewport>");
|
|
112
|
+
const elementRef = useRef2(null);
|
|
113
|
+
const newest = toasts.at(-1)?.id;
|
|
114
|
+
useLayoutEffect(() => {
|
|
115
|
+
const element = elementRef.current;
|
|
116
|
+
viewportRef.current = element;
|
|
117
|
+
if (!element || typeof element.showPopover !== "function") return;
|
|
118
|
+
if (element.matches(":popover-open")) element.hidePopover();
|
|
119
|
+
element.showPopover();
|
|
120
|
+
}, [newest, viewportRef]);
|
|
121
|
+
return useRender({
|
|
122
|
+
render,
|
|
123
|
+
defaultTagName: "section",
|
|
124
|
+
props: {
|
|
125
|
+
popover: "manual",
|
|
126
|
+
"aria-label": "Notifications",
|
|
127
|
+
"aria-live": "polite",
|
|
128
|
+
tabIndex: -1,
|
|
129
|
+
className,
|
|
130
|
+
ref: elementRef,
|
|
131
|
+
children: typeof children === "function" ? children(toasts) : children,
|
|
132
|
+
onPointerEnter() {
|
|
133
|
+
setPointerInside(true);
|
|
134
|
+
},
|
|
135
|
+
onPointerLeave() {
|
|
136
|
+
setPointerInside(false);
|
|
137
|
+
},
|
|
138
|
+
onFocus() {
|
|
139
|
+
setFocusInside(true);
|
|
140
|
+
},
|
|
141
|
+
onBlur(event) {
|
|
142
|
+
const next = event.relatedTarget;
|
|
143
|
+
if (!next || !event.currentTarget.contains(next)) setFocusInside(false);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
consumerProps: rest
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/toast/ToastRoot.tsx
|
|
151
|
+
import { useEffect as useEffect2, useRef as useRef3 } from "react";
|
|
152
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
153
|
+
function ToastRoot({ toast, className, children, render, ...rest }) {
|
|
154
|
+
const { close, paused, viewportRef } = useToastContext("<Toast.Root>");
|
|
155
|
+
const elementRef = useRef3(null);
|
|
156
|
+
const { id, timeout } = toast;
|
|
157
|
+
const remaining = useRef3(timeout);
|
|
158
|
+
const lastTimeout = useRef3(timeout);
|
|
159
|
+
if (lastTimeout.current !== timeout) {
|
|
160
|
+
lastTimeout.current = timeout;
|
|
161
|
+
remaining.current = timeout;
|
|
162
|
+
}
|
|
163
|
+
useEffect2(() => {
|
|
164
|
+
if (paused || timeout <= 0) return;
|
|
165
|
+
const started = Date.now();
|
|
166
|
+
const timer = setTimeout(() => close(id), remaining.current);
|
|
167
|
+
return () => {
|
|
168
|
+
clearTimeout(timer);
|
|
169
|
+
remaining.current = Math.max(0, remaining.current - (Date.now() - started));
|
|
170
|
+
};
|
|
171
|
+
}, [paused, timeout, id, close]);
|
|
172
|
+
const focusInside = useRef3(false);
|
|
173
|
+
useEffect2(
|
|
174
|
+
() => () => {
|
|
175
|
+
if (focusInside.current) viewportRef.current?.focus();
|
|
176
|
+
},
|
|
177
|
+
[viewportRef]
|
|
178
|
+
);
|
|
179
|
+
const element = useRender({
|
|
180
|
+
render,
|
|
181
|
+
defaultTagName: "div",
|
|
182
|
+
props: {
|
|
183
|
+
role: toast.priority === "high" ? "alert" : void 0,
|
|
184
|
+
"aria-atomic": true,
|
|
185
|
+
"data-type": toast.type,
|
|
186
|
+
className,
|
|
187
|
+
children,
|
|
188
|
+
ref: elementRef,
|
|
189
|
+
onFocus() {
|
|
190
|
+
focusInside.current = true;
|
|
191
|
+
},
|
|
192
|
+
onBlur(event) {
|
|
193
|
+
const next = event.relatedTarget;
|
|
194
|
+
if (!next || !event.currentTarget.contains(next)) focusInside.current = false;
|
|
195
|
+
},
|
|
196
|
+
onKeyDown(event) {
|
|
197
|
+
if (event.key === "Escape") {
|
|
198
|
+
event.preventDefault();
|
|
199
|
+
close(id);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
consumerProps: rest
|
|
204
|
+
});
|
|
205
|
+
return /* @__PURE__ */ jsx2(ToastRootContext.Provider, { value: toast, children: element });
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/toast/ToastTitle.tsx
|
|
209
|
+
function ToastTitle({ className, children, render, ...rest }) {
|
|
210
|
+
const toast = useToastRootContext("Title");
|
|
211
|
+
return useRender({
|
|
212
|
+
render,
|
|
213
|
+
defaultTagName: "p",
|
|
214
|
+
props: { className, children: children ?? toast.title },
|
|
215
|
+
consumerProps: rest
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// src/toast/ToastDescription.tsx
|
|
220
|
+
function ToastDescription({ className, children, render, ...rest }) {
|
|
221
|
+
const toast = useToastRootContext("Description");
|
|
222
|
+
return useRender({
|
|
223
|
+
render,
|
|
224
|
+
defaultTagName: "div",
|
|
225
|
+
props: { className, children: children ?? toast.description },
|
|
226
|
+
consumerProps: rest
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/toast/ToastAction.tsx
|
|
231
|
+
function ToastAction({ className, children, render, ...rest }) {
|
|
232
|
+
useToastRootContext("Action");
|
|
233
|
+
return useRender({
|
|
234
|
+
render,
|
|
235
|
+
defaultTagName: "button",
|
|
236
|
+
props: { type: "button", className, children },
|
|
237
|
+
consumerProps: rest
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/toast/ToastClose.tsx
|
|
242
|
+
function ToastClose({ className, children, render, ...rest }) {
|
|
243
|
+
const { close } = useToastContext("<Toast.Close>");
|
|
244
|
+
const { id } = useToastRootContext("Close");
|
|
245
|
+
return useRender({
|
|
246
|
+
render,
|
|
247
|
+
defaultTagName: "button",
|
|
248
|
+
props: {
|
|
249
|
+
type: "button",
|
|
250
|
+
className,
|
|
251
|
+
children,
|
|
252
|
+
onClick() {
|
|
253
|
+
close(id);
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
consumerProps: rest
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
export {
|
|
260
|
+
index_parts_exports as Toast,
|
|
261
|
+
useToastManager
|
|
262
|
+
};
|
|
@@ -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
|
+
};
|