@compa11y/react 0.1.0 → 0.1.3

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.
Files changed (76) hide show
  1. package/README.md +487 -5
  2. package/dist/chunk-36S2JYVF.cjs +1 -0
  3. package/dist/chunk-AJ7JSWUT.cjs +1 -0
  4. package/dist/chunk-DDFEION3.cjs +1 -0
  5. package/dist/chunk-DWU3PTJO.cjs +1 -0
  6. package/dist/chunk-FD4F6ONU.cjs +1 -0
  7. package/dist/chunk-FOVHQAY5.cjs +1 -0
  8. package/dist/chunk-GITBIGD4.js +1 -0
  9. package/dist/chunk-HEA4NAOM.js +1 -0
  10. package/dist/chunk-IZ7LLPPV.js +1 -0
  11. package/dist/chunk-JS3UD7KS.cjs +1 -0
  12. package/dist/chunk-MAR6RBHF.cjs +1 -0
  13. package/dist/chunk-MD4AVTLT.js +1 -0
  14. package/dist/chunk-SB6ASQ36.js +1 -0
  15. package/dist/chunk-VMM4K2K4.js +1 -0
  16. package/dist/chunk-XEJXACWE.js +1 -0
  17. package/dist/chunk-ZB3SYGHE.js +1 -0
  18. package/dist/components/combobox/index.cjs +1 -31
  19. package/dist/components/combobox/index.js +1 -6
  20. package/dist/components/dialog/index.cjs +1 -46
  21. package/dist/components/dialog/index.js +1 -5
  22. package/dist/components/menu/index.cjs +1 -46
  23. package/dist/components/menu/index.js +1 -5
  24. package/dist/components/tabs/index.cjs +1 -35
  25. package/dist/components/tabs/index.js +1 -6
  26. package/dist/components/toast/index.cjs +1 -24
  27. package/dist/components/toast/index.js +1 -3
  28. package/dist/index.cjs +1 -702
  29. package/dist/index.d.cts +760 -3
  30. package/dist/index.d.ts +760 -3
  31. package/dist/index.js +1 -430
  32. package/package.json +44 -3
  33. package/dist/chunk-2S4C6FGA.js +0 -380
  34. package/dist/chunk-2S4C6FGA.js.map +0 -1
  35. package/dist/chunk-52J4Z3QD.cjs +0 -45
  36. package/dist/chunk-52J4Z3QD.cjs.map +0 -1
  37. package/dist/chunk-C7QK2I7H.js +0 -373
  38. package/dist/chunk-C7QK2I7H.js.map +0 -1
  39. package/dist/chunk-D2UMS62N.cjs +0 -245
  40. package/dist/chunk-D2UMS62N.cjs.map +0 -1
  41. package/dist/chunk-E265U2RK.js +0 -234
  42. package/dist/chunk-E265U2RK.js.map +0 -1
  43. package/dist/chunk-E4XJRXWM.js +0 -215
  44. package/dist/chunk-E4XJRXWM.js.map +0 -1
  45. package/dist/chunk-GDLOJH6K.cjs +0 -110
  46. package/dist/chunk-GDLOJH6K.cjs.map +0 -1
  47. package/dist/chunk-IR46CNNY.cjs +0 -329
  48. package/dist/chunk-IR46CNNY.cjs.map +0 -1
  49. package/dist/chunk-JXYOE7SH.js +0 -103
  50. package/dist/chunk-JXYOE7SH.js.map +0 -1
  51. package/dist/chunk-O3YYQZ5O.js +0 -317
  52. package/dist/chunk-O3YYQZ5O.js.map +0 -1
  53. package/dist/chunk-OIVTOU4Z.cjs +0 -386
  54. package/dist/chunk-OIVTOU4Z.cjs.map +0 -1
  55. package/dist/chunk-OND5B7UG.js +0 -85
  56. package/dist/chunk-OND5B7UG.js.map +0 -1
  57. package/dist/chunk-R4FR6M6I.cjs +0 -383
  58. package/dist/chunk-R4FR6M6I.cjs.map +0 -1
  59. package/dist/chunk-RBDQCIS7.cjs +0 -89
  60. package/dist/chunk-RBDQCIS7.cjs.map +0 -1
  61. package/dist/chunk-SOBS7MIH.cjs +0 -220
  62. package/dist/chunk-SOBS7MIH.cjs.map +0 -1
  63. package/dist/chunk-WURPAE3R.js +0 -41
  64. package/dist/chunk-WURPAE3R.js.map +0 -1
  65. package/dist/components/combobox/index.cjs.map +0 -1
  66. package/dist/components/combobox/index.js.map +0 -1
  67. package/dist/components/dialog/index.cjs.map +0 -1
  68. package/dist/components/dialog/index.js.map +0 -1
  69. package/dist/components/menu/index.cjs.map +0 -1
  70. package/dist/components/menu/index.js.map +0 -1
  71. package/dist/components/tabs/index.cjs.map +0 -1
  72. package/dist/components/tabs/index.js.map +0 -1
  73. package/dist/components/toast/index.cjs.map +0 -1
  74. package/dist/components/toast/index.js.map +0 -1
  75. package/dist/index.cjs.map +0 -1
  76. package/dist/index.js.map +0 -1
@@ -1,383 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkGDLOJH6K_cjs = require('./chunk-GDLOJH6K.cjs');
4
- var chunk52J4Z3QD_cjs = require('./chunk-52J4Z3QD.cjs');
5
- var react = require('react');
6
- var jsxRuntime = require('react/jsx-runtime');
7
-
8
- var ActionMenuContext = react.createContext(null);
9
- function useActionMenuContext() {
10
- const context = react.useContext(ActionMenuContext);
11
- if (!context) {
12
- throw new Error(
13
- "ActionMenu compound components must be used within an ActionMenu component"
14
- );
15
- }
16
- return context;
17
- }
18
- var ActionMenuProvider = ActionMenuContext.Provider;
19
- function ActionMenu({
20
- defaultOpen = false,
21
- open: controlledOpen,
22
- onOpenChange,
23
- children,
24
- unstyled = false
25
- }) {
26
- const [uncontrolledOpen, setUncontrolledOpen] = react.useState(defaultOpen);
27
- const isOpen = controlledOpen ?? uncontrolledOpen;
28
- const [highlightedIndex, setHighlightedIndex] = react.useState(-1);
29
- const itemsRef = react.useRef([]);
30
- const onSelectRef = react.useRef(null);
31
- const menuId = chunk52J4Z3QD_cjs.useId("action-menu");
32
- const triggerId = chunk52J4Z3QD_cjs.useId("action-menu-trigger");
33
- const setOpen = react.useCallback(
34
- (value) => {
35
- if (controlledOpen === void 0) {
36
- setUncontrolledOpen(value);
37
- }
38
- onOpenChange?.(value);
39
- if (!value) {
40
- setHighlightedIndex(-1);
41
- }
42
- },
43
- [controlledOpen, onOpenChange]
44
- );
45
- const open = react.useCallback(() => setOpen(true), [setOpen]);
46
- const close = react.useCallback(() => setOpen(false), [setOpen]);
47
- const toggle = react.useCallback(() => setOpen(!isOpen), [setOpen, isOpen]);
48
- const registerItem = react.useCallback((id) => {
49
- const index = itemsRef.current.length;
50
- itemsRef.current.push(id);
51
- return index;
52
- }, []);
53
- const unregisterItem = react.useCallback((id) => {
54
- const index = itemsRef.current.indexOf(id);
55
- if (index > -1) {
56
- itemsRef.current.splice(index, 1);
57
- }
58
- }, []);
59
- const getItemCount = react.useCallback(() => itemsRef.current.length, []);
60
- const selectItem = react.useCallback(
61
- (index) => {
62
- onSelectRef.current?.(index);
63
- close();
64
- },
65
- [close]
66
- );
67
- const contextValue = {
68
- isOpen,
69
- open,
70
- close,
71
- toggle,
72
- highlightedIndex,
73
- setHighlightedIndex,
74
- menuId,
75
- triggerId,
76
- registerItem,
77
- unregisterItem,
78
- getItemCount,
79
- selectItem,
80
- unstyled
81
- };
82
- return /* @__PURE__ */ jsxRuntime.jsx(ActionMenuProvider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
83
- "div",
84
- {
85
- style: { position: "relative", display: "inline-block" },
86
- "data-compa11y-action-menu": true,
87
- children
88
- }
89
- ) });
90
- }
91
- var ActionMenuTrigger = react.forwardRef(function ActionMenuTrigger2({ children, onClick, onKeyDown, ...props }, ref) {
92
- const {
93
- isOpen,
94
- toggle,
95
- open,
96
- close,
97
- triggerId,
98
- menuId,
99
- setHighlightedIndex,
100
- getItemCount
101
- } = useActionMenuContext();
102
- const handleClick = (event) => {
103
- onClick?.(event);
104
- if (!event.defaultPrevented) {
105
- toggle();
106
- }
107
- };
108
- const keyboardProps = chunkGDLOJH6K_cjs.useKeyboard(
109
- {
110
- ArrowDown: () => {
111
- if (!isOpen) {
112
- open();
113
- }
114
- setHighlightedIndex(0);
115
- },
116
- ArrowUp: () => {
117
- if (!isOpen) {
118
- open();
119
- }
120
- setHighlightedIndex(getItemCount() - 1);
121
- },
122
- Enter: () => toggle(),
123
- Space: () => toggle(),
124
- Escape: () => close()
125
- },
126
- { preventDefault: true }
127
- );
128
- const handleKeyDown = (event) => {
129
- onKeyDown?.(event);
130
- if (!event.defaultPrevented) {
131
- keyboardProps.onKeyDown(event);
132
- }
133
- };
134
- return /* @__PURE__ */ jsxRuntime.jsx(
135
- "button",
136
- {
137
- ref,
138
- id: triggerId,
139
- type: "button",
140
- tabIndex: 0,
141
- "aria-haspopup": "menu",
142
- "aria-expanded": isOpen,
143
- "aria-controls": isOpen ? menuId : void 0,
144
- onClick: handleClick,
145
- onKeyDown: handleKeyDown,
146
- "data-compa11y-action-menu-trigger": true,
147
- ...props,
148
- children
149
- }
150
- );
151
- });
152
- var ActionMenuContent = react.forwardRef(function ActionMenuContent2({ children, onKeyDown, style, ...props }, ref) {
153
- const {
154
- isOpen,
155
- close,
156
- menuId,
157
- triggerId,
158
- highlightedIndex,
159
- setHighlightedIndex,
160
- getItemCount,
161
- unstyled
162
- } = useActionMenuContext();
163
- const menuRef = react.useRef(null);
164
- const clickHighlightedItem = () => {
165
- if (highlightedIndex >= 0 && menuRef.current) {
166
- const items = menuRef.current.querySelectorAll('[role="menuitem"]');
167
- const item = items[highlightedIndex];
168
- if (item && item.getAttribute("aria-disabled") !== "true") {
169
- item.click();
170
- }
171
- }
172
- };
173
- const keyboardProps = chunkGDLOJH6K_cjs.useKeyboard(
174
- {
175
- ArrowDown: () => {
176
- const count = getItemCount();
177
- setHighlightedIndex((highlightedIndex + 1) % count);
178
- },
179
- ArrowUp: () => {
180
- const count = getItemCount();
181
- setHighlightedIndex((highlightedIndex - 1 + count) % count);
182
- },
183
- Home: () => setHighlightedIndex(0),
184
- End: () => setHighlightedIndex(getItemCount() - 1),
185
- Enter: () => clickHighlightedItem(),
186
- Space: () => clickHighlightedItem(),
187
- Escape: () => close(),
188
- Tab: () => {
189
- close();
190
- return false;
191
- }
192
- },
193
- { preventDefault: true }
194
- );
195
- const handleKeyDown = (event) => {
196
- onKeyDown?.(event);
197
- if (!event.defaultPrevented) {
198
- keyboardProps.onKeyDown(event);
199
- }
200
- };
201
- react.useEffect(() => {
202
- if (isOpen && menuRef.current) {
203
- menuRef.current.focus();
204
- }
205
- }, [isOpen]);
206
- react.useEffect(() => {
207
- if (!isOpen) return;
208
- const handleClick = (event) => {
209
- const target = event.target;
210
- const menu = menuRef.current;
211
- const trigger = document.getElementById(triggerId);
212
- if (menu && !menu.contains(target) && trigger && !trigger.contains(target)) {
213
- close();
214
- }
215
- };
216
- document.addEventListener("mousedown", handleClick);
217
- return () => document.removeEventListener("mousedown", handleClick);
218
- }, [isOpen, close, triggerId]);
219
- if (!isOpen) {
220
- return null;
221
- }
222
- const contentStructuralStyles = {
223
- position: "absolute",
224
- top: "100%",
225
- left: 0,
226
- marginTop: "4px",
227
- zIndex: 1e3
228
- };
229
- const contentVisualStyles = unstyled ? {} : {
230
- minWidth: "160px",
231
- backgroundColor: "white",
232
- border: "1px solid #e0e0e0",
233
- borderRadius: "4px",
234
- boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
235
- padding: "4px 0"
236
- };
237
- const contentStyles = {
238
- ...contentStructuralStyles,
239
- ...contentVisualStyles
240
- };
241
- return /* @__PURE__ */ jsxRuntime.jsx(
242
- "div",
243
- {
244
- ref: (node) => {
245
- menuRef.current = node;
246
- if (typeof ref === "function") {
247
- ref(node);
248
- } else if (ref) {
249
- ref.current = node;
250
- }
251
- },
252
- id: menuId,
253
- role: "menu",
254
- "aria-labelledby": triggerId,
255
- tabIndex: -1,
256
- onKeyDown: handleKeyDown,
257
- style: { ...contentStyles, ...style },
258
- "data-compa11y-action-menu-content": true,
259
- ...props,
260
- children
261
- }
262
- );
263
- });
264
- var ActionMenuItem = react.forwardRef(
265
- function ActionMenuItem2({
266
- children,
267
- disabled = false,
268
- onSelect,
269
- onClick,
270
- onMouseEnter,
271
- style,
272
- ...props
273
- }, ref) {
274
- const {
275
- registerItem,
276
- unregisterItem,
277
- highlightedIndex,
278
- setHighlightedIndex,
279
- close,
280
- unstyled
281
- } = useActionMenuContext();
282
- const itemId = chunk52J4Z3QD_cjs.useId("action-menu-item");
283
- const indexRef = react.useRef(-1);
284
- react.useEffect(() => {
285
- if (!disabled) {
286
- indexRef.current = registerItem(itemId);
287
- }
288
- return () => {
289
- if (!disabled) {
290
- unregisterItem(itemId);
291
- }
292
- };
293
- }, [itemId, disabled, registerItem, unregisterItem]);
294
- const isHighlighted = indexRef.current === highlightedIndex;
295
- const handleClick = (event) => {
296
- onClick?.(event);
297
- if (!event.defaultPrevented && !disabled) {
298
- onSelect?.();
299
- close();
300
- }
301
- };
302
- const handleMouseEnter = (event) => {
303
- onMouseEnter?.(event);
304
- if (!disabled) {
305
- setHighlightedIndex(indexRef.current);
306
- }
307
- };
308
- const itemBehaviorStyles = {
309
- cursor: disabled ? "not-allowed" : "pointer",
310
- opacity: disabled ? 0.5 : 1
311
- };
312
- const itemVisualStyles = unstyled ? {} : {
313
- padding: "8px 16px",
314
- backgroundColor: isHighlighted ? "#f0f0f0" : "transparent"
315
- };
316
- const itemStyles = {
317
- ...itemBehaviorStyles,
318
- ...itemVisualStyles
319
- };
320
- return /* @__PURE__ */ jsxRuntime.jsx(
321
- "div",
322
- {
323
- ref,
324
- id: itemId,
325
- role: "menuitem",
326
- tabIndex: -1,
327
- "aria-disabled": disabled,
328
- "data-highlighted": isHighlighted,
329
- "data-disabled": disabled,
330
- onClick: handleClick,
331
- onMouseEnter: handleMouseEnter,
332
- style: { ...itemStyles, ...style },
333
- "data-compa11y-action-menu-item": true,
334
- ...props,
335
- children
336
- }
337
- );
338
- }
339
- );
340
- var ActionMenuSeparator = react.forwardRef(function ActionMenuSeparator2(props, ref) {
341
- return /* @__PURE__ */ jsxRuntime.jsx(
342
- "div",
343
- {
344
- ref,
345
- role: "separator",
346
- "data-compa11y-action-menu-separator": true,
347
- ...props
348
- }
349
- );
350
- });
351
- var ActionMenuLabel = react.forwardRef(
352
- function ActionMenuLabel2({ children, ...props }, ref) {
353
- return /* @__PURE__ */ jsxRuntime.jsx(
354
- "div",
355
- {
356
- ref,
357
- role: "presentation",
358
- "data-compa11y-action-menu-label": true,
359
- ...props,
360
- children
361
- }
362
- );
363
- }
364
- );
365
- var ActionMenuCompound = Object.assign(ActionMenu, {
366
- Trigger: ActionMenuTrigger,
367
- Content: ActionMenuContent,
368
- Item: ActionMenuItem,
369
- Separator: ActionMenuSeparator,
370
- Label: ActionMenuLabel
371
- });
372
-
373
- exports.ActionMenu = ActionMenu;
374
- exports.ActionMenuCompound = ActionMenuCompound;
375
- exports.ActionMenuContent = ActionMenuContent;
376
- exports.ActionMenuItem = ActionMenuItem;
377
- exports.ActionMenuLabel = ActionMenuLabel;
378
- exports.ActionMenuProvider = ActionMenuProvider;
379
- exports.ActionMenuSeparator = ActionMenuSeparator;
380
- exports.ActionMenuTrigger = ActionMenuTrigger;
381
- exports.useActionMenuContext = useActionMenuContext;
382
- //# sourceMappingURL=chunk-R4FR6M6I.cjs.map
383
- //# sourceMappingURL=chunk-R4FR6M6I.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/menu/menu-context.ts","../src/components/menu/menu.tsx"],"names":["createContext","useContext","useState","useRef","useId","useCallback","jsx","forwardRef","ActionMenuTrigger","useKeyboard","ActionMenuContent","useEffect","ActionMenuItem","ActionMenuSeparator","ActionMenuLabel"],"mappings":"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","file":"chunk-R4FR6M6I.cjs","sourcesContent":["import { createContext, useContext } from 'react';\n\nexport interface ActionMenuContextValue {\n /** Whether the menu is open */\n isOpen: boolean;\n /** Open the menu */\n open: () => void;\n /** Close the menu */\n close: () => void;\n /** Toggle the menu */\n toggle: () => void;\n /** Currently highlighted item index */\n highlightedIndex: number;\n /** Set highlighted item */\n setHighlightedIndex: (index: number) => void;\n /** ID for the menu element */\n menuId: string;\n /** ID for the trigger element */\n triggerId: string;\n /** Register a menu item */\n registerItem: (id: string) => number;\n /** Unregister a menu item */\n unregisterItem: (id: string) => void;\n /** Get item count */\n getItemCount: () => number;\n /** Select an item */\n selectItem: (index: number) => void;\n /** Whether default styles are disabled */\n unstyled: boolean;\n}\n\nconst ActionMenuContext = createContext<ActionMenuContextValue | null>(null);\n\nexport function useActionMenuContext(): ActionMenuContextValue {\n const context = useContext(ActionMenuContext);\n if (!context) {\n throw new Error(\n 'ActionMenu compound components must be used within an ActionMenu component'\n );\n }\n return context;\n}\n\nexport const ActionMenuProvider = ActionMenuContext.Provider;\n","import React, {\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useId } from '../../hooks/use-id';\nimport { useKeyboard } from '../../hooks/use-keyboard';\nimport {\n ActionMenuProvider,\n useActionMenuContext,\n type ActionMenuContextValue,\n} from './menu-context';\n\n// ============================================================================\n// ActionMenu Root\n// ============================================================================\n\nexport interface ActionMenuProps {\n /** Whether the menu is initially open */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Called when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Menu content */\n children: React.ReactNode;\n /** Remove default styles to allow full customization via className */\n unstyled?: boolean;\n}\n\nexport function ActionMenu({\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n children,\n unstyled = false,\n}: ActionMenuProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);\n const isOpen = controlledOpen ?? uncontrolledOpen;\n\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const itemsRef = useRef<string[]>([]);\n const onSelectRef = useRef<((index: number) => void) | null>(null);\n\n const menuId = useId('action-menu');\n const triggerId = useId('action-menu-trigger');\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (controlledOpen === undefined) {\n setUncontrolledOpen(value);\n }\n onOpenChange?.(value);\n\n if (!value) {\n setHighlightedIndex(-1);\n }\n },\n [controlledOpen, onOpenChange]\n );\n\n const open = useCallback(() => setOpen(true), [setOpen]);\n const close = useCallback(() => setOpen(false), [setOpen]);\n const toggle = useCallback(() => setOpen(!isOpen), [setOpen, isOpen]);\n\n const registerItem = useCallback((id: string) => {\n const index = itemsRef.current.length;\n itemsRef.current.push(id);\n return index;\n }, []);\n\n const unregisterItem = useCallback((id: string) => {\n const index = itemsRef.current.indexOf(id);\n if (index > -1) {\n itemsRef.current.splice(index, 1);\n }\n }, []);\n\n const getItemCount = useCallback(() => itemsRef.current.length, []);\n\n const selectItem = useCallback(\n (index: number) => {\n onSelectRef.current?.(index);\n close();\n },\n [close]\n );\n\n const contextValue: ActionMenuContextValue = {\n isOpen,\n open,\n close,\n toggle,\n highlightedIndex,\n setHighlightedIndex,\n menuId,\n triggerId,\n registerItem,\n unregisterItem,\n getItemCount,\n selectItem,\n unstyled,\n };\n\n return (\n <ActionMenuProvider value={contextValue}>\n <div\n style={{ position: 'relative', display: 'inline-block' }}\n data-compa11y-action-menu\n >\n {children}\n </div>\n </ActionMenuProvider>\n );\n}\n\nexport interface ActionMenuTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode;\n}\n\nexport const ActionMenuTrigger = forwardRef<\n HTMLButtonElement,\n ActionMenuTriggerProps\n>(function ActionMenuTrigger({ children, onClick, onKeyDown, ...props }, ref) {\n const {\n isOpen,\n toggle,\n open,\n close,\n triggerId,\n menuId,\n setHighlightedIndex,\n getItemCount,\n } = useActionMenuContext();\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (!event.defaultPrevented) {\n toggle();\n }\n };\n\n const keyboardProps = useKeyboard(\n {\n ArrowDown: () => {\n if (!isOpen) {\n open();\n }\n setHighlightedIndex(0);\n },\n ArrowUp: () => {\n if (!isOpen) {\n open();\n }\n setHighlightedIndex(getItemCount() - 1);\n },\n Enter: () => toggle(),\n Space: () => toggle(),\n Escape: () => close(),\n },\n { preventDefault: true }\n );\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n if (!event.defaultPrevented) {\n keyboardProps.onKeyDown(event);\n }\n };\n\n return (\n <button\n ref={ref}\n id={triggerId}\n type=\"button\"\n // Safari fix: Ensure button is in tab order (Safari skips buttons by default)\n tabIndex={0}\n aria-haspopup=\"menu\"\n aria-expanded={isOpen}\n aria-controls={isOpen ? menuId : undefined}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n data-compa11y-action-menu-trigger\n {...props}\n >\n {children}\n </button>\n );\n});\n\nexport interface ActionMenuContentProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n}\n\nexport const ActionMenuContent = forwardRef<\n HTMLDivElement,\n ActionMenuContentProps\n>(function ActionMenuContent({ children, onKeyDown, style, ...props }, ref) {\n const {\n isOpen,\n close,\n menuId,\n triggerId,\n highlightedIndex,\n setHighlightedIndex,\n getItemCount,\n unstyled,\n } = useActionMenuContext();\n const menuRef = useRef<HTMLDivElement>(null);\n\n const clickHighlightedItem = () => {\n if (highlightedIndex >= 0 && menuRef.current) {\n const items = menuRef.current.querySelectorAll('[role=\"menuitem\"]');\n const item = items[highlightedIndex] as HTMLElement;\n if (item && item.getAttribute('aria-disabled') !== 'true') {\n item.click();\n }\n }\n };\n\n const keyboardProps = useKeyboard(\n {\n ArrowDown: () => {\n const count = getItemCount();\n setHighlightedIndex((highlightedIndex + 1) % count);\n },\n ArrowUp: () => {\n const count = getItemCount();\n setHighlightedIndex((highlightedIndex - 1 + count) % count);\n },\n Home: () => setHighlightedIndex(0),\n End: () => setHighlightedIndex(getItemCount() - 1),\n Enter: () => clickHighlightedItem(),\n Space: () => clickHighlightedItem(),\n Escape: () => close(),\n Tab: () => {\n close();\n return false; // Allow default tab behavior\n },\n },\n { preventDefault: true }\n );\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (!event.defaultPrevented) {\n keyboardProps.onKeyDown(event);\n }\n };\n\n useEffect(() => {\n if (isOpen && menuRef.current) {\n menuRef.current.focus();\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (!isOpen) return;\n\n const handleClick = (event: MouseEvent) => {\n const target = event.target as Node;\n const menu = menuRef.current;\n const trigger = document.getElementById(triggerId);\n\n if (\n menu &&\n !menu.contains(target) &&\n trigger &&\n !trigger.contains(target)\n ) {\n close();\n }\n };\n\n document.addEventListener('mousedown', handleClick);\n return () => document.removeEventListener('mousedown', handleClick);\n }, [isOpen, close, triggerId]);\n\n if (!isOpen) {\n return null;\n }\n\n // Structural styles - always applied, required for dropdown positioning\n const contentStructuralStyles: React.CSSProperties = {\n position: 'absolute',\n top: '100%',\n left: 0,\n marginTop: '4px',\n zIndex: 1000,\n };\n\n // Visual styles - only applied when not unstyled\n const contentVisualStyles: React.CSSProperties = unstyled\n ? {}\n : {\n minWidth: '160px',\n backgroundColor: 'white',\n border: '1px solid #e0e0e0',\n borderRadius: '4px',\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\n padding: '4px 0',\n };\n\n const contentStyles: React.CSSProperties = {\n ...contentStructuralStyles,\n ...contentVisualStyles,\n };\n\n return (\n <div\n ref={(node) => {\n (menuRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n }}\n id={menuId}\n role=\"menu\"\n aria-labelledby={triggerId}\n tabIndex={-1}\n onKeyDown={handleKeyDown}\n style={{ ...contentStyles, ...style }}\n data-compa11y-action-menu-content\n {...props}\n >\n {children}\n </div>\n );\n});\n\nexport interface ActionMenuItemProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Whether the item is disabled */\n disabled?: boolean;\n /** Called when item is selected */\n onSelect?: () => void;\n children: React.ReactNode;\n}\n\nexport const ActionMenuItem = forwardRef<HTMLDivElement, ActionMenuItemProps>(\n function ActionMenuItem(\n {\n children,\n disabled = false,\n onSelect,\n onClick,\n onMouseEnter,\n style,\n ...props\n },\n ref\n ) {\n const {\n registerItem,\n unregisterItem,\n highlightedIndex,\n setHighlightedIndex,\n close,\n unstyled,\n } = useActionMenuContext();\n const itemId = useId('action-menu-item');\n const indexRef = useRef(-1);\n\n useEffect(() => {\n if (!disabled) {\n indexRef.current = registerItem(itemId);\n }\n return () => {\n if (!disabled) {\n unregisterItem(itemId);\n }\n };\n }, [itemId, disabled, registerItem, unregisterItem]);\n\n const isHighlighted = indexRef.current === highlightedIndex;\n\n const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n if (!event.defaultPrevented && !disabled) {\n onSelect?.();\n close();\n }\n };\n\n const handleMouseEnter = (event: React.MouseEvent<HTMLDivElement>) => {\n onMouseEnter?.(event);\n if (!disabled) {\n setHighlightedIndex(indexRef.current);\n }\n };\n\n // Behavioral styles - always applied for correct UX\n const itemBehaviorStyles: React.CSSProperties = {\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n };\n\n // Visual styles - only applied when not unstyled\n const itemVisualStyles: React.CSSProperties = unstyled\n ? {}\n : {\n padding: '8px 16px',\n backgroundColor: isHighlighted ? '#f0f0f0' : 'transparent',\n };\n\n const itemStyles: React.CSSProperties = {\n ...itemBehaviorStyles,\n ...itemVisualStyles,\n };\n\n return (\n <div\n ref={ref}\n id={itemId}\n role=\"menuitem\"\n tabIndex={-1}\n aria-disabled={disabled}\n data-highlighted={isHighlighted}\n data-disabled={disabled}\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n style={{ ...itemStyles, ...style }}\n data-compa11y-action-menu-item\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nexport interface ActionMenuSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const ActionMenuSeparator = forwardRef<\n HTMLDivElement,\n ActionMenuSeparatorProps\n>(function ActionMenuSeparator(props, ref) {\n return (\n <div\n ref={ref}\n role=\"separator\"\n data-compa11y-action-menu-separator\n {...props}\n />\n );\n});\n\nexport interface ActionMenuLabelProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n}\n\nexport const ActionMenuLabel = forwardRef<HTMLDivElement, ActionMenuLabelProps>(\n function ActionMenuLabel({ children, ...props }, ref) {\n return (\n <div\n ref={ref}\n role=\"presentation\"\n data-compa11y-action-menu-label\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nexport const ActionMenuCompound = Object.assign(ActionMenu, {\n Trigger: ActionMenuTrigger,\n Content: ActionMenuContent,\n Item: ActionMenuItem,\n Separator: ActionMenuSeparator,\n Label: ActionMenuLabel,\n});\n"]}
@@ -1,89 +0,0 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
- var core = require('@compa11y/core');
5
-
6
- // src/hooks/use-announcer.ts
7
- function useAnnouncer() {
8
- react.useEffect(() => {
9
- const cleanup = core.initAnnouncer();
10
- return cleanup;
11
- }, []);
12
- const announceMessage = react.useCallback(
13
- (message, options) => {
14
- core.announce(message, options);
15
- },
16
- []
17
- );
18
- const polite = react.useCallback(
19
- (message, options) => {
20
- core.announcePolite(message, options);
21
- },
22
- []
23
- );
24
- const assertive = react.useCallback(
25
- (message, options) => {
26
- core.announceAssertive(message, options);
27
- },
28
- []
29
- );
30
- const queue = react.useCallback(
31
- (message, options) => {
32
- core.queueAnnouncement(message, options);
33
- },
34
- []
35
- );
36
- const clear = react.useCallback(() => {
37
- core.clearAnnouncements();
38
- }, []);
39
- return {
40
- announce: announceMessage,
41
- polite,
42
- assertive,
43
- queue,
44
- clear
45
- };
46
- }
47
- function useAnnounceOnChange(value, getMessage, options) {
48
- const { skipInitial = true, ...announceOptions } = options ?? {};
49
- const isFirstRender = react.useRef(true);
50
- const previousValue = react.useRef(value);
51
- react.useEffect(() => {
52
- if (isFirstRender.current && skipInitial) {
53
- isFirstRender.current = false;
54
- previousValue.current = value;
55
- return;
56
- }
57
- if (previousValue.current !== value) {
58
- core.announce(getMessage(value), announceOptions);
59
- previousValue.current = value;
60
- }
61
- }, [value, getMessage, announceOptions]);
62
- }
63
- function useAnnounceLoading(isLoading, options = {}) {
64
- const {
65
- loadingMessage = "Loading...",
66
- loadedMessage = "Content loaded",
67
- errorMessage = "An error occurred",
68
- error
69
- } = options;
70
- const wasLoading = react.useRef(false);
71
- react.useEffect(() => {
72
- if (isLoading && !wasLoading.current) {
73
- core.announcePolite(loadingMessage);
74
- } else if (!isLoading && wasLoading.current) {
75
- if (error) {
76
- core.announceAssertive(errorMessage);
77
- } else {
78
- core.announcePolite(loadedMessage);
79
- }
80
- }
81
- wasLoading.current = isLoading;
82
- }, [isLoading, error, loadingMessage, loadedMessage, errorMessage]);
83
- }
84
-
85
- exports.useAnnounceLoading = useAnnounceLoading;
86
- exports.useAnnounceOnChange = useAnnounceOnChange;
87
- exports.useAnnouncer = useAnnouncer;
88
- //# sourceMappingURL=chunk-RBDQCIS7.cjs.map
89
- //# sourceMappingURL=chunk-RBDQCIS7.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/use-announcer.ts"],"names":["useEffect","initAnnouncer","useCallback","announce","announcePolite","announceAssertive","queueAnnouncement","clearAnnouncements","useRef"],"mappings":"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","file":"chunk-RBDQCIS7.cjs","sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\nimport {\n announce,\n announcePolite,\n announceAssertive,\n queueAnnouncement,\n clearAnnouncements,\n initAnnouncer,\n type AnnouncerOptions,\n} from '@compa11y/core';\n\n/**\n * Hook for screen reader announcements\n *\n * @example\n * ```tsx\n * function SearchResults({ results }) {\n * const { announce } = useAnnouncer();\n *\n * useEffect(() => {\n * announce(`Found ${results.length} results`);\n * }, [results.length, announce]);\n *\n * return <ul>...</ul>;\n * }\n * ```\n */\nexport function useAnnouncer() {\n // Ensure announcer is initialized\n useEffect(() => {\n const cleanup = initAnnouncer();\n return cleanup;\n }, []);\n\n const announceMessage = useCallback(\n (message: string, options?: AnnouncerOptions) => {\n announce(message, options);\n },\n []\n );\n\n const polite = useCallback(\n (message: string, options?: Omit<AnnouncerOptions, 'politeness'>) => {\n announcePolite(message, options);\n },\n []\n );\n\n const assertive = useCallback(\n (message: string, options?: Omit<AnnouncerOptions, 'politeness'>) => {\n announceAssertive(message, options);\n },\n []\n );\n\n const queue = useCallback(\n (message: string, options?: AnnouncerOptions & { debounce?: number }) => {\n queueAnnouncement(message, options);\n },\n []\n );\n\n const clear = useCallback(() => {\n clearAnnouncements();\n }, []);\n\n return {\n announce: announceMessage,\n polite,\n assertive,\n queue,\n clear,\n };\n}\n\n/**\n * Announce a message when a value changes\n *\n * @example\n * ```tsx\n * function Counter({ count }) {\n * useAnnounceOnChange(count, (value) => `Count is now ${value}`);\n * return <span>{count}</span>;\n * }\n * ```\n */\nexport function useAnnounceOnChange<T>(\n value: T,\n getMessage: (value: T) => string,\n options?: AnnouncerOptions & { skipInitial?: boolean }\n): void {\n const { skipInitial = true, ...announceOptions } = options ?? {};\n const isFirstRender = useRef(true);\n const previousValue = useRef(value);\n\n useEffect(() => {\n // Skip initial render if specified\n if (isFirstRender.current && skipInitial) {\n isFirstRender.current = false;\n previousValue.current = value;\n return;\n }\n\n // Only announce if value changed\n if (previousValue.current !== value) {\n announce(getMessage(value), announceOptions);\n previousValue.current = value;\n }\n }, [value, getMessage, announceOptions]);\n}\n\n/**\n * Announce loading states\n *\n * @example\n * ```tsx\n * function DataList({ isLoading }) {\n * useAnnounceLoading(isLoading, {\n * loadingMessage: 'Loading data...',\n * loadedMessage: 'Data loaded',\n * });\n *\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useAnnounceLoading(\n isLoading: boolean,\n options: {\n loadingMessage?: string;\n loadedMessage?: string;\n errorMessage?: string;\n error?: Error | null;\n } = {}\n): void {\n const {\n loadingMessage = 'Loading...',\n loadedMessage = 'Content loaded',\n errorMessage = 'An error occurred',\n error,\n } = options;\n\n const wasLoading = useRef(false);\n\n useEffect(() => {\n if (isLoading && !wasLoading.current) {\n announcePolite(loadingMessage);\n } else if (!isLoading && wasLoading.current) {\n if (error) {\n announceAssertive(errorMessage);\n } else {\n announcePolite(loadedMessage);\n }\n }\n wasLoading.current = isLoading;\n }, [isLoading, error, loadingMessage, loadedMessage, errorMessage]);\n}\n"]}