@gunkin/uiify 0.0.4-alpha → 0.0.6-alpha
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/components/color-picker/ColorPicker.d.ts +4 -34
- package/dist/components/color-picker/ColorPicker.d.ts.map +1 -1
- package/dist/components/color-picker/ColorPicker.js +96 -164
- package/dist/components/color-picker/ColorPicker.js.map +1 -1
- package/dist/components/color-picker/index.d.ts +2 -3
- package/dist/components/color-picker/index.d.ts.map +1 -1
- package/dist/components/color-picker/index.js +2 -40
- package/dist/components/color-picker/index.js.map +1 -1
- package/dist/components/color-picker/types.d.ts +13 -69
- package/dist/components/color-picker/types.d.ts.map +1 -1
- package/dist/components/context-menu/ContextMenu.d.ts.map +1 -1
- package/dist/components/context-menu/ContextMenu.js +13 -1
- package/dist/components/context-menu/ContextMenu.js.map +1 -1
- package/dist/components/number-field/NumberField.d.ts.map +1 -1
- package/dist/components/number-field/NumberField.js +5 -1
- package/dist/components/number-field/NumberField.js.map +1 -1
- package/dist/components/slider/Slider.d.ts.map +1 -1
- package/dist/components/slider/Slider.js +15 -0
- package/dist/components/slider/Slider.js.map +1 -1
- package/dist/components/slider/client/SliderClient.d.ts +7 -0
- package/dist/components/slider/client/SliderClient.d.ts.map +1 -0
- package/dist/components/slider/client/SliderClient.js +170 -0
- package/dist/components/slider/client/SliderClient.js.map +1 -0
- package/dist/components/slider/client/index.d.ts +3 -0
- package/dist/components/slider/client/index.d.ts.map +1 -0
- package/dist/components/slider/client/index.js +5 -0
- package/dist/components/slider/client/index.js.map +1 -0
- package/dist/components/slider/client.d.ts +1 -0
- package/dist/components/slider/client.js +1 -0
- package/dist/components/slider/slider-values.d.ts +4 -0
- package/dist/components/slider/slider-values.d.ts.map +1 -0
- package/dist/components/slider/slider-values.js +26 -0
- package/dist/components/slider/slider-values.js.map +1 -0
- package/dist/components/slider/types.d.ts +26 -1
- package/dist/components/slider/types.d.ts.map +1 -1
- package/dist/styles/index.css +1 -1
- package/package.json +1 -1
- package/dist/components/color-picker/color.d.ts +0 -15
- package/dist/components/color-picker/color.d.ts.map +0 -1
- package/dist/components/color-picker/color.js +0 -190
- package/dist/components/color-picker/color.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/context-menu/ContextMenu.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type {\n ElementType,\n FocusEvent,\n KeyboardEvent,\n MouseEvent,\n PointerEvent,\n ReactElement,\n SyntheticEvent,\n} from \"react\";\nimport { useMergedRefs } from \"@gunkin/uiify/hooks\";\nimport { createPartContext, splitRef } from \"@gunkin/uiify/core\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { RovingFocusItem, RovingFocusRoot } from \"@gunkin/uiify/core/roving-focus\";\nimport { useRenderElement } from \"@gunkin/uiify/core/render\";\nimport { createMenuSelectEvent } from \"../internal/menu/menu-utils.js\";\nimport { focusMenuItem } from \"../internal/menu/focus-menu-item.js\";\nimport { MenuLabel, MenuSeparator } from \"../internal/menu/menu-parts.js\";\nimport { useMenuSurface } from \"../internal/menu/use-menu-surface.js\";\nimport type { MenuSelectEvent } from \"../internal/menu/types.js\";\nimport type {\n ContextMenuContextValue,\n ContextMenuRootProps,\n ContextMenuTriggerProps,\n ContextMenuContentProps,\n ContextMenuItemProps,\n ContextMenuCheckboxItemOwnProps,\n ContextMenuRadioItemOwnProps,\n ContextMenuSubOwnProps,\n ContextMenuSubTriggerOwnProps,\n ContextMenuSubContentOwnProps,\n} from \"./types.js\";\n\nexport type { MenuSelectEvent };\n\nconst [ContextMenuProvider, useContextMenuContext] =\n createPartContext<ContextMenuContextValue>(\"ContextMenu\");\n\nexport function ContextMenuRoot(props: ContextMenuRootProps): ReactElement | null {\n const { children, defaultOpen, onOpenChange, open } = props;\n const virtualAnchorRef = useRef<HTMLSpanElement | null>(null);\n const [radioValue, setRadioValue] = useState<string | undefined>();\n const [pointerAnchor, setPointerAnchor] = useState(false);\n const surface = useMenuSurface({\n align: \"start\",\n mode: \"manual\",\n side: \"bottom\",\n ...(defaultOpen !== undefined ? { defaultOpen } : {}),\n ...(open !== undefined ? { open } : {}),\n ...(onOpenChange ? { onOpenChange } : {}),\n });\n const { contentRef, openPopover, setTriggerElement } = surface;\n\n const openAtPointer = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n event.preventDefault();\n virtualAnchorRef.current?.style.setProperty(\"--uiify-context-menu-x\", `${event.clientX}px`);\n virtualAnchorRef.current?.style.setProperty(\"--uiify-context-menu-y\", `${event.clientY}px`);\n setPointerAnchor(true);\n setTriggerElement(event.currentTarget);\n openPopover();\n queueMicrotask(() => focusMenuItem(contentRef.current));\n },\n [contentRef, openPopover, setTriggerElement],\n );\n\n const contextValue = useMemo<ContextMenuContextValue>(\n () => ({\n ...surface,\n anchorProps: pointerAnchor ? {} : surface.anchorProps,\n openAtPointer,\n radioValue,\n setRadioValue,\n }),\n [pointerAnchor, surface, openAtPointer, radioValue],\n );\n\n return (\n <ContextMenuProvider value={contextValue}>\n <span\n aria-hidden\n ref={(element) => {\n virtualAnchorRef.current = element;\n }}\n data-virtual-anchor=\"\"\n {...(pointerAnchor ? surface.anchorProps : {})}\n style={\n {\n position: \"fixed\",\n left: \"var(--uiify-context-menu-x, 0px)\",\n top: \"var(--uiify-context-menu-y, 0px)\",\n width: 0,\n height: 0,\n pointerEvents: \"none\",\n } as React.CSSProperties\n }\n />\n {children}\n </ContextMenuProvider>\n );\n}\nContextMenuRoot.displayName = \"ContextMenuRoot\";\n\nexport function ContextMenuTrigger<TAs extends ElementType = \"div\">(\n props: ContextMenuTriggerProps<TAs>,\n): ReactElement | null {\n const { as, render, className, ...consumerProps } = props as ContextMenuTriggerProps<\"div\">;\n const { anchorProps, open, openAtPointer, setTriggerElement } = useContextMenuContext(\"Trigger\");\n const [consumerRef, withoutRef] = splitRef<HTMLElement, typeof consumerProps>(consumerProps);\n const mergedRef = useMergedRefs(setTriggerElement, consumerRef);\n const { onContextMenu: consumerOnContextMenu } = withoutRef as {\n onContextMenu?: (event: MouseEvent<HTMLElement>) => void;\n };\n\n return useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...withoutRef,\n ...anchorProps,\n ref: mergedRef,\n ...(className ? { className } : {}),\n onContextMenu: composeEventHandlers(consumerOnContextMenu, openAtPointer),\n },\n render,\n state: { open },\n });\n}\n\nexport function ContextMenuContent<TAs extends ElementType = \"div\">(\n props: ContextMenuContentProps<TAs>,\n): ReactElement | null {\n const { as, className, children, render, ...consumerProps } =\n props as ContextMenuContentProps<\"div\">;\n const { close, contentRef, focusTrigger, open, popupProps, popupRef, positionerProps } =\n useContextMenuContext(\"Content\");\n const [consumerRef, withoutRef] = splitRef<HTMLElement, typeof consumerProps>(consumerProps);\n const mergedRef = useMergedRefs(popupRef, contentRef, consumerRef);\n const { onKeyDown: consumerOnKeyDown } = withoutRef as {\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n close();\n focusTrigger();\n }\n };\n\n const contentProps = {\n ...withoutRef,\n ...popupProps,\n ...positionerProps,\n ref: mergedRef,\n role: \"menu\",\n \"data-part\": \"content\",\n \"data-uiify-menu\": \"\",\n \"data-state\": open ? \"open\" : \"closed\",\n ...(className ? { className } : {}),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n };\n\n if (render) {\n return (\n <RovingFocusRoot\n orientation=\"vertical\"\n render={(renderProps) => render(renderProps, { open })}\n {...contentProps}\n />\n );\n }\n\n return <RovingFocusRoot as={as ?? \"div\"} orientation=\"vertical\" {...contentProps} />;\n}\nContextMenuContent.displayName = \"ContextMenuContent\";\n\nexport function ContextMenuItem<TAs extends ElementType = \"div\">(\n props: ContextMenuItemProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n children,\n className,\n disabled = false,\n onSelect,\n textValue,\n ...consumerProps\n } = props as ContextMenuItemProps<\"div\">;\n const { close, focusTrigger } = useContextMenuContext(\"Item\");\n const { onClick: consumerOnClick, onKeyDown: consumerOnKeyDown } = consumerProps as {\n onClick?: (event: SyntheticEvent<HTMLElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n };\n\n const handleSelect = (event: SyntheticEvent<HTMLElement>) => {\n if (disabled) return;\n const selectEvent = createMenuSelectEvent();\n onSelect?.(selectEvent);\n if (!selectEvent.defaultPrevented) {\n close();\n focusTrigger();\n }\n event.preventDefault();\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") handleSelect(event);\n };\n\n const itemProps = {\n ...consumerProps,\n role: \"menuitem\",\n \"data-part\": \"item\",\n ...(className ? { className } : {}),\n onClick: composeEventHandlers(consumerOnClick, handleSelect),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n };\n\n if (render) {\n return (\n <RovingFocusItem\n disabled={disabled}\n render={render}\n {...(textValue !== undefined ? { textValue } : {})}\n {...(itemProps as object)}\n />\n );\n }\n\n return (\n <RovingFocusItem\n as={as ?? \"div\"}\n disabled={disabled}\n {...(textValue !== undefined ? { textValue } : {})}\n {...(itemProps as object)}\n />\n );\n}\nContextMenuItem.displayName = \"ContextMenuItem\";\n\n/**\n * Shared \"activate this menu item\" logic for CheckboxItem and RadioItem: run\n * the item-specific action, close the menu, and return focus to the trigger,\n * unless disabled. Not promoted to internal/menu — it has no second consumer\n * yet, so it remains local to this component.\n */\nfunction useItemActivation(\n disabled: boolean,\n action: () => void,\n close: () => void,\n focusTrigger: () => void,\n): {\n readonly handleKeyDown: (event: KeyboardEvent<HTMLElement>) => void;\n readonly handleSelect: (event: SyntheticEvent<HTMLElement>) => void;\n} {\n const handleSelect = (event: SyntheticEvent<HTMLElement>) => {\n if (disabled) return;\n action();\n close();\n focusTrigger();\n event.preventDefault();\n };\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") handleSelect(event);\n };\n return { handleKeyDown, handleSelect };\n}\n\nexport function ContextMenuCheckboxItem(\n props: ContextMenuCheckboxItemOwnProps,\n): ReactElement | null {\n const {\n checked = false,\n children,\n className,\n disabled = false,\n onCheckedChange,\n textValue,\n ...consumerProps\n } = props;\n const { close, focusTrigger } = useContextMenuContext(\"CheckboxItem\");\n const isChecked = checked === true;\n const isIndeterminate = checked === \"indeterminate\";\n const { onClick: consumerOnClick, onKeyDown: consumerOnKeyDown } = consumerProps as {\n onClick?: (event: SyntheticEvent<HTMLElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n };\n const { handleKeyDown, handleSelect } = useItemActivation(\n disabled,\n () => onCheckedChange?.(!isChecked),\n close,\n focusTrigger,\n );\n\n return (\n <RovingFocusItem\n disabled={disabled}\n {...(textValue !== undefined ? { textValue } : {})}\n {...{\n ...consumerProps,\n role: \"menuitemcheckbox\",\n \"data-part\": \"item\",\n \"aria-checked\": (isIndeterminate ? \"mixed\" : isChecked) as boolean | \"mixed\",\n \"data-state\": isIndeterminate ? \"indeterminate\" : isChecked ? \"checked\" : \"unchecked\",\n ...(className ? { className } : {}),\n onClick: composeEventHandlers(consumerOnClick, handleSelect),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n }}\n />\n );\n}\nContextMenuCheckboxItem.displayName = \"ContextMenuCheckboxItem\";\n\nexport function ContextMenuRadioItem(props: ContextMenuRadioItemOwnProps): ReactElement | null {\n const { children, className, disabled = false, textValue, value, ...consumerProps } = props;\n const { close, focusTrigger, radioValue, setRadioValue } = useContextMenuContext(\"RadioItem\");\n const checked = radioValue === value;\n const { onClick: consumerOnClick, onKeyDown: consumerOnKeyDown } = consumerProps as {\n onClick?: (event: SyntheticEvent<HTMLElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n };\n const { handleKeyDown, handleSelect } = useItemActivation(\n disabled,\n () => setRadioValue(value),\n close,\n focusTrigger,\n );\n\n return (\n <RovingFocusItem\n disabled={disabled}\n {...(textValue !== undefined ? { textValue } : {})}\n {...{\n ...consumerProps,\n role: \"menuitemradio\",\n \"data-part\": \"item\",\n \"aria-checked\": checked,\n \"data-state\": checked ? \"checked\" : \"unchecked\",\n ...(className ? { className } : {}),\n onClick: composeEventHandlers(consumerOnClick, handleSelect),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n }}\n />\n );\n}\nContextMenuRadioItem.displayName = \"ContextMenuRadioItem\";\n\ninterface ContextMenuSubValue {\n readonly open: boolean;\n readonly setOpen: (open: boolean) => void;\n}\n\nconst [ContextMenuSubProvider, useContextMenuSubContext] = createPartContext<ContextMenuSubValue>(\n \"ContextMenu\",\n \"Sub\",\n);\n\nexport function ContextMenuSub(props: ContextMenuSubOwnProps): ReactElement | null {\n const { children } = props;\n const [open, setOpen] = useState(false);\n const value = useMemo(() => ({ open, setOpen }), [open]);\n return <ContextMenuSubProvider value={value}>{children}</ContextMenuSubProvider>;\n}\nContextMenuSub.displayName = \"ContextMenuSub\";\n\nexport function ContextMenuSubTrigger(props: ContextMenuSubTriggerOwnProps): ReactElement | null {\n const { children, className, disabled = false, textValue, ...consumerProps } = props;\n const sub = useContextMenuSubContext(\"SubTrigger\");\n const {\n onFocus: consumerOnFocus,\n onKeyDown: consumerOnKeyDown,\n onPointerEnter: consumerOnPointerEnter,\n } = consumerProps as {\n onFocus?: (event: FocusEvent<HTMLElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n onPointerEnter?: (event: PointerEvent<HTMLElement>) => void;\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n sub.setOpen(true);\n }\n };\n\n return (\n <RovingFocusItem\n disabled={disabled}\n {...(textValue !== undefined ? { textValue } : {})}\n {...{\n ...consumerProps,\n role: \"menuitem\",\n \"data-part\": \"item\",\n \"aria-haspopup\": \"menu\" as const,\n \"aria-expanded\": sub.open,\n ...(className ? { className } : {}),\n onPointerEnter: composeEventHandlers(consumerOnPointerEnter, () => sub.setOpen(true)),\n onFocus: composeEventHandlers(consumerOnFocus, () => sub.setOpen(true)),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n }}\n />\n );\n}\nContextMenuSubTrigger.displayName = \"ContextMenuSubTrigger\";\n\nexport function ContextMenuSubContent(props: ContextMenuSubContentOwnProps): ReactElement | null {\n const { children, className } = props;\n const sub = useContextMenuSubContext(\"SubContent\");\n\n const element = useRenderElement({\n defaultTag: \"div\",\n props: {\n role: \"menu\",\n \"data-part\": \"sub-content\",\n \"data-uiify-menu\": \"\",\n \"data-state\": sub.open ? \"open\" : \"closed\",\n hidden: !sub.open ? true : undefined,\n ...(className ? { className } : {}),\n children: sub.open ? children : null,\n },\n state: { open: sub.open },\n });\n\n if (!sub.open) return null;\n return element;\n}\n\nexport const ContextMenuLabel = MenuLabel;\n\nexport const ContextMenuSeparator = MenuSeparator;\n\nexport const ContextMenu = {\n CheckboxItem: ContextMenuCheckboxItem,\n Content: ContextMenuContent,\n Item: ContextMenuItem,\n Label: ContextMenuLabel,\n RadioItem: ContextMenuRadioItem,\n Root: ContextMenuRoot,\n Separator: ContextMenuSeparator,\n Sub: Object.assign(ContextMenuSub, {\n Content: ContextMenuSubContent,\n Trigger: ContextMenuSubTrigger,\n }),\n Trigger: ContextMenuTrigger,\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/context-menu/ContextMenu.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type {\n ElementType,\n FocusEvent,\n KeyboardEvent,\n MouseEvent,\n PointerEvent as ReactPointerEvent,\n ReactElement,\n SyntheticEvent,\n} from \"react\";\nimport { useIsomorphicLayoutEffect, useMergedRefs } from \"@gunkin/uiify/hooks\";\nimport { createPartContext, splitRef } from \"@gunkin/uiify/core\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { RovingFocusItem, RovingFocusRoot } from \"@gunkin/uiify/core/roving-focus\";\nimport { useRenderElement } from \"@gunkin/uiify/core/render\";\nimport { createMenuSelectEvent } from \"../internal/menu/menu-utils.js\";\nimport { focusMenuItem } from \"../internal/menu/focus-menu-item.js\";\nimport { MenuLabel, MenuSeparator } from \"../internal/menu/menu-parts.js\";\nimport { useMenuSurface } from \"../internal/menu/use-menu-surface.js\";\nimport type { MenuSelectEvent } from \"../internal/menu/types.js\";\nimport type {\n ContextMenuContextValue,\n ContextMenuRootProps,\n ContextMenuTriggerProps,\n ContextMenuContentProps,\n ContextMenuItemProps,\n ContextMenuCheckboxItemOwnProps,\n ContextMenuRadioItemOwnProps,\n ContextMenuSubOwnProps,\n ContextMenuSubTriggerOwnProps,\n ContextMenuSubContentOwnProps,\n} from \"./types.js\";\n\nexport type { MenuSelectEvent };\n\nconst [ContextMenuProvider, useContextMenuContext] =\n createPartContext<ContextMenuContextValue>(\"ContextMenu\");\n\nexport function ContextMenuRoot(props: ContextMenuRootProps): ReactElement | null {\n const { children, defaultOpen, onOpenChange, open } = props;\n const virtualAnchorRef = useRef<HTMLSpanElement | null>(null);\n const [radioValue, setRadioValue] = useState<string | undefined>();\n const [pointerAnchor, setPointerAnchor] = useState(false);\n const surface = useMenuSurface({\n align: \"start\",\n mode: \"manual\",\n side: \"bottom\",\n ...(defaultOpen !== undefined ? { defaultOpen } : {}),\n ...(open !== undefined ? { open } : {}),\n ...(onOpenChange ? { onOpenChange } : {}),\n });\n const { contentRef, openPopover, setTriggerElement } = surface;\n\n const openAtPointer = useCallback(\n (event: MouseEvent<HTMLElement>) => {\n event.preventDefault();\n virtualAnchorRef.current?.style.setProperty(\"--uiify-context-menu-x\", `${event.clientX}px`);\n virtualAnchorRef.current?.style.setProperty(\"--uiify-context-menu-y\", `${event.clientY}px`);\n setPointerAnchor(true);\n setTriggerElement(event.currentTarget);\n openPopover();\n queueMicrotask(() => focusMenuItem(contentRef.current));\n },\n [contentRef, openPopover, setTriggerElement],\n );\n\n const contextValue = useMemo<ContextMenuContextValue>(\n () => ({\n ...surface,\n anchorProps: pointerAnchor ? {} : surface.anchorProps,\n openAtPointer,\n radioValue,\n setRadioValue,\n }),\n [pointerAnchor, surface, openAtPointer, radioValue],\n );\n\n return (\n <ContextMenuProvider value={contextValue}>\n <span\n aria-hidden\n ref={(element) => {\n virtualAnchorRef.current = element;\n }}\n data-virtual-anchor=\"\"\n {...(pointerAnchor ? surface.anchorProps : {})}\n style={\n {\n position: \"fixed\",\n left: \"var(--uiify-context-menu-x, 0px)\",\n top: \"var(--uiify-context-menu-y, 0px)\",\n width: 0,\n height: 0,\n pointerEvents: \"none\",\n } as React.CSSProperties\n }\n />\n {children}\n </ContextMenuProvider>\n );\n}\nContextMenuRoot.displayName = \"ContextMenuRoot\";\n\nexport function ContextMenuTrigger<TAs extends ElementType = \"div\">(\n props: ContextMenuTriggerProps<TAs>,\n): ReactElement | null {\n const { as, render, className, ...consumerProps } = props as ContextMenuTriggerProps<\"div\">;\n const { anchorProps, open, openAtPointer, setTriggerElement } = useContextMenuContext(\"Trigger\");\n const [consumerRef, withoutRef] = splitRef<HTMLElement, typeof consumerProps>(consumerProps);\n const mergedRef = useMergedRefs(setTriggerElement, consumerRef);\n const { onContextMenu: consumerOnContextMenu } = withoutRef as {\n onContextMenu?: (event: MouseEvent<HTMLElement>) => void;\n };\n\n return useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...withoutRef,\n ...anchorProps,\n ref: mergedRef,\n ...(className ? { className } : {}),\n onContextMenu: composeEventHandlers(consumerOnContextMenu, openAtPointer),\n },\n render,\n state: { open },\n });\n}\n\nexport function ContextMenuContent<TAs extends ElementType = \"div\">(\n props: ContextMenuContentProps<TAs>,\n): ReactElement | null {\n const { as, className, children, render, ...consumerProps } =\n props as ContextMenuContentProps<\"div\">;\n const { close, contentRef, focusTrigger, open, popupProps, popupRef, positionerProps } =\n useContextMenuContext(\"Content\");\n const [consumerRef, withoutRef] = splitRef<HTMLElement, typeof consumerProps>(consumerProps);\n const mergedRef = useMergedRefs(popupRef, contentRef, consumerRef);\n\n useIsomorphicLayoutEffect(() => {\n if (!open) return;\n\n const content = contentRef.current;\n const ownerDocument = content?.ownerDocument;\n if (!content || !ownerDocument) return;\n\n const handlePointerDown = (event: PointerEvent) => {\n if (event.composedPath().includes(content)) return;\n close();\n };\n\n ownerDocument.addEventListener(\"pointerdown\", handlePointerDown, true);\n return () => ownerDocument.removeEventListener(\"pointerdown\", handlePointerDown, true);\n }, [close, contentRef, open]);\n\n const { onKeyDown: consumerOnKeyDown } = withoutRef as {\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n close();\n focusTrigger();\n }\n };\n\n const contentProps = {\n ...withoutRef,\n ...popupProps,\n ...positionerProps,\n ref: mergedRef,\n role: \"menu\",\n \"data-part\": \"content\",\n \"data-uiify-menu\": \"\",\n \"data-state\": open ? \"open\" : \"closed\",\n ...(className ? { className } : {}),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n };\n\n if (render) {\n return (\n <RovingFocusRoot\n orientation=\"vertical\"\n render={(renderProps) => render(renderProps, { open })}\n {...contentProps}\n />\n );\n }\n\n return <RovingFocusRoot as={as ?? \"div\"} orientation=\"vertical\" {...contentProps} />;\n}\nContextMenuContent.displayName = \"ContextMenuContent\";\n\nexport function ContextMenuItem<TAs extends ElementType = \"div\">(\n props: ContextMenuItemProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n children,\n className,\n disabled = false,\n onSelect,\n textValue,\n ...consumerProps\n } = props as ContextMenuItemProps<\"div\">;\n const { close, focusTrigger } = useContextMenuContext(\"Item\");\n const { onClick: consumerOnClick, onKeyDown: consumerOnKeyDown } = consumerProps as {\n onClick?: (event: SyntheticEvent<HTMLElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n };\n\n const handleSelect = (event: SyntheticEvent<HTMLElement>) => {\n if (disabled) return;\n const selectEvent = createMenuSelectEvent();\n onSelect?.(selectEvent);\n if (!selectEvent.defaultPrevented) {\n close();\n focusTrigger();\n }\n event.preventDefault();\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") handleSelect(event);\n };\n\n const itemProps = {\n ...consumerProps,\n role: \"menuitem\",\n \"data-part\": \"item\",\n ...(className ? { className } : {}),\n onClick: composeEventHandlers(consumerOnClick, handleSelect),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n };\n\n if (render) {\n return (\n <RovingFocusItem\n disabled={disabled}\n render={render}\n {...(textValue !== undefined ? { textValue } : {})}\n {...(itemProps as object)}\n />\n );\n }\n\n return (\n <RovingFocusItem\n as={as ?? \"div\"}\n disabled={disabled}\n {...(textValue !== undefined ? { textValue } : {})}\n {...(itemProps as object)}\n />\n );\n}\nContextMenuItem.displayName = \"ContextMenuItem\";\n\n/**\n * Shared \"activate this menu item\" logic for CheckboxItem and RadioItem: run\n * the item-specific action, close the menu, and return focus to the trigger,\n * unless disabled. Not promoted to internal/menu — it has no second consumer\n * yet, so it remains local to this component.\n */\nfunction useItemActivation(\n disabled: boolean,\n action: () => void,\n close: () => void,\n focusTrigger: () => void,\n): {\n readonly handleKeyDown: (event: KeyboardEvent<HTMLElement>) => void;\n readonly handleSelect: (event: SyntheticEvent<HTMLElement>) => void;\n} {\n const handleSelect = (event: SyntheticEvent<HTMLElement>) => {\n if (disabled) return;\n action();\n close();\n focusTrigger();\n event.preventDefault();\n };\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") handleSelect(event);\n };\n return { handleKeyDown, handleSelect };\n}\n\nexport function ContextMenuCheckboxItem(\n props: ContextMenuCheckboxItemOwnProps,\n): ReactElement | null {\n const {\n checked = false,\n children,\n className,\n disabled = false,\n onCheckedChange,\n textValue,\n ...consumerProps\n } = props;\n const { close, focusTrigger } = useContextMenuContext(\"CheckboxItem\");\n const isChecked = checked === true;\n const isIndeterminate = checked === \"indeterminate\";\n const { onClick: consumerOnClick, onKeyDown: consumerOnKeyDown } = consumerProps as {\n onClick?: (event: SyntheticEvent<HTMLElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n };\n const { handleKeyDown, handleSelect } = useItemActivation(\n disabled,\n () => onCheckedChange?.(!isChecked),\n close,\n focusTrigger,\n );\n\n return (\n <RovingFocusItem\n disabled={disabled}\n {...(textValue !== undefined ? { textValue } : {})}\n {...{\n ...consumerProps,\n role: \"menuitemcheckbox\",\n \"data-part\": \"item\",\n \"aria-checked\": (isIndeterminate ? \"mixed\" : isChecked) as boolean | \"mixed\",\n \"data-state\": isIndeterminate ? \"indeterminate\" : isChecked ? \"checked\" : \"unchecked\",\n ...(className ? { className } : {}),\n onClick: composeEventHandlers(consumerOnClick, handleSelect),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n }}\n />\n );\n}\nContextMenuCheckboxItem.displayName = \"ContextMenuCheckboxItem\";\n\nexport function ContextMenuRadioItem(props: ContextMenuRadioItemOwnProps): ReactElement | null {\n const { children, className, disabled = false, textValue, value, ...consumerProps } = props;\n const { close, focusTrigger, radioValue, setRadioValue } = useContextMenuContext(\"RadioItem\");\n const checked = radioValue === value;\n const { onClick: consumerOnClick, onKeyDown: consumerOnKeyDown } = consumerProps as {\n onClick?: (event: SyntheticEvent<HTMLElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n };\n const { handleKeyDown, handleSelect } = useItemActivation(\n disabled,\n () => setRadioValue(value),\n close,\n focusTrigger,\n );\n\n return (\n <RovingFocusItem\n disabled={disabled}\n {...(textValue !== undefined ? { textValue } : {})}\n {...{\n ...consumerProps,\n role: \"menuitemradio\",\n \"data-part\": \"item\",\n \"aria-checked\": checked,\n \"data-state\": checked ? \"checked\" : \"unchecked\",\n ...(className ? { className } : {}),\n onClick: composeEventHandlers(consumerOnClick, handleSelect),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n }}\n />\n );\n}\nContextMenuRadioItem.displayName = \"ContextMenuRadioItem\";\n\ninterface ContextMenuSubValue {\n readonly open: boolean;\n readonly setOpen: (open: boolean) => void;\n}\n\nconst [ContextMenuSubProvider, useContextMenuSubContext] = createPartContext<ContextMenuSubValue>(\n \"ContextMenu\",\n \"Sub\",\n);\n\nexport function ContextMenuSub(props: ContextMenuSubOwnProps): ReactElement | null {\n const { children } = props;\n const [open, setOpen] = useState(false);\n const value = useMemo(() => ({ open, setOpen }), [open]);\n return <ContextMenuSubProvider value={value}>{children}</ContextMenuSubProvider>;\n}\nContextMenuSub.displayName = \"ContextMenuSub\";\n\nexport function ContextMenuSubTrigger(props: ContextMenuSubTriggerOwnProps): ReactElement | null {\n const { children, className, disabled = false, textValue, ...consumerProps } = props;\n const sub = useContextMenuSubContext(\"SubTrigger\");\n const {\n onFocus: consumerOnFocus,\n onKeyDown: consumerOnKeyDown,\n onPointerEnter: consumerOnPointerEnter,\n } = consumerProps as {\n onFocus?: (event: FocusEvent<HTMLElement>) => void;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n onPointerEnter?: (event: ReactPointerEvent<HTMLElement>) => void;\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key === \"ArrowRight\") {\n event.preventDefault();\n sub.setOpen(true);\n }\n };\n\n return (\n <RovingFocusItem\n disabled={disabled}\n {...(textValue !== undefined ? { textValue } : {})}\n {...{\n ...consumerProps,\n role: \"menuitem\",\n \"data-part\": \"item\",\n \"aria-haspopup\": \"menu\" as const,\n \"aria-expanded\": sub.open,\n ...(className ? { className } : {}),\n onPointerEnter: composeEventHandlers(consumerOnPointerEnter, () => sub.setOpen(true)),\n onFocus: composeEventHandlers(consumerOnFocus, () => sub.setOpen(true)),\n onKeyDown: composeEventHandlers(consumerOnKeyDown, handleKeyDown),\n children,\n }}\n />\n );\n}\nContextMenuSubTrigger.displayName = \"ContextMenuSubTrigger\";\n\nexport function ContextMenuSubContent(props: ContextMenuSubContentOwnProps): ReactElement | null {\n const { children, className } = props;\n const sub = useContextMenuSubContext(\"SubContent\");\n\n const element = useRenderElement({\n defaultTag: \"div\",\n props: {\n role: \"menu\",\n \"data-part\": \"sub-content\",\n \"data-uiify-menu\": \"\",\n \"data-state\": sub.open ? \"open\" : \"closed\",\n hidden: !sub.open ? true : undefined,\n ...(className ? { className } : {}),\n children: sub.open ? children : null,\n },\n state: { open: sub.open },\n });\n\n if (!sub.open) return null;\n return element;\n}\n\nexport const ContextMenuLabel = MenuLabel;\n\nexport const ContextMenuSeparator = MenuSeparator;\n\nexport const ContextMenu = {\n CheckboxItem: ContextMenuCheckboxItem,\n Content: ContextMenuContent,\n Item: ContextMenuItem,\n Label: ContextMenuLabel,\n RadioItem: ContextMenuRadioItem,\n Root: ContextMenuRoot,\n Separator: ContextMenuSeparator,\n Sub: Object.assign(ContextMenuSub, {\n Content: ContextMenuSubContent,\n Trigger: ContextMenuSubTrigger,\n }),\n Trigger: ContextMenuTrigger,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NumberField.d.ts","sourceRoot":"","sources":["../../../src/components/number-field/NumberField.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,WAAW,EAGhB,KAAK,YAAY,EAGlB,MAAM,OAAO,CAAC;AAOf,OAAO,KAAK,EAEV,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,eAAe,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EAC7D,KAAK,EAAE,oBAAoB,CAAC,GAAG,CAAC,GAC/B,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"NumberField.d.ts","sourceRoot":"","sources":["../../../src/components/number-field/NumberField.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,WAAW,EAGhB,KAAK,YAAY,EAGlB,MAAM,OAAO,CAAC;AAOf,OAAO,KAAK,EAEV,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,eAAe,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EAC7D,KAAK,EAAE,oBAAoB,CAAC,GAAG,CAAC,GAC/B,YAAY,GAAG,IAAI,CAoIrB;yBAtIe,eAAe;;;AAyI/B,wBAAgB,gBAAgB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EAC9D,KAAK,EAAE,qBAAqB,CAAC,GAAG,CAAC,GAChC,YAAY,GAAG,IAAI,CAWrB;AAED,wBAAgB,gBAAgB,CAAC,GAAG,SAAS,WAAW,GAAG,OAAO,EAChE,KAAK,EAAE,qBAAqB,CAAC,GAAG,CAAC,GAChC,YAAY,GAAG,IAAI,CAsFrB;AAED,wBAAgB,oBAAoB,CAAC,GAAG,SAAS,WAAW,GAAG,QAAQ,EACrE,KAAK,EAAE,yBAAyB,CAAC,GAAG,CAAC,GACpC,YAAY,GAAG,IAAI,CAiCrB;AAED,wBAAgB,oBAAoB,CAAC,GAAG,SAAS,WAAW,GAAG,QAAQ,EACrE,KAAK,EAAE,yBAAyB,CAAC,GAAG,CAAC,GACpC,YAAY,GAAG,IAAI,CAiCrB;AAED,eAAO,MAAM,WAAW;;;;;;CAMvB,CAAC"}
|
|
@@ -122,7 +122,11 @@ function NumberFieldRoot(props) {
|
|
|
122
122
|
const element = useRenderElement({
|
|
123
123
|
as,
|
|
124
124
|
defaultTag: "div",
|
|
125
|
-
props: {
|
|
125
|
+
props: {
|
|
126
|
+
...consumerProps,
|
|
127
|
+
"data-disabled": disabled ? "" : void 0,
|
|
128
|
+
"data-uiify-number-field": ""
|
|
129
|
+
},
|
|
126
130
|
render,
|
|
127
131
|
state: { disabled, readOnly, required }
|
|
128
132
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/number-field/NumberField.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useMemo,\n useRef,\n useState,\n type ElementType,\n type FocusEvent,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type SyntheticEvent,\n} from \"react\";\nimport { useControllableState, useId } from \"@gunkin/uiify/hooks\";\nimport { createPartContext } from \"@gunkin/uiify/core\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { useRenderElement, type PolymorphicProps } from \"@gunkin/uiify/core/render\";\nimport { clampNumber, createFormatter, formatNumber, parseNumber, stepNumber } from \"./format.js\";\nimport { usePressRepeat } from \"./use-press-repeat.js\";\nimport type {\n NumberFieldContextValue,\n NumberFieldRootProps,\n NumberFieldGroupProps,\n NumberFieldInputProps,\n NumberFieldIncrementProps,\n NumberFieldDecrementProps,\n} from \"./types.js\";\n\nexport type {\n NumberFieldDecrementProps,\n NumberFieldGroupProps,\n NumberFieldIncrementProps,\n NumberFieldInputProps,\n NumberFieldRootOwnProps,\n NumberFieldRootProps,\n} from \"./types.js\";\n\nconst [NumberFieldProvider, useNumberFieldContext] =\n createPartContext<NumberFieldContextValue>(\"NumberField\");\n\nexport function NumberFieldRoot<TAs extends ElementType = \"div\">(\n props: NumberFieldRootProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n value: controlledValue,\n defaultValue,\n onChange,\n min,\n max,\n step = 1,\n formatOptions,\n clampValueOnBlur = true,\n disabled = false,\n readOnly = false,\n required = false,\n ...consumerProps\n } = props as NumberFieldRootProps<ElementType>;\n\n const inputId = useId();\n const inputRef = useRef<HTMLInputElement>(null);\n const formatter = useMemo(() => createFormatter(formatOptions), [formatOptions]);\n const [value, setValue] = useControllableState<number | undefined>({\n value: controlledValue,\n defaultValue,\n onChange,\n });\n const [editing, setEditing] = useState(false);\n const [displayValue, setDisplayValue] = useState(() =>\n value === undefined ? \"\" : formatNumber(value, formatter),\n );\n\n const syncDisplay = useCallback(\n (next: number | undefined) => {\n setDisplayValue(next === undefined ? \"\" : formatNumber(next, formatter));\n },\n [formatter],\n );\n\n const applyValue = useCallback(\n (next: number | undefined) => {\n const clamped =\n next === undefined ? undefined : clampValueOnBlur ? clampNumber(next, min, max) : next;\n setValue(clamped);\n syncDisplay(clamped);\n },\n [clampValueOnBlur, max, min, setValue, syncDisplay],\n );\n\n const increment = useCallback(\n (multiplier = 1) => {\n if (disabled || readOnly) return;\n const base = value ?? min ?? 0;\n applyValue(stepNumber(base, multiplier, step, min, max));\n },\n [applyValue, disabled, max, min, readOnly, step, value],\n );\n\n const decrement = useCallback(\n (multiplier = 1) => {\n increment(-multiplier);\n },\n [increment],\n );\n\n const commitInput = useCallback(\n (raw: string) => {\n const parsed = parseNumber(raw, formatter);\n if (parsed === undefined) {\n syncDisplay(value);\n return;\n }\n applyValue(parsed);\n },\n [applyValue, formatter, syncDisplay, value],\n );\n\n const contextValue = useMemo<NumberFieldContextValue>(\n () => ({\n clampValueOnBlur,\n commitInput,\n decrement,\n disabled,\n displayValue: editing\n ? displayValue\n : value === undefined\n ? \"\"\n : formatNumber(value, formatter),\n formatter,\n increment,\n inputId,\n inputRef,\n max,\n min,\n numericValue: value,\n readOnly,\n required,\n setDisplayValue,\n setEditing,\n step,\n }),\n [\n clampValueOnBlur,\n commitInput,\n decrement,\n disabled,\n displayValue,\n editing,\n formatter,\n increment,\n inputId,\n max,\n min,\n readOnly,\n required,\n step,\n value,\n ],\n );\n\n const element = useRenderElement({\n as,\n defaultTag: \"div\",\n props: { ...consumerProps, \"data-disabled\": disabled ? \"\" : undefined },\n render,\n state: { disabled, readOnly, required },\n });\n\n return <NumberFieldProvider value={contextValue}>{element}</NumberFieldProvider>;\n}\nNumberFieldRoot.displayName = \"NumberFieldRoot\";\n\nexport function NumberFieldGroup<TAs extends ElementType = \"div\">(\n props: NumberFieldGroupProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as NumberFieldGroupProps<ElementType>;\n const { disabled } = useNumberFieldContext(\"Group\");\n\n return useRenderElement({\n as,\n defaultTag: \"div\",\n props: { ...consumerProps, \"data-disabled\": disabled ? \"\" : undefined },\n render,\n state: { disabled },\n });\n}\n\nexport function NumberFieldInput<TAs extends ElementType = \"input\">(\n props: NumberFieldInputProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as NumberFieldInputProps<\"input\">;\n const {\n commitInput,\n decrement,\n disabled,\n displayValue,\n increment,\n inputId,\n inputRef,\n max,\n min,\n numericValue,\n readOnly,\n required,\n setDisplayValue,\n setEditing,\n } = useNumberFieldContext(\"Input\");\n\n const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly) return;\n switch (event.key) {\n case \"ArrowUp\":\n event.preventDefault();\n increment();\n break;\n case \"ArrowDown\":\n event.preventDefault();\n decrement();\n break;\n case \"PageUp\":\n event.preventDefault();\n increment(10);\n break;\n case \"PageDown\":\n event.preventDefault();\n decrement(10);\n break;\n case \"Home\":\n event.preventDefault();\n if (min !== undefined) commitInput(String(min));\n break;\n case \"End\":\n event.preventDefault();\n if (max !== undefined) commitInput(String(max));\n break;\n default:\n break;\n }\n };\n\n return useRenderElement({\n as,\n defaultTag: \"input\",\n props: {\n ...consumerProps,\n id: inputId,\n ref: inputRef,\n role: \"spinbutton\",\n inputMode: \"decimal\",\n \"aria-valuenow\": numericValue,\n \"aria-valuemin\": min,\n \"aria-valuemax\": max,\n \"aria-required\": required || undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-readonly\": readOnly ? \"\" : undefined,\n disabled: disabled || undefined,\n readOnly: readOnly || undefined,\n required: required || undefined,\n value: displayValue,\n onFocus: composeEventHandlers(consumerProps.onFocus, () => setEditing(true)),\n onBlur: composeEventHandlers(consumerProps.onBlur, (event: FocusEvent<HTMLInputElement>) => {\n setEditing(false);\n commitInput(event.currentTarget.value);\n }),\n onChange: composeEventHandlers(\n consumerProps.onChange,\n (event: SyntheticEvent<HTMLInputElement>) => {\n setDisplayValue(event.currentTarget.value);\n },\n ),\n onKeyDown: composeEventHandlers(consumerProps.onKeyDown, onKeyDown),\n },\n render,\n state: { disabled, readOnly, required },\n });\n}\n\nexport function NumberFieldIncrement<TAs extends ElementType = \"button\">(\n props: NumberFieldIncrementProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as PolymorphicProps<\n \"button\",\n { readonly children?: ReactNode }\n >;\n const { disabled, increment, readOnly } = useNumberFieldContext(\"Increment\");\n const inactive = disabled || readOnly;\n const repeatProps = usePressRepeat(() => increment(), inactive);\n\n return useRenderElement({\n as,\n defaultTag: \"button\",\n props: {\n ...consumerProps,\n type: \"button\",\n tabIndex: -1,\n \"data-disabled\": inactive ? \"\" : undefined,\n disabled: inactive || undefined,\n onClick: composeEventHandlers(consumerProps.onClick, () => increment()),\n onPointerDown: composeEventHandlers(consumerProps.onPointerDown, repeatProps.onPointerDown),\n onPointerUp: composeEventHandlers(consumerProps.onPointerUp, repeatProps.onPointerUp),\n onPointerLeave: composeEventHandlers(\n consumerProps.onPointerLeave,\n repeatProps.onPointerLeave,\n ),\n onPointerCancel: composeEventHandlers(\n consumerProps.onPointerCancel,\n repeatProps.onPointerCancel,\n ),\n },\n render,\n state: { disabled: inactive },\n });\n}\n\nexport function NumberFieldDecrement<TAs extends ElementType = \"button\">(\n props: NumberFieldDecrementProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as PolymorphicProps<\n \"button\",\n { readonly children?: ReactNode }\n >;\n const { decrement, disabled, readOnly } = useNumberFieldContext(\"Decrement\");\n const inactive = disabled || readOnly;\n const repeatProps = usePressRepeat(() => decrement(), inactive);\n\n return useRenderElement({\n as,\n defaultTag: \"button\",\n props: {\n ...consumerProps,\n type: \"button\",\n tabIndex: -1,\n \"data-disabled\": inactive ? \"\" : undefined,\n disabled: inactive || undefined,\n onClick: composeEventHandlers(consumerProps.onClick, () => decrement()),\n onPointerDown: composeEventHandlers(consumerProps.onPointerDown, repeatProps.onPointerDown),\n onPointerUp: composeEventHandlers(consumerProps.onPointerUp, repeatProps.onPointerUp),\n onPointerLeave: composeEventHandlers(\n consumerProps.onPointerLeave,\n repeatProps.onPointerLeave,\n ),\n onPointerCancel: composeEventHandlers(\n consumerProps.onPointerCancel,\n repeatProps.onPointerCancel,\n ),\n },\n render,\n state: { disabled: inactive },\n });\n}\n\nexport const NumberField = {\n Root: NumberFieldRoot,\n Group: NumberFieldGroup,\n Input: NumberFieldInput,\n Increment: NumberFieldIncrement,\n Decrement: NumberFieldDecrement,\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/number-field/NumberField.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useCallback,\n useMemo,\n useRef,\n useState,\n type ElementType,\n type FocusEvent,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type SyntheticEvent,\n} from \"react\";\nimport { useControllableState, useId } from \"@gunkin/uiify/hooks\";\nimport { createPartContext } from \"@gunkin/uiify/core\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { useRenderElement, type PolymorphicProps } from \"@gunkin/uiify/core/render\";\nimport { clampNumber, createFormatter, formatNumber, parseNumber, stepNumber } from \"./format.js\";\nimport { usePressRepeat } from \"./use-press-repeat.js\";\nimport type {\n NumberFieldContextValue,\n NumberFieldRootProps,\n NumberFieldGroupProps,\n NumberFieldInputProps,\n NumberFieldIncrementProps,\n NumberFieldDecrementProps,\n} from \"./types.js\";\n\nexport type {\n NumberFieldDecrementProps,\n NumberFieldGroupProps,\n NumberFieldIncrementProps,\n NumberFieldInputProps,\n NumberFieldRootOwnProps,\n NumberFieldRootProps,\n} from \"./types.js\";\n\nconst [NumberFieldProvider, useNumberFieldContext] =\n createPartContext<NumberFieldContextValue>(\"NumberField\");\n\nexport function NumberFieldRoot<TAs extends ElementType = \"div\">(\n props: NumberFieldRootProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n value: controlledValue,\n defaultValue,\n onChange,\n min,\n max,\n step = 1,\n formatOptions,\n clampValueOnBlur = true,\n disabled = false,\n readOnly = false,\n required = false,\n ...consumerProps\n } = props as NumberFieldRootProps<ElementType>;\n\n const inputId = useId();\n const inputRef = useRef<HTMLInputElement>(null);\n const formatter = useMemo(() => createFormatter(formatOptions), [formatOptions]);\n const [value, setValue] = useControllableState<number | undefined>({\n value: controlledValue,\n defaultValue,\n onChange,\n });\n const [editing, setEditing] = useState(false);\n const [displayValue, setDisplayValue] = useState(() =>\n value === undefined ? \"\" : formatNumber(value, formatter),\n );\n\n const syncDisplay = useCallback(\n (next: number | undefined) => {\n setDisplayValue(next === undefined ? \"\" : formatNumber(next, formatter));\n },\n [formatter],\n );\n\n const applyValue = useCallback(\n (next: number | undefined) => {\n const clamped =\n next === undefined ? undefined : clampValueOnBlur ? clampNumber(next, min, max) : next;\n setValue(clamped);\n syncDisplay(clamped);\n },\n [clampValueOnBlur, max, min, setValue, syncDisplay],\n );\n\n const increment = useCallback(\n (multiplier = 1) => {\n if (disabled || readOnly) return;\n const base = value ?? min ?? 0;\n applyValue(stepNumber(base, multiplier, step, min, max));\n },\n [applyValue, disabled, max, min, readOnly, step, value],\n );\n\n const decrement = useCallback(\n (multiplier = 1) => {\n increment(-multiplier);\n },\n [increment],\n );\n\n const commitInput = useCallback(\n (raw: string) => {\n const parsed = parseNumber(raw, formatter);\n if (parsed === undefined) {\n syncDisplay(value);\n return;\n }\n applyValue(parsed);\n },\n [applyValue, formatter, syncDisplay, value],\n );\n\n const contextValue = useMemo<NumberFieldContextValue>(\n () => ({\n clampValueOnBlur,\n commitInput,\n decrement,\n disabled,\n displayValue: editing\n ? displayValue\n : value === undefined\n ? \"\"\n : formatNumber(value, formatter),\n formatter,\n increment,\n inputId,\n inputRef,\n max,\n min,\n numericValue: value,\n readOnly,\n required,\n setDisplayValue,\n setEditing,\n step,\n }),\n [\n clampValueOnBlur,\n commitInput,\n decrement,\n disabled,\n displayValue,\n editing,\n formatter,\n increment,\n inputId,\n max,\n min,\n readOnly,\n required,\n step,\n value,\n ],\n );\n\n const element = useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...consumerProps,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-uiify-number-field\": \"\",\n },\n render,\n state: { disabled, readOnly, required },\n });\n\n return <NumberFieldProvider value={contextValue}>{element}</NumberFieldProvider>;\n}\nNumberFieldRoot.displayName = \"NumberFieldRoot\";\n\nexport function NumberFieldGroup<TAs extends ElementType = \"div\">(\n props: NumberFieldGroupProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as NumberFieldGroupProps<ElementType>;\n const { disabled } = useNumberFieldContext(\"Group\");\n\n return useRenderElement({\n as,\n defaultTag: \"div\",\n props: { ...consumerProps, \"data-disabled\": disabled ? \"\" : undefined },\n render,\n state: { disabled },\n });\n}\n\nexport function NumberFieldInput<TAs extends ElementType = \"input\">(\n props: NumberFieldInputProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as NumberFieldInputProps<\"input\">;\n const {\n commitInput,\n decrement,\n disabled,\n displayValue,\n increment,\n inputId,\n inputRef,\n max,\n min,\n numericValue,\n readOnly,\n required,\n setDisplayValue,\n setEditing,\n } = useNumberFieldContext(\"Input\");\n\n const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (disabled || readOnly) return;\n switch (event.key) {\n case \"ArrowUp\":\n event.preventDefault();\n increment();\n break;\n case \"ArrowDown\":\n event.preventDefault();\n decrement();\n break;\n case \"PageUp\":\n event.preventDefault();\n increment(10);\n break;\n case \"PageDown\":\n event.preventDefault();\n decrement(10);\n break;\n case \"Home\":\n event.preventDefault();\n if (min !== undefined) commitInput(String(min));\n break;\n case \"End\":\n event.preventDefault();\n if (max !== undefined) commitInput(String(max));\n break;\n default:\n break;\n }\n };\n\n return useRenderElement({\n as,\n defaultTag: \"input\",\n props: {\n ...consumerProps,\n id: inputId,\n ref: inputRef,\n role: \"spinbutton\",\n inputMode: \"decimal\",\n \"aria-valuenow\": numericValue,\n \"aria-valuemin\": min,\n \"aria-valuemax\": max,\n \"aria-required\": required || undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-readonly\": readOnly ? \"\" : undefined,\n disabled: disabled || undefined,\n readOnly: readOnly || undefined,\n required: required || undefined,\n value: displayValue,\n onFocus: composeEventHandlers(consumerProps.onFocus, () => setEditing(true)),\n onBlur: composeEventHandlers(consumerProps.onBlur, (event: FocusEvent<HTMLInputElement>) => {\n setEditing(false);\n commitInput(event.currentTarget.value);\n }),\n onChange: composeEventHandlers(\n consumerProps.onChange,\n (event: SyntheticEvent<HTMLInputElement>) => {\n setDisplayValue(event.currentTarget.value);\n },\n ),\n onKeyDown: composeEventHandlers(consumerProps.onKeyDown, onKeyDown),\n },\n render,\n state: { disabled, readOnly, required },\n });\n}\n\nexport function NumberFieldIncrement<TAs extends ElementType = \"button\">(\n props: NumberFieldIncrementProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as PolymorphicProps<\n \"button\",\n { readonly children?: ReactNode }\n >;\n const { disabled, increment, readOnly } = useNumberFieldContext(\"Increment\");\n const inactive = disabled || readOnly;\n const repeatProps = usePressRepeat(() => increment(), inactive);\n\n return useRenderElement({\n as,\n defaultTag: \"button\",\n props: {\n ...consumerProps,\n type: \"button\",\n tabIndex: -1,\n \"data-disabled\": inactive ? \"\" : undefined,\n disabled: inactive || undefined,\n onClick: composeEventHandlers(consumerProps.onClick, () => increment()),\n onPointerDown: composeEventHandlers(consumerProps.onPointerDown, repeatProps.onPointerDown),\n onPointerUp: composeEventHandlers(consumerProps.onPointerUp, repeatProps.onPointerUp),\n onPointerLeave: composeEventHandlers(\n consumerProps.onPointerLeave,\n repeatProps.onPointerLeave,\n ),\n onPointerCancel: composeEventHandlers(\n consumerProps.onPointerCancel,\n repeatProps.onPointerCancel,\n ),\n },\n render,\n state: { disabled: inactive },\n });\n}\n\nexport function NumberFieldDecrement<TAs extends ElementType = \"button\">(\n props: NumberFieldDecrementProps<TAs>,\n): ReactElement | null {\n const { as, render, ...consumerProps } = props as PolymorphicProps<\n \"button\",\n { readonly children?: ReactNode }\n >;\n const { decrement, disabled, readOnly } = useNumberFieldContext(\"Decrement\");\n const inactive = disabled || readOnly;\n const repeatProps = usePressRepeat(() => decrement(), inactive);\n\n return useRenderElement({\n as,\n defaultTag: \"button\",\n props: {\n ...consumerProps,\n type: \"button\",\n tabIndex: -1,\n \"data-disabled\": inactive ? \"\" : undefined,\n disabled: inactive || undefined,\n onClick: composeEventHandlers(consumerProps.onClick, () => decrement()),\n onPointerDown: composeEventHandlers(consumerProps.onPointerDown, repeatProps.onPointerDown),\n onPointerUp: composeEventHandlers(consumerProps.onPointerUp, repeatProps.onPointerUp),\n onPointerLeave: composeEventHandlers(\n consumerProps.onPointerLeave,\n repeatProps.onPointerLeave,\n ),\n onPointerCancel: composeEventHandlers(\n consumerProps.onPointerCancel,\n repeatProps.onPointerCancel,\n ),\n },\n render,\n state: { disabled: inactive },\n });\n}\n\nexport const NumberField = {\n Root: NumberFieldRoot,\n Group: NumberFieldGroup,\n Input: NumberFieldInput,\n Increment: NumberFieldIncrement,\n Decrement: NumberFieldDecrement,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../../src/components/slider/Slider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../../src/components/slider/Slider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,WAAW,EAAE,YAAY,EAAkB,MAAM,OAAO,CAAC;AAGtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9C,wBAAgB,MAAM,CAAC,GAAG,SAAS,WAAW,GAAG,OAAO,EACtD,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,GACtB,YAAY,GAAG,IAAI,CAwDrB"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { composeEventHandlers } from "@gunkin/uiify/core/compose-event-handlers";
|
|
2
2
|
import { useRenderElement } from "@gunkin/uiify/core/render";
|
|
3
|
+
function getProgressPercentage(value, min, max) {
|
|
4
|
+
if (max <= min) return 0;
|
|
5
|
+
return Number(Math.min(100, Math.max(0, (value - min) / (max - min) * 100)).toFixed(4));
|
|
6
|
+
}
|
|
3
7
|
function Slider(props) {
|
|
4
8
|
const {
|
|
5
9
|
as,
|
|
@@ -14,7 +18,17 @@ function Slider(props) {
|
|
|
14
18
|
...consumerProps
|
|
15
19
|
} = props;
|
|
16
20
|
const isControlled = value !== void 0;
|
|
21
|
+
const progressValue = value ?? defaultValue ?? min + (max - min) / 2;
|
|
22
|
+
const progress = getProgressPercentage(progressValue, min, max);
|
|
23
|
+
const style = {
|
|
24
|
+
...consumerProps.style,
|
|
25
|
+
"--uiify-slider-progress": `${progress}%`
|
|
26
|
+
};
|
|
17
27
|
const handleChange = (event) => {
|
|
28
|
+
if (!isControlled) {
|
|
29
|
+
const nextProgress = getProgressPercentage(event.currentTarget.valueAsNumber, min, max);
|
|
30
|
+
event.currentTarget.style.setProperty("--uiify-slider-progress", `${nextProgress}%`);
|
|
31
|
+
}
|
|
18
32
|
onValueChange?.(event.currentTarget.valueAsNumber);
|
|
19
33
|
};
|
|
20
34
|
const consumerOnChange = consumerProps.onChange;
|
|
@@ -23,6 +37,7 @@ function Slider(props) {
|
|
|
23
37
|
defaultTag: "input",
|
|
24
38
|
props: {
|
|
25
39
|
...consumerProps,
|
|
40
|
+
style,
|
|
26
41
|
type: "range",
|
|
27
42
|
"data-uiify-slider": "",
|
|
28
43
|
min,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/slider/Slider.tsx"],"sourcesContent":["import type { ElementType, ReactElement, SyntheticEvent } from \"react\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { useRenderElement } from \"@gunkin/uiify/core/render\";\nimport type { SliderProps } from \"./types.js\";\n\nexport function Slider<TAs extends ElementType = \"input\">(\n props: SliderProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n value,\n defaultValue,\n onValueChange,\n min = 0,\n max = 100,\n step = 1,\n disabled = false,\n ...consumerProps\n } = props as SliderProps<\"input\">;\n\n const isControlled = value !== undefined;\n\n const handleChange = (event: SyntheticEvent<HTMLInputElement>): void => {\n onValueChange?.(event.currentTarget.valueAsNumber);\n };\n\n const consumerOnChange = (\n consumerProps as Record<string, unknown> & {\n onChange?: (event: SyntheticEvent<HTMLInputElement>) => void;\n }\n ).onChange;\n\n return useRenderElement({\n as,\n defaultTag: \"input\",\n props: {\n ...consumerProps,\n type: \"range\",\n \"data-uiify-slider\": \"\",\n min,\n max,\n step,\n disabled: disabled || undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-state\": isControlled ? String(value) : undefined,\n onChange: composeEventHandlers(consumerOnChange, handleChange),\n ...(isControlled ? { value } : defaultValue !== undefined ? { defaultValue } : {}),\n },\n render,\n state: { min, max, step, disabled },\n });\n}\n"],"mappings":"AACA,SAAS,4BAA4B;AACrC,SAAS,wBAAwB;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/slider/Slider.tsx"],"sourcesContent":["import type { CSSProperties, ElementType, ReactElement, SyntheticEvent } from \"react\";\nimport { composeEventHandlers } from \"@gunkin/uiify/core/compose-event-handlers\";\nimport { useRenderElement } from \"@gunkin/uiify/core/render\";\nimport type { SliderProps } from \"./types.js\";\n\nfunction getProgressPercentage(value: number, min: number, max: number): number {\n if (max <= min) return 0;\n return Number(Math.min(100, Math.max(0, ((value - min) / (max - min)) * 100)).toFixed(4));\n}\n\nexport function Slider<TAs extends ElementType = \"input\">(\n props: SliderProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n value,\n defaultValue,\n onValueChange,\n min = 0,\n max = 100,\n step = 1,\n disabled = false,\n ...consumerProps\n } = props as SliderProps<\"input\">;\n\n const isControlled = value !== undefined;\n const progressValue = value ?? defaultValue ?? min + (max - min) / 2;\n const progress = getProgressPercentage(progressValue, min, max);\n const style = {\n ...(consumerProps as { style?: CSSProperties }).style,\n \"--uiify-slider-progress\": `${progress}%`,\n } as CSSProperties;\n\n const handleChange = (event: SyntheticEvent<HTMLInputElement>): void => {\n if (!isControlled) {\n const nextProgress = getProgressPercentage(event.currentTarget.valueAsNumber, min, max);\n event.currentTarget.style.setProperty(\"--uiify-slider-progress\", `${nextProgress}%`);\n }\n onValueChange?.(event.currentTarget.valueAsNumber);\n };\n\n const consumerOnChange = (\n consumerProps as Record<string, unknown> & {\n onChange?: (event: SyntheticEvent<HTMLInputElement>) => void;\n }\n ).onChange;\n\n return useRenderElement({\n as,\n defaultTag: \"input\",\n props: {\n ...consumerProps,\n style,\n type: \"range\",\n \"data-uiify-slider\": \"\",\n min,\n max,\n step,\n disabled: disabled || undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-state\": isControlled ? String(value) : undefined,\n onChange: composeEventHandlers(consumerOnChange, handleChange),\n ...(isControlled ? { value } : defaultValue !== undefined ? { defaultValue } : {}),\n },\n render,\n state: { min, max, step, disabled },\n });\n}\n"],"mappings":"AACA,SAAS,4BAA4B;AACrC,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB,OAAe,KAAa,KAAqB;AAC9E,MAAI,OAAO,IAAK,QAAO;AACvB,SAAO,OAAO,KAAK,IAAI,KAAK,KAAK,IAAI,IAAK,QAAQ,QAAQ,MAAM,OAAQ,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC1F;AAEO,SAAS,OACd,OACqB;AACrB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,IACX,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,eAAe,UAAU;AAC/B,QAAM,gBAAgB,SAAS,gBAAgB,OAAO,MAAM,OAAO;AACnE,QAAM,WAAW,sBAAsB,eAAe,KAAK,GAAG;AAC9D,QAAM,QAAQ;AAAA,IACZ,GAAI,cAA4C;AAAA,IAChD,2BAA2B,GAAG,QAAQ;AAAA,EACxC;AAEA,QAAM,eAAe,CAAC,UAAkD;AACtE,QAAI,CAAC,cAAc;AACjB,YAAM,eAAe,sBAAsB,MAAM,cAAc,eAAe,KAAK,GAAG;AACtF,YAAM,cAAc,MAAM,YAAY,2BAA2B,GAAG,YAAY,GAAG;AAAA,IACrF;AACA,oBAAgB,MAAM,cAAc,aAAa;AAAA,EACnD;AAEA,QAAM,mBACJ,cAGA;AAEF,SAAO,iBAAiB;AAAA,IACtB;AAAA,IACA,YAAY;AAAA,IACZ,OAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,MAAM;AAAA,MACN,qBAAqB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,YAAY;AAAA,MACtB,iBAAiB,WAAW,KAAK;AAAA,MACjC,cAAc,eAAe,OAAO,KAAK,IAAI;AAAA,MAC7C,UAAU,qBAAqB,kBAAkB,YAAY;AAAA,MAC7D,GAAI,eAAe,EAAE,MAAM,IAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,IAClF;AAAA,IACA;AAAA,IACA,OAAO,EAAE,KAAK,KAAK,MAAM,SAAS;AAAA,EACpC,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ElementType, ReactElement } from "react";
|
|
2
|
+
import type { SliderClientProps } from "../types.js";
|
|
3
|
+
export declare function SliderClient<TAs extends ElementType = "div">(props: SliderClientProps<TAs>): ReactElement | null;
|
|
4
|
+
export declare namespace SliderClient {
|
|
5
|
+
var displayName: string;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=SliderClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SliderClient.d.ts","sourceRoot":"","sources":["../../../../src/components/slider/client/SliderClient.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,WAAW,EAEX,YAAY,EAEb,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAE,iBAAiB,EAAiC,MAAM,aAAa,CAAC;AA+CpF,wBAAgB,YAAY,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,EAC1D,KAAK,EAAE,iBAAiB,CAAC,GAAG,CAAC,GAC5B,YAAY,GAAG,IAAI,CA4KrB;yBA9Ke,YAAY"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { useControllableState } from "@gunkin/uiify/hooks";
|
|
5
|
+
import { useRenderElement } from "@gunkin/uiify/core/render";
|
|
6
|
+
import { getSliderStops, snapSliderToStops } from "../slider-values.js";
|
|
7
|
+
function normalizeValue(value, min, max) {
|
|
8
|
+
if (typeof value === "number") return Math.max(min, Math.min(max, value));
|
|
9
|
+
const first = Math.max(min, Math.min(max, value[0]));
|
|
10
|
+
const second = Math.max(min, Math.min(max, value[1]));
|
|
11
|
+
return first <= second ? [first, second] : [second, first];
|
|
12
|
+
}
|
|
13
|
+
function normalizeSelection(value, min, max, step, stops) {
|
|
14
|
+
const normalized = normalizeValue(value, min, max);
|
|
15
|
+
if (step !== null) return normalized;
|
|
16
|
+
if (typeof normalized === "number") return snapSliderToStops(normalized, stops);
|
|
17
|
+
const lowerStops = stops.filter((stop) => stop <= normalized[1]);
|
|
18
|
+
const lower = snapSliderToStops(normalized[0], lowerStops);
|
|
19
|
+
const upperStops = stops.filter((stop) => stop >= lower);
|
|
20
|
+
return [lower, snapSliderToStops(normalized[1], upperStops)];
|
|
21
|
+
}
|
|
22
|
+
function position(value, min, max) {
|
|
23
|
+
if (max <= min) return 0;
|
|
24
|
+
return Math.max(0, Math.min(100, (value - min) / (max - min) * 100));
|
|
25
|
+
}
|
|
26
|
+
function marksInRange(marks, min, max) {
|
|
27
|
+
return marks.filter(({ value }) => Number.isFinite(value) && value >= min && value <= max);
|
|
28
|
+
}
|
|
29
|
+
function SliderClient(props) {
|
|
30
|
+
const {
|
|
31
|
+
as,
|
|
32
|
+
render,
|
|
33
|
+
value: controlledValue,
|
|
34
|
+
defaultValue,
|
|
35
|
+
onValueChange,
|
|
36
|
+
min = 0,
|
|
37
|
+
max = 100,
|
|
38
|
+
step = 1,
|
|
39
|
+
disabled = false,
|
|
40
|
+
orientation = "horizontal",
|
|
41
|
+
marks = [],
|
|
42
|
+
thumbLabels,
|
|
43
|
+
"aria-label": ariaLabel,
|
|
44
|
+
"aria-labelledby": ariaLabelledBy,
|
|
45
|
+
...consumerProps
|
|
46
|
+
} = props;
|
|
47
|
+
const stops = getSliderStops(min, max, marks);
|
|
48
|
+
const initialValue = normalizeSelection(defaultValue ?? min, min, max, step, stops);
|
|
49
|
+
const safeControlledValue = controlledValue === void 0 ? void 0 : normalizeSelection(controlledValue, min, max, step, stops);
|
|
50
|
+
const [value, setValue] = useControllableState({
|
|
51
|
+
defaultValue: initialValue,
|
|
52
|
+
onChange: onValueChange,
|
|
53
|
+
value: safeControlledValue
|
|
54
|
+
});
|
|
55
|
+
const [enhanced, setEnhanced] = useState(false);
|
|
56
|
+
useEffect(() => setEnhanced(true), []);
|
|
57
|
+
const normalizedValue = normalizeValue(value, min, max);
|
|
58
|
+
const values = typeof normalizedValue === "number" ? [normalizedValue] : [normalizedValue[0], normalizedValue[1]];
|
|
59
|
+
const isRange = values.length === 2;
|
|
60
|
+
const consumerStyle = "style" in consumerProps ? consumerProps.style : void 0;
|
|
61
|
+
const consumerRole = "role" in consumerProps ? consumerProps.role : void 0;
|
|
62
|
+
const positionStyles = values.map((currentValue) => ({
|
|
63
|
+
"--uiify-slider-position": String(position(currentValue, min, max)) + "%"
|
|
64
|
+
}));
|
|
65
|
+
const rootStyle = {
|
|
66
|
+
...consumerStyle,
|
|
67
|
+
"--uiify-slider-start": String(position(values[0], min, max)) + "%",
|
|
68
|
+
"--uiify-slider-end": String(position(values[values.length - 1], min, max)) + "%",
|
|
69
|
+
"--uiify-slider-middle": String(
|
|
70
|
+
(position(values[0], min, max) + position(values[values.length - 1], min, max)) / 2
|
|
71
|
+
) + "%"
|
|
72
|
+
};
|
|
73
|
+
const visibleMarks = marksInRange(marks, min, max);
|
|
74
|
+
const setThumbValue = (index, proposed) => {
|
|
75
|
+
if (disabled) return;
|
|
76
|
+
if (!isRange) {
|
|
77
|
+
const next = step === null ? snapSliderToStops(proposed, stops) : proposed;
|
|
78
|
+
setValue(next);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const lower = index === 0 ? min : values[0];
|
|
82
|
+
const upper = index === 0 ? values[1] : max;
|
|
83
|
+
const availableStops = stops.filter((stop) => stop >= lower && stop <= upper);
|
|
84
|
+
const snapped = step === null ? snapSliderToStops(proposed, availableStops) : proposed;
|
|
85
|
+
const nextValue = index === 0 ? [Math.min(snapped, values[1]), values[1]] : [values[0], Math.max(snapped, values[0])];
|
|
86
|
+
setValue(nextValue);
|
|
87
|
+
};
|
|
88
|
+
const handleChange = (index, event) => {
|
|
89
|
+
setThumbValue(index, event.currentTarget.valueAsNumber);
|
|
90
|
+
};
|
|
91
|
+
const handleKeyDown = (index, event) => {
|
|
92
|
+
if (disabled || step !== null) return;
|
|
93
|
+
const direction = event.key === "ArrowRight" || event.key === "ArrowUp" ? 1 : event.key === "ArrowLeft" || event.key === "ArrowDown" ? -1 : 0;
|
|
94
|
+
if (direction === 0) return;
|
|
95
|
+
event.preventDefault();
|
|
96
|
+
const currentValue = values[index];
|
|
97
|
+
const availableStops = isRange ? stops.filter((stop) => index === 0 ? stop <= values[1] : stop >= values[0]) : stops;
|
|
98
|
+
const currentIndex = availableStops.indexOf(currentValue);
|
|
99
|
+
const nextValue = availableStops[currentIndex + direction];
|
|
100
|
+
if (nextValue !== void 0) setThumbValue(index, nextValue);
|
|
101
|
+
};
|
|
102
|
+
const inputNodes = values.map((currentValue, index) => {
|
|
103
|
+
const inputLabel = isRange ? thumbLabels?.[index] ?? (index === 0 ? "Minimum value" : "Maximum value") : ariaLabel;
|
|
104
|
+
const inputLabelledBy = isRange ? void 0 : ariaLabelledBy;
|
|
105
|
+
return /* @__PURE__ */ jsx(
|
|
106
|
+
"input",
|
|
107
|
+
{
|
|
108
|
+
type: "range",
|
|
109
|
+
min,
|
|
110
|
+
max,
|
|
111
|
+
step: step === null ? "any" : step,
|
|
112
|
+
value: currentValue,
|
|
113
|
+
disabled,
|
|
114
|
+
"aria-label": inputLabel,
|
|
115
|
+
"aria-labelledby": inputLabelledBy,
|
|
116
|
+
"aria-orientation": orientation,
|
|
117
|
+
"data-part": "thumb",
|
|
118
|
+
"data-state": String(currentValue),
|
|
119
|
+
"data-orientation": orientation,
|
|
120
|
+
"data-disabled": disabled ? "" : void 0,
|
|
121
|
+
onChange: (event) => handleChange(index, event),
|
|
122
|
+
onKeyDown: (event) => handleKeyDown(index, event)
|
|
123
|
+
},
|
|
124
|
+
index
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
return useRenderElement({
|
|
128
|
+
as,
|
|
129
|
+
defaultTag: "div",
|
|
130
|
+
props: {
|
|
131
|
+
...consumerProps,
|
|
132
|
+
role: isRange ? "group" : consumerRole,
|
|
133
|
+
"aria-label": isRange ? ariaLabel : void 0,
|
|
134
|
+
"aria-labelledby": isRange ? ariaLabelledBy : void 0,
|
|
135
|
+
"data-uiify-slider-client": "",
|
|
136
|
+
"data-part": "root",
|
|
137
|
+
"data-range": isRange ? "" : void 0,
|
|
138
|
+
"data-state": isRange ? "range" : String(values[0]),
|
|
139
|
+
"data-orientation": orientation,
|
|
140
|
+
"data-disabled": disabled ? "" : void 0,
|
|
141
|
+
"data-enhanced": enhanced ? "" : void 0,
|
|
142
|
+
style: rootStyle,
|
|
143
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
144
|
+
/* @__PURE__ */ jsxs("div", { "data-part": "track", "aria-hidden": "true", children: [
|
|
145
|
+
/* @__PURE__ */ jsx("span", { "data-part": "range" }),
|
|
146
|
+
visibleMarks.map((mark) => /* @__PURE__ */ jsx(
|
|
147
|
+
"span",
|
|
148
|
+
{
|
|
149
|
+
"data-part": "mark",
|
|
150
|
+
style: {
|
|
151
|
+
"--uiify-slider-position": String(position(mark.value, min, max)) + "%"
|
|
152
|
+
},
|
|
153
|
+
children: mark.label
|
|
154
|
+
},
|
|
155
|
+
mark.value
|
|
156
|
+
)),
|
|
157
|
+
positionStyles.map((style, index) => /* @__PURE__ */ jsx("span", { "data-part": "visual-thumb", style }, index))
|
|
158
|
+
] }),
|
|
159
|
+
inputNodes
|
|
160
|
+
] })
|
|
161
|
+
},
|
|
162
|
+
render,
|
|
163
|
+
state: { disabled, orientation, value: normalizedValue }
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
SliderClient.displayName = "SliderClient";
|
|
167
|
+
export {
|
|
168
|
+
SliderClient
|
|
169
|
+
};
|
|
170
|
+
//# sourceMappingURL=SliderClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/slider/client/SliderClient.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n CSSProperties,\n ElementType,\n KeyboardEvent,\n ReactElement,\n SyntheticEvent,\n} from \"react\";\nimport { useEffect, useState } from \"react\";\nimport { useControllableState } from \"@gunkin/uiify/hooks\";\nimport { useRenderElement } from \"@gunkin/uiify/core/render\";\n\nimport { getSliderStops, snapSliderToStops } from \"../slider-values.js\";\nimport type { SliderClientProps, SliderClientValue, SliderMark } from \"../types.js\";\n\ntype SliderPositionStyle = CSSProperties & {\n readonly \"--uiify-slider-position\"?: string;\n readonly \"--uiify-slider-start\"?: string;\n readonly \"--uiify-slider-end\"?: string;\n readonly \"--uiify-slider-middle\"?: string;\n};\n\nfunction normalizeValue(value: SliderClientValue, min: number, max: number): SliderClientValue {\n if (typeof value === \"number\") return Math.max(min, Math.min(max, value));\n\n const first = Math.max(min, Math.min(max, value[0]));\n const second = Math.max(min, Math.min(max, value[1]));\n return first <= second ? [first, second] : [second, first];\n}\n\nfunction normalizeSelection(\n value: SliderClientValue,\n min: number,\n max: number,\n step: number | null,\n stops: readonly number[],\n): SliderClientValue {\n const normalized = normalizeValue(value, min, max);\n if (step !== null) return normalized;\n if (typeof normalized === \"number\") return snapSliderToStops(normalized, stops);\n\n const lowerStops = stops.filter((stop) => stop <= normalized[1]);\n const lower = snapSliderToStops(normalized[0], lowerStops);\n const upperStops = stops.filter((stop) => stop >= lower);\n return [lower, snapSliderToStops(normalized[1], upperStops)];\n}\n\nfunction position(value: number, min: number, max: number): number {\n if (max <= min) return 0;\n return Math.max(0, Math.min(100, ((value - min) / (max - min)) * 100));\n}\n\nfunction marksInRange(\n marks: readonly SliderMark[],\n min: number,\n max: number,\n): readonly SliderMark[] {\n return marks.filter(({ value }) => Number.isFinite(value) && value >= min && value <= max);\n}\n\nexport function SliderClient<TAs extends ElementType = \"div\">(\n props: SliderClientProps<TAs>,\n): ReactElement | null {\n const {\n as,\n render,\n value: controlledValue,\n defaultValue,\n onValueChange,\n min = 0,\n max = 100,\n step = 1,\n disabled = false,\n orientation = \"horizontal\",\n marks = [],\n thumbLabels,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...consumerProps\n } = props as SliderClientProps<\"div\">;\n\n const stops = getSliderStops(min, max, marks);\n const initialValue = normalizeSelection(defaultValue ?? min, min, max, step, stops);\n const safeControlledValue =\n controlledValue === undefined\n ? undefined\n : normalizeSelection(controlledValue, min, max, step, stops);\n const [value, setValue] = useControllableState<SliderClientValue>({\n defaultValue: initialValue,\n onChange: onValueChange,\n value: safeControlledValue,\n });\n const [enhanced, setEnhanced] = useState(false);\n useEffect(() => setEnhanced(true), []);\n\n const normalizedValue = normalizeValue(value, min, max);\n const values: readonly number[] =\n typeof normalizedValue === \"number\"\n ? [normalizedValue]\n : [normalizedValue[0], normalizedValue[1]];\n const isRange = values.length === 2;\n const consumerStyle = \"style\" in consumerProps ? consumerProps.style : undefined;\n const consumerRole = \"role\" in consumerProps ? consumerProps.role : undefined;\n const positionStyles: readonly SliderPositionStyle[] = values.map((currentValue) => ({\n \"--uiify-slider-position\": String(position(currentValue, min, max)) + \"%\",\n }));\n const rootStyle: SliderPositionStyle = {\n ...consumerStyle,\n \"--uiify-slider-start\": String(position(values[0]!, min, max)) + \"%\",\n \"--uiify-slider-end\": String(position(values[values.length - 1]!, min, max)) + \"%\",\n \"--uiify-slider-middle\":\n String(\n (position(values[0]!, min, max) + position(values[values.length - 1]!, min, max)) / 2,\n ) + \"%\",\n };\n const visibleMarks = marksInRange(marks, min, max);\n\n const setThumbValue = (index: number, proposed: number): void => {\n if (disabled) return;\n\n if (!isRange) {\n const next = step === null ? snapSliderToStops(proposed, stops) : proposed;\n setValue(next);\n return;\n }\n\n const lower = index === 0 ? min : values[0]!;\n const upper = index === 0 ? values[1]! : max;\n const availableStops = stops.filter((stop) => stop >= lower && stop <= upper);\n const snapped = step === null ? snapSliderToStops(proposed, availableStops) : proposed;\n const nextValue =\n index === 0\n ? ([Math.min(snapped, values[1]!), values[1]!] as const)\n : ([values[0]!, Math.max(snapped, values[0]!)] as const);\n setValue(nextValue);\n };\n\n const handleChange = (index: number, event: SyntheticEvent<HTMLInputElement>): void => {\n setThumbValue(index, event.currentTarget.valueAsNumber);\n };\n\n const handleKeyDown = (index: number, event: KeyboardEvent<HTMLInputElement>): void => {\n if (disabled || step !== null) return;\n\n const direction =\n event.key === \"ArrowRight\" || event.key === \"ArrowUp\"\n ? 1\n : event.key === \"ArrowLeft\" || event.key === \"ArrowDown\"\n ? -1\n : 0;\n if (direction === 0) return;\n\n event.preventDefault();\n const currentValue = values[index]!;\n const availableStops = isRange\n ? stops.filter((stop) => (index === 0 ? stop <= values[1]! : stop >= values[0]!))\n : stops;\n const currentIndex = availableStops.indexOf(currentValue);\n const nextValue = availableStops[currentIndex + direction];\n if (nextValue !== undefined) setThumbValue(index, nextValue);\n };\n\n const inputNodes = values.map((currentValue, index) => {\n const inputLabel = isRange\n ? (thumbLabels?.[index] ?? (index === 0 ? \"Minimum value\" : \"Maximum value\"))\n : ariaLabel;\n const inputLabelledBy = isRange ? undefined : ariaLabelledBy;\n\n return (\n <input\n key={index}\n type=\"range\"\n min={min}\n max={max}\n step={step === null ? \"any\" : step}\n value={currentValue}\n disabled={disabled}\n aria-label={inputLabel}\n aria-labelledby={inputLabelledBy}\n aria-orientation={orientation}\n data-part=\"thumb\"\n data-state={String(currentValue)}\n data-orientation={orientation}\n data-disabled={disabled ? \"\" : undefined}\n onChange={(event) => handleChange(index, event)}\n onKeyDown={(event) => handleKeyDown(index, event)}\n />\n );\n });\n\n return useRenderElement({\n as,\n defaultTag: \"div\",\n props: {\n ...consumerProps,\n role: isRange ? \"group\" : consumerRole,\n \"aria-label\": isRange ? ariaLabel : undefined,\n \"aria-labelledby\": isRange ? ariaLabelledBy : undefined,\n \"data-uiify-slider-client\": \"\",\n \"data-part\": \"root\",\n \"data-range\": isRange ? \"\" : undefined,\n \"data-state\": isRange ? \"range\" : String(values[0]),\n \"data-orientation\": orientation,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-enhanced\": enhanced ? \"\" : undefined,\n style: rootStyle,\n children: (\n <>\n <div data-part=\"track\" aria-hidden=\"true\">\n <span data-part=\"range\" />\n {visibleMarks.map((mark) => (\n <span\n key={mark.value}\n data-part=\"mark\"\n style={\n {\n \"--uiify-slider-position\": String(position(mark.value, min, max)) + \"%\",\n } as SliderPositionStyle\n }\n >\n {mark.label}\n </span>\n ))}\n {positionStyles.map((style, index) => (\n <span key={index} data-part=\"visual-thumb\" style={style} />\n ))}\n </div>\n {inputNodes}\n </>\n ),\n },\n render,\n state: { disabled, orientation, value: normalizedValue },\n });\n}\n\nSliderClient.displayName = \"SliderClient\";\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/slider/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EACV,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,UAAU,GACX,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/slider/client/index.ts"],"sourcesContent":["export { SliderClient } from \"./SliderClient.js\";\nexport type {\n SliderClientOwnProps,\n SliderClientProps,\n SliderClientRenderState,\n SliderClientValue,\n SliderMark,\n} from \"../types.js\";\n"],"mappings":"AAAA,SAAS,oBAAoB;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./client/index.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./client/index.js";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SliderMark } from "./types.js";
|
|
2
|
+
export declare function getSliderStops(min: number, max: number, marks: readonly SliderMark[]): readonly number[];
|
|
3
|
+
export declare function snapSliderToStops(value: number, stops: readonly number[]): number;
|
|
4
|
+
//# sourceMappingURL=slider-values.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slider-values.d.ts","sourceRoot":"","sources":["../../../src/components/slider/slider-values.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,UAAU,EAAE,GAC3B,SAAS,MAAM,EAAE,CAUnB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAajF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function getSliderStops(min, max, marks) {
|
|
2
|
+
return [
|
|
3
|
+
.../* @__PURE__ */ new Set([
|
|
4
|
+
min,
|
|
5
|
+
...marks.map(({ value }) => value).filter((value) => Number.isFinite(value) && value >= min && value <= max),
|
|
6
|
+
max
|
|
7
|
+
])
|
|
8
|
+
].sort((a, b) => a - b);
|
|
9
|
+
}
|
|
10
|
+
function snapSliderToStops(value, stops) {
|
|
11
|
+
let closest = stops[0];
|
|
12
|
+
let closestDistance = Math.abs(value - closest);
|
|
13
|
+
for (const stop of stops.slice(1)) {
|
|
14
|
+
const distance = Math.abs(value - stop);
|
|
15
|
+
if (distance < closestDistance) {
|
|
16
|
+
closest = stop;
|
|
17
|
+
closestDistance = distance;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return closest;
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
getSliderStops,
|
|
24
|
+
snapSliderToStops
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=slider-values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/slider/slider-values.ts"],"sourcesContent":["import type { SliderMark } from \"./types.js\";\n\nexport function getSliderStops(\n min: number,\n max: number,\n marks: readonly SliderMark[],\n): readonly number[] {\n return [\n ...new Set([\n min,\n ...marks\n .map(({ value }) => value)\n .filter((value) => Number.isFinite(value) && value >= min && value <= max),\n max,\n ]),\n ].sort((a, b) => a - b);\n}\n\nexport function snapSliderToStops(value: number, stops: readonly number[]): number {\n let closest = stops[0]!;\n let closestDistance = Math.abs(value - closest);\n\n for (const stop of stops.slice(1)) {\n const distance = Math.abs(value - stop);\n if (distance < closestDistance) {\n closest = stop;\n closestDistance = distance;\n }\n }\n\n return closest;\n}\n"],"mappings":"AAEO,SAAS,eACd,KACA,KACA,OACmB;AACnB,SAAO;AAAA,IACL,GAAG,oBAAI,IAAI;AAAA,MACT;AAAA,MACA,GAAG,MACA,IAAI,CAAC,EAAE,MAAM,MAAM,KAAK,EACxB,OAAO,CAAC,UAAU,OAAO,SAAS,KAAK,KAAK,SAAS,OAAO,SAAS,GAAG;AAAA,MAC3E;AAAA,IACF,CAAC;AAAA,EACH,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACxB;AAEO,SAAS,kBAAkB,OAAe,OAAkC;AACjF,MAAI,UAAU,MAAM,CAAC;AACrB,MAAI,kBAAkB,KAAK,IAAI,QAAQ,OAAO;AAE9C,aAAW,QAAQ,MAAM,MAAM,CAAC,GAAG;AACjC,UAAM,WAAW,KAAK,IAAI,QAAQ,IAAI;AACtC,QAAI,WAAW,iBAAiB;AAC9B,gBAAU;AACV,wBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type { ElementType } from "react";
|
|
1
|
+
import type { ElementType, ReactNode } from "react";
|
|
2
2
|
import type { RenderableProps } from "@gunkin/uiify/core/render";
|
|
3
|
+
export interface SliderMark {
|
|
4
|
+
readonly value: number;
|
|
5
|
+
readonly label?: ReactNode;
|
|
6
|
+
}
|
|
3
7
|
export interface SliderOwnProps {
|
|
4
8
|
readonly value?: number;
|
|
5
9
|
readonly defaultValue?: number;
|
|
@@ -9,5 +13,26 @@ export interface SliderOwnProps {
|
|
|
9
13
|
readonly step?: number;
|
|
10
14
|
readonly disabled?: boolean;
|
|
11
15
|
}
|
|
16
|
+
export type SliderClientValue = number | readonly [number, number];
|
|
17
|
+
export interface SliderClientOwnProps {
|
|
18
|
+
readonly value?: SliderClientValue;
|
|
19
|
+
readonly defaultValue?: SliderClientValue;
|
|
20
|
+
readonly onValueChange?: (value: SliderClientValue) => void;
|
|
21
|
+
readonly min?: number;
|
|
22
|
+
readonly max?: number;
|
|
23
|
+
readonly step?: number | null;
|
|
24
|
+
readonly disabled?: boolean;
|
|
25
|
+
readonly orientation?: "horizontal" | "vertical";
|
|
26
|
+
readonly marks?: readonly SliderMark[];
|
|
27
|
+
readonly thumbLabels?: readonly [string, string];
|
|
28
|
+
readonly "aria-label"?: string;
|
|
29
|
+
readonly "aria-labelledby"?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface SliderClientRenderState {
|
|
32
|
+
readonly disabled: boolean;
|
|
33
|
+
readonly orientation: "horizontal" | "vertical";
|
|
34
|
+
readonly value: SliderClientValue;
|
|
35
|
+
}
|
|
36
|
+
export type SliderClientProps<TAs extends ElementType = "div"> = RenderableProps<TAs, SliderClientOwnProps, SliderClientRenderState, HTMLDivElement>;
|
|
12
37
|
export type SliderProps<TAs extends ElementType = "input"> = RenderableProps<TAs, SliderOwnProps, SliderOwnProps, HTMLInputElement>;
|
|
13
38
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/slider/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/slider/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,UAAU,CAAC;IAChD,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;CACnC;AAED,MAAM,MAAM,iBAAiB,CAAC,GAAG,SAAS,WAAW,GAAG,KAAK,IAAI,eAAe,CAC9E,GAAG,EACH,oBAAoB,EACpB,uBAAuB,EACvB,cAAc,CACf,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,GAAG,SAAS,WAAW,GAAG,OAAO,IAAI,eAAe,CAC1E,GAAG,EACH,cAAc,EACd,cAAc,EACd,gBAAgB,CACjB,CAAC"}
|