@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
1 lines • 6.76 kB
Source Map (JSON)
{"version":3,"file":"Segmented.mjs","names":["useControlledState"],"sources":["../../../src/base-ui/Segmented/Segmented.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\nimport {\n type CSSProperties,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport {\n SegmentedIndicator,\n SegmentedItem,\n SegmentedItemIcon,\n SegmentedItemLabel,\n SegmentedRoot,\n} from './atoms';\nimport type { SegmentedOption, SegmentedProps } from './type';\n\nconst normalizeOption = <Value extends string>(\n option: SegmentedOption<Value> | Value,\n): SegmentedOption<Value> =>\n typeof option === 'string' ? { label: option, value: option } : option;\n\nconst Segmented = <Value extends string = string>({\n block = false,\n className,\n classNames,\n defaultValue,\n disabled = false,\n glass = false,\n id,\n name,\n onChange,\n options,\n ref,\n shadow = false,\n size = 'middle',\n style,\n styles: customStyles,\n value,\n variant = 'filled',\n vertical = false,\n}: SegmentedProps<Value>) => {\n const [innerValue, setInnerValue] = useControlledState<Value | undefined>(defaultValue, {\n defaultValue,\n onChange: (next) => {\n if (next != null) onChange?.(next);\n },\n value,\n });\n\n const listRef = useRef<HTMLDivElement | null>(null);\n\n const mergedRef = useCallback(\n (node: HTMLDivElement | null) => {\n listRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.RefObject<HTMLDivElement | null>).current = node;\n },\n [ref],\n );\n\n const normalizedOptions = useMemo(\n () => (options ?? []).map((o) => normalizeOption<Value>(o)),\n [options],\n );\n\n const updateIndicator = useCallback(() => {\n const list = listRef.current;\n if (!list) return;\n const active = list.querySelector<HTMLElement>('[data-segmented-item][data-pressed]');\n if (!active) {\n list.style.setProperty('--active-item-width', '0px');\n list.style.setProperty('--active-item-height', '0px');\n return;\n }\n list.style.setProperty('--active-item-left', `${active.offsetLeft}px`);\n list.style.setProperty('--active-item-top', `${active.offsetTop}px`);\n list.style.setProperty('--active-item-width', `${active.offsetWidth}px`);\n list.style.setProperty('--active-item-height', `${active.offsetHeight}px`);\n }, []);\n\n useLayoutEffect(() => {\n updateIndicator();\n }, [innerValue, normalizedOptions, vertical, size, block, updateIndicator]);\n\n useEffect(() => {\n const list = listRef.current;\n if (!list || typeof ResizeObserver === 'undefined') return;\n const ro = new ResizeObserver(() => updateIndicator());\n ro.observe(list);\n return () => ro.disconnect();\n }, [updateIndicator]);\n\n const groupValue = useMemo<Value[]>(() => (innerValue != null ? [innerValue] : []), [innerValue]);\n\n const rootStyle: CSSProperties = { ...style, ...customStyles?.root };\n\n return (\n <SegmentedRoot<Value>\n block={block}\n className={cx(classNames?.root, className)}\n disabled={disabled}\n glass={glass}\n id={id}\n orientation={vertical ? 'vertical' : 'horizontal'}\n ref={mergedRef}\n shadow={shadow}\n style={rootStyle}\n value={groupValue}\n variant={variant}\n onValueChange={(next) => {\n const picked = next[0];\n if (picked != null) setInnerValue(picked);\n }}\n >\n <SegmentedIndicator className={classNames?.indicator} style={customStyles?.indicator} />\n {normalizedOptions.map((opt) => (\n <SegmentedItem<Value>\n aria-label={typeof opt.label === 'string' ? opt.label : undefined}\n block={block}\n className={cx(classNames?.item, opt.className)}\n data-segmented-item=\"\"\n disabled={disabled || opt.disabled}\n key={opt.value}\n name={name}\n size={size}\n style={customStyles?.item}\n title={opt.title}\n value={opt.value}\n >\n {opt.icon != null && (\n <SegmentedItemIcon className={classNames?.itemIcon} style={customStyles?.itemIcon}>\n {opt.icon}\n </SegmentedItemIcon>\n )}\n {opt.label != null && (\n <SegmentedItemLabel className={classNames?.itemLabel} style={customStyles?.itemLabel}>\n {opt.label}\n </SegmentedItemLabel>\n )}\n </SegmentedItem>\n ))}\n </SegmentedRoot>\n );\n};\n\nSegmented.displayName = 'Segmented';\n\nexport default Segmented;\n"],"mappings":"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"}