UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

1 lines • 6.23 kB
{"version":3,"file":"Rate.mjs","names":["useControlledState"],"sources":["../../../src/base-ui/Rate/Rate.tsx"],"sourcesContent":["'use client';\n\nimport { cssVar, cx } from 'antd-style';\nimport { Star } from 'lucide-react';\nimport { type KeyboardEvent, memo, useState } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport { styles } from './style';\nimport type { RateProps } from './type';\n\nconst clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));\n\nconst formatValue = (value: number) => String(Math.round(value * 100) / 100);\n\nconst Rate = memo<RateProps>(\n ({\n allowHalf = false,\n character,\n className,\n color = cssVar.colorWarning,\n count = 5,\n defaultValue = 0,\n disabled = false,\n gap,\n onChange,\n onKeyDown,\n onPointerLeave,\n readOnly = false,\n size = 20,\n style,\n value,\n ...rest\n }) => {\n const [mergedValue, setMergedValue] = useControlledState(defaultValue, { onChange, value });\n const [hoverValue, setHoverValue] = useState<number | null>(null);\n\n const interactive = !readOnly && !disabled;\n const step = allowHalf ? 0.5 : 1;\n const displayValue = clamp(hoverValue ?? mergedValue, 0, count);\n const label = `${formatValue(clamp(mergedValue, 0, count))} out of ${count}`;\n const icon = character ?? <Star fill=\"currentColor\" size={size} />;\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (!interactive || event.defaultPrevented) return;\n\n const next = {\n ArrowDown: mergedValue - step,\n ArrowLeft: mergedValue - step,\n ArrowRight: mergedValue + step,\n ArrowUp: mergedValue + step,\n End: count,\n Home: 0,\n }[event.key];\n if (next === undefined) return;\n\n event.preventDefault();\n setMergedValue(clamp(Math.round(next / step) * step, 0, count));\n };\n\n const a11yProps = readOnly\n ? { 'aria-label': label, 'role': 'img' }\n : {\n 'aria-disabled': disabled || undefined,\n 'aria-valuemax': count,\n 'aria-valuemin': 0,\n 'aria-valuenow': mergedValue,\n 'aria-valuetext': label,\n 'role': 'slider',\n 'tabIndex': disabled ? -1 : 0,\n };\n\n return (\n <div\n className={cx(styles.root, className)}\n style={{ gap: gap ?? size / 2, ...style }}\n onKeyDown={handleKeyDown}\n onPointerLeave={(event) => {\n onPointerLeave?.(event);\n setHoverValue(null);\n }}\n {...a11yProps}\n {...rest}\n >\n {Array.from({ length: count }, (_, index) => {\n const fill = clamp(displayValue - index, 0, 1);\n const targets = allowHalf ? [index + 0.5, index + 1] : [index + 1];\n\n return (\n <span\n aria-hidden=\"true\"\n className={styles.star}\n data-index={index}\n key={index}\n style={{ fontSize: size, height: size }}\n >\n <span className={cx(styles.icon, styles.empty)} style={{ minWidth: size }}>\n {icon}\n </span>\n <span className={styles.fill} style={{ color, width: `${fill * 100}%` }}>\n <span className={styles.icon} style={{ minWidth: size }}>\n {icon}\n </span>\n </span>\n {interactive &&\n targets.map((target) => (\n <span\n className={styles.half}\n data-half={target % 1 === 0 && allowHalf ? 'end' : 'start'}\n data-value={target}\n key={target}\n style={allowHalf ? undefined : { width: '100%' }}\n onClick={() => setMergedValue(target)}\n onPointerEnter={() => setHoverValue(target)}\n />\n ))}\n </span>\n );\n })}\n </div>\n );\n },\n);\n\nRate.displayName = 'Rate';\n\nexport default Rate;\n"],"mappings":"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"}