@alankrit2/ui 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -144,6 +144,27 @@ interface ButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
144
144
 
145
145
  declare const Button: React$1.ForwardRefExoticComponent<ButtonProps & React$1.RefAttributes<HTMLButtonElement>>;
146
146
 
147
+ interface DropdownProps {
148
+ children: React$1.ReactNode;
149
+ open?: boolean;
150
+ onOpenChange?: (open: boolean) => void;
151
+ defaultOpen?: boolean;
152
+ }
153
+ interface DropdownTriggerProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
154
+ asChild?: boolean;
155
+ }
156
+ interface DropdownContentProps extends React$1.HTMLAttributes<HTMLDivElement> {
157
+ sideOffset?: number;
158
+ align?: 'start' | 'center' | 'end';
159
+ }
160
+ interface DropdownItemProps extends React$1.HTMLAttributes<HTMLDivElement> {
161
+ asChild?: boolean;
162
+ onSelect?: (event: React$1.MouseEvent<HTMLDivElement>) => void;
163
+ disabled?: boolean;
164
+ }
165
+
166
+ declare const DropdownRoot: any;
167
+
147
168
  interface UseControlledOptions<T> {
148
169
  /** Controlled value */
149
170
  value?: T;
@@ -193,6 +214,9 @@ declare function useBodyScrollLock(enabled?: boolean): void;
193
214
  */
194
215
  declare function useStableId(idProp?: string): string;
195
216
 
217
+ type Handler = (event: MouseEvent | TouchEvent) => void;
218
+ declare function useClickOutside(ref: React.RefObject<HTMLElement | null>, handler: Handler, enabled?: boolean): void;
219
+
196
220
  interface SlotProps extends React$1.HTMLAttributes<HTMLElement> {
197
221
  children?: React$1.ReactNode;
198
222
  }
@@ -208,4 +232,4 @@ declare const Slot: React$1.ForwardRefExoticComponent<SlotProps & React$1.RefAtt
208
232
  */
209
233
  declare function composeRefs<T>(...refs: Array<React.Ref<T> | undefined>): (node: T | null) => void;
210
234
 
211
- export { Button, type ButtonProps, _default as Dialog, type DialogCloseProps, type DialogContentProps, type DialogDescriptionProps, type DialogOverlayProps, type DialogPortalProps, type DialogProps, type DialogTitleProps, type DialogTriggerProps, Slot, composeRefs, useBodyScrollLock, useControlled, useEscapeKeydown, useFocusTrap, useStableId };
235
+ export { Button, type ButtonProps, _default as Dialog, type DialogCloseProps, type DialogContentProps, type DialogDescriptionProps, type DialogOverlayProps, type DialogPortalProps, type DialogProps, type DialogTitleProps, type DialogTriggerProps, DropdownRoot as Dropdown, type DropdownContentProps, type DropdownItemProps, type DropdownProps, type DropdownTriggerProps, Slot, composeRefs, useBodyScrollLock, useClickOutside, useControlled, useEscapeKeydown, useFocusTrap, useStableId };
package/dist/index.d.ts CHANGED
@@ -144,6 +144,27 @@ interface ButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
144
144
 
145
145
  declare const Button: React$1.ForwardRefExoticComponent<ButtonProps & React$1.RefAttributes<HTMLButtonElement>>;
146
146
 
147
+ interface DropdownProps {
148
+ children: React$1.ReactNode;
149
+ open?: boolean;
150
+ onOpenChange?: (open: boolean) => void;
151
+ defaultOpen?: boolean;
152
+ }
153
+ interface DropdownTriggerProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
154
+ asChild?: boolean;
155
+ }
156
+ interface DropdownContentProps extends React$1.HTMLAttributes<HTMLDivElement> {
157
+ sideOffset?: number;
158
+ align?: 'start' | 'center' | 'end';
159
+ }
160
+ interface DropdownItemProps extends React$1.HTMLAttributes<HTMLDivElement> {
161
+ asChild?: boolean;
162
+ onSelect?: (event: React$1.MouseEvent<HTMLDivElement>) => void;
163
+ disabled?: boolean;
164
+ }
165
+
166
+ declare const DropdownRoot: any;
167
+
147
168
  interface UseControlledOptions<T> {
148
169
  /** Controlled value */
149
170
  value?: T;
@@ -193,6 +214,9 @@ declare function useBodyScrollLock(enabled?: boolean): void;
193
214
  */
194
215
  declare function useStableId(idProp?: string): string;
195
216
 
217
+ type Handler = (event: MouseEvent | TouchEvent) => void;
218
+ declare function useClickOutside(ref: React.RefObject<HTMLElement | null>, handler: Handler, enabled?: boolean): void;
219
+
196
220
  interface SlotProps extends React$1.HTMLAttributes<HTMLElement> {
197
221
  children?: React$1.ReactNode;
198
222
  }
@@ -208,4 +232,4 @@ declare const Slot: React$1.ForwardRefExoticComponent<SlotProps & React$1.RefAtt
208
232
  */
209
233
  declare function composeRefs<T>(...refs: Array<React.Ref<T> | undefined>): (node: T | null) => void;
210
234
 
211
- export { Button, type ButtonProps, _default as Dialog, type DialogCloseProps, type DialogContentProps, type DialogDescriptionProps, type DialogOverlayProps, type DialogPortalProps, type DialogProps, type DialogTitleProps, type DialogTriggerProps, Slot, composeRefs, useBodyScrollLock, useControlled, useEscapeKeydown, useFocusTrap, useStableId };
235
+ export { Button, type ButtonProps, _default as Dialog, type DialogCloseProps, type DialogContentProps, type DialogDescriptionProps, type DialogOverlayProps, type DialogPortalProps, type DialogProps, type DialogTitleProps, type DialogTriggerProps, DropdownRoot as Dropdown, type DropdownContentProps, type DropdownItemProps, type DropdownProps, type DropdownTriggerProps, Slot, composeRefs, useBodyScrollLock, useClickOutside, useControlled, useEscapeKeydown, useFocusTrap, useStableId };
package/dist/index.js CHANGED
@@ -390,12 +390,163 @@ var Button = React8__namespace.forwardRef(
390
390
  );
391
391
  Button.displayName = "Button";
392
392
  var button_default = Button;
393
+ function useClickOutside(ref, handler, enabled = true) {
394
+ React8.useEffect(() => {
395
+ if (!enabled) return;
396
+ const listener = (event) => {
397
+ const el = ref.current;
398
+ if (!el || el.contains(event.target)) {
399
+ return;
400
+ }
401
+ handler(event);
402
+ };
403
+ document.addEventListener("mousedown", listener);
404
+ document.addEventListener("touchstart", listener);
405
+ return () => {
406
+ document.removeEventListener("mousedown", listener);
407
+ document.removeEventListener("touchstart", listener);
408
+ };
409
+ }, [ref, handler, enabled]);
410
+ }
411
+ var DropdownContext = React8__namespace.createContext(void 0);
412
+ var useDropdown = () => {
413
+ const context = React8__namespace.useContext(DropdownContext);
414
+ if (!context) {
415
+ throw new Error("useDropdown must be used within a Dropdown");
416
+ }
417
+ return context;
418
+ };
419
+ function Dropdown({
420
+ children,
421
+ open: openProp,
422
+ onOpenChange: setOpenProp,
423
+ defaultOpen = false
424
+ }) {
425
+ const [open, setOpen] = useControlled({
426
+ value: openProp,
427
+ onChange: setOpenProp,
428
+ defaultValue: defaultOpen
429
+ });
430
+ const triggerRef = React8__namespace.useRef(null);
431
+ const contextValue = React8__namespace.useMemo(
432
+ () => ({
433
+ open: !!open,
434
+ onOpenChange: setOpen,
435
+ triggerRef
436
+ }),
437
+ [open, setOpen]
438
+ );
439
+ return /* @__PURE__ */ jsxRuntime.jsx(DropdownContext.Provider, { value: contextValue, children });
440
+ }
441
+ var DropdownTrigger = React8__namespace.forwardRef(
442
+ ({ asChild, onClick, ...props }, ref) => {
443
+ const { open, onOpenChange, triggerRef } = useDropdown();
444
+ const Comp = asChild ? Slot : "button";
445
+ const composedRef = composeRefs(ref, triggerRef);
446
+ return /* @__PURE__ */ jsxRuntime.jsx(
447
+ Comp,
448
+ {
449
+ ref: composedRef,
450
+ "aria-haspopup": "menu",
451
+ "aria-expanded": open,
452
+ "data-state": open ? "open" : "closed",
453
+ onClick: (e) => {
454
+ onClick?.(e);
455
+ onOpenChange(!open);
456
+ },
457
+ ...props
458
+ }
459
+ );
460
+ }
461
+ );
462
+ DropdownTrigger.displayName = "Dropdown.Trigger";
463
+ var DropdownContent = React8__namespace.forwardRef(
464
+ ({ children, style, sideOffset = 4, align = "center", ...props }, ref) => {
465
+ const { open, onOpenChange, triggerRef } = useDropdown();
466
+ const contentRef = React8__namespace.useRef(null);
467
+ const composedRef = composeRefs(ref, contentRef);
468
+ const [position, setPosition] = React8__namespace.useState({ top: 0, left: 0 });
469
+ useClickOutside(contentRef, (e) => {
470
+ if (triggerRef.current?.contains(e.target)) {
471
+ return;
472
+ }
473
+ onOpenChange(false);
474
+ }, open);
475
+ useEscapeKeydown(() => onOpenChange(false));
476
+ React8__namespace.useEffect(() => {
477
+ if (open && triggerRef.current && contentRef.current) {
478
+ const triggerRect = triggerRef.current.getBoundingClientRect();
479
+ const contentRect = contentRef.current.getBoundingClientRect();
480
+ let top = triggerRect.bottom + sideOffset + window.scrollY;
481
+ let left = triggerRect.left + window.scrollX;
482
+ if (align === "center") {
483
+ left = triggerRect.left + window.scrollX + triggerRect.width / 2 - contentRect.width / 2;
484
+ } else if (align === "end") {
485
+ left = triggerRect.right + window.scrollX - contentRect.width;
486
+ }
487
+ setPosition({ top, left });
488
+ }
489
+ }, [open, sideOffset, align]);
490
+ if (!open) return null;
491
+ return ReactDOM.createPortal(
492
+ /* @__PURE__ */ jsxRuntime.jsx(
493
+ "div",
494
+ {
495
+ ref: composedRef,
496
+ role: "menu",
497
+ style: {
498
+ position: "absolute",
499
+ top: position.top,
500
+ left: position.left,
501
+ zIndex: 50,
502
+ ...style
503
+ },
504
+ "data-state": open ? "open" : "closed",
505
+ ...props,
506
+ children
507
+ }
508
+ ),
509
+ document.body
510
+ );
511
+ }
512
+ );
513
+ DropdownContent.displayName = "Dropdown.Content";
514
+ var DropdownItem = React8__namespace.forwardRef(
515
+ ({ asChild, onClick, onSelect, disabled, ...props }, ref) => {
516
+ const { onOpenChange } = useDropdown();
517
+ const Comp = asChild ? Slot : "div";
518
+ return /* @__PURE__ */ jsxRuntime.jsx(
519
+ Comp,
520
+ {
521
+ ref,
522
+ role: "menuitem",
523
+ "aria-disabled": disabled,
524
+ "data-disabled": disabled,
525
+ onClick: (e) => {
526
+ if (disabled) return;
527
+ onClick?.(e);
528
+ onSelect?.(e);
529
+ onOpenChange(false);
530
+ },
531
+ ...props
532
+ }
533
+ );
534
+ }
535
+ );
536
+ DropdownItem.displayName = "Dropdown.Item";
537
+ var DropdownRoot = Dropdown;
538
+ DropdownRoot.Trigger = DropdownTrigger;
539
+ DropdownRoot.Content = DropdownContent;
540
+ DropdownRoot.Item = DropdownItem;
541
+ var dropdown_default = DropdownRoot;
393
542
 
394
543
  exports.Button = button_default;
395
544
  exports.Dialog = dialog_default;
545
+ exports.Dropdown = dropdown_default;
396
546
  exports.Slot = Slot;
397
547
  exports.composeRefs = composeRefs;
398
548
  exports.useBodyScrollLock = useBodyScrollLock;
549
+ exports.useClickOutside = useClickOutside;
399
550
  exports.useControlled = useControlled;
400
551
  exports.useEscapeKeydown = useEscapeKeydown;
401
552
  exports.useFocusTrap = useFocusTrap;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/use-controlled.ts","../src/hooks/use-focus-trap.ts","../src/hooks/use-escape-keydown.ts","../src/hooks/use-body-scroll-lock.ts","../src/hooks/use-id.ts","../src/utils/compose-refs.ts","../src/primitives/slot.tsx","../src/components/dialog/dialog-context.ts","../src/components/dialog/dialog.tsx","../src/components/button/button.tsx"],"names":["React","React2","React3","React4","React5","React6","React7","React8","jsx","ReactDOM","React9"],"mappings":"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","file":"index.js","sourcesContent":["import * as React from 'react';\n\ninterface UseControlledOptions<T> {\n /** Controlled value */\n value?: T;\n /** Default value for uncontrolled mode */\n defaultValue?: T;\n /** Change handler */\n onChange?: (value: T) => void;\n}\n\n/**\n * Hook for managing controlled/uncontrolled state pattern.\n * Supports both controlled (value + onChange) and uncontrolled (defaultValue) modes.\n * \n * @example\n * // Controlled\n * const [value, setValue] = useControlled({ value: externalValue, onChange: setExternalValue });\n * \n * // Uncontrolled\n * const [value, setValue] = useControlled({ defaultValue: false });\n */\nexport function useControlled<T>({\n value: valueProp,\n defaultValue,\n onChange,\n}: UseControlledOptions<T>): [T, (newValue: T) => void] {\n const [valueState, setValueState] = React.useState<T>(defaultValue as T);\n const isControlled = valueProp !== undefined;\n\n const value = isControlled ? valueProp : valueState;\n\n const setValue = React.useCallback(\n (newValue: T) => {\n if (!isControlled) {\n setValueState(newValue);\n }\n onChange?.(newValue);\n },\n [isControlled, onChange]\n );\n\n return [value as T, setValue];\n}\n","import * as React from 'react';\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'textarea:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\n/**\n * Hook for trapping focus within a container.\n * Handles Tab/Shift+Tab cycling and prevents focus escape.\n * \n * @param containerRef - Ref to the container element\n * @param enabled - Whether the focus trap is active\n * @param autoFocus - Whether to auto-focus the first element on mount\n */\nexport function useFocusTrap(\n containerRef: React.RefObject<HTMLElement | null>,\n enabled = true,\n autoFocus = true\n) {\n const previouslyFocusedElement = React.useRef<HTMLElement | null>(null);\n\n React.useEffect(() => {\n if (!enabled || !containerRef.current) return;\n\n const container = containerRef.current;\n\n // Store the previously focused element\n previouslyFocusedElement.current = document.activeElement as HTMLElement;\n\n // Get all focusable elements\n const getFocusableElements = (): HTMLElement[] => {\n return Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)\n );\n };\n\n // Auto-focus first element if enabled\n if (autoFocus) {\n const focusableElements = getFocusableElements();\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n }\n }\n\n // Handle Tab key to cycle focus\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return;\n\n const focusableElements = getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (event.shiftKey) {\n // Shift + Tab: move focus to last element if on first\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n // Tab: move focus to first element if on last\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n\n // Restore focus to previously focused element\n if (previouslyFocusedElement.current) {\n previouslyFocusedElement.current.focus();\n }\n };\n }, [enabled, autoFocus, containerRef]);\n}\n","import * as React from 'react';\n\n/**\n * Hook for handling Escape key press events.\n * Automatically cleans up event listener on unmount.\n */\nexport function useEscapeKeydown(\n handler: (event: KeyboardEvent) => void,\n enabled = true\n) {\n React.useEffect(() => {\n if (!enabled) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n handler(event);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [handler, enabled]);\n}\n","import * as React from 'react';\n\n/**\n * Hook for preventing body scroll when a modal/dialog is open.\n * This is an accessibility requirement to prevent background scrolling.\n */\nexport function useBodyScrollLock(enabled = true) {\n React.useEffect(() => {\n if (!enabled) return;\n\n const originalOverflow = document.body.style.overflow;\n const originalPaddingRight = document.body.style.paddingRight;\n\n // Prevent scroll\n document.body.style.overflow = 'hidden';\n\n // Prevent layout shift by adding padding to compensate for scrollbar\n const scrollbarWidth =\n window.innerWidth - document.documentElement.clientWidth;\n if (scrollbarWidth > 0) {\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n }\n\n return () => {\n document.body.style.overflow = originalOverflow;\n document.body.style.paddingRight = originalPaddingRight;\n };\n }, [enabled]);\n}\n","import * as React from 'react';\n\nlet count = 0;\nfunction generateId() {\n return `headless-ui-${++count}`;\n}\n\n/**\n * Hook for generating stable, unique IDs.\n * Uses React's useId when available, with a fallback for older versions.\n */\nexport function useStableId(idProp?: string): string {\n const [id] = React.useState(() => idProp || generateId());\n return idProp || id;\n}\n","/**\n * Composes multiple refs into a single ref callback.\n * Useful when you need to forward a ref while also using it internally.\n */\nexport function composeRefs<T>(...refs: Array<React.Ref<T> | undefined>) {\n return (node: T | null) => {\n refs.forEach((ref) => {\n if (!ref) return;\n\n if (typeof ref === 'function') {\n ref(node);\n } else {\n (ref as React.MutableRefObject<T | null>).current = node;\n }\n });\n };\n}\n","import * as React from 'react';\nimport { composeRefs } from '../utils/compose-refs';\n\ninterface SlotProps extends React.HTMLAttributes<HTMLElement> {\n children?: React.ReactNode;\n}\n\n/**\n * Slot component for the asChild pattern.\n * When asChild is true, merges props with the child element instead of rendering a wrapper.\n */\nexport const Slot = React.forwardRef<HTMLElement, SlotProps>(\n (props, forwardedRef) => {\n const { children, ...slotProps } = props;\n\n if (!React.isValidElement(children)) {\n return null;\n }\n\n return React.cloneElement(children, {\n ...mergeProps(slotProps, children.props),\n ref: forwardedRef\n ? composeRefs(forwardedRef, (children as any).ref)\n : (children as any).ref,\n });\n }\n);\n\nSlot.displayName = 'Slot';\n\n/**\n * Merges props from the Slot with props from the child element.\n * Event handlers are composed, other props from child take precedence.\n */\nfunction mergeProps(slotProps: any, childProps: any) {\n const merged = { ...childProps };\n\n for (const key in childProps) {\n const slotValue = slotProps[key];\n const childValue = childProps[key];\n\n // Compose event handlers\n if (/^on[A-Z]/.test(key)) {\n if (slotValue && childValue) {\n merged[key] = (...args: any[]) => {\n childValue(...args);\n slotValue(...args);\n };\n } else if (slotValue) {\n merged[key] = slotValue;\n }\n }\n // Child props take precedence for non-event handlers\n else if (key === 'style') {\n merged[key] = { ...slotValue, ...childValue };\n } else if (key === 'className') {\n merged[key] = [slotValue, childValue].filter(Boolean).join(' ');\n }\n }\n\n // Add slot props that don't exist in child\n for (const key in slotProps) {\n if (!(key in childProps)) {\n merged[key] = slotProps[key];\n }\n }\n\n return merged;\n}\n","import * as React from 'react';\n\nexport interface DialogContextValue {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n triggerRef: React.RefObject<HTMLElement | null>;\n contentRef: React.RefObject<HTMLElement | null>;\n titleId: string;\n descriptionId: string;\n}\n\nexport const DialogContext = React.createContext<DialogContextValue | null>(\n null\n);\n\n/**\n * Hook to access Dialog context.\n * Throws an error if used outside of a Dialog component.\n */\nexport function useDialogContext(componentName: string): DialogContextValue {\n const context = React.useContext(DialogContext);\n\n if (!context) {\n throw new Error(\n `<${componentName}> must be used within a <Dialog> component.`\n );\n }\n\n return context;\n}\n","import * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport { useControlled } from '../../hooks/use-controlled';\nimport { useFocusTrap } from '../../hooks/use-focus-trap';\nimport { useEscapeKeydown } from '../../hooks/use-escape-keydown';\nimport { useBodyScrollLock } from '../../hooks/use-body-scroll-lock';\nimport { useStableId } from '../../hooks/use-id';\nimport { Slot } from '../../primitives/slot';\nimport { DialogContext, useDialogContext } from './dialog-context';\nimport type {\n DialogProps,\n DialogTriggerProps,\n DialogPortalProps,\n DialogOverlayProps,\n DialogContentProps,\n DialogTitleProps,\n DialogDescriptionProps,\n DialogCloseProps,\n} from './types';\n\n/**\n * Dialog Root Component\n * \n * Provides context for all Dialog sub-components.\n * Supports both controlled and uncontrolled state.\n * \n * @example\n * // Controlled\n * <Dialog open={open} onOpenChange={setOpen}>\n * ...\n * </Dialog>\n * \n * // Uncontrolled\n * <Dialog defaultOpen={false}>\n * ...\n * </Dialog>\n */\nexport function Dialog({\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n children,\n}: DialogProps) {\n const [open, setOpen] = useControlled({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const triggerRef = React.useRef<HTMLElement>(null);\n const contentRef = React.useRef<HTMLElement>(null);\n const titleId = useStableId();\n const descriptionId = useStableId();\n\n const contextValue = React.useMemo(\n () => ({\n open,\n onOpenChange: setOpen,\n triggerRef,\n contentRef,\n titleId,\n descriptionId,\n }),\n [open, setOpen, titleId, descriptionId]\n );\n\n return (\n <DialogContext.Provider value={contextValue}>\n {children}\n </DialogContext.Provider>\n );\n}\n\n/**\n * Dialog Trigger Component\n * \n * Button that opens the dialog when clicked.\n * Supports asChild pattern for custom elements.\n * \n * @example\n * <Dialog.Trigger>Open Dialog</Dialog.Trigger>\n * \n * // With asChild\n * <Dialog.Trigger asChild>\n * <button className=\"custom-button\">Open</button>\n * </Dialog.Trigger>\n */\nconst DialogTrigger = React.forwardRef<HTMLButtonElement, DialogTriggerProps>(\n ({ asChild = false, children, onClick, ...props }, forwardedRef) => {\n const { onOpenChange, triggerRef } = useDialogContext('Dialog.Trigger');\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n onOpenChange(true);\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={(node: any) => {\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else {\n forwardedRef.current = node;\n }\n }\n (triggerRef as React.MutableRefObject<HTMLElement | null>).current =\n node;\n }}\n type={asChild ? undefined : 'button'}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n );\n }\n);\n\nDialogTrigger.displayName = 'Dialog.Trigger';\n\n/**\n * Dialog Portal Component\n * \n * Renders children in a portal outside the DOM hierarchy.\n * Only renders when dialog is open.\n * \n * @example\n * <Dialog.Portal>\n * <Dialog.Overlay />\n * <Dialog.Content>...</Dialog.Content>\n * </Dialog.Portal>\n */\nfunction DialogPortal({ container, children }: DialogPortalProps) {\n const { open } = useDialogContext('Dialog.Portal');\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!open || !mounted) return null;\n\n return ReactDOM.createPortal(\n children,\n container || document.body\n );\n}\n\n/**\n * Dialog Overlay Component\n * \n * Semi-transparent backdrop behind the dialog.\n * Clicking it closes the dialog.\n * \n * @example\n * <Dialog.Overlay style={{ backgroundColor: 'rgba(0, 0, 0, 0.5)' }} />\n */\nconst DialogOverlay = React.forwardRef<HTMLDivElement, DialogOverlayProps>(\n ({ onClick, ...props }, forwardedRef) => {\n const { onOpenChange } = useDialogContext('Dialog.Overlay');\n\n const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n onOpenChange(false);\n };\n\n return (\n <div\n ref={forwardedRef}\n onClick={handleClick}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 9998,\n }}\n {...props}\n />\n );\n }\n);\n\nDialogOverlay.displayName = 'Dialog.Overlay';\n\n/**\n * Dialog Content Component\n * \n * Main container for dialog content.\n * Implements focus trap, keyboard handling, and ARIA attributes.\n * \n * @example\n * <Dialog.Content>\n * <Dialog.Title>Title</Dialog.Title>\n * <Dialog.Description>Description</Dialog.Description>\n * <Dialog.Close>Close</Dialog.Close>\n * </Dialog.Content>\n */\nconst DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps>(\n (\n { onEscapeKeyDown, onOverlayClick, children, ...props },\n forwardedRef\n ) => {\n const { open, onOpenChange, contentRef, titleId, descriptionId } =\n useDialogContext('Dialog.Content');\n\n // Focus trap\n useFocusTrap(contentRef, open, true);\n\n // Body scroll lock\n useBodyScrollLock(open);\n\n // Escape key handling\n useEscapeKeydown(\n (event) => {\n onEscapeKeyDown?.(event);\n onOpenChange(false);\n },\n open\n );\n\n // Prevent clicks inside content from closing dialog\n const handleContentClick = (event: React.MouseEvent<HTMLDivElement>) => {\n event.stopPropagation();\n };\n\n return (\n <div\n ref={(node) => {\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else {\n forwardedRef.current = node;\n }\n }\n (contentRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={descriptionId}\n onClick={handleContentClick}\n style={{\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 9999,\n }}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nDialogContent.displayName = 'Dialog.Content';\n\n/**\n * Dialog Title Component\n * \n * Title for the dialog, linked via aria-labelledby.\n * \n * @example\n * <Dialog.Title>Confirm Action</Dialog.Title>\n */\nconst DialogTitle = React.forwardRef<HTMLHeadingElement, DialogTitleProps>(\n ({ children, ...props }, forwardedRef) => {\n const { titleId } = useDialogContext('Dialog.Title');\n\n return (\n <h2 ref={forwardedRef} id={titleId} {...props}>\n {children}\n </h2>\n );\n }\n);\n\nDialogTitle.displayName = 'Dialog.Title';\n\n/**\n * Dialog Description Component\n * \n * Description for the dialog, linked via aria-describedby.\n * \n * @example\n * <Dialog.Description>This action cannot be undone.</Dialog.Description>\n */\nconst DialogDescription = React.forwardRef<\n HTMLParagraphElement,\n DialogDescriptionProps\n>(({ children, ...props }, forwardedRef) => {\n const { descriptionId } = useDialogContext('Dialog.Description');\n\n return (\n <p ref={forwardedRef} id={descriptionId} {...props}>\n {children}\n </p>\n );\n});\n\nDialogDescription.displayName = 'Dialog.Description';\n\n/**\n * Dialog Close Component\n * \n * Button that closes the dialog when clicked.\n * Supports asChild pattern for custom elements.\n * \n * @example\n * <Dialog.Close>Cancel</Dialog.Close>\n * \n * // With asChild\n * <Dialog.Close asChild>\n * <button className=\"custom-button\">Close</button>\n * </Dialog.Close>\n */\nconst DialogClose = React.forwardRef<HTMLButtonElement, DialogCloseProps>(\n ({ asChild = false, children, onClick, ...props }, forwardedRef) => {\n const { onOpenChange } = useDialogContext('Dialog.Close');\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n onOpenChange(false);\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={forwardedRef}\n type={asChild ? undefined : 'button'}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n );\n }\n);\n\nDialogClose.displayName = 'Dialog.Close';\n\n// Attach sub-components to Dialog\nDialog.Trigger = DialogTrigger;\nDialog.Portal = DialogPortal;\nDialog.Overlay = DialogOverlay;\nDialog.Content = DialogContent;\nDialog.Title = DialogTitle;\nDialog.Description = DialogDescription;\nDialog.Close = DialogClose;\n\n// Type augmentation for compound components\nexport interface DialogComponent extends React.FC<DialogProps> {\n Trigger: typeof DialogTrigger;\n Portal: typeof DialogPortal;\n Overlay: typeof DialogOverlay;\n Content: typeof DialogContent;\n Title: typeof DialogTitle;\n Description: typeof DialogDescription;\n Close: typeof DialogClose;\n}\n\nexport default Dialog as DialogComponent;\n","import * as React from 'react';\nimport { Slot } from '../../primitives/slot';\nimport { ButtonProps } from './types';\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return <Comp ref={ref} {...props} />;\n }\n);\n\nButton.displayName = 'Button';\n\nexport default Button;\n"]}
1
+ {"version":3,"sources":["../src/hooks/use-controlled.ts","../src/hooks/use-focus-trap.ts","../src/hooks/use-escape-keydown.ts","../src/hooks/use-body-scroll-lock.ts","../src/hooks/use-id.ts","../src/utils/compose-refs.ts","../src/primitives/slot.tsx","../src/components/dialog/dialog-context.ts","../src/components/dialog/dialog.tsx","../src/components/button/button.tsx","../src/hooks/use-click-outside.ts","../src/components/dropdown/dropdown.tsx"],"names":["React","React2","React3","React4","React5","React6","React7","React8","jsx","ReactDOM","React9","useEffect","React10","createPortal"],"mappings":"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","file":"index.js","sourcesContent":["import * as React from 'react';\n\ninterface UseControlledOptions<T> {\n /** Controlled value */\n value?: T;\n /** Default value for uncontrolled mode */\n defaultValue?: T;\n /** Change handler */\n onChange?: (value: T) => void;\n}\n\n/**\n * Hook for managing controlled/uncontrolled state pattern.\n * Supports both controlled (value + onChange) and uncontrolled (defaultValue) modes.\n * \n * @example\n * // Controlled\n * const [value, setValue] = useControlled({ value: externalValue, onChange: setExternalValue });\n * \n * // Uncontrolled\n * const [value, setValue] = useControlled({ defaultValue: false });\n */\nexport function useControlled<T>({\n value: valueProp,\n defaultValue,\n onChange,\n}: UseControlledOptions<T>): [T, (newValue: T) => void] {\n const [valueState, setValueState] = React.useState<T>(defaultValue as T);\n const isControlled = valueProp !== undefined;\n\n const value = isControlled ? valueProp : valueState;\n\n const setValue = React.useCallback(\n (newValue: T) => {\n if (!isControlled) {\n setValueState(newValue);\n }\n onChange?.(newValue);\n },\n [isControlled, onChange]\n );\n\n return [value as T, setValue];\n}\n","import * as React from 'react';\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'textarea:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\n/**\n * Hook for trapping focus within a container.\n * Handles Tab/Shift+Tab cycling and prevents focus escape.\n * \n * @param containerRef - Ref to the container element\n * @param enabled - Whether the focus trap is active\n * @param autoFocus - Whether to auto-focus the first element on mount\n */\nexport function useFocusTrap(\n containerRef: React.RefObject<HTMLElement | null>,\n enabled = true,\n autoFocus = true\n) {\n const previouslyFocusedElement = React.useRef<HTMLElement | null>(null);\n\n React.useEffect(() => {\n if (!enabled || !containerRef.current) return;\n\n const container = containerRef.current;\n\n // Store the previously focused element\n previouslyFocusedElement.current = document.activeElement as HTMLElement;\n\n // Get all focusable elements\n const getFocusableElements = (): HTMLElement[] => {\n return Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)\n );\n };\n\n // Auto-focus first element if enabled\n if (autoFocus) {\n const focusableElements = getFocusableElements();\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n }\n }\n\n // Handle Tab key to cycle focus\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return;\n\n const focusableElements = getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (event.shiftKey) {\n // Shift + Tab: move focus to last element if on first\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n // Tab: move focus to first element if on last\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n\n // Restore focus to previously focused element\n if (previouslyFocusedElement.current) {\n previouslyFocusedElement.current.focus();\n }\n };\n }, [enabled, autoFocus, containerRef]);\n}\n","import * as React from 'react';\n\n/**\n * Hook for handling Escape key press events.\n * Automatically cleans up event listener on unmount.\n */\nexport function useEscapeKeydown(\n handler: (event: KeyboardEvent) => void,\n enabled = true\n) {\n React.useEffect(() => {\n if (!enabled) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n handler(event);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [handler, enabled]);\n}\n","import * as React from 'react';\n\n/**\n * Hook for preventing body scroll when a modal/dialog is open.\n * This is an accessibility requirement to prevent background scrolling.\n */\nexport function useBodyScrollLock(enabled = true) {\n React.useEffect(() => {\n if (!enabled) return;\n\n const originalOverflow = document.body.style.overflow;\n const originalPaddingRight = document.body.style.paddingRight;\n\n // Prevent scroll\n document.body.style.overflow = 'hidden';\n\n // Prevent layout shift by adding padding to compensate for scrollbar\n const scrollbarWidth =\n window.innerWidth - document.documentElement.clientWidth;\n if (scrollbarWidth > 0) {\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n }\n\n return () => {\n document.body.style.overflow = originalOverflow;\n document.body.style.paddingRight = originalPaddingRight;\n };\n }, [enabled]);\n}\n","import * as React from 'react';\n\nlet count = 0;\nfunction generateId() {\n return `headless-ui-${++count}`;\n}\n\n/**\n * Hook for generating stable, unique IDs.\n * Uses React's useId when available, with a fallback for older versions.\n */\nexport function useStableId(idProp?: string): string {\n const [id] = React.useState(() => idProp || generateId());\n return idProp || id;\n}\n","/**\n * Composes multiple refs into a single ref callback.\n * Useful when you need to forward a ref while also using it internally.\n */\nexport function composeRefs<T>(...refs: Array<React.Ref<T> | undefined>) {\n return (node: T | null) => {\n refs.forEach((ref) => {\n if (!ref) return;\n\n if (typeof ref === 'function') {\n ref(node);\n } else {\n (ref as React.MutableRefObject<T | null>).current = node;\n }\n });\n };\n}\n","import * as React from 'react';\nimport { composeRefs } from '../utils/compose-refs';\n\ninterface SlotProps extends React.HTMLAttributes<HTMLElement> {\n children?: React.ReactNode;\n}\n\n/**\n * Slot component for the asChild pattern.\n * When asChild is true, merges props with the child element instead of rendering a wrapper.\n */\nexport const Slot = React.forwardRef<HTMLElement, SlotProps>(\n (props, forwardedRef) => {\n const { children, ...slotProps } = props;\n\n if (!React.isValidElement(children)) {\n return null;\n }\n\n return React.cloneElement(children, {\n ...mergeProps(slotProps, children.props),\n ref: forwardedRef\n ? composeRefs(forwardedRef, (children as any).ref)\n : (children as any).ref,\n });\n }\n);\n\nSlot.displayName = 'Slot';\n\n/**\n * Merges props from the Slot with props from the child element.\n * Event handlers are composed, other props from child take precedence.\n */\nfunction mergeProps(slotProps: any, childProps: any) {\n const merged = { ...childProps };\n\n for (const key in childProps) {\n const slotValue = slotProps[key];\n const childValue = childProps[key];\n\n // Compose event handlers\n if (/^on[A-Z]/.test(key)) {\n if (slotValue && childValue) {\n merged[key] = (...args: any[]) => {\n childValue(...args);\n slotValue(...args);\n };\n } else if (slotValue) {\n merged[key] = slotValue;\n }\n }\n // Child props take precedence for non-event handlers\n else if (key === 'style') {\n merged[key] = { ...slotValue, ...childValue };\n } else if (key === 'className') {\n merged[key] = [slotValue, childValue].filter(Boolean).join(' ');\n }\n }\n\n // Add slot props that don't exist in child\n for (const key in slotProps) {\n if (!(key in childProps)) {\n merged[key] = slotProps[key];\n }\n }\n\n return merged;\n}\n","import * as React from 'react';\n\nexport interface DialogContextValue {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n triggerRef: React.RefObject<HTMLElement | null>;\n contentRef: React.RefObject<HTMLElement | null>;\n titleId: string;\n descriptionId: string;\n}\n\nexport const DialogContext = React.createContext<DialogContextValue | null>(\n null\n);\n\n/**\n * Hook to access Dialog context.\n * Throws an error if used outside of a Dialog component.\n */\nexport function useDialogContext(componentName: string): DialogContextValue {\n const context = React.useContext(DialogContext);\n\n if (!context) {\n throw new Error(\n `<${componentName}> must be used within a <Dialog> component.`\n );\n }\n\n return context;\n}\n","import * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport { useControlled } from '../../hooks/use-controlled';\nimport { useFocusTrap } from '../../hooks/use-focus-trap';\nimport { useEscapeKeydown } from '../../hooks/use-escape-keydown';\nimport { useBodyScrollLock } from '../../hooks/use-body-scroll-lock';\nimport { useStableId } from '../../hooks/use-id';\nimport { Slot } from '../../primitives/slot';\nimport { DialogContext, useDialogContext } from './dialog-context';\nimport type {\n DialogProps,\n DialogTriggerProps,\n DialogPortalProps,\n DialogOverlayProps,\n DialogContentProps,\n DialogTitleProps,\n DialogDescriptionProps,\n DialogCloseProps,\n} from './types';\n\n/**\n * Dialog Root Component\n * \n * Provides context for all Dialog sub-components.\n * Supports both controlled and uncontrolled state.\n * \n * @example\n * // Controlled\n * <Dialog open={open} onOpenChange={setOpen}>\n * ...\n * </Dialog>\n * \n * // Uncontrolled\n * <Dialog defaultOpen={false}>\n * ...\n * </Dialog>\n */\nexport function Dialog({\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n children,\n}: DialogProps) {\n const [open, setOpen] = useControlled({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const triggerRef = React.useRef<HTMLElement>(null);\n const contentRef = React.useRef<HTMLElement>(null);\n const titleId = useStableId();\n const descriptionId = useStableId();\n\n const contextValue = React.useMemo(\n () => ({\n open,\n onOpenChange: setOpen,\n triggerRef,\n contentRef,\n titleId,\n descriptionId,\n }),\n [open, setOpen, titleId, descriptionId]\n );\n\n return (\n <DialogContext.Provider value={contextValue}>\n {children}\n </DialogContext.Provider>\n );\n}\n\n/**\n * Dialog Trigger Component\n * \n * Button that opens the dialog when clicked.\n * Supports asChild pattern for custom elements.\n * \n * @example\n * <Dialog.Trigger>Open Dialog</Dialog.Trigger>\n * \n * // With asChild\n * <Dialog.Trigger asChild>\n * <button className=\"custom-button\">Open</button>\n * </Dialog.Trigger>\n */\nconst DialogTrigger = React.forwardRef<HTMLButtonElement, DialogTriggerProps>(\n ({ asChild = false, children, onClick, ...props }, forwardedRef) => {\n const { onOpenChange, triggerRef } = useDialogContext('Dialog.Trigger');\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n onOpenChange(true);\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={(node: any) => {\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else {\n forwardedRef.current = node;\n }\n }\n (triggerRef as React.MutableRefObject<HTMLElement | null>).current =\n node;\n }}\n type={asChild ? undefined : 'button'}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n );\n }\n);\n\nDialogTrigger.displayName = 'Dialog.Trigger';\n\n/**\n * Dialog Portal Component\n * \n * Renders children in a portal outside the DOM hierarchy.\n * Only renders when dialog is open.\n * \n * @example\n * <Dialog.Portal>\n * <Dialog.Overlay />\n * <Dialog.Content>...</Dialog.Content>\n * </Dialog.Portal>\n */\nfunction DialogPortal({ container, children }: DialogPortalProps) {\n const { open } = useDialogContext('Dialog.Portal');\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!open || !mounted) return null;\n\n return ReactDOM.createPortal(\n children,\n container || document.body\n );\n}\n\n/**\n * Dialog Overlay Component\n * \n * Semi-transparent backdrop behind the dialog.\n * Clicking it closes the dialog.\n * \n * @example\n * <Dialog.Overlay style={{ backgroundColor: 'rgba(0, 0, 0, 0.5)' }} />\n */\nconst DialogOverlay = React.forwardRef<HTMLDivElement, DialogOverlayProps>(\n ({ onClick, ...props }, forwardedRef) => {\n const { onOpenChange } = useDialogContext('Dialog.Overlay');\n\n const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n onOpenChange(false);\n };\n\n return (\n <div\n ref={forwardedRef}\n onClick={handleClick}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 9998,\n }}\n {...props}\n />\n );\n }\n);\n\nDialogOverlay.displayName = 'Dialog.Overlay';\n\n/**\n * Dialog Content Component\n * \n * Main container for dialog content.\n * Implements focus trap, keyboard handling, and ARIA attributes.\n * \n * @example\n * <Dialog.Content>\n * <Dialog.Title>Title</Dialog.Title>\n * <Dialog.Description>Description</Dialog.Description>\n * <Dialog.Close>Close</Dialog.Close>\n * </Dialog.Content>\n */\nconst DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps>(\n (\n { onEscapeKeyDown, onOverlayClick, children, ...props },\n forwardedRef\n ) => {\n const { open, onOpenChange, contentRef, titleId, descriptionId } =\n useDialogContext('Dialog.Content');\n\n // Focus trap\n useFocusTrap(contentRef, open, true);\n\n // Body scroll lock\n useBodyScrollLock(open);\n\n // Escape key handling\n useEscapeKeydown(\n (event) => {\n onEscapeKeyDown?.(event);\n onOpenChange(false);\n },\n open\n );\n\n // Prevent clicks inside content from closing dialog\n const handleContentClick = (event: React.MouseEvent<HTMLDivElement>) => {\n event.stopPropagation();\n };\n\n return (\n <div\n ref={(node) => {\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else {\n forwardedRef.current = node;\n }\n }\n (contentRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={descriptionId}\n onClick={handleContentClick}\n style={{\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 9999,\n }}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nDialogContent.displayName = 'Dialog.Content';\n\n/**\n * Dialog Title Component\n * \n * Title for the dialog, linked via aria-labelledby.\n * \n * @example\n * <Dialog.Title>Confirm Action</Dialog.Title>\n */\nconst DialogTitle = React.forwardRef<HTMLHeadingElement, DialogTitleProps>(\n ({ children, ...props }, forwardedRef) => {\n const { titleId } = useDialogContext('Dialog.Title');\n\n return (\n <h2 ref={forwardedRef} id={titleId} {...props}>\n {children}\n </h2>\n );\n }\n);\n\nDialogTitle.displayName = 'Dialog.Title';\n\n/**\n * Dialog Description Component\n * \n * Description for the dialog, linked via aria-describedby.\n * \n * @example\n * <Dialog.Description>This action cannot be undone.</Dialog.Description>\n */\nconst DialogDescription = React.forwardRef<\n HTMLParagraphElement,\n DialogDescriptionProps\n>(({ children, ...props }, forwardedRef) => {\n const { descriptionId } = useDialogContext('Dialog.Description');\n\n return (\n <p ref={forwardedRef} id={descriptionId} {...props}>\n {children}\n </p>\n );\n});\n\nDialogDescription.displayName = 'Dialog.Description';\n\n/**\n * Dialog Close Component\n * \n * Button that closes the dialog when clicked.\n * Supports asChild pattern for custom elements.\n * \n * @example\n * <Dialog.Close>Cancel</Dialog.Close>\n * \n * // With asChild\n * <Dialog.Close asChild>\n * <button className=\"custom-button\">Close</button>\n * </Dialog.Close>\n */\nconst DialogClose = React.forwardRef<HTMLButtonElement, DialogCloseProps>(\n ({ asChild = false, children, onClick, ...props }, forwardedRef) => {\n const { onOpenChange } = useDialogContext('Dialog.Close');\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n onOpenChange(false);\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={forwardedRef}\n type={asChild ? undefined : 'button'}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n );\n }\n);\n\nDialogClose.displayName = 'Dialog.Close';\n\n// Attach sub-components to Dialog\nDialog.Trigger = DialogTrigger;\nDialog.Portal = DialogPortal;\nDialog.Overlay = DialogOverlay;\nDialog.Content = DialogContent;\nDialog.Title = DialogTitle;\nDialog.Description = DialogDescription;\nDialog.Close = DialogClose;\n\n// Type augmentation for compound components\nexport interface DialogComponent extends React.FC<DialogProps> {\n Trigger: typeof DialogTrigger;\n Portal: typeof DialogPortal;\n Overlay: typeof DialogOverlay;\n Content: typeof DialogContent;\n Title: typeof DialogTitle;\n Description: typeof DialogDescription;\n Close: typeof DialogClose;\n}\n\nexport default Dialog as DialogComponent;\n","import * as React from 'react';\nimport { Slot } from '../../primitives/slot';\nimport { ButtonProps } from './types';\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return <Comp ref={ref} {...props} />;\n }\n);\n\nButton.displayName = 'Button';\n\nexport default Button;\n","import { useEffect } from 'react';\n\ntype Handler = (event: MouseEvent | TouchEvent) => void;\n\nexport function useClickOutside(\n ref: React.RefObject<HTMLElement | null>,\n handler: Handler,\n enabled: boolean = true\n) {\n useEffect(() => {\n if (!enabled) return;\n\n const listener = (event: MouseEvent | TouchEvent) => {\n const el = ref.current;\n if (!el || el.contains(event.target as Node)) {\n return;\n }\n handler(event);\n };\n\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n\n return () => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n };\n }, [ref, handler, enabled]);\n}\n","import * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { useControlled } from '../../hooks/use-controlled';\nimport { useClickOutside } from '../../hooks/use-click-outside';\nimport { useEscapeKeydown } from '../../hooks/use-escape-keydown';\nimport { Slot } from '../../primitives/slot';\nimport { composeRefs } from '../../utils/compose-refs';\nimport {\n DropdownProps,\n DropdownTriggerProps,\n DropdownContentProps,\n DropdownItemProps,\n DropdownContextValue,\n} from './types';\n\nconst DropdownContext = React.createContext<DropdownContextValue | undefined>(undefined);\n\nconst useDropdown = () => {\n const context = React.useContext(DropdownContext);\n if (!context) {\n throw new Error('useDropdown must be used within a Dropdown');\n }\n return context;\n};\n\nexport function Dropdown({\n children,\n open: openProp,\n onOpenChange: setOpenProp,\n defaultOpen = false,\n}: DropdownProps) {\n const [open, setOpen] = useControlled({\n value: openProp,\n onChange: setOpenProp,\n defaultValue: defaultOpen,\n });\n\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n\n const contextValue = React.useMemo(\n () => ({\n open: !!open,\n onOpenChange: setOpen,\n triggerRef,\n }),\n [open, setOpen]\n );\n\n return (\n <DropdownContext.Provider value={contextValue}>\n {children}\n </DropdownContext.Provider>\n );\n}\n\nconst DropdownTrigger = React.forwardRef<HTMLButtonElement, DropdownTriggerProps>(\n ({ asChild, onClick, ...props }, ref) => {\n const { open, onOpenChange, triggerRef } = useDropdown();\n const Comp = asChild ? Slot : 'button';\n const composedRef = composeRefs(ref, triggerRef);\n\n return (\n <Comp\n ref={composedRef}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n data-state={open ? 'open' : 'closed'}\n onClick={(e) => {\n onClick?.(e);\n onOpenChange(!open);\n }}\n {...props}\n />\n );\n }\n);\nDropdownTrigger.displayName = 'Dropdown.Trigger';\n\nconst DropdownContent = React.forwardRef<HTMLDivElement, DropdownContentProps>(\n ({ children, style, sideOffset = 4, align = 'center', ...props }, ref) => {\n const { open, onOpenChange, triggerRef } = useDropdown();\n const contentRef = React.useRef<HTMLDivElement>(null);\n const composedRef = composeRefs(ref, contentRef);\n const [position, setPosition] = React.useState<{ top: number; left: number }>({ top: 0, left: 0 });\n\n useClickOutside(contentRef, (e) => {\n // Ignore clicks on the trigger to avoid double-toggling\n if (triggerRef.current?.contains(e.target as Node)) {\n return;\n }\n onOpenChange(false);\n }, open);\n\n useEscapeKeydown(() => onOpenChange(false));\n\n React.useEffect(() => {\n if (open && triggerRef.current && contentRef.current) {\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n \n let top = triggerRect.bottom + sideOffset + window.scrollY;\n let left = triggerRect.left + window.scrollX;\n \n if (align === 'center') {\n left = triggerRect.left + window.scrollX + (triggerRect.width / 2) - (contentRect.width / 2);\n } else if (align === 'end') {\n left = triggerRect.right + window.scrollX - contentRect.width;\n }\n \n // Basic boundary check (optional, can be improved)\n // if (left < 0) left = 10;\n \n setPosition({ top, left });\n }\n }, [open, sideOffset, align]);\n\n if (!open) return null;\n\n return createPortal(\n <div\n ref={composedRef}\n role=\"menu\"\n style={{\n position: 'absolute',\n top: position.top,\n left: position.left,\n zIndex: 50,\n ...style,\n }}\n data-state={open ? 'open' : 'closed'}\n {...props}\n >\n {children}\n </div>,\n document.body\n );\n }\n);\nDropdownContent.displayName = 'Dropdown.Content';\n\nconst DropdownItem = React.forwardRef<HTMLDivElement, DropdownItemProps>(\n ({ asChild, onClick, onSelect, disabled, ...props }, ref) => {\n const { onOpenChange } = useDropdown();\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n ref={ref}\n role=\"menuitem\"\n aria-disabled={disabled}\n data-disabled={disabled}\n onClick={(e) => {\n if (disabled) return;\n onClick?.(e);\n onSelect?.(e);\n onOpenChange(false);\n }}\n {...props}\n />\n );\n }\n);\nDropdownItem.displayName = 'Dropdown.Item';\n\n// Attach subcomponents\nconst DropdownRoot = Dropdown as any;\nDropdownRoot.Trigger = DropdownTrigger;\nDropdownRoot.Content = DropdownContent;\nDropdownRoot.Item = DropdownItem;\n\nexport default DropdownRoot;\n"]}
package/dist/index.mjs CHANGED
@@ -1,5 +1,7 @@
1
1
  import * as React8 from 'react';
2
+ import { useEffect } from 'react';
2
3
  import * as ReactDOM from 'react-dom';
4
+ import { createPortal } from 'react-dom';
3
5
  import { jsx } from 'react/jsx-runtime';
4
6
 
5
7
  // src/components/dialog/dialog.tsx
@@ -367,7 +369,156 @@ var Button = React8.forwardRef(
367
369
  );
368
370
  Button.displayName = "Button";
369
371
  var button_default = Button;
372
+ function useClickOutside(ref, handler, enabled = true) {
373
+ useEffect(() => {
374
+ if (!enabled) return;
375
+ const listener = (event) => {
376
+ const el = ref.current;
377
+ if (!el || el.contains(event.target)) {
378
+ return;
379
+ }
380
+ handler(event);
381
+ };
382
+ document.addEventListener("mousedown", listener);
383
+ document.addEventListener("touchstart", listener);
384
+ return () => {
385
+ document.removeEventListener("mousedown", listener);
386
+ document.removeEventListener("touchstart", listener);
387
+ };
388
+ }, [ref, handler, enabled]);
389
+ }
390
+ var DropdownContext = React8.createContext(void 0);
391
+ var useDropdown = () => {
392
+ const context = React8.useContext(DropdownContext);
393
+ if (!context) {
394
+ throw new Error("useDropdown must be used within a Dropdown");
395
+ }
396
+ return context;
397
+ };
398
+ function Dropdown({
399
+ children,
400
+ open: openProp,
401
+ onOpenChange: setOpenProp,
402
+ defaultOpen = false
403
+ }) {
404
+ const [open, setOpen] = useControlled({
405
+ value: openProp,
406
+ onChange: setOpenProp,
407
+ defaultValue: defaultOpen
408
+ });
409
+ const triggerRef = React8.useRef(null);
410
+ const contextValue = React8.useMemo(
411
+ () => ({
412
+ open: !!open,
413
+ onOpenChange: setOpen,
414
+ triggerRef
415
+ }),
416
+ [open, setOpen]
417
+ );
418
+ return /* @__PURE__ */ jsx(DropdownContext.Provider, { value: contextValue, children });
419
+ }
420
+ var DropdownTrigger = React8.forwardRef(
421
+ ({ asChild, onClick, ...props }, ref) => {
422
+ const { open, onOpenChange, triggerRef } = useDropdown();
423
+ const Comp = asChild ? Slot : "button";
424
+ const composedRef = composeRefs(ref, triggerRef);
425
+ return /* @__PURE__ */ jsx(
426
+ Comp,
427
+ {
428
+ ref: composedRef,
429
+ "aria-haspopup": "menu",
430
+ "aria-expanded": open,
431
+ "data-state": open ? "open" : "closed",
432
+ onClick: (e) => {
433
+ onClick?.(e);
434
+ onOpenChange(!open);
435
+ },
436
+ ...props
437
+ }
438
+ );
439
+ }
440
+ );
441
+ DropdownTrigger.displayName = "Dropdown.Trigger";
442
+ var DropdownContent = React8.forwardRef(
443
+ ({ children, style, sideOffset = 4, align = "center", ...props }, ref) => {
444
+ const { open, onOpenChange, triggerRef } = useDropdown();
445
+ const contentRef = React8.useRef(null);
446
+ const composedRef = composeRefs(ref, contentRef);
447
+ const [position, setPosition] = React8.useState({ top: 0, left: 0 });
448
+ useClickOutside(contentRef, (e) => {
449
+ if (triggerRef.current?.contains(e.target)) {
450
+ return;
451
+ }
452
+ onOpenChange(false);
453
+ }, open);
454
+ useEscapeKeydown(() => onOpenChange(false));
455
+ React8.useEffect(() => {
456
+ if (open && triggerRef.current && contentRef.current) {
457
+ const triggerRect = triggerRef.current.getBoundingClientRect();
458
+ const contentRect = contentRef.current.getBoundingClientRect();
459
+ let top = triggerRect.bottom + sideOffset + window.scrollY;
460
+ let left = triggerRect.left + window.scrollX;
461
+ if (align === "center") {
462
+ left = triggerRect.left + window.scrollX + triggerRect.width / 2 - contentRect.width / 2;
463
+ } else if (align === "end") {
464
+ left = triggerRect.right + window.scrollX - contentRect.width;
465
+ }
466
+ setPosition({ top, left });
467
+ }
468
+ }, [open, sideOffset, align]);
469
+ if (!open) return null;
470
+ return createPortal(
471
+ /* @__PURE__ */ jsx(
472
+ "div",
473
+ {
474
+ ref: composedRef,
475
+ role: "menu",
476
+ style: {
477
+ position: "absolute",
478
+ top: position.top,
479
+ left: position.left,
480
+ zIndex: 50,
481
+ ...style
482
+ },
483
+ "data-state": open ? "open" : "closed",
484
+ ...props,
485
+ children
486
+ }
487
+ ),
488
+ document.body
489
+ );
490
+ }
491
+ );
492
+ DropdownContent.displayName = "Dropdown.Content";
493
+ var DropdownItem = React8.forwardRef(
494
+ ({ asChild, onClick, onSelect, disabled, ...props }, ref) => {
495
+ const { onOpenChange } = useDropdown();
496
+ const Comp = asChild ? Slot : "div";
497
+ return /* @__PURE__ */ jsx(
498
+ Comp,
499
+ {
500
+ ref,
501
+ role: "menuitem",
502
+ "aria-disabled": disabled,
503
+ "data-disabled": disabled,
504
+ onClick: (e) => {
505
+ if (disabled) return;
506
+ onClick?.(e);
507
+ onSelect?.(e);
508
+ onOpenChange(false);
509
+ },
510
+ ...props
511
+ }
512
+ );
513
+ }
514
+ );
515
+ DropdownItem.displayName = "Dropdown.Item";
516
+ var DropdownRoot = Dropdown;
517
+ DropdownRoot.Trigger = DropdownTrigger;
518
+ DropdownRoot.Content = DropdownContent;
519
+ DropdownRoot.Item = DropdownItem;
520
+ var dropdown_default = DropdownRoot;
370
521
 
371
- export { button_default as Button, dialog_default as Dialog, Slot, composeRefs, useBodyScrollLock, useControlled, useEscapeKeydown, useFocusTrap, useStableId };
522
+ export { button_default as Button, dialog_default as Dialog, dropdown_default as Dropdown, Slot, composeRefs, useBodyScrollLock, useClickOutside, useControlled, useEscapeKeydown, useFocusTrap, useStableId };
372
523
  //# sourceMappingURL=index.mjs.map
373
524
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/use-controlled.ts","../src/hooks/use-focus-trap.ts","../src/hooks/use-escape-keydown.ts","../src/hooks/use-body-scroll-lock.ts","../src/hooks/use-id.ts","../src/utils/compose-refs.ts","../src/primitives/slot.tsx","../src/components/dialog/dialog-context.ts","../src/components/dialog/dialog.tsx","../src/components/button/button.tsx"],"names":["React","React2","React3","React4","React5","React6","React7","React9","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["import * as React from 'react';\n\ninterface UseControlledOptions<T> {\n /** Controlled value */\n value?: T;\n /** Default value for uncontrolled mode */\n defaultValue?: T;\n /** Change handler */\n onChange?: (value: T) => void;\n}\n\n/**\n * Hook for managing controlled/uncontrolled state pattern.\n * Supports both controlled (value + onChange) and uncontrolled (defaultValue) modes.\n * \n * @example\n * // Controlled\n * const [value, setValue] = useControlled({ value: externalValue, onChange: setExternalValue });\n * \n * // Uncontrolled\n * const [value, setValue] = useControlled({ defaultValue: false });\n */\nexport function useControlled<T>({\n value: valueProp,\n defaultValue,\n onChange,\n}: UseControlledOptions<T>): [T, (newValue: T) => void] {\n const [valueState, setValueState] = React.useState<T>(defaultValue as T);\n const isControlled = valueProp !== undefined;\n\n const value = isControlled ? valueProp : valueState;\n\n const setValue = React.useCallback(\n (newValue: T) => {\n if (!isControlled) {\n setValueState(newValue);\n }\n onChange?.(newValue);\n },\n [isControlled, onChange]\n );\n\n return [value as T, setValue];\n}\n","import * as React from 'react';\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'textarea:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\n/**\n * Hook for trapping focus within a container.\n * Handles Tab/Shift+Tab cycling and prevents focus escape.\n * \n * @param containerRef - Ref to the container element\n * @param enabled - Whether the focus trap is active\n * @param autoFocus - Whether to auto-focus the first element on mount\n */\nexport function useFocusTrap(\n containerRef: React.RefObject<HTMLElement | null>,\n enabled = true,\n autoFocus = true\n) {\n const previouslyFocusedElement = React.useRef<HTMLElement | null>(null);\n\n React.useEffect(() => {\n if (!enabled || !containerRef.current) return;\n\n const container = containerRef.current;\n\n // Store the previously focused element\n previouslyFocusedElement.current = document.activeElement as HTMLElement;\n\n // Get all focusable elements\n const getFocusableElements = (): HTMLElement[] => {\n return Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)\n );\n };\n\n // Auto-focus first element if enabled\n if (autoFocus) {\n const focusableElements = getFocusableElements();\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n }\n }\n\n // Handle Tab key to cycle focus\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return;\n\n const focusableElements = getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (event.shiftKey) {\n // Shift + Tab: move focus to last element if on first\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n // Tab: move focus to first element if on last\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n\n // Restore focus to previously focused element\n if (previouslyFocusedElement.current) {\n previouslyFocusedElement.current.focus();\n }\n };\n }, [enabled, autoFocus, containerRef]);\n}\n","import * as React from 'react';\n\n/**\n * Hook for handling Escape key press events.\n * Automatically cleans up event listener on unmount.\n */\nexport function useEscapeKeydown(\n handler: (event: KeyboardEvent) => void,\n enabled = true\n) {\n React.useEffect(() => {\n if (!enabled) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n handler(event);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [handler, enabled]);\n}\n","import * as React from 'react';\n\n/**\n * Hook for preventing body scroll when a modal/dialog is open.\n * This is an accessibility requirement to prevent background scrolling.\n */\nexport function useBodyScrollLock(enabled = true) {\n React.useEffect(() => {\n if (!enabled) return;\n\n const originalOverflow = document.body.style.overflow;\n const originalPaddingRight = document.body.style.paddingRight;\n\n // Prevent scroll\n document.body.style.overflow = 'hidden';\n\n // Prevent layout shift by adding padding to compensate for scrollbar\n const scrollbarWidth =\n window.innerWidth - document.documentElement.clientWidth;\n if (scrollbarWidth > 0) {\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n }\n\n return () => {\n document.body.style.overflow = originalOverflow;\n document.body.style.paddingRight = originalPaddingRight;\n };\n }, [enabled]);\n}\n","import * as React from 'react';\n\nlet count = 0;\nfunction generateId() {\n return `headless-ui-${++count}`;\n}\n\n/**\n * Hook for generating stable, unique IDs.\n * Uses React's useId when available, with a fallback for older versions.\n */\nexport function useStableId(idProp?: string): string {\n const [id] = React.useState(() => idProp || generateId());\n return idProp || id;\n}\n","/**\n * Composes multiple refs into a single ref callback.\n * Useful when you need to forward a ref while also using it internally.\n */\nexport function composeRefs<T>(...refs: Array<React.Ref<T> | undefined>) {\n return (node: T | null) => {\n refs.forEach((ref) => {\n if (!ref) return;\n\n if (typeof ref === 'function') {\n ref(node);\n } else {\n (ref as React.MutableRefObject<T | null>).current = node;\n }\n });\n };\n}\n","import * as React from 'react';\nimport { composeRefs } from '../utils/compose-refs';\n\ninterface SlotProps extends React.HTMLAttributes<HTMLElement> {\n children?: React.ReactNode;\n}\n\n/**\n * Slot component for the asChild pattern.\n * When asChild is true, merges props with the child element instead of rendering a wrapper.\n */\nexport const Slot = React.forwardRef<HTMLElement, SlotProps>(\n (props, forwardedRef) => {\n const { children, ...slotProps } = props;\n\n if (!React.isValidElement(children)) {\n return null;\n }\n\n return React.cloneElement(children, {\n ...mergeProps(slotProps, children.props),\n ref: forwardedRef\n ? composeRefs(forwardedRef, (children as any).ref)\n : (children as any).ref,\n });\n }\n);\n\nSlot.displayName = 'Slot';\n\n/**\n * Merges props from the Slot with props from the child element.\n * Event handlers are composed, other props from child take precedence.\n */\nfunction mergeProps(slotProps: any, childProps: any) {\n const merged = { ...childProps };\n\n for (const key in childProps) {\n const slotValue = slotProps[key];\n const childValue = childProps[key];\n\n // Compose event handlers\n if (/^on[A-Z]/.test(key)) {\n if (slotValue && childValue) {\n merged[key] = (...args: any[]) => {\n childValue(...args);\n slotValue(...args);\n };\n } else if (slotValue) {\n merged[key] = slotValue;\n }\n }\n // Child props take precedence for non-event handlers\n else if (key === 'style') {\n merged[key] = { ...slotValue, ...childValue };\n } else if (key === 'className') {\n merged[key] = [slotValue, childValue].filter(Boolean).join(' ');\n }\n }\n\n // Add slot props that don't exist in child\n for (const key in slotProps) {\n if (!(key in childProps)) {\n merged[key] = slotProps[key];\n }\n }\n\n return merged;\n}\n","import * as React from 'react';\n\nexport interface DialogContextValue {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n triggerRef: React.RefObject<HTMLElement | null>;\n contentRef: React.RefObject<HTMLElement | null>;\n titleId: string;\n descriptionId: string;\n}\n\nexport const DialogContext = React.createContext<DialogContextValue | null>(\n null\n);\n\n/**\n * Hook to access Dialog context.\n * Throws an error if used outside of a Dialog component.\n */\nexport function useDialogContext(componentName: string): DialogContextValue {\n const context = React.useContext(DialogContext);\n\n if (!context) {\n throw new Error(\n `<${componentName}> must be used within a <Dialog> component.`\n );\n }\n\n return context;\n}\n","import * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport { useControlled } from '../../hooks/use-controlled';\nimport { useFocusTrap } from '../../hooks/use-focus-trap';\nimport { useEscapeKeydown } from '../../hooks/use-escape-keydown';\nimport { useBodyScrollLock } from '../../hooks/use-body-scroll-lock';\nimport { useStableId } from '../../hooks/use-id';\nimport { Slot } from '../../primitives/slot';\nimport { DialogContext, useDialogContext } from './dialog-context';\nimport type {\n DialogProps,\n DialogTriggerProps,\n DialogPortalProps,\n DialogOverlayProps,\n DialogContentProps,\n DialogTitleProps,\n DialogDescriptionProps,\n DialogCloseProps,\n} from './types';\n\n/**\n * Dialog Root Component\n * \n * Provides context for all Dialog sub-components.\n * Supports both controlled and uncontrolled state.\n * \n * @example\n * // Controlled\n * <Dialog open={open} onOpenChange={setOpen}>\n * ...\n * </Dialog>\n * \n * // Uncontrolled\n * <Dialog defaultOpen={false}>\n * ...\n * </Dialog>\n */\nexport function Dialog({\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n children,\n}: DialogProps) {\n const [open, setOpen] = useControlled({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const triggerRef = React.useRef<HTMLElement>(null);\n const contentRef = React.useRef<HTMLElement>(null);\n const titleId = useStableId();\n const descriptionId = useStableId();\n\n const contextValue = React.useMemo(\n () => ({\n open,\n onOpenChange: setOpen,\n triggerRef,\n contentRef,\n titleId,\n descriptionId,\n }),\n [open, setOpen, titleId, descriptionId]\n );\n\n return (\n <DialogContext.Provider value={contextValue}>\n {children}\n </DialogContext.Provider>\n );\n}\n\n/**\n * Dialog Trigger Component\n * \n * Button that opens the dialog when clicked.\n * Supports asChild pattern for custom elements.\n * \n * @example\n * <Dialog.Trigger>Open Dialog</Dialog.Trigger>\n * \n * // With asChild\n * <Dialog.Trigger asChild>\n * <button className=\"custom-button\">Open</button>\n * </Dialog.Trigger>\n */\nconst DialogTrigger = React.forwardRef<HTMLButtonElement, DialogTriggerProps>(\n ({ asChild = false, children, onClick, ...props }, forwardedRef) => {\n const { onOpenChange, triggerRef } = useDialogContext('Dialog.Trigger');\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n onOpenChange(true);\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={(node: any) => {\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else {\n forwardedRef.current = node;\n }\n }\n (triggerRef as React.MutableRefObject<HTMLElement | null>).current =\n node;\n }}\n type={asChild ? undefined : 'button'}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n );\n }\n);\n\nDialogTrigger.displayName = 'Dialog.Trigger';\n\n/**\n * Dialog Portal Component\n * \n * Renders children in a portal outside the DOM hierarchy.\n * Only renders when dialog is open.\n * \n * @example\n * <Dialog.Portal>\n * <Dialog.Overlay />\n * <Dialog.Content>...</Dialog.Content>\n * </Dialog.Portal>\n */\nfunction DialogPortal({ container, children }: DialogPortalProps) {\n const { open } = useDialogContext('Dialog.Portal');\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!open || !mounted) return null;\n\n return ReactDOM.createPortal(\n children,\n container || document.body\n );\n}\n\n/**\n * Dialog Overlay Component\n * \n * Semi-transparent backdrop behind the dialog.\n * Clicking it closes the dialog.\n * \n * @example\n * <Dialog.Overlay style={{ backgroundColor: 'rgba(0, 0, 0, 0.5)' }} />\n */\nconst DialogOverlay = React.forwardRef<HTMLDivElement, DialogOverlayProps>(\n ({ onClick, ...props }, forwardedRef) => {\n const { onOpenChange } = useDialogContext('Dialog.Overlay');\n\n const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n onOpenChange(false);\n };\n\n return (\n <div\n ref={forwardedRef}\n onClick={handleClick}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 9998,\n }}\n {...props}\n />\n );\n }\n);\n\nDialogOverlay.displayName = 'Dialog.Overlay';\n\n/**\n * Dialog Content Component\n * \n * Main container for dialog content.\n * Implements focus trap, keyboard handling, and ARIA attributes.\n * \n * @example\n * <Dialog.Content>\n * <Dialog.Title>Title</Dialog.Title>\n * <Dialog.Description>Description</Dialog.Description>\n * <Dialog.Close>Close</Dialog.Close>\n * </Dialog.Content>\n */\nconst DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps>(\n (\n { onEscapeKeyDown, onOverlayClick, children, ...props },\n forwardedRef\n ) => {\n const { open, onOpenChange, contentRef, titleId, descriptionId } =\n useDialogContext('Dialog.Content');\n\n // Focus trap\n useFocusTrap(contentRef, open, true);\n\n // Body scroll lock\n useBodyScrollLock(open);\n\n // Escape key handling\n useEscapeKeydown(\n (event) => {\n onEscapeKeyDown?.(event);\n onOpenChange(false);\n },\n open\n );\n\n // Prevent clicks inside content from closing dialog\n const handleContentClick = (event: React.MouseEvent<HTMLDivElement>) => {\n event.stopPropagation();\n };\n\n return (\n <div\n ref={(node) => {\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else {\n forwardedRef.current = node;\n }\n }\n (contentRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={descriptionId}\n onClick={handleContentClick}\n style={{\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 9999,\n }}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nDialogContent.displayName = 'Dialog.Content';\n\n/**\n * Dialog Title Component\n * \n * Title for the dialog, linked via aria-labelledby.\n * \n * @example\n * <Dialog.Title>Confirm Action</Dialog.Title>\n */\nconst DialogTitle = React.forwardRef<HTMLHeadingElement, DialogTitleProps>(\n ({ children, ...props }, forwardedRef) => {\n const { titleId } = useDialogContext('Dialog.Title');\n\n return (\n <h2 ref={forwardedRef} id={titleId} {...props}>\n {children}\n </h2>\n );\n }\n);\n\nDialogTitle.displayName = 'Dialog.Title';\n\n/**\n * Dialog Description Component\n * \n * Description for the dialog, linked via aria-describedby.\n * \n * @example\n * <Dialog.Description>This action cannot be undone.</Dialog.Description>\n */\nconst DialogDescription = React.forwardRef<\n HTMLParagraphElement,\n DialogDescriptionProps\n>(({ children, ...props }, forwardedRef) => {\n const { descriptionId } = useDialogContext('Dialog.Description');\n\n return (\n <p ref={forwardedRef} id={descriptionId} {...props}>\n {children}\n </p>\n );\n});\n\nDialogDescription.displayName = 'Dialog.Description';\n\n/**\n * Dialog Close Component\n * \n * Button that closes the dialog when clicked.\n * Supports asChild pattern for custom elements.\n * \n * @example\n * <Dialog.Close>Cancel</Dialog.Close>\n * \n * // With asChild\n * <Dialog.Close asChild>\n * <button className=\"custom-button\">Close</button>\n * </Dialog.Close>\n */\nconst DialogClose = React.forwardRef<HTMLButtonElement, DialogCloseProps>(\n ({ asChild = false, children, onClick, ...props }, forwardedRef) => {\n const { onOpenChange } = useDialogContext('Dialog.Close');\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n onOpenChange(false);\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={forwardedRef}\n type={asChild ? undefined : 'button'}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n );\n }\n);\n\nDialogClose.displayName = 'Dialog.Close';\n\n// Attach sub-components to Dialog\nDialog.Trigger = DialogTrigger;\nDialog.Portal = DialogPortal;\nDialog.Overlay = DialogOverlay;\nDialog.Content = DialogContent;\nDialog.Title = DialogTitle;\nDialog.Description = DialogDescription;\nDialog.Close = DialogClose;\n\n// Type augmentation for compound components\nexport interface DialogComponent extends React.FC<DialogProps> {\n Trigger: typeof DialogTrigger;\n Portal: typeof DialogPortal;\n Overlay: typeof DialogOverlay;\n Content: typeof DialogContent;\n Title: typeof DialogTitle;\n Description: typeof DialogDescription;\n Close: typeof DialogClose;\n}\n\nexport default Dialog as DialogComponent;\n","import * as React from 'react';\nimport { Slot } from '../../primitives/slot';\nimport { ButtonProps } from './types';\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return <Comp ref={ref} {...props} />;\n }\n);\n\nButton.displayName = 'Button';\n\nexport default Button;\n"]}
1
+ {"version":3,"sources":["../src/hooks/use-controlled.ts","../src/hooks/use-focus-trap.ts","../src/hooks/use-escape-keydown.ts","../src/hooks/use-body-scroll-lock.ts","../src/hooks/use-id.ts","../src/utils/compose-refs.ts","../src/primitives/slot.tsx","../src/components/dialog/dialog-context.ts","../src/components/dialog/dialog.tsx","../src/components/button/button.tsx","../src/hooks/use-click-outside.ts","../src/components/dropdown/dropdown.tsx"],"names":["React","React2","React3","React4","React5","React6","React7","React9","jsx","useEffect","React10","createPortal"],"mappings":"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","file":"index.mjs","sourcesContent":["import * as React from 'react';\n\ninterface UseControlledOptions<T> {\n /** Controlled value */\n value?: T;\n /** Default value for uncontrolled mode */\n defaultValue?: T;\n /** Change handler */\n onChange?: (value: T) => void;\n}\n\n/**\n * Hook for managing controlled/uncontrolled state pattern.\n * Supports both controlled (value + onChange) and uncontrolled (defaultValue) modes.\n * \n * @example\n * // Controlled\n * const [value, setValue] = useControlled({ value: externalValue, onChange: setExternalValue });\n * \n * // Uncontrolled\n * const [value, setValue] = useControlled({ defaultValue: false });\n */\nexport function useControlled<T>({\n value: valueProp,\n defaultValue,\n onChange,\n}: UseControlledOptions<T>): [T, (newValue: T) => void] {\n const [valueState, setValueState] = React.useState<T>(defaultValue as T);\n const isControlled = valueProp !== undefined;\n\n const value = isControlled ? valueProp : valueState;\n\n const setValue = React.useCallback(\n (newValue: T) => {\n if (!isControlled) {\n setValueState(newValue);\n }\n onChange?.(newValue);\n },\n [isControlled, onChange]\n );\n\n return [value as T, setValue];\n}\n","import * as React from 'react';\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'textarea:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\n/**\n * Hook for trapping focus within a container.\n * Handles Tab/Shift+Tab cycling and prevents focus escape.\n * \n * @param containerRef - Ref to the container element\n * @param enabled - Whether the focus trap is active\n * @param autoFocus - Whether to auto-focus the first element on mount\n */\nexport function useFocusTrap(\n containerRef: React.RefObject<HTMLElement | null>,\n enabled = true,\n autoFocus = true\n) {\n const previouslyFocusedElement = React.useRef<HTMLElement | null>(null);\n\n React.useEffect(() => {\n if (!enabled || !containerRef.current) return;\n\n const container = containerRef.current;\n\n // Store the previously focused element\n previouslyFocusedElement.current = document.activeElement as HTMLElement;\n\n // Get all focusable elements\n const getFocusableElements = (): HTMLElement[] => {\n return Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)\n );\n };\n\n // Auto-focus first element if enabled\n if (autoFocus) {\n const focusableElements = getFocusableElements();\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n }\n }\n\n // Handle Tab key to cycle focus\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return;\n\n const focusableElements = getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (event.shiftKey) {\n // Shift + Tab: move focus to last element if on first\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n // Tab: move focus to first element if on last\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n\n return () => {\n container.removeEventListener('keydown', handleKeyDown);\n\n // Restore focus to previously focused element\n if (previouslyFocusedElement.current) {\n previouslyFocusedElement.current.focus();\n }\n };\n }, [enabled, autoFocus, containerRef]);\n}\n","import * as React from 'react';\n\n/**\n * Hook for handling Escape key press events.\n * Automatically cleans up event listener on unmount.\n */\nexport function useEscapeKeydown(\n handler: (event: KeyboardEvent) => void,\n enabled = true\n) {\n React.useEffect(() => {\n if (!enabled) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n handler(event);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [handler, enabled]);\n}\n","import * as React from 'react';\n\n/**\n * Hook for preventing body scroll when a modal/dialog is open.\n * This is an accessibility requirement to prevent background scrolling.\n */\nexport function useBodyScrollLock(enabled = true) {\n React.useEffect(() => {\n if (!enabled) return;\n\n const originalOverflow = document.body.style.overflow;\n const originalPaddingRight = document.body.style.paddingRight;\n\n // Prevent scroll\n document.body.style.overflow = 'hidden';\n\n // Prevent layout shift by adding padding to compensate for scrollbar\n const scrollbarWidth =\n window.innerWidth - document.documentElement.clientWidth;\n if (scrollbarWidth > 0) {\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n }\n\n return () => {\n document.body.style.overflow = originalOverflow;\n document.body.style.paddingRight = originalPaddingRight;\n };\n }, [enabled]);\n}\n","import * as React from 'react';\n\nlet count = 0;\nfunction generateId() {\n return `headless-ui-${++count}`;\n}\n\n/**\n * Hook for generating stable, unique IDs.\n * Uses React's useId when available, with a fallback for older versions.\n */\nexport function useStableId(idProp?: string): string {\n const [id] = React.useState(() => idProp || generateId());\n return idProp || id;\n}\n","/**\n * Composes multiple refs into a single ref callback.\n * Useful when you need to forward a ref while also using it internally.\n */\nexport function composeRefs<T>(...refs: Array<React.Ref<T> | undefined>) {\n return (node: T | null) => {\n refs.forEach((ref) => {\n if (!ref) return;\n\n if (typeof ref === 'function') {\n ref(node);\n } else {\n (ref as React.MutableRefObject<T | null>).current = node;\n }\n });\n };\n}\n","import * as React from 'react';\nimport { composeRefs } from '../utils/compose-refs';\n\ninterface SlotProps extends React.HTMLAttributes<HTMLElement> {\n children?: React.ReactNode;\n}\n\n/**\n * Slot component for the asChild pattern.\n * When asChild is true, merges props with the child element instead of rendering a wrapper.\n */\nexport const Slot = React.forwardRef<HTMLElement, SlotProps>(\n (props, forwardedRef) => {\n const { children, ...slotProps } = props;\n\n if (!React.isValidElement(children)) {\n return null;\n }\n\n return React.cloneElement(children, {\n ...mergeProps(slotProps, children.props),\n ref: forwardedRef\n ? composeRefs(forwardedRef, (children as any).ref)\n : (children as any).ref,\n });\n }\n);\n\nSlot.displayName = 'Slot';\n\n/**\n * Merges props from the Slot with props from the child element.\n * Event handlers are composed, other props from child take precedence.\n */\nfunction mergeProps(slotProps: any, childProps: any) {\n const merged = { ...childProps };\n\n for (const key in childProps) {\n const slotValue = slotProps[key];\n const childValue = childProps[key];\n\n // Compose event handlers\n if (/^on[A-Z]/.test(key)) {\n if (slotValue && childValue) {\n merged[key] = (...args: any[]) => {\n childValue(...args);\n slotValue(...args);\n };\n } else if (slotValue) {\n merged[key] = slotValue;\n }\n }\n // Child props take precedence for non-event handlers\n else if (key === 'style') {\n merged[key] = { ...slotValue, ...childValue };\n } else if (key === 'className') {\n merged[key] = [slotValue, childValue].filter(Boolean).join(' ');\n }\n }\n\n // Add slot props that don't exist in child\n for (const key in slotProps) {\n if (!(key in childProps)) {\n merged[key] = slotProps[key];\n }\n }\n\n return merged;\n}\n","import * as React from 'react';\n\nexport interface DialogContextValue {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n triggerRef: React.RefObject<HTMLElement | null>;\n contentRef: React.RefObject<HTMLElement | null>;\n titleId: string;\n descriptionId: string;\n}\n\nexport const DialogContext = React.createContext<DialogContextValue | null>(\n null\n);\n\n/**\n * Hook to access Dialog context.\n * Throws an error if used outside of a Dialog component.\n */\nexport function useDialogContext(componentName: string): DialogContextValue {\n const context = React.useContext(DialogContext);\n\n if (!context) {\n throw new Error(\n `<${componentName}> must be used within a <Dialog> component.`\n );\n }\n\n return context;\n}\n","import * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport { useControlled } from '../../hooks/use-controlled';\nimport { useFocusTrap } from '../../hooks/use-focus-trap';\nimport { useEscapeKeydown } from '../../hooks/use-escape-keydown';\nimport { useBodyScrollLock } from '../../hooks/use-body-scroll-lock';\nimport { useStableId } from '../../hooks/use-id';\nimport { Slot } from '../../primitives/slot';\nimport { DialogContext, useDialogContext } from './dialog-context';\nimport type {\n DialogProps,\n DialogTriggerProps,\n DialogPortalProps,\n DialogOverlayProps,\n DialogContentProps,\n DialogTitleProps,\n DialogDescriptionProps,\n DialogCloseProps,\n} from './types';\n\n/**\n * Dialog Root Component\n * \n * Provides context for all Dialog sub-components.\n * Supports both controlled and uncontrolled state.\n * \n * @example\n * // Controlled\n * <Dialog open={open} onOpenChange={setOpen}>\n * ...\n * </Dialog>\n * \n * // Uncontrolled\n * <Dialog defaultOpen={false}>\n * ...\n * </Dialog>\n */\nexport function Dialog({\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n children,\n}: DialogProps) {\n const [open, setOpen] = useControlled({\n value: openProp,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const triggerRef = React.useRef<HTMLElement>(null);\n const contentRef = React.useRef<HTMLElement>(null);\n const titleId = useStableId();\n const descriptionId = useStableId();\n\n const contextValue = React.useMemo(\n () => ({\n open,\n onOpenChange: setOpen,\n triggerRef,\n contentRef,\n titleId,\n descriptionId,\n }),\n [open, setOpen, titleId, descriptionId]\n );\n\n return (\n <DialogContext.Provider value={contextValue}>\n {children}\n </DialogContext.Provider>\n );\n}\n\n/**\n * Dialog Trigger Component\n * \n * Button that opens the dialog when clicked.\n * Supports asChild pattern for custom elements.\n * \n * @example\n * <Dialog.Trigger>Open Dialog</Dialog.Trigger>\n * \n * // With asChild\n * <Dialog.Trigger asChild>\n * <button className=\"custom-button\">Open</button>\n * </Dialog.Trigger>\n */\nconst DialogTrigger = React.forwardRef<HTMLButtonElement, DialogTriggerProps>(\n ({ asChild = false, children, onClick, ...props }, forwardedRef) => {\n const { onOpenChange, triggerRef } = useDialogContext('Dialog.Trigger');\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n onOpenChange(true);\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={(node: any) => {\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else {\n forwardedRef.current = node;\n }\n }\n (triggerRef as React.MutableRefObject<HTMLElement | null>).current =\n node;\n }}\n type={asChild ? undefined : 'button'}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n );\n }\n);\n\nDialogTrigger.displayName = 'Dialog.Trigger';\n\n/**\n * Dialog Portal Component\n * \n * Renders children in a portal outside the DOM hierarchy.\n * Only renders when dialog is open.\n * \n * @example\n * <Dialog.Portal>\n * <Dialog.Overlay />\n * <Dialog.Content>...</Dialog.Content>\n * </Dialog.Portal>\n */\nfunction DialogPortal({ container, children }: DialogPortalProps) {\n const { open } = useDialogContext('Dialog.Portal');\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!open || !mounted) return null;\n\n return ReactDOM.createPortal(\n children,\n container || document.body\n );\n}\n\n/**\n * Dialog Overlay Component\n * \n * Semi-transparent backdrop behind the dialog.\n * Clicking it closes the dialog.\n * \n * @example\n * <Dialog.Overlay style={{ backgroundColor: 'rgba(0, 0, 0, 0.5)' }} />\n */\nconst DialogOverlay = React.forwardRef<HTMLDivElement, DialogOverlayProps>(\n ({ onClick, ...props }, forwardedRef) => {\n const { onOpenChange } = useDialogContext('Dialog.Overlay');\n\n const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n onOpenChange(false);\n };\n\n return (\n <div\n ref={forwardedRef}\n onClick={handleClick}\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 9998,\n }}\n {...props}\n />\n );\n }\n);\n\nDialogOverlay.displayName = 'Dialog.Overlay';\n\n/**\n * Dialog Content Component\n * \n * Main container for dialog content.\n * Implements focus trap, keyboard handling, and ARIA attributes.\n * \n * @example\n * <Dialog.Content>\n * <Dialog.Title>Title</Dialog.Title>\n * <Dialog.Description>Description</Dialog.Description>\n * <Dialog.Close>Close</Dialog.Close>\n * </Dialog.Content>\n */\nconst DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps>(\n (\n { onEscapeKeyDown, onOverlayClick, children, ...props },\n forwardedRef\n ) => {\n const { open, onOpenChange, contentRef, titleId, descriptionId } =\n useDialogContext('Dialog.Content');\n\n // Focus trap\n useFocusTrap(contentRef, open, true);\n\n // Body scroll lock\n useBodyScrollLock(open);\n\n // Escape key handling\n useEscapeKeydown(\n (event) => {\n onEscapeKeyDown?.(event);\n onOpenChange(false);\n },\n open\n );\n\n // Prevent clicks inside content from closing dialog\n const handleContentClick = (event: React.MouseEvent<HTMLDivElement>) => {\n event.stopPropagation();\n };\n\n return (\n <div\n ref={(node) => {\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n forwardedRef(node);\n } else {\n forwardedRef.current = node;\n }\n }\n (contentRef as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={descriptionId}\n onClick={handleContentClick}\n style={{\n position: 'fixed',\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n zIndex: 9999,\n }}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nDialogContent.displayName = 'Dialog.Content';\n\n/**\n * Dialog Title Component\n * \n * Title for the dialog, linked via aria-labelledby.\n * \n * @example\n * <Dialog.Title>Confirm Action</Dialog.Title>\n */\nconst DialogTitle = React.forwardRef<HTMLHeadingElement, DialogTitleProps>(\n ({ children, ...props }, forwardedRef) => {\n const { titleId } = useDialogContext('Dialog.Title');\n\n return (\n <h2 ref={forwardedRef} id={titleId} {...props}>\n {children}\n </h2>\n );\n }\n);\n\nDialogTitle.displayName = 'Dialog.Title';\n\n/**\n * Dialog Description Component\n * \n * Description for the dialog, linked via aria-describedby.\n * \n * @example\n * <Dialog.Description>This action cannot be undone.</Dialog.Description>\n */\nconst DialogDescription = React.forwardRef<\n HTMLParagraphElement,\n DialogDescriptionProps\n>(({ children, ...props }, forwardedRef) => {\n const { descriptionId } = useDialogContext('Dialog.Description');\n\n return (\n <p ref={forwardedRef} id={descriptionId} {...props}>\n {children}\n </p>\n );\n});\n\nDialogDescription.displayName = 'Dialog.Description';\n\n/**\n * Dialog Close Component\n * \n * Button that closes the dialog when clicked.\n * Supports asChild pattern for custom elements.\n * \n * @example\n * <Dialog.Close>Cancel</Dialog.Close>\n * \n * // With asChild\n * <Dialog.Close asChild>\n * <button className=\"custom-button\">Close</button>\n * </Dialog.Close>\n */\nconst DialogClose = React.forwardRef<HTMLButtonElement, DialogCloseProps>(\n ({ asChild = false, children, onClick, ...props }, forwardedRef) => {\n const { onOpenChange } = useDialogContext('Dialog.Close');\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n onOpenChange(false);\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={forwardedRef}\n type={asChild ? undefined : 'button'}\n onClick={handleClick}\n {...props}\n >\n {children}\n </Comp>\n );\n }\n);\n\nDialogClose.displayName = 'Dialog.Close';\n\n// Attach sub-components to Dialog\nDialog.Trigger = DialogTrigger;\nDialog.Portal = DialogPortal;\nDialog.Overlay = DialogOverlay;\nDialog.Content = DialogContent;\nDialog.Title = DialogTitle;\nDialog.Description = DialogDescription;\nDialog.Close = DialogClose;\n\n// Type augmentation for compound components\nexport interface DialogComponent extends React.FC<DialogProps> {\n Trigger: typeof DialogTrigger;\n Portal: typeof DialogPortal;\n Overlay: typeof DialogOverlay;\n Content: typeof DialogContent;\n Title: typeof DialogTitle;\n Description: typeof DialogDescription;\n Close: typeof DialogClose;\n}\n\nexport default Dialog as DialogComponent;\n","import * as React from 'react';\nimport { Slot } from '../../primitives/slot';\nimport { ButtonProps } from './types';\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return <Comp ref={ref} {...props} />;\n }\n);\n\nButton.displayName = 'Button';\n\nexport default Button;\n","import { useEffect } from 'react';\n\ntype Handler = (event: MouseEvent | TouchEvent) => void;\n\nexport function useClickOutside(\n ref: React.RefObject<HTMLElement | null>,\n handler: Handler,\n enabled: boolean = true\n) {\n useEffect(() => {\n if (!enabled) return;\n\n const listener = (event: MouseEvent | TouchEvent) => {\n const el = ref.current;\n if (!el || el.contains(event.target as Node)) {\n return;\n }\n handler(event);\n };\n\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n\n return () => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n };\n }, [ref, handler, enabled]);\n}\n","import * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { useControlled } from '../../hooks/use-controlled';\nimport { useClickOutside } from '../../hooks/use-click-outside';\nimport { useEscapeKeydown } from '../../hooks/use-escape-keydown';\nimport { Slot } from '../../primitives/slot';\nimport { composeRefs } from '../../utils/compose-refs';\nimport {\n DropdownProps,\n DropdownTriggerProps,\n DropdownContentProps,\n DropdownItemProps,\n DropdownContextValue,\n} from './types';\n\nconst DropdownContext = React.createContext<DropdownContextValue | undefined>(undefined);\n\nconst useDropdown = () => {\n const context = React.useContext(DropdownContext);\n if (!context) {\n throw new Error('useDropdown must be used within a Dropdown');\n }\n return context;\n};\n\nexport function Dropdown({\n children,\n open: openProp,\n onOpenChange: setOpenProp,\n defaultOpen = false,\n}: DropdownProps) {\n const [open, setOpen] = useControlled({\n value: openProp,\n onChange: setOpenProp,\n defaultValue: defaultOpen,\n });\n\n const triggerRef = React.useRef<HTMLButtonElement>(null);\n\n const contextValue = React.useMemo(\n () => ({\n open: !!open,\n onOpenChange: setOpen,\n triggerRef,\n }),\n [open, setOpen]\n );\n\n return (\n <DropdownContext.Provider value={contextValue}>\n {children}\n </DropdownContext.Provider>\n );\n}\n\nconst DropdownTrigger = React.forwardRef<HTMLButtonElement, DropdownTriggerProps>(\n ({ asChild, onClick, ...props }, ref) => {\n const { open, onOpenChange, triggerRef } = useDropdown();\n const Comp = asChild ? Slot : 'button';\n const composedRef = composeRefs(ref, triggerRef);\n\n return (\n <Comp\n ref={composedRef}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n data-state={open ? 'open' : 'closed'}\n onClick={(e) => {\n onClick?.(e);\n onOpenChange(!open);\n }}\n {...props}\n />\n );\n }\n);\nDropdownTrigger.displayName = 'Dropdown.Trigger';\n\nconst DropdownContent = React.forwardRef<HTMLDivElement, DropdownContentProps>(\n ({ children, style, sideOffset = 4, align = 'center', ...props }, ref) => {\n const { open, onOpenChange, triggerRef } = useDropdown();\n const contentRef = React.useRef<HTMLDivElement>(null);\n const composedRef = composeRefs(ref, contentRef);\n const [position, setPosition] = React.useState<{ top: number; left: number }>({ top: 0, left: 0 });\n\n useClickOutside(contentRef, (e) => {\n // Ignore clicks on the trigger to avoid double-toggling\n if (triggerRef.current?.contains(e.target as Node)) {\n return;\n }\n onOpenChange(false);\n }, open);\n\n useEscapeKeydown(() => onOpenChange(false));\n\n React.useEffect(() => {\n if (open && triggerRef.current && contentRef.current) {\n const triggerRect = triggerRef.current.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n \n let top = triggerRect.bottom + sideOffset + window.scrollY;\n let left = triggerRect.left + window.scrollX;\n \n if (align === 'center') {\n left = triggerRect.left + window.scrollX + (triggerRect.width / 2) - (contentRect.width / 2);\n } else if (align === 'end') {\n left = triggerRect.right + window.scrollX - contentRect.width;\n }\n \n // Basic boundary check (optional, can be improved)\n // if (left < 0) left = 10;\n \n setPosition({ top, left });\n }\n }, [open, sideOffset, align]);\n\n if (!open) return null;\n\n return createPortal(\n <div\n ref={composedRef}\n role=\"menu\"\n style={{\n position: 'absolute',\n top: position.top,\n left: position.left,\n zIndex: 50,\n ...style,\n }}\n data-state={open ? 'open' : 'closed'}\n {...props}\n >\n {children}\n </div>,\n document.body\n );\n }\n);\nDropdownContent.displayName = 'Dropdown.Content';\n\nconst DropdownItem = React.forwardRef<HTMLDivElement, DropdownItemProps>(\n ({ asChild, onClick, onSelect, disabled, ...props }, ref) => {\n const { onOpenChange } = useDropdown();\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n ref={ref}\n role=\"menuitem\"\n aria-disabled={disabled}\n data-disabled={disabled}\n onClick={(e) => {\n if (disabled) return;\n onClick?.(e);\n onSelect?.(e);\n onOpenChange(false);\n }}\n {...props}\n />\n );\n }\n);\nDropdownItem.displayName = 'Dropdown.Item';\n\n// Attach subcomponents\nconst DropdownRoot = Dropdown as any;\nDropdownRoot.Trigger = DropdownTrigger;\nDropdownRoot.Content = DropdownContent;\nDropdownRoot.Item = DropdownItem;\n\nexport default DropdownRoot;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alankrit2/ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Production-quality, headless, accessible React UI components",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",