@puzzle-ui/ui 0.4.0 → 0.5.1
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/README.md +61 -77
- package/dist/components/actions/button/button.css +5 -2
- package/dist/components/actions/button-group/button-group.css +16 -17
- package/dist/components/data-display/badge/badge.css +15 -2
- package/dist/components/data-display/badge/index.cjs +13 -2
- package/dist/components/data-display/badge/index.cjs.map +1 -1
- package/dist/components/data-display/badge/index.d.cts +7 -2
- package/dist/components/data-display/badge/index.d.ts +7 -2
- package/dist/components/data-display/badge/index.js +13 -2
- package/dist/components/data-display/badge/index.js.map +1 -1
- package/dist/components/data-display/rating/index.cjs +84 -0
- package/dist/components/data-display/rating/index.cjs.map +1 -0
- package/dist/components/data-display/rating/index.d.cts +3 -0
- package/dist/components/data-display/rating/index.d.ts +3 -0
- package/dist/components/data-display/rating/index.js +84 -0
- package/dist/components/data-display/rating/index.js.map +1 -0
- package/dist/components/data-display/rating/rating.css +72 -0
- package/dist/components/data-display/rating/rating.types.d.cts +15 -0
- package/dist/components/data-display/rating/rating.types.d.ts +15 -0
- package/dist/components/data-display/rating/rating.utils.cjs +27 -0
- package/dist/components/data-display/rating/rating.utils.cjs.map +1 -0
- package/dist/components/data-display/rating/rating.utils.js +25 -0
- package/dist/components/data-display/rating/rating.utils.js.map +1 -0
- package/dist/components/forms/checkbox/checkbox.css +2 -10
- package/dist/components/forms/input-group/input-group.d.cts +4 -2
- package/dist/components/forms/input-group/input-group.d.ts +4 -2
- package/dist/components/forms/radio-group/index.d.cts +2 -1
- package/dist/components/forms/radio-group/index.d.ts +2 -1
- package/dist/components/forms/stepper/index.d.cts +4 -2
- package/dist/components/forms/stepper/index.d.ts +4 -2
- package/dist/components/forms/time-picker/index.cjs +108 -0
- package/dist/components/forms/time-picker/index.cjs.map +1 -0
- package/dist/components/forms/time-picker/index.d.cts +3 -0
- package/dist/components/forms/time-picker/index.d.ts +3 -0
- package/dist/components/forms/time-picker/index.js +108 -0
- package/dist/components/forms/time-picker/index.js.map +1 -0
- package/dist/components/forms/time-picker/time-picker.css +166 -0
- package/dist/components/forms/time-picker/time-picker.types.d.cts +34 -0
- package/dist/components/forms/time-picker/time-picker.types.d.ts +34 -0
- package/dist/components/forms/time-picker/time-picker.utils.cjs +25 -0
- package/dist/components/forms/time-picker/time-picker.utils.cjs.map +1 -0
- package/dist/components/forms/time-picker/time-picker.utils.js +24 -0
- package/dist/components/forms/time-picker/time-picker.utils.js.map +1 -0
- package/dist/components/forms/token-input/index.cjs +189 -0
- package/dist/components/forms/token-input/index.cjs.map +1 -0
- package/dist/components/forms/token-input/index.d.cts +3 -0
- package/dist/components/forms/token-input/index.d.ts +3 -0
- package/dist/components/forms/token-input/index.js +189 -0
- package/dist/components/forms/token-input/index.js.map +1 -0
- package/dist/components/forms/token-input/token-input.css +145 -0
- package/dist/components/forms/token-input/token-input.types.d.cts +48 -0
- package/dist/components/forms/token-input/token-input.types.d.ts +48 -0
- package/dist/components/forms/token-input/token-input.utils.cjs +30 -0
- package/dist/components/forms/token-input/token-input.utils.cjs.map +1 -0
- package/dist/components/forms/token-input/token-input.utils.js +24 -0
- package/dist/components/forms/token-input/token-input.utils.js.map +1 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.css +14 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.cjs +11 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.cjs.map +1 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.js +11 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio.utils.js.map +1 -0
- package/dist/components/layout/aspect-ratio/index.cjs +16 -0
- package/dist/components/layout/aspect-ratio/index.cjs.map +1 -0
- package/dist/components/layout/aspect-ratio/index.d.cts +11 -0
- package/dist/components/layout/aspect-ratio/index.d.ts +11 -0
- package/dist/components/layout/aspect-ratio/index.js +16 -0
- package/dist/components/layout/aspect-ratio/index.js.map +1 -0
- package/dist/components/layout/container/container.css +1 -0
- package/dist/components/layout/page-layout/page-layout.css +1 -0
- package/dist/components/layout/scroll-area/index.cjs +27 -0
- package/dist/components/layout/scroll-area/index.cjs.map +1 -0
- package/dist/components/layout/scroll-area/index.d.cts +15 -0
- package/dist/components/layout/scroll-area/index.d.ts +15 -0
- package/dist/components/layout/scroll-area/index.js +27 -0
- package/dist/components/layout/scroll-area/index.js.map +1 -0
- package/dist/components/layout/scroll-area/scroll-area.css +25 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.cjs +8 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.cjs.map +1 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.d.cts +2 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.d.ts +2 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.js +8 -0
- package/dist/components/layout/scroll-area/scroll-area.utils.js.map +1 -0
- package/dist/components/layout/section/index.cjs +10 -4
- package/dist/components/layout/section/index.cjs.map +1 -1
- package/dist/components/layout/section/index.d.cts +1 -1
- package/dist/components/layout/section/index.d.ts +1 -1
- package/dist/components/layout/section/index.js +11 -5
- package/dist/components/layout/section/index.js.map +1 -1
- package/dist/components/layout/section/section.css +9 -3
- package/dist/components/layout/section/types.d.cts +5 -5
- package/dist/components/layout/section/types.d.ts +5 -5
- package/dist/components/layout/separator/index.cjs +18 -0
- package/dist/components/layout/separator/index.cjs.map +1 -0
- package/dist/components/layout/separator/index.d.cts +17 -0
- package/dist/components/layout/separator/index.d.ts +17 -0
- package/dist/components/layout/separator/index.js +18 -0
- package/dist/components/layout/separator/index.js.map +1 -0
- package/dist/components/layout/separator/separator.css +15 -0
- package/dist/components/layout/separator/separator.utils.cjs +11 -0
- package/dist/components/layout/separator/separator.utils.cjs.map +1 -0
- package/dist/components/layout/separator/separator.utils.d.cts +2 -0
- package/dist/components/layout/separator/separator.utils.d.ts +2 -0
- package/dist/components/layout/separator/separator.utils.js +11 -0
- package/dist/components/layout/separator/separator.utils.js.map +1 -0
- package/dist/components/layout/stack/index.cjs +18 -2
- package/dist/components/layout/stack/index.cjs.map +1 -1
- package/dist/components/layout/stack/index.d.cts +8 -6
- package/dist/components/layout/stack/index.d.ts +8 -6
- package/dist/components/layout/stack/index.js +18 -2
- package/dist/components/layout/stack/index.js.map +1 -1
- package/dist/components/layout/stack/stack.css +118 -138
- package/dist/components/navigation/carousel/index.cjs +4 -1
- package/dist/components/navigation/carousel/index.cjs.map +1 -1
- package/dist/components/navigation/carousel/index.js +4 -1
- package/dist/components/navigation/carousel/index.js.map +1 -1
- package/dist/components/navigation/tabs/index.d.cts +3 -2
- package/dist/components/navigation/tabs/index.d.ts +3 -2
- package/dist/components/navigation/tree-view/index.cjs +1 -1
- package/dist/components/navigation/tree-view/index.cjs.map +1 -1
- package/dist/components/navigation/tree-view/index.d.cts +5 -1
- package/dist/components/navigation/tree-view/index.d.ts +5 -1
- package/dist/components/navigation/tree-view/index.js +1 -1
- package/dist/components/navigation/tree-view/index.js.map +1 -1
- package/dist/components/navigation/tree-view/tree-view.css +5 -3
- package/dist/components/overlays/context-menu/context-menu.css +151 -0
- package/dist/components/overlays/context-menu/context-menu.types.d.cts +69 -0
- package/dist/components/overlays/context-menu/context-menu.types.d.ts +69 -0
- package/dist/components/overlays/context-menu/context-menu.utils.cjs +46 -0
- package/dist/components/overlays/context-menu/context-menu.utils.cjs.map +1 -0
- package/dist/components/overlays/context-menu/context-menu.utils.js +40 -0
- package/dist/components/overlays/context-menu/context-menu.utils.js.map +1 -0
- package/dist/components/overlays/context-menu/index.cjs +830 -0
- package/dist/components/overlays/context-menu/index.cjs.map +1 -0
- package/dist/components/overlays/context-menu/index.d.cts +42 -0
- package/dist/components/overlays/context-menu/index.d.ts +42 -0
- package/dist/components/overlays/context-menu/index.js +818 -0
- package/dist/components/overlays/context-menu/index.js.map +1 -0
- package/dist/components/typography/heading.cjs +6 -2
- package/dist/components/typography/heading.cjs.map +1 -1
- package/dist/components/typography/heading.d.cts +3 -2
- package/dist/components/typography/heading.d.ts +3 -2
- package/dist/components/typography/heading.js +6 -2
- package/dist/components/typography/heading.js.map +1 -1
- package/dist/components/typography/text.cjs +6 -2
- package/dist/components/typography/text.cjs.map +1 -1
- package/dist/components/typography/text.d.cts +3 -2
- package/dist/components/typography/text.d.ts +3 -2
- package/dist/components/typography/text.js +6 -2
- package/dist/components/typography/text.js.map +1 -1
- package/dist/components/utilities/preview/index.cjs +88 -20
- package/dist/components/utilities/preview/index.cjs.map +1 -1
- package/dist/components/utilities/preview/index.d.cts +6 -2
- package/dist/components/utilities/preview/index.d.ts +6 -2
- package/dist/components/utilities/preview/index.js +88 -20
- package/dist/components/utilities/preview/index.js.map +1 -1
- package/dist/components/utilities/preview/preview.css +26 -11
- package/dist/components/utilities/transition/index.d.cts +1 -1
- package/dist/components/utilities/transition/index.d.ts +1 -1
- package/dist/index.cjs +123 -97
- package/dist/index.d.cts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +8 -1
- package/package.json +11 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/overlays/context-menu/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Children,\n cloneElement,\n createContext,\n forwardRef,\n Fragment,\n isValidElement,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type MutableRefObject,\n type PointerEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefObject,\n} from \"react\";\n\nimport { cn } from \"@puzzle-ui/core\";\n\nimport {\n Popout,\n usePopoutPositioned,\n type PopoutTriggerProps,\n} from \"../popout\";\n\nimport {\n findMenuItemIndexByText,\n findNextMenuItemIndex,\n focusElement,\n getEnabledMenuItems,\n getMenuItemText,\n setRef,\n} from \"./context-menu.utils\";\n\nimport type {\n ContextMenuCheckboxItemProps,\n ContextMenuContentProps,\n ContextMenuGroupProps,\n ContextMenuItemProps,\n ContextMenuLabelProps,\n ContextMenuProps,\n ContextMenuRadioGroupProps,\n ContextMenuRadioItemProps,\n ContextMenuSeparatorProps,\n ContextMenuSubContentProps,\n ContextMenuSubProps,\n ContextMenuSubTriggerProps,\n ContextMenuTriggerProps,\n} from \"./context-menu.types\";\n\nimport \"./context-menu.css\";\n\ntype ContextMenuPoint = {\n x: number;\n y: number;\n};\n\ntype FocusPosition = \"first\" | \"last\";\n\ntype ContextMenuContextValue = {\n open: boolean;\n disabled: boolean;\n triggerId: string;\n contentId: string;\n triggerRef: RefObject<HTMLElement | null>;\n focusPositionRef: RefObject<FocusPosition>;\n openAt: (point: ContextMenuPoint, position?: FocusPosition) => void;\n changeOpen: (open: boolean) => void;\n close: (restoreFocus?: boolean) => void;\n};\n\ntype RadioGroupContextValue = {\n value: string | undefined;\n setValue: (value: string) => void;\n};\n\ntype SubContextValue = {\n open: boolean;\n setOpen: (open: boolean) => void;\n triggerId: string;\n contentId: string;\n triggerRef: MutableRefObject<HTMLButtonElement | null>;\n close: (restoreFocus?: boolean) => void;\n};\n\nconst ContextMenuContext = createContext<ContextMenuContextValue | null>(null);\nconst RadioGroupContext = createContext<RadioGroupContextValue | null>(null);\nconst SubContext = createContext<SubContextValue | null>(null);\n\nconst useContextMenuContext = () => {\n const context = useContext(ContextMenuContext);\n\n if (!context) {\n throw new Error(\n \"ContextMenu components must be rendered inside ContextMenu.\",\n );\n }\n\n return context;\n};\n\nconst useRadioGroupContext = () => {\n const context = useContext(RadioGroupContext);\n\n if (!context) {\n throw new Error(\n \"ContextMenu.RadioItem must be rendered inside ContextMenu.RadioGroup.\",\n );\n }\n\n return context;\n};\n\nconst useSubContext = () => {\n const context = useContext(SubContext);\n\n if (!context) {\n throw new Error(\n \"ContextMenu.SubTrigger and SubContent must be rendered inside ContextMenu.Sub.\",\n );\n }\n\n return context;\n};\n\nconst getMenuElements = (children: ReactNode): ReactElement[] =>\n Children.toArray(children).flatMap((child): ReactElement[] => {\n if (\n isValidElement<{ children?: ReactNode }>(child) &&\n child.type === Fragment\n ) {\n return getMenuElements(child.props.children);\n }\n\n return isValidElement(child) ? [child] : [];\n });\n\nconst ContextMenuRoot = ({\n children,\n open,\n defaultOpen = false,\n onOpenChange,\n disabled = false,\n triggerClassName,\n contentClassName,\n}: ContextMenuProps) => {\n const baseId = useId();\n const triggerId = `${baseId}-trigger`;\n const contentId = `${baseId}-content`;\n\n const childElements = getMenuElements(children);\n const triggers = childElements.filter(\n (child) => child.type === ContextMenuTrigger,\n );\n const contents = childElements.filter(\n (child) => child.type === ContextMenuContent,\n );\n\n const triggerElement = triggers[0] as\n | ReactElement<ContextMenuTriggerProps>\n | undefined;\n const contentElement = contents[0] as\n | ReactElement<ContextMenuContentProps>\n | undefined;\n\n if (\n triggers.length !== 1 ||\n contents.length !== 1 ||\n !triggerElement ||\n !contentElement\n ) {\n throw new Error(\n \"ContextMenu requires exactly one ContextMenu.Trigger and one ContextMenu.Content.\",\n );\n }\n\n const controlled = open !== undefined;\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const triggerDisabled = disabled || triggerElement.props.disabled === true;\n const isOpen =\n !triggerDisabled && (controlled ? (open ?? false) : internalOpen);\n\n const [point, setPoint] = useState<ContextMenuPoint>({\n x: 0,\n y: 0,\n });\n\n const triggerRef = useRef<HTMLElement | null>(null);\n const focusPositionRef = useRef<FocusPosition>(\"first\");\n\n const changeOpen = useCallback(\n (nextOpen: boolean) => {\n if (triggerDisabled && nextOpen) {\n return;\n }\n\n if (nextOpen === isOpen) {\n return;\n }\n\n if (!controlled) {\n setInternalOpen(nextOpen);\n }\n\n onOpenChange?.(nextOpen);\n },\n [controlled, isOpen, onOpenChange, triggerDisabled],\n );\n\n const openAt = useCallback(\n (nextPoint: ContextMenuPoint, position: FocusPosition = \"first\") => {\n if (triggerDisabled) {\n return;\n }\n\n setPoint({\n x: Math.max(0, nextPoint.x),\n y: Math.max(0, nextPoint.y),\n });\n\n focusPositionRef.current = position;\n changeOpen(true);\n },\n [changeOpen, triggerDisabled],\n );\n\n const close = useCallback(\n (restoreFocus = false) => {\n changeOpen(false);\n\n if (restoreFocus) {\n focusElement(triggerRef.current ?? undefined);\n }\n },\n [changeOpen],\n );\n\n const context = useMemo<ContextMenuContextValue>(\n () => ({\n open: isOpen,\n disabled: triggerDisabled,\n triggerId,\n contentId,\n triggerRef,\n focusPositionRef,\n openAt,\n changeOpen,\n close,\n }),\n [isOpen, triggerDisabled, triggerId, contentId, openAt, changeOpen, close],\n );\n\n const trigger = cloneElement(triggerElement, {\n id: triggerId,\n disabled: triggerDisabled,\n className: cn(triggerElement.props.className, triggerClassName),\n });\n\n const content = cloneElement(contentElement, {\n id: contentId,\n className: cn(contentElement.props.className, contentClassName),\n });\n\n const anchor = (\n <span\n aria-hidden=\"true\"\n className=\"puzzle-context-menu__anchor\"\n style={{\n left: point.x,\n top: point.y,\n }}\n tabIndex={-1}\n />\n );\n\n useEffect(() => {\n if (!isOpen || !triggerRef.current) {\n return;\n }\n\n const ownerDocument = triggerRef.current.ownerDocument;\n\n const handleOutsidePointerDown = (event: globalThis.PointerEvent) => {\n const target = event.target;\n\n if (!(target instanceof ownerDocument.defaultView!.Node)) {\n return;\n }\n\n if (\n triggerRef.current?.contains(target) ||\n (target instanceof Element &&\n target.closest(\".puzzle-context-menu__popover\"))\n ) {\n return;\n }\n\n changeOpen(false);\n };\n\n ownerDocument.addEventListener(\n \"pointerdown\",\n handleOutsidePointerDown,\n true,\n );\n\n return () => {\n ownerDocument.removeEventListener(\n \"pointerdown\",\n handleOutsidePointerDown,\n true,\n );\n };\n }, [isOpen, changeOpen]);\n\n return (\n <ContextMenuContext.Provider value={context}>\n {trigger}\n\n <Popout\n trigger={anchor as ReactElement<PopoutTriggerProps>}\n open={isOpen}\n onOpenChange={(nextOpen) => {\n if (nextOpen) {\n changeOpen(true);\n } else {\n close(true);\n }\n }}\n position=\"bottom\"\n align=\"start\"\n offset={0}\n collisionPadding={8}\n closeOnOutsideClick={false}\n closeOnEscape\n contentClassName=\"puzzle-context-menu__popover\"\n >\n {content}\n </Popout>\n </ContextMenuContext.Provider>\n );\n};\n\nconst ContextMenuTrigger = ({\n children,\n asChild = false,\n disabled = false,\n id,\n className,\n ref,\n onContextMenu,\n onClick,\n onKeyDown,\n onPointerDown,\n onPointerMove,\n onPointerUp,\n onPointerCancel,\n ...triggerProps\n}: ContextMenuTriggerProps) => {\n const context = useContextMenuContext();\n const longPressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pointerStartRef = useRef<{ x: number; y: number } | null>(null);\n\n const isDisabled = disabled || context.disabled;\n\n const clearLongPress = useCallback(() => {\n if (longPressTimerRef.current !== null) {\n clearTimeout(longPressTimerRef.current);\n longPressTimerRef.current = null;\n }\n }, []);\n\n useEffect(() => clearLongPress, [clearLongPress]);\n\n const handleRef = useCallback(\n (node: HTMLElement | null) => {\n context.triggerRef.current = node;\n setRef(ref, node);\n },\n [context.triggerRef, ref],\n );\n\n const handleContextMenu = (event: MouseEvent<HTMLElement>) => {\n onContextMenu?.(event);\n\n if (event.defaultPrevented || isDisabled) {\n return;\n }\n\n event.preventDefault();\n context.triggerRef.current = event.currentTarget;\n\n context.openAt({\n x: event.clientX,\n y: event.clientY,\n });\n };\n\n const handleClick = (event: MouseEvent<HTMLElement>) => {\n onClick?.(event);\n\n if (event.defaultPrevented || isDisabled || event.button !== 0) {\n return;\n }\n\n if (event.ctrlKey) {\n event.preventDefault();\n context.triggerRef.current = event.currentTarget;\n context.openAt({\n x: event.clientX,\n y: event.clientY,\n });\n return;\n }\n\n if (context.open) {\n context.close(false);\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented || isDisabled) {\n return;\n }\n\n const target = event.currentTarget;\n const rect = target.getBoundingClientRect();\n\n if (\n event.key === \"ContextMenu\" ||\n (event.shiftKey && event.key === \"F10\")\n ) {\n event.preventDefault();\n context.triggerRef.current = target;\n context.openAt({ x: rect.left, y: rect.bottom });\n return;\n }\n\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n context.triggerRef.current = target;\n context.openAt(\n { x: rect.left, y: rect.bottom },\n event.key === \"ArrowUp\" ? \"last\" : \"first\",\n );\n }\n };\n\n const handlePointerDown = (event: PointerEvent<HTMLElement>) => {\n onPointerDown?.(event);\n\n if (event.defaultPrevented || isDisabled || event.pointerType !== \"touch\") {\n return;\n }\n\n pointerStartRef.current = {\n x: event.clientX,\n y: event.clientY,\n };\n\n const target = event.currentTarget;\n\n longPressTimerRef.current = setTimeout(() => {\n const rect = target.getBoundingClientRect();\n\n context.triggerRef.current = target;\n context.openAt({\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n });\n }, 550);\n };\n\n const handlePointerMove = (event: PointerEvent<HTMLElement>) => {\n onPointerMove?.(event);\n\n const start = pointerStartRef.current;\n\n if (\n start &&\n (Math.abs(event.clientX - start.x) > 10 ||\n Math.abs(event.clientY - start.y) > 10)\n ) {\n clearLongPress();\n pointerStartRef.current = null;\n }\n };\n\n const handlePointerEnd = (\n event: PointerEvent<HTMLElement>,\n callback?: (event: PointerEvent<HTMLElement>) => void,\n ) => {\n callback?.(event);\n clearLongPress();\n pointerStartRef.current = null;\n };\n\n const commonProps = {\n ...triggerProps,\n id,\n ref: handleRef,\n className: cn(\"puzzle-context-menu__trigger\", className),\n role: \"button\",\n tabIndex: isDisabled ? -1 : (triggerProps.tabIndex ?? 0),\n \"aria-haspopup\": \"menu\" as const,\n \"aria-expanded\": context.open,\n \"aria-controls\": context.open ? context.contentId : undefined,\n \"aria-disabled\": isDisabled || undefined,\n \"data-state\": context.open ? \"open\" : \"closed\",\n onContextMenu: handleContextMenu,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n onPointerDown: handlePointerDown,\n onPointerMove: handlePointerMove,\n onPointerUp: (event: PointerEvent<HTMLElement>) =>\n handlePointerEnd(event, onPointerUp),\n onPointerCancel: (event: PointerEvent<HTMLElement>) =>\n handlePointerEnd(event, onPointerCancel),\n };\n\n if (!asChild) {\n return <div {...commonProps}>{children}</div>;\n }\n\n const child = Children.only(children);\n\n if (!isValidElement(child) || child.type === Fragment) {\n throw new Error(\n \"ContextMenu.Trigger with asChild expects one non-Fragment element.\",\n );\n }\n\n const childProps = child.props as HTMLAttributes<HTMLElement> & {\n ref?: Ref<HTMLElement>;\n className?: string;\n disabled?: boolean;\n onContextMenu?: (event: MouseEvent<HTMLElement>) => void;\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n onPointerDown?: (event: PointerEvent<HTMLElement>) => void;\n onPointerMove?: (event: PointerEvent<HTMLElement>) => void;\n onPointerUp?: (event: PointerEvent<HTMLElement>) => void;\n onPointerCancel?: (event: PointerEvent<HTMLElement>) => void;\n };\n\n const childDisabled =\n isDisabled ||\n childProps.disabled === true ||\n childProps[\"aria-disabled\"] === true ||\n childProps[\"aria-disabled\"] === \"true\";\n\n return cloneElement(child as ReactElement<Record<string, unknown>>, {\n ...commonProps,\n ref: (node: HTMLElement | null) => {\n handleRef(node);\n setRef(childProps.ref, node);\n },\n className: cn(\n \"puzzle-context-menu__trigger\",\n childProps.className,\n className,\n ),\n role: child.type === \"button\" ? undefined : \"button\",\n tabIndex: childDisabled ? -1 : (childProps.tabIndex ?? 0),\n \"aria-disabled\": childDisabled || undefined,\n disabled: child.type === \"button\" ? childDisabled : undefined,\n onContextMenu: (event: MouseEvent<HTMLElement>) => {\n if (childDisabled) {\n event.preventDefault();\n return;\n }\n\n childProps.onContextMenu?.(event);\n\n if (!event.defaultPrevented) {\n handleContextMenu(event);\n }\n },\n onClick: (event: MouseEvent<HTMLElement>) => {\n if (childDisabled) {\n return;\n }\n\n childProps.onClick?.(event);\n\n if (!event.defaultPrevented) {\n handleClick(event);\n }\n },\n onKeyDown: (event: KeyboardEvent<HTMLElement>) => {\n childProps.onKeyDown?.(event);\n if (!event.defaultPrevented) {\n handleKeyDown(event);\n }\n },\n onPointerDown: (event: PointerEvent<HTMLElement>) => {\n childProps.onPointerDown?.(event);\n if (!event.defaultPrevented) {\n handlePointerDown(event);\n }\n },\n onPointerMove: (event: PointerEvent<HTMLElement>) => {\n childProps.onPointerMove?.(event);\n if (!event.defaultPrevented) {\n handlePointerMove(event);\n }\n },\n onPointerUp: (event: PointerEvent<HTMLElement>) => {\n childProps.onPointerUp?.(event);\n handlePointerEnd(event);\n },\n onPointerCancel: (event: PointerEvent<HTMLElement>) => {\n childProps.onPointerCancel?.(event);\n handlePointerEnd(event);\n },\n });\n};\n\nconst ContextMenuContent = ({\n children,\n id,\n className,\n style,\n maxHeight = \"min(24rem, calc(100dvh - 1rem))\",\n onKeyDown,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...contentProps\n}: ContextMenuContentProps) => {\n const context = useContextMenuContext();\n const positioned = usePopoutPositioned();\n const menuRef = useRef<HTMLDivElement | null>(null);\n const typeaheadRef = useRef(\"\");\n const typeaheadTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const initialFocusDoneRef = useRef(false);\n\n useEffect(() => {\n if (!context.open) {\n initialFocusDoneRef.current = false;\n typeaheadRef.current = \"\";\n\n if (typeaheadTimerRef.current !== null) {\n clearTimeout(typeaheadTimerRef.current);\n typeaheadTimerRef.current = null;\n }\n }\n }, [context.open]);\n\n useEffect(() => {\n if (!context.open || !positioned || initialFocusDoneRef.current) {\n return;\n }\n\n const menu = menuRef.current;\n\n if (!menu) {\n return;\n }\n\n initialFocusDoneRef.current = true;\n\n const items = getEnabledMenuItems(menu);\n const target =\n context.focusPositionRef.current === \"last\"\n ? items[items.length - 1]\n : items[0];\n\n focusElement(target ?? menu);\n }, [context.open, context.focusPositionRef, positioned]);\n\n useEffect(\n () => () => {\n if (typeaheadTimerRef.current !== null) {\n clearTimeout(typeaheadTimerRef.current);\n }\n },\n [],\n );\n\n const focusIndex = (items: HTMLElement[], index: number) => {\n if (index >= 0 && index < items.length) {\n focusElement(items[index]);\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n const menu = menuRef.current;\n\n if (!menu) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n context.close(true);\n return;\n }\n\n if (event.key === \"Tab\") {\n const ownerDocument = event.currentTarget.ownerDocument;\n const trigger = context.triggerRef.current;\n const selector = [\n \"a[href]\",\n \"area[href]\",\n \"button:not([disabled])\",\n \"input:not([disabled]):not([type='hidden'])\",\n \"select:not([disabled])\",\n \"textarea:not([disabled])\",\n \"iframe\",\n \"summary\",\n \"[contenteditable='true']\",\n \"[tabindex]:not([tabindex='-1'])\",\n ].join(\",\");\n\n const tabbableElements = Array.from(\n ownerDocument.querySelectorAll<HTMLElement>(selector),\n ).filter((element) => {\n if (\n menu.contains(element) ||\n element.hidden ||\n element.tabIndex < 0 ||\n element.getAttribute(\"aria-disabled\") === \"true\" ||\n element.closest(\"[hidden], [inert], [aria-hidden='true']\")\n ) {\n return false;\n }\n\n const computedStyle =\n ownerDocument.defaultView?.getComputedStyle(element);\n\n return (\n computedStyle?.display !== \"none\" &&\n computedStyle?.visibility !== \"hidden\"\n );\n });\n\n const triggerIndex = trigger ? tabbableElements.indexOf(trigger) : -1;\n const direction = event.shiftKey ? -1 : 1;\n const targetIndex = triggerIndex + direction;\n const target =\n triggerIndex >= 0 && tabbableElements.length > 0\n ? tabbableElements[\n (targetIndex + tabbableElements.length) % tabbableElements.length\n ]\n : undefined;\n\n context.close(false);\n\n if (target) {\n event.preventDefault();\n focusElement(target);\n }\n\n return;\n }\n\n const items = getEnabledMenuItems(menu);\n const activeIndex = items.indexOf(\n menu.ownerDocument.activeElement as HTMLElement,\n );\n\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n\n const direction = event.key === \"ArrowDown\" ? 1 : -1;\n const startIndex =\n activeIndex < 0 ? (direction === 1 ? -1 : 0) : activeIndex;\n\n const nextIndex = findNextMenuItemIndex(\n items.map(() => ({ disabled: false })),\n startIndex,\n direction,\n );\n\n focusIndex(items, nextIndex);\n return;\n }\n\n if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n focusIndex(items, event.key === \"Home\" ? 0 : items.length - 1);\n return;\n }\n\n if (event.key === \"ArrowRight\") {\n const activeItem = items[activeIndex];\n\n if (activeItem?.hasAttribute(\"data-puzzle-context-menu-sub-trigger\")) {\n event.preventDefault();\n activeItem.click();\n }\n\n return;\n }\n\n if (\n event.key.length !== 1 ||\n event.key === \" \" ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey\n ) {\n return;\n }\n\n event.preventDefault();\n\n const nextBuffer = `${typeaheadRef.current}${event.key}`;\n const repeatedCharacter = [...nextBuffer].every(\n (character) =>\n character.toLocaleLowerCase() === nextBuffer[0]!.toLocaleLowerCase(),\n );\n const query = repeatedCharacter ? event.key : nextBuffer;\n\n typeaheadRef.current = query;\n\n if (typeaheadTimerRef.current !== null) {\n clearTimeout(typeaheadTimerRef.current);\n }\n\n typeaheadTimerRef.current = setTimeout(() => {\n typeaheadRef.current = \"\";\n typeaheadTimerRef.current = null;\n }, 500);\n\n const nextIndex = findMenuItemIndexByText(\n items.map((item) => ({\n text: getMenuItemText(item),\n })),\n query,\n activeIndex,\n );\n\n focusIndex(items, nextIndex);\n };\n\n return (\n <div\n {...contentProps}\n ref={menuRef}\n id={id ?? context.contentId}\n className={cn(\"puzzle-context-menu__content\", className)}\n role=\"menu\"\n aria-orientation=\"vertical\"\n aria-label={ariaLabel}\n aria-labelledby={\n ariaLabel ? undefined : (ariaLabelledBy ?? context.triggerId)\n }\n tabIndex={-1}\n data-state={context.open ? \"open\" : \"closed\"}\n style={{ ...style, maxHeight }}\n onKeyDown={handleKeyDown}\n >\n {children}\n </div>\n );\n};\n\nconst ContextMenuItem = ({\n children,\n className,\n disabled = false,\n \"aria-disabled\": ariaDisabled,\n textValue,\n closeOnSelect = true,\n variant = \"default\",\n onClick,\n onSelect,\n ...itemProps\n}: ContextMenuItemProps) => {\n const context = useContextMenuContext();\n const itemDisabled =\n disabled || ariaDisabled === true || ariaDisabled === \"true\";\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (itemDisabled) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n onClick?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n onSelect?.(event);\n\n if (!event.defaultPrevented && closeOnSelect) {\n context.close(true);\n }\n };\n\n return (\n <button\n {...(itemProps as ButtonHTMLAttributes<HTMLButtonElement>)}\n type=\"button\"\n className={cn(\n \"puzzle-context-menu__item\",\n variant === \"danger\" && \"puzzle-context-menu__item--danger\",\n className,\n )}\n role=\"menuitem\"\n tabIndex={-1}\n disabled={itemDisabled}\n aria-disabled={itemDisabled || undefined}\n data-puzzle-context-menu-item=\"true\"\n data-text-value={textValue}\n onClick={handleClick}\n >\n <span className=\"puzzle-context-menu__item-label\">{children}</span>\n </button>\n );\n};\n\nconst ContextMenuGroup = ({\n children,\n className,\n \"aria-label\": ariaLabel,\n ...groupProps\n}: ContextMenuGroupProps) => (\n <div\n {...groupProps}\n className={cn(\"puzzle-context-menu__group\", className)}\n role=\"group\"\n aria-label={ariaLabel}\n >\n {children}\n </div>\n);\n\nconst ContextMenuLabel = ({\n children,\n className,\n ...labelProps\n}: ContextMenuLabelProps) => (\n <div {...labelProps} className={cn(\"puzzle-context-menu__label\", className)}>\n {children}\n </div>\n);\n\nconst ContextMenuSeparator = ({\n className,\n ...separatorProps\n}: ContextMenuSeparatorProps) => (\n <div\n {...separatorProps}\n className={cn(\"puzzle-context-menu__separator\", className)}\n role=\"separator\"\n aria-orientation=\"horizontal\"\n />\n);\n\nconst ContextMenuCheckboxItem = ({\n children,\n checked,\n defaultChecked = false,\n onCheckedChange,\n closeOnSelect = false,\n textValue,\n className,\n disabled = false,\n \"aria-disabled\": ariaDisabled,\n onClick,\n onSelect,\n ...itemProps\n}: ContextMenuCheckboxItemProps) => {\n const context = useContextMenuContext();\n const itemDisabled =\n disabled || ariaDisabled === true || ariaDisabled === \"true\";\n const controlled = checked !== undefined;\n const [internalChecked, setInternalChecked] = useState(defaultChecked);\n const resolvedChecked = checked ?? internalChecked;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (itemDisabled) {\n event.preventDefault();\n return;\n }\n\n onClick?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n onSelect?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n const nextChecked = resolvedChecked !== true;\n\n if (!controlled) {\n setInternalChecked(nextChecked);\n }\n\n onCheckedChange?.(nextChecked);\n\n if (closeOnSelect) {\n context.close(true);\n }\n };\n\n return (\n <button\n {...(itemProps as ButtonHTMLAttributes<HTMLButtonElement>)}\n type=\"button\"\n className={cn(\"puzzle-context-menu__item\", className)}\n role=\"menuitemcheckbox\"\n tabIndex={-1}\n disabled={itemDisabled}\n aria-disabled={itemDisabled || undefined}\n aria-checked={\n resolvedChecked === \"indeterminate\" ? \"mixed\" : resolvedChecked\n }\n data-state={\n resolvedChecked === \"indeterminate\"\n ? \"indeterminate\"\n : resolvedChecked\n ? \"checked\"\n : \"unchecked\"\n }\n data-puzzle-context-menu-item=\"true\"\n data-text-value={textValue}\n onClick={handleClick}\n >\n <span className=\"puzzle-context-menu__indicator\" aria-hidden=\"true\">\n {resolvedChecked === \"indeterminate\" ? \"−\" : resolvedChecked ? \"✓\" : \"\"}\n </span>\n <span className=\"puzzle-context-menu__item-label\">{children}</span>\n </button>\n );\n};\n\nconst ContextMenuRadioGroup = ({\n children,\n value,\n defaultValue,\n onValueChange,\n className,\n ...groupProps\n}: ContextMenuRadioGroupProps) => {\n const controlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue);\n const resolvedValue = controlled ? value : internalValue;\n\n const setValue = useCallback(\n (nextValue: string) => {\n if (nextValue === resolvedValue) {\n return;\n }\n\n if (!controlled) {\n setInternalValue(nextValue);\n }\n\n onValueChange?.(nextValue);\n },\n [controlled, onValueChange, resolvedValue],\n );\n\n return (\n <RadioGroupContext.Provider value={{ value: resolvedValue, setValue }}>\n <div\n {...groupProps}\n className={cn(\"puzzle-context-menu__group\", className)}\n role=\"group\"\n >\n {children}\n </div>\n </RadioGroupContext.Provider>\n );\n};\n\nconst ContextMenuRadioItem = ({\n children,\n value,\n closeOnSelect = true,\n textValue,\n className,\n disabled = false,\n \"aria-disabled\": ariaDisabled,\n onClick,\n onSelect,\n ...itemProps\n}: ContextMenuRadioItemProps) => {\n const context = useContextMenuContext();\n const radioGroup = useRadioGroupContext();\n const checked = radioGroup.value === value;\n const itemDisabled =\n disabled || ariaDisabled === true || ariaDisabled === \"true\";\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (itemDisabled) {\n event.preventDefault();\n return;\n }\n\n onClick?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n onSelect?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n radioGroup.setValue(value);\n\n if (closeOnSelect) {\n context.close(true);\n }\n };\n\n return (\n <button\n {...(itemProps as ButtonHTMLAttributes<HTMLButtonElement>)}\n type=\"button\"\n className={cn(\"puzzle-context-menu__item\", className)}\n role=\"menuitemradio\"\n tabIndex={-1}\n disabled={itemDisabled}\n aria-disabled={itemDisabled || undefined}\n aria-checked={checked}\n data-state={checked ? \"checked\" : \"unchecked\"}\n data-puzzle-context-menu-item=\"true\"\n data-text-value={textValue}\n onClick={handleClick}\n >\n <span className=\"puzzle-context-menu__indicator\" aria-hidden=\"true\">\n {checked ? \"●\" : \"\"}\n </span>\n <span className=\"puzzle-context-menu__item-label\">{children}</span>\n </button>\n );\n};\n\nconst ContextMenuSub = ({\n children,\n defaultOpen = false,\n}: ContextMenuSubProps) => {\n const rootContext = useContextMenuContext();\n const baseId = useId();\n const triggerId = `${baseId}-trigger`;\n const contentId = `${baseId}-content`;\n\n const [open, setOpen] = useState(defaultOpen);\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n\n const elements = getMenuElements(children);\n const triggers = elements.filter(\n (child) => child.type === ContextMenuSubTrigger,\n );\n const contents = elements.filter(\n (child) => child.type === ContextMenuSubContent,\n );\n\n const triggerElement = triggers[0] as\n | ReactElement<ContextMenuSubTriggerProps>\n | undefined;\n const contentElement = contents[0] as\n | ReactElement<ContextMenuSubContentProps>\n | undefined;\n\n if (\n triggers.length !== 1 ||\n contents.length !== 1 ||\n !triggerElement ||\n !contentElement\n ) {\n throw new Error(\n \"ContextMenu.Sub requires exactly one SubTrigger and one SubContent.\",\n );\n }\n\n useEffect(() => {\n if (!rootContext.open) {\n setOpen(false);\n }\n }, [rootContext.open]);\n\n const close = useCallback((restoreFocus = false) => {\n setOpen(false);\n\n if (restoreFocus) {\n focusElement(triggerRef.current ?? undefined);\n }\n }, []);\n\n const subContext = useMemo<SubContextValue>(\n () => ({\n open,\n setOpen,\n triggerId,\n contentId,\n triggerRef,\n close,\n }),\n [open, triggerId, contentId, close],\n );\n\n const trigger = cloneElement(triggerElement, {\n id: triggerId,\n });\n\n const content = cloneElement(contentElement, {\n id: contentId,\n });\n\n return (\n <SubContext.Provider value={subContext}>\n <Popout\n trigger={trigger as ReactElement<PopoutTriggerProps>}\n open={open}\n onOpenChange={setOpen}\n position=\"right\"\n align=\"start\"\n offset={4}\n collisionPadding={8}\n action=\"hover\"\n closeOnOutsideClick\n closeOnEscape\n contentClassName=\"puzzle-context-menu__popover puzzle-context-menu__submenu-popover\"\n >\n {content}\n </Popout>\n </SubContext.Provider>\n );\n};\n\nconst ContextMenuSubTrigger = forwardRef<\n HTMLButtonElement,\n ContextMenuSubTriggerProps\n>(\n (\n { children, className, disabled = false, onClick, onKeyDown, ...props },\n ref,\n ) => {\n const context = useSubContext();\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (!event.defaultPrevented && !disabled) {\n context.setOpen(true);\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n\n if (!event.defaultPrevented && !disabled && event.key === \"ArrowRight\") {\n event.preventDefault();\n context.setOpen(true);\n }\n\n if (!event.defaultPrevented && !disabled && event.key === \"ArrowLeft\") {\n event.preventDefault();\n context.close(true);\n }\n };\n\n return (\n <button\n {...props}\n ref={(node) => {\n context.triggerRef.current = node;\n setRef(ref, node);\n }}\n id={context.triggerId}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n className={cn(\"puzzle-context-menu__item\", className)}\n aria-haspopup=\"menu\"\n aria-expanded={context.open}\n aria-controls={context.open ? context.contentId : undefined}\n aria-disabled={disabled || undefined}\n disabled={disabled}\n data-puzzle-context-menu-item=\"true\"\n data-puzzle-context-menu-sub-trigger=\"true\"\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onPointerEnter={() => {\n if (!disabled) {\n context.setOpen(true);\n }\n }}\n >\n <span className=\"puzzle-context-menu__item-label\">{children}</span>\n <span\n className=\"puzzle-context-menu__submenu-indicator\"\n aria-hidden=\"true\"\n >\n ›\n </span>\n </button>\n );\n },\n);\n\nContextMenuSubTrigger.displayName = \"ContextMenuSubTrigger\";\n\nconst ContextMenuSubContent = ({\n children,\n id,\n className,\n style,\n maxHeight = \"min(24rem, calc(100dvh - 1rem))\",\n onKeyDown,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...contentProps\n}: ContextMenuSubContentProps) => {\n const context = useSubContext();\n const positioned = usePopoutPositioned();\n const menuRef = useRef<HTMLDivElement | null>(null);\n const typeaheadRef = useRef(\"\");\n const typeaheadTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const initialFocusDoneRef = useRef(false);\n\n useEffect(() => {\n if (!context.open) {\n initialFocusDoneRef.current = false;\n typeaheadRef.current = \"\";\n\n if (typeaheadTimerRef.current !== null) {\n clearTimeout(typeaheadTimerRef.current);\n typeaheadTimerRef.current = null;\n }\n }\n }, [context.open]);\n\n useEffect(\n () => () => {\n if (typeaheadTimerRef.current !== null) {\n clearTimeout(typeaheadTimerRef.current);\n }\n },\n [],\n );\n\n useEffect(() => {\n if (!context.open || !positioned || initialFocusDoneRef.current) {\n return;\n }\n\n const menu = menuRef.current;\n\n if (!menu) {\n return;\n }\n\n initialFocusDoneRef.current = true;\n const items = getEnabledMenuItems(menu);\n focusElement(items[0] ?? menu);\n }, [context.open, positioned]);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n\n if (event.defaultPrevented) {\n return;\n }\n\n event.stopPropagation();\n\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n context.close(true);\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n context.close(true);\n return;\n }\n\n const menu = menuRef.current;\n\n if (!menu) {\n return;\n }\n\n const items = getEnabledMenuItems(menu);\n const activeIndex = items.indexOf(\n menu.ownerDocument.activeElement as HTMLElement,\n );\n\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n\n const direction = event.key === \"ArrowDown\" ? 1 : -1;\n const startIndex =\n activeIndex < 0 ? (direction === 1 ? -1 : 0) : activeIndex;\n\n const nextIndex = findNextMenuItemIndex(\n items.map(() => ({ disabled: false })),\n startIndex,\n direction,\n );\n\n if (nextIndex >= 0) {\n focusElement(items[nextIndex]);\n }\n\n return;\n }\n\n if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n const target = event.key === \"Home\" ? items[0] : items[items.length - 1];\n\n if (target) {\n focusElement(target);\n }\n\n return;\n }\n\n if (\n event.key.length !== 1 ||\n event.key === \" \" ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey\n ) {\n return;\n }\n\n event.preventDefault();\n\n const nextBuffer = `${typeaheadRef.current}${event.key}`;\n const repeatedCharacter = [...nextBuffer].every(\n (character) =>\n character.toLocaleLowerCase() === nextBuffer[0]!.toLocaleLowerCase(),\n );\n const query = repeatedCharacter ? event.key : nextBuffer;\n\n typeaheadRef.current = query;\n\n if (typeaheadTimerRef.current !== null) {\n clearTimeout(typeaheadTimerRef.current);\n }\n\n typeaheadTimerRef.current = setTimeout(() => {\n typeaheadRef.current = \"\";\n typeaheadTimerRef.current = null;\n }, 500);\n\n const nextIndex = findMenuItemIndexByText(\n items.map((item) => ({\n text: getMenuItemText(item),\n })),\n query,\n activeIndex,\n );\n\n if (nextIndex >= 0) {\n focusElement(items[nextIndex]);\n }\n };\n\n return (\n <div\n {...contentProps}\n ref={menuRef}\n id={id ?? context.contentId}\n className={cn(\"puzzle-context-menu__content\", className)}\n role=\"menu\"\n aria-orientation=\"vertical\"\n aria-label={ariaLabel}\n aria-labelledby={\n ariaLabel ? undefined : (ariaLabelledBy ?? context.triggerId)\n }\n tabIndex={-1}\n data-state={context.open ? \"open\" : \"closed\"}\n style={{ ...style, maxHeight }}\n onKeyDown={handleKeyDown}\n >\n {children}\n </div>\n );\n};\n\ntype ContextMenuComponent = typeof ContextMenuRoot & {\n Trigger: typeof ContextMenuTrigger;\n Content: typeof ContextMenuContent;\n Item: typeof ContextMenuItem;\n Group: typeof ContextMenuGroup;\n Label: typeof ContextMenuLabel;\n Separator: typeof ContextMenuSeparator;\n CheckboxItem: typeof ContextMenuCheckboxItem;\n RadioGroup: typeof ContextMenuRadioGroup;\n RadioItem: typeof ContextMenuRadioItem;\n Sub: typeof ContextMenuSub & {\n Trigger: typeof ContextMenuSubTrigger;\n Content: typeof ContextMenuSubContent;\n };\n SubTrigger: typeof ContextMenuSubTrigger;\n SubContent: typeof ContextMenuSubContent;\n};\n\nconst ContextMenuSubCompound = Object.assign(ContextMenuSub, {\n Trigger: ContextMenuSubTrigger,\n Content: ContextMenuSubContent,\n});\n\nconst ContextMenu = Object.assign(ContextMenuRoot, {\n Trigger: ContextMenuTrigger,\n Content: ContextMenuContent,\n Item: ContextMenuItem,\n Group: ContextMenuGroup,\n Label: ContextMenuLabel,\n Separator: ContextMenuSeparator,\n CheckboxItem: ContextMenuCheckboxItem,\n RadioGroup: ContextMenuRadioGroup,\n RadioItem: ContextMenuRadioItem,\n Sub: ContextMenuSubCompound,\n SubTrigger: ContextMenuSubTrigger,\n SubContent: ContextMenuSubContent,\n}) as ContextMenuComponent;\n\nexport {\n ContextMenu,\n ContextMenuTrigger,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuGroup,\n ContextMenuLabel,\n ContextMenuSeparator,\n ContextMenuCheckboxItem,\n ContextMenuRadioGroup,\n ContextMenuRadioItem,\n ContextMenuSubCompound as ContextMenuSub,\n ContextMenuSubTrigger,\n ContextMenuSubContent,\n};\n\nexport type {\n ContextMenuProps,\n ContextMenuTriggerProps,\n ContextMenuContentProps,\n ContextMenuItemProps,\n ContextMenuGroupProps,\n ContextMenuLabelProps,\n ContextMenuSeparatorProps,\n ContextMenuCheckboxItemProps,\n ContextMenuRadioGroupProps,\n ContextMenuRadioItemProps,\n ContextMenuSubProps,\n ContextMenuSubTriggerProps,\n ContextMenuSubContentProps,\n};\n\nexport type {\n ContextMenuItemVariant,\n ContextMenuCheckedState,\n} from \"./context-menu.types\";\n"],"mappings":"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"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
let _puzzle_ui_core = require("@puzzle-ui/core");
|
|
2
2
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
3
|
// src/components/typography/heading.tsx
|
|
4
|
-
const Heading = ({ level, as, className, ...props }) => {
|
|
4
|
+
const Heading = ({ level, as, className, textAlign, style, ...props }) => {
|
|
5
5
|
const Component = as ?? "h2";
|
|
6
6
|
const classes = (0, _puzzle_ui_core.cn)("puzzle-heading", `puzzle-typography-${level}`, className);
|
|
7
7
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
|
|
8
|
+
...props,
|
|
8
9
|
className: classes,
|
|
9
|
-
|
|
10
|
+
style: textAlign === void 0 ? style : {
|
|
11
|
+
...style,
|
|
12
|
+
textAlign
|
|
13
|
+
}
|
|
10
14
|
});
|
|
11
15
|
};
|
|
12
16
|
exports.Heading = Heading;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heading.cjs","names":["cn"],"sources":["../../../src/components/typography/heading.tsx"],"sourcesContent":["import { cn } from \"@puzzle-ui/core\";\nimport type { ComponentPropsWithRef, ElementType } from \"react\";\n\ntype HeadingLevel =\n | \"display1\"\n | \"display2\"\n | \"headline1\"\n | \"headline2\"\n | \"headline3\"\n | \"headline4\";\n\ntype PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E;\n} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | \"as\">;\n\ntype HeadingOwnProps = {\n level: HeadingLevel;\n};\n\ntype HeadingProps<E extends ElementType = \"h2\"> = PolymorphicProps<\n E,\n HeadingOwnProps\n>;\n\nconst Heading = <E extends ElementType = \"h2\">({\n level,\n as,\n className,\n ...props\n}: HeadingProps<E>) => {\n const Component = as ?? \"h2\";\n const classes = cn(\"puzzle-heading\", `puzzle-typography-${level}`, className);\n return <Component
|
|
1
|
+
{"version":3,"file":"heading.cjs","names":["cn"],"sources":["../../../src/components/typography/heading.tsx"],"sourcesContent":["import { cn } from \"@puzzle-ui/core\";\nimport type { ComponentPropsWithRef, CSSProperties, ElementType } from \"react\";\n\ntype HeadingLevel =\n | \"display1\"\n | \"display2\"\n | \"headline1\"\n | \"headline2\"\n | \"headline3\"\n | \"headline4\";\n\ntype PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E;\n} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | \"as\">;\n\ntype HeadingOwnProps = {\n level: HeadingLevel;\n textAlign?: CSSProperties[\"textAlign\"];\n};\n\ntype HeadingProps<E extends ElementType = \"h2\"> = PolymorphicProps<\n E,\n HeadingOwnProps\n>;\n\nconst Heading = <E extends ElementType = \"h2\">({\n level,\n as,\n className,\n textAlign,\n style,\n ...props\n}: HeadingProps<E>) => {\n const Component = as ?? \"h2\";\n const classes = cn(\"puzzle-heading\", `puzzle-typography-${level}`, className);\n return (\n <Component\n {...props}\n className={classes}\n style={textAlign === undefined ? style : { ...style, textAlign }}\n ></Component>\n );\n};\n\nexport { Heading, type HeadingProps, type HeadingLevel };\n"],"mappings":";;;AAyBA,MAAM,WAAyC,EAC7C,OACA,IACA,WACA,WACA,OACA,GAAG,YACkB;CACrB,MAAM,YAAY,MAAM;CACxB,MAAM,WAAA,GAAUA,gBAAAA,GAAAA,CAAG,kBAAkB,qBAAqB,SAAS,SAAS;CAC5E,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;EACE,GAAI;EACJ,WAAW;EACX,OAAO,cAAc,KAAA,IAAY,QAAQ;GAAE,GAAG;GAAO;EAAU;CACrD,CAAA;AAEhB"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { ComponentPropsWithRef, ElementType } from "react";
|
|
1
|
+
import { CSSProperties, ComponentPropsWithRef, ElementType } from "react";
|
|
2
2
|
type HeadingLevel = "display1" | "display2" | "headline1" | "headline2" | "headline3" | "headline4";
|
|
3
3
|
type PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {
|
|
4
4
|
as?: E;
|
|
5
5
|
} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | "as">;
|
|
6
6
|
type HeadingOwnProps = {
|
|
7
7
|
level: HeadingLevel;
|
|
8
|
+
textAlign?: CSSProperties["textAlign"];
|
|
8
9
|
};
|
|
9
10
|
type HeadingProps<E extends ElementType = "h2"> = PolymorphicProps<E, HeadingOwnProps>;
|
|
10
|
-
declare const Heading: <E extends ElementType = "h2">({ level, as, className, ...props }: HeadingProps<E>) => import("react").JSX.Element;
|
|
11
|
+
declare const Heading: <E extends ElementType = "h2">({ level, as, className, textAlign, style, ...props }: HeadingProps<E>) => import("react").JSX.Element;
|
|
11
12
|
export { Heading, type HeadingLevel, type HeadingProps };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { ComponentPropsWithRef, ElementType } from "react";
|
|
1
|
+
import { CSSProperties, ComponentPropsWithRef, ElementType } from "react";
|
|
2
2
|
type HeadingLevel = "display1" | "display2" | "headline1" | "headline2" | "headline3" | "headline4";
|
|
3
3
|
type PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {
|
|
4
4
|
as?: E;
|
|
5
5
|
} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | "as">;
|
|
6
6
|
type HeadingOwnProps = {
|
|
7
7
|
level: HeadingLevel;
|
|
8
|
+
textAlign?: CSSProperties["textAlign"];
|
|
8
9
|
};
|
|
9
10
|
type HeadingProps<E extends ElementType = "h2"> = PolymorphicProps<E, HeadingOwnProps>;
|
|
10
|
-
declare const Heading: <E extends ElementType = "h2">({ level, as, className, ...props }: HeadingProps<E>) => import("react").JSX.Element;
|
|
11
|
+
declare const Heading: <E extends ElementType = "h2">({ level, as, className, textAlign, style, ...props }: HeadingProps<E>) => import("react").JSX.Element;
|
|
11
12
|
export { Heading, type HeadingLevel, type HeadingProps };
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { cn } from "@puzzle-ui/core";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
// src/components/typography/heading.tsx
|
|
4
|
-
const Heading = ({ level, as, className, ...props }) => {
|
|
4
|
+
const Heading = ({ level, as, className, textAlign, style, ...props }) => {
|
|
5
5
|
const Component = as ?? "h2";
|
|
6
6
|
const classes = cn("puzzle-heading", `puzzle-typography-${level}`, className);
|
|
7
7
|
return /* @__PURE__ */ jsx(Component, {
|
|
8
|
+
...props,
|
|
8
9
|
className: classes,
|
|
9
|
-
|
|
10
|
+
style: textAlign === void 0 ? style : {
|
|
11
|
+
...style,
|
|
12
|
+
textAlign
|
|
13
|
+
}
|
|
10
14
|
});
|
|
11
15
|
};
|
|
12
16
|
export { Heading };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heading.js","names":[],"sources":["../../../src/components/typography/heading.tsx"],"sourcesContent":["import { cn } from \"@puzzle-ui/core\";\nimport type { ComponentPropsWithRef, ElementType } from \"react\";\n\ntype HeadingLevel =\n | \"display1\"\n | \"display2\"\n | \"headline1\"\n | \"headline2\"\n | \"headline3\"\n | \"headline4\";\n\ntype PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E;\n} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | \"as\">;\n\ntype HeadingOwnProps = {\n level: HeadingLevel;\n};\n\ntype HeadingProps<E extends ElementType = \"h2\"> = PolymorphicProps<\n E,\n HeadingOwnProps\n>;\n\nconst Heading = <E extends ElementType = \"h2\">({\n level,\n as,\n className,\n ...props\n}: HeadingProps<E>) => {\n const Component = as ?? \"h2\";\n const classes = cn(\"puzzle-heading\", `puzzle-typography-${level}`, className);\n return <Component
|
|
1
|
+
{"version":3,"file":"heading.js","names":[],"sources":["../../../src/components/typography/heading.tsx"],"sourcesContent":["import { cn } from \"@puzzle-ui/core\";\nimport type { ComponentPropsWithRef, CSSProperties, ElementType } from \"react\";\n\ntype HeadingLevel =\n | \"display1\"\n | \"display2\"\n | \"headline1\"\n | \"headline2\"\n | \"headline3\"\n | \"headline4\";\n\ntype PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E;\n} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | \"as\">;\n\ntype HeadingOwnProps = {\n level: HeadingLevel;\n textAlign?: CSSProperties[\"textAlign\"];\n};\n\ntype HeadingProps<E extends ElementType = \"h2\"> = PolymorphicProps<\n E,\n HeadingOwnProps\n>;\n\nconst Heading = <E extends ElementType = \"h2\">({\n level,\n as,\n className,\n textAlign,\n style,\n ...props\n}: HeadingProps<E>) => {\n const Component = as ?? \"h2\";\n const classes = cn(\"puzzle-heading\", `puzzle-typography-${level}`, className);\n return (\n <Component\n {...props}\n className={classes}\n style={textAlign === undefined ? style : { ...style, textAlign }}\n ></Component>\n );\n};\n\nexport { Heading, type HeadingProps, type HeadingLevel };\n"],"mappings":";;;AAyBA,MAAM,WAAyC,EAC7C,OACA,IACA,WACA,WACA,OACA,GAAG,YACkB;CACrB,MAAM,YAAY,MAAM;CACxB,MAAM,UAAU,GAAG,kBAAkB,qBAAqB,SAAS,SAAS;CAC5E,OACE,oBAAC,WAAD;EACE,GAAI;EACJ,WAAW;EACX,OAAO,cAAc,KAAA,IAAY,QAAQ;GAAE,GAAG;GAAO;EAAU;CACrD,CAAA;AAEhB"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
let _puzzle_ui_core = require("@puzzle-ui/core");
|
|
2
2
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
3
|
// src/components/typography/text.tsx
|
|
4
|
-
const Text = ({ as, type = "body1", className, ...props }) => {
|
|
4
|
+
const Text = ({ as, type = "body1", className, textAlign, style, ...props }) => {
|
|
5
5
|
const Component = as ?? "span";
|
|
6
6
|
const classes = (0, _puzzle_ui_core.cn)("puzzle-text", `puzzle-typography-${type}`, className);
|
|
7
7
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, {
|
|
8
8
|
...props,
|
|
9
|
-
className: classes
|
|
9
|
+
className: classes,
|
|
10
|
+
style: textAlign === void 0 ? style : {
|
|
11
|
+
...style,
|
|
12
|
+
textAlign
|
|
13
|
+
}
|
|
10
14
|
});
|
|
11
15
|
};
|
|
12
16
|
exports.Text = Text;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.cjs","names":["cn"],"sources":["../../../src/components/typography/text.tsx"],"sourcesContent":["import { cn } from \"@puzzle-ui/core\";\nimport type { TypographyStyle } from \"@puzzle-ui/theme\";\nimport type { ComponentPropsWithRef, ElementType } from \"react\";\n\ntype TextType = Omit<\n TypographyStyle,\n \"headline1\" | \"headline2\" | \"headline3\" | \"headline4\"\n>;\n\ntype PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E;\n} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | \"as\">;\n\ntype TextOwnProps = {\n type?: TextType;\n};\n\ntype TextProps<E extends ElementType = \"span\"> = PolymorphicProps<\n E,\n TextOwnProps\n>;\n\nconst Text = <E extends ElementType = \"span\">({\n as,\n type = \"body1\",\n className,\n ...props\n}: TextProps<E>) => {\n const Component = as ?? \"span\";\n const classes = cn(\"puzzle-text\", `puzzle-typography-${type}`, className);\n return <Component
|
|
1
|
+
{"version":3,"file":"text.cjs","names":["cn"],"sources":["../../../src/components/typography/text.tsx"],"sourcesContent":["import { cn } from \"@puzzle-ui/core\";\nimport type { TypographyStyle } from \"@puzzle-ui/theme\";\nimport type { ComponentPropsWithRef, CSSProperties, ElementType } from \"react\";\n\ntype TextType = Omit<\n TypographyStyle,\n \"headline1\" | \"headline2\" | \"headline3\" | \"headline4\"\n>;\n\ntype PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E;\n} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | \"as\">;\n\ntype TextOwnProps = {\n type?: TextType;\n textAlign?: CSSProperties[\"textAlign\"];\n};\n\ntype TextProps<E extends ElementType = \"span\"> = PolymorphicProps<\n E,\n TextOwnProps\n>;\n\nconst Text = <E extends ElementType = \"span\">({\n as,\n type = \"body1\",\n className,\n textAlign,\n style,\n ...props\n}: TextProps<E>) => {\n const Component = as ?? \"span\";\n const classes = cn(\"puzzle-text\", `puzzle-typography-${type}`, className);\n return (\n <Component\n {...props}\n className={classes}\n style={textAlign === undefined ? style : { ...style, textAlign }}\n ></Component>\n );\n};\n\nexport { Text, type TextProps, type TextType };\n"],"mappings":";;;AAuBA,MAAM,QAAwC,EAC5C,IACA,OAAO,SACP,WACA,WACA,OACA,GAAG,YACe;CAClB,MAAM,YAAY,MAAM;CACxB,MAAM,WAAA,GAAUA,gBAAAA,GAAAA,CAAG,eAAe,qBAAqB,QAAQ,SAAS;CACxE,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD;EACE,GAAI;EACJ,WAAW;EACX,OAAO,cAAc,KAAA,IAAY,QAAQ;GAAE,GAAG;GAAO;EAAU;CACrD,CAAA;AAEhB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentPropsWithRef, ElementType } from "react";
|
|
1
|
+
import { CSSProperties, ComponentPropsWithRef, ElementType } from "react";
|
|
2
2
|
import { TypographyStyle } from "@puzzle-ui/theme";
|
|
3
3
|
type TextType = Omit<TypographyStyle, "headline1" | "headline2" | "headline3" | "headline4">;
|
|
4
4
|
type PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {
|
|
@@ -6,7 +6,8 @@ type PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {
|
|
|
6
6
|
} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | "as">;
|
|
7
7
|
type TextOwnProps = {
|
|
8
8
|
type?: TextType;
|
|
9
|
+
textAlign?: CSSProperties["textAlign"];
|
|
9
10
|
};
|
|
10
11
|
type TextProps<E extends ElementType = "span"> = PolymorphicProps<E, TextOwnProps>;
|
|
11
|
-
declare const Text: <E extends ElementType = "span">({ as, type, className, ...props }: TextProps<E>) => import("react").JSX.Element;
|
|
12
|
+
declare const Text: <E extends ElementType = "span">({ as, type, className, textAlign, style, ...props }: TextProps<E>) => import("react").JSX.Element;
|
|
12
13
|
export { Text, type TextProps, type TextType };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentPropsWithRef, ElementType } from "react";
|
|
1
|
+
import { CSSProperties, ComponentPropsWithRef, ElementType } from "react";
|
|
2
2
|
import { TypographyStyle } from "@puzzle-ui/theme";
|
|
3
3
|
type TextType = Omit<TypographyStyle, "headline1" | "headline2" | "headline3" | "headline4">;
|
|
4
4
|
type PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {
|
|
@@ -6,7 +6,8 @@ type PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {
|
|
|
6
6
|
} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | "as">;
|
|
7
7
|
type TextOwnProps = {
|
|
8
8
|
type?: TextType;
|
|
9
|
+
textAlign?: CSSProperties["textAlign"];
|
|
9
10
|
};
|
|
10
11
|
type TextProps<E extends ElementType = "span"> = PolymorphicProps<E, TextOwnProps>;
|
|
11
|
-
declare const Text: <E extends ElementType = "span">({ as, type, className, ...props }: TextProps<E>) => import("react").JSX.Element;
|
|
12
|
+
declare const Text: <E extends ElementType = "span">({ as, type, className, textAlign, style, ...props }: TextProps<E>) => import("react").JSX.Element;
|
|
12
13
|
export { Text, type TextProps, type TextType };
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { cn } from "@puzzle-ui/core";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
// src/components/typography/text.tsx
|
|
4
|
-
const Text = ({ as, type = "body1", className, ...props }) => {
|
|
4
|
+
const Text = ({ as, type = "body1", className, textAlign, style, ...props }) => {
|
|
5
5
|
const Component = as ?? "span";
|
|
6
6
|
const classes = cn("puzzle-text", `puzzle-typography-${type}`, className);
|
|
7
7
|
return /* @__PURE__ */ jsx(Component, {
|
|
8
8
|
...props,
|
|
9
|
-
className: classes
|
|
9
|
+
className: classes,
|
|
10
|
+
style: textAlign === void 0 ? style : {
|
|
11
|
+
...style,
|
|
12
|
+
textAlign
|
|
13
|
+
}
|
|
10
14
|
});
|
|
11
15
|
};
|
|
12
16
|
export { Text };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"sources":["../../../src/components/typography/text.tsx"],"sourcesContent":["import { cn } from \"@puzzle-ui/core\";\nimport type { TypographyStyle } from \"@puzzle-ui/theme\";\nimport type { ComponentPropsWithRef, ElementType } from \"react\";\n\ntype TextType = Omit<\n TypographyStyle,\n \"headline1\" | \"headline2\" | \"headline3\" | \"headline4\"\n>;\n\ntype PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E;\n} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | \"as\">;\n\ntype TextOwnProps = {\n type?: TextType;\n};\n\ntype TextProps<E extends ElementType = \"span\"> = PolymorphicProps<\n E,\n TextOwnProps\n>;\n\nconst Text = <E extends ElementType = \"span\">({\n as,\n type = \"body1\",\n className,\n ...props\n}: TextProps<E>) => {\n const Component = as ?? \"span\";\n const classes = cn(\"puzzle-text\", `puzzle-typography-${type}`, className);\n return <Component
|
|
1
|
+
{"version":3,"file":"text.js","names":[],"sources":["../../../src/components/typography/text.tsx"],"sourcesContent":["import { cn } from \"@puzzle-ui/core\";\nimport type { TypographyStyle } from \"@puzzle-ui/theme\";\nimport type { ComponentPropsWithRef, CSSProperties, ElementType } from \"react\";\n\ntype TextType = Omit<\n TypographyStyle,\n \"headline1\" | \"headline2\" | \"headline3\" | \"headline4\"\n>;\n\ntype PolymorphicProps<E extends ElementType, OwnProps> = OwnProps & {\n as?: E;\n} & Omit<ComponentPropsWithRef<E>, keyof OwnProps | \"as\">;\n\ntype TextOwnProps = {\n type?: TextType;\n textAlign?: CSSProperties[\"textAlign\"];\n};\n\ntype TextProps<E extends ElementType = \"span\"> = PolymorphicProps<\n E,\n TextOwnProps\n>;\n\nconst Text = <E extends ElementType = \"span\">({\n as,\n type = \"body1\",\n className,\n textAlign,\n style,\n ...props\n}: TextProps<E>) => {\n const Component = as ?? \"span\";\n const classes = cn(\"puzzle-text\", `puzzle-typography-${type}`, className);\n return (\n <Component\n {...props}\n className={classes}\n style={textAlign === undefined ? style : { ...style, textAlign }}\n ></Component>\n );\n};\n\nexport { Text, type TextProps, type TextType };\n"],"mappings":";;;AAuBA,MAAM,QAAwC,EAC5C,IACA,OAAO,SACP,WACA,WACA,OACA,GAAG,YACe;CAClB,MAAM,YAAY,MAAM;CACxB,MAAM,UAAU,GAAG,eAAe,qBAAqB,QAAQ,SAAS;CACxE,OACE,oBAAC,WAAD;EACE,GAAI;EACJ,WAAW;EACX,OAAO,cAAc,KAAA,IAAY,QAAQ;GAAE,GAAG;GAAO;EAAU;CACrD,CAAA;AAEhB"}
|
|
@@ -9,6 +9,7 @@ let _puzzle_ui_hooks = require("@puzzle-ui/hooks");
|
|
|
9
9
|
let react_dom = require("react-dom");
|
|
10
10
|
let _puzzle_ui_icons = require("@puzzle-ui/icons");
|
|
11
11
|
let _puzzle_ui_theme_scope_context = require("@puzzle-ui/theme/scope-context");
|
|
12
|
+
let _puzzle_ui_theme = require("@puzzle-ui/theme");
|
|
12
13
|
// src/components/utilities/preview/index.tsx
|
|
13
14
|
const PREVIEW_DEVICES = {
|
|
14
15
|
mobile: {
|
|
@@ -61,7 +62,7 @@ const PreviewBackground = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
|
61
62
|
patternOpacity: .25,
|
|
62
63
|
...props
|
|
63
64
|
});
|
|
64
|
-
const Preview = ({ children, className, defaultDevice = "mobile", code, height, align, justify, hideDevices = false }) => {
|
|
65
|
+
const Preview = ({ children, className, defaultDevice = "mobile", code, fit = "content", height, padding = "var(--puzzle-space-8, 2rem)", align = "center", justify = "center", hideDevices = false }) => {
|
|
65
66
|
const generatedId = (0, react.useId)();
|
|
66
67
|
const frameRootId = `${generatedId}-root`;
|
|
67
68
|
const previewTabId = `${generatedId}-tab-preview`;
|
|
@@ -73,15 +74,28 @@ const Preview = ({ children, className, defaultDevice = "mobile", code, height,
|
|
|
73
74
|
const [frameRoot, setFrameRoot] = (0, react.useState)(null);
|
|
74
75
|
const [scale, setScale] = (0, react.useState)(1);
|
|
75
76
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
77
|
+
const [contentHeight, setContentHeight] = (0, react.useState)(PREVIEW_DEVICES.mobile.height);
|
|
78
|
+
const [contentMeasured, setContentMeasured] = (0, react.useState)(false);
|
|
76
79
|
const containerRef = (0, react.useRef)(null);
|
|
80
|
+
const contentRef = (0, react.useRef)(null);
|
|
77
81
|
const iframeRef = (0, react.useRef)(null);
|
|
78
82
|
const copyTimeoutRef = (0, react.useRef)(null);
|
|
79
83
|
const config = PREVIEW_DEVICES[device];
|
|
80
|
-
const
|
|
84
|
+
const fitsContent = height === void 0 && fit === "content";
|
|
85
|
+
const frameHeight = height ?? (fitsContent ? contentHeight : config.height);
|
|
86
|
+
const showPlaceholder = fitsContent && !contentMeasured;
|
|
81
87
|
const hasCode = code !== void 0;
|
|
82
88
|
const [direction, setDirection] = (0, react.useState)("ltr");
|
|
89
|
+
const [desktopControlsVisible, setDesktopControlsVisible] = (0, react.useState)(true);
|
|
83
90
|
const sectionRef = (0, react.useRef)(null);
|
|
84
91
|
const isKeyboardNavigation = (0, react.useRef)(false);
|
|
92
|
+
(0, react.useEffect)(() => {
|
|
93
|
+
const query = window.matchMedia(`(min-width: ${_puzzle_ui_theme.BREAKPOINTS.desktop}px)`);
|
|
94
|
+
const update = () => setDesktopControlsVisible(query.matches);
|
|
95
|
+
update();
|
|
96
|
+
query.addEventListener("change", update);
|
|
97
|
+
return () => query.removeEventListener("change", update);
|
|
98
|
+
}, []);
|
|
85
99
|
(0, react.useLayoutEffect)(() => {
|
|
86
100
|
const section = sectionRef.current;
|
|
87
101
|
if (section) {
|
|
@@ -95,7 +109,10 @@ const Preview = ({ children, className, defaultDevice = "mobile", code, height,
|
|
|
95
109
|
initialActiveId: activeTab
|
|
96
110
|
});
|
|
97
111
|
const deviceFocus = (0, _puzzle_ui_hooks.useRovingFocus)({
|
|
98
|
-
items: PREVIEW_DEVICE_ITEMS
|
|
112
|
+
items: PREVIEW_DEVICE_ITEMS.map((item) => ({
|
|
113
|
+
...item,
|
|
114
|
+
disabled: item.id === "desktop" && !desktopControlsVisible
|
|
115
|
+
})),
|
|
99
116
|
dir: direction,
|
|
100
117
|
initialActiveId: device
|
|
101
118
|
});
|
|
@@ -142,6 +159,7 @@ const Preview = ({ children, className, defaultDevice = "mobile", code, height,
|
|
|
142
159
|
targetRoot.style.setProperty("height", "100%", "important");
|
|
143
160
|
targetRoot.style.setProperty("min-height", "100%", "important");
|
|
144
161
|
targetRoot.style.setProperty("margin", "0", "important");
|
|
162
|
+
targetRoot.style.setProperty("padding", "0", "important");
|
|
145
163
|
targetRoot.style.setProperty("overflow-x", "hidden", "important");
|
|
146
164
|
targetRoot.style.setProperty("overflow-y", "auto", "important");
|
|
147
165
|
targetRoot.style.setProperty("scrollbar-width", "none", "important");
|
|
@@ -153,6 +171,7 @@ const Preview = ({ children, className, defaultDevice = "mobile", code, height,
|
|
|
153
171
|
body.style.setProperty("height", "auto", "important");
|
|
154
172
|
body.style.setProperty("min-height", "100%", "important");
|
|
155
173
|
body.style.setProperty("margin", "0", "important");
|
|
174
|
+
body.style.setProperty("padding", "0", "important");
|
|
156
175
|
body.style.setProperty("overflow", "visible", "important");
|
|
157
176
|
frameDocument.getElementById(frameRootId)?.style.removeProperty("min-height");
|
|
158
177
|
const scrollbarStyle = frameDocument.createElement("style");
|
|
@@ -174,6 +193,7 @@ const Preview = ({ children, className, defaultDevice = "mobile", code, height,
|
|
|
174
193
|
frameHead.appendChild(scrollbarStyle);
|
|
175
194
|
}, [frameRootId]);
|
|
176
195
|
const updateScale = (0, react.useCallback)((availableWidth) => {
|
|
196
|
+
if (availableWidth <= 0) return;
|
|
177
197
|
const nextScale = Math.min(1, Math.max(0, availableWidth) / config.width);
|
|
178
198
|
setScale((current) => Math.abs(current - nextScale) < .001 ? current : nextScale);
|
|
179
199
|
}, [config.width]);
|
|
@@ -228,6 +248,33 @@ const Preview = ({ children, className, defaultDevice = "mobile", code, height,
|
|
|
228
248
|
(0, react.useEffect)(() => {
|
|
229
249
|
initializeFrame();
|
|
230
250
|
}, [initializeFrame]);
|
|
251
|
+
useIsomorphicLayoutEffect(() => {
|
|
252
|
+
const content = contentRef.current;
|
|
253
|
+
if (!fitsContent || !frameRoot || !content || activeTab !== "preview") return;
|
|
254
|
+
const measure = () => {
|
|
255
|
+
const measuredHeight = Math.ceil(Math.max(content.getBoundingClientRect().height, content.scrollHeight));
|
|
256
|
+
setContentHeight(Math.min(PREVIEW_DEVICES.mobile.height, Math.max(1, measuredHeight)));
|
|
257
|
+
setContentMeasured(true);
|
|
258
|
+
};
|
|
259
|
+
measure();
|
|
260
|
+
const observer = new ResizeObserver(measure);
|
|
261
|
+
observer.observe(content);
|
|
262
|
+
const mutations = new MutationObserver(measure);
|
|
263
|
+
mutations.observe(content, {
|
|
264
|
+
subtree: true,
|
|
265
|
+
childList: true,
|
|
266
|
+
characterData: true,
|
|
267
|
+
attributes: true
|
|
268
|
+
});
|
|
269
|
+
return () => {
|
|
270
|
+
observer.disconnect();
|
|
271
|
+
mutations.disconnect();
|
|
272
|
+
};
|
|
273
|
+
}, [
|
|
274
|
+
activeTab,
|
|
275
|
+
fitsContent,
|
|
276
|
+
frameRoot
|
|
277
|
+
]);
|
|
231
278
|
const handleCopyCode = (0, react.useCallback)(async () => {
|
|
232
279
|
if (code === void 0) return;
|
|
233
280
|
try {
|
|
@@ -251,18 +298,26 @@ const Preview = ({ children, className, defaultDevice = "mobile", code, height,
|
|
|
251
298
|
width: config.width,
|
|
252
299
|
height: frameHeight,
|
|
253
300
|
transform: `scale(${scale})`,
|
|
254
|
-
transformOrigin: "top left"
|
|
301
|
+
transformOrigin: "top left",
|
|
302
|
+
visibility: showPlaceholder ? "hidden" : void 0
|
|
255
303
|
};
|
|
256
304
|
const contentStyle = {
|
|
257
305
|
display: "flex",
|
|
258
306
|
boxSizing: "border-box",
|
|
259
|
-
|
|
307
|
+
padding,
|
|
308
|
+
minHeight: fitsContent ? void 0 : "100vh",
|
|
260
309
|
alignItems: align ? ALIGN_VALUES[align] : void 0,
|
|
261
310
|
justifyContent: justify ? JUSTIFY_VALUES[justify] : void 0
|
|
262
311
|
};
|
|
263
312
|
const viewportStyle = {
|
|
264
313
|
width: config.width * scale,
|
|
265
|
-
|
|
314
|
+
height: showPlaceholder ? void 0 : frameHeight * scale,
|
|
315
|
+
maxHeight: showPlaceholder ? PREVIEW_DEVICES.mobile.height * scale : void 0
|
|
316
|
+
};
|
|
317
|
+
const placeholderStyle = {
|
|
318
|
+
...contentStyle,
|
|
319
|
+
width: config.width,
|
|
320
|
+
zoom: scale === 1 ? void 0 : scale
|
|
266
321
|
};
|
|
267
322
|
const panelProps = {
|
|
268
323
|
id: panelId,
|
|
@@ -313,6 +368,7 @@ const Preview = ({ children, className, defaultDevice = "mobile", code, height,
|
|
|
313
368
|
role: "group",
|
|
314
369
|
"aria-label": "Device size",
|
|
315
370
|
children: Object.keys(PREVIEW_DEVICES).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
371
|
+
"data-device": item,
|
|
316
372
|
ref: deviceFocus.getItemRef(item),
|
|
317
373
|
type: "button",
|
|
318
374
|
className: (0, _puzzle_ui_core.cn)("puzzle-preview__device", device === item && "puzzle-preview__device--active"),
|
|
@@ -353,21 +409,33 @@ const Preview = ({ children, className, defaultDevice = "mobile", code, height,
|
|
|
353
409
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
354
410
|
className: "puzzle-preview__viewport",
|
|
355
411
|
style: viewportStyle,
|
|
356
|
-
children: [
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
style:
|
|
412
|
+
children: [
|
|
413
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
414
|
+
ref: iframeRef,
|
|
415
|
+
className: "puzzle-preview__frame",
|
|
416
|
+
srcDoc: createPreviewDocument(frameRootId),
|
|
417
|
+
title: `${config.label} component preview`,
|
|
418
|
+
onLoad: initializeFrame,
|
|
419
|
+
style: frameStyle
|
|
420
|
+
}),
|
|
421
|
+
showPlaceholder && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
422
|
+
className: "puzzle-preview__placeholder",
|
|
423
|
+
style: placeholderStyle,
|
|
424
|
+
"aria-hidden": "true",
|
|
425
|
+
inert: true,
|
|
426
|
+
"data-preview-placeholder": "",
|
|
368
427
|
children
|
|
369
|
-
})
|
|
370
|
-
|
|
428
|
+
}),
|
|
429
|
+
frameRoot && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_puzzle_ui_theme_scope_context.ThemeScopeProvider, {
|
|
430
|
+
scopeId: themeScope?.scopeId ?? null,
|
|
431
|
+
theme: themeScope?.theme ?? "system",
|
|
432
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
433
|
+
ref: contentRef,
|
|
434
|
+
style: contentStyle,
|
|
435
|
+
children
|
|
436
|
+
})
|
|
437
|
+
}), frameRoot)
|
|
438
|
+
]
|
|
371
439
|
})
|
|
372
440
|
}), activeTab === "code" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
373
441
|
className: "puzzle-preview__code",
|