nfx-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +235 -0
- package/dist/animations.cjs +3 -0
- package/dist/animations.d.ts +102 -0
- package/dist/animations.mjs +14 -0
- package/dist/apis.cjs +5 -0
- package/dist/apis.cjs.map +1 -0
- package/dist/apis.d.ts +7 -0
- package/dist/apis.mjs +18 -0
- package/dist/apis.mjs.map +1 -0
- package/dist/chunk-BounceLoading-B54QEw0n.mjs +244 -0
- package/dist/chunk-BounceLoading-B54QEw0n.mjs.map +1 -0
- package/dist/chunk-BounceLoading-C6n4BZVJ.cjs +11 -0
- package/dist/chunk-BounceLoading-C6n4BZVJ.cjs.map +1 -0
- package/dist/chunk-animations-Brp-bsaE.mjs +1243 -0
- package/dist/chunk-animations-Brp-bsaE.mjs.map +1 -0
- package/dist/chunk-animations-e2F3zuP9.cjs +190 -0
- package/dist/chunk-animations-e2F3zuP9.cjs.map +1 -0
- package/dist/chunk-chunk-BFrxaqQT.cjs +1 -0
- package/dist/chunk-i18n-Bp6pPM9n.mjs +207 -0
- package/dist/chunk-i18n-Bp6pPM9n.mjs.map +1 -0
- package/dist/chunk-i18n-_7W7guSV.cjs +3 -0
- package/dist/chunk-i18n-_7W7guSV.cjs.map +1 -0
- package/dist/chunk-lstorage-BVCD00Ow.mjs +27 -0
- package/dist/chunk-lstorage-BVCD00Ow.mjs.map +1 -0
- package/dist/chunk-lstorage-BnxLXHgH.cjs +3 -0
- package/dist/chunk-lstorage-BnxLXHgH.cjs.map +1 -0
- package/dist/chunk-lucide-BhgnmTNo.mjs +158 -0
- package/dist/chunk-lucide-BhgnmTNo.mjs.map +1 -0
- package/dist/chunk-lucide-CP2lvOPY.cjs +3 -0
- package/dist/chunk-lucide-CP2lvOPY.cjs.map +1 -0
- package/dist/chunk-preference-CYl68oeU.cjs +3 -0
- package/dist/chunk-preference-CYl68oeU.cjs.map +1 -0
- package/dist/chunk-preference-DImtu5jI.mjs +51 -0
- package/dist/chunk-preference-DImtu5jI.mjs.map +1 -0
- package/dist/chunk-types-BE3JCLff.cjs +3 -0
- package/dist/chunk-types-BE3JCLff.cjs.map +1 -0
- package/dist/chunk-types-BkFxelHl.mjs +20 -0
- package/dist/chunk-types-BkFxelHl.mjs.map +1 -0
- package/dist/chunk-types-C_opkZGr.cjs +3 -0
- package/dist/chunk-types-C_opkZGr.cjs.map +1 -0
- package/dist/chunk-types-CkbZrFqZ.cjs +3 -0
- package/dist/chunk-types-CkbZrFqZ.cjs.map +1 -0
- package/dist/chunk-types-DNPBKfmx.mjs +11 -0
- package/dist/chunk-types-DNPBKfmx.mjs.map +1 -0
- package/dist/chunk-types-SD4MzUGp.mjs +11 -0
- package/dist/chunk-types-SD4MzUGp.mjs.map +1 -0
- package/dist/chunk-useLayout-BAJHOIL3.cjs +3 -0
- package/dist/chunk-useLayout-BAJHOIL3.cjs.map +1 -0
- package/dist/chunk-useLayout-DPxlynT-.mjs +12 -0
- package/dist/chunk-useLayout-DPxlynT-.mjs.map +1 -0
- package/dist/chunk-useTheme-DgleVMMh.cjs +3 -0
- package/dist/chunk-useTheme-DgleVMMh.cjs.map +1 -0
- package/dist/chunk-useTheme-oHcq3d0o.mjs +13 -0
- package/dist/chunk-useTheme-oHcq3d0o.mjs.map +1 -0
- package/dist/components.cjs +8 -0
- package/dist/components.cjs.map +1 -0
- package/dist/components.d.ts +411 -0
- package/dist/components.mjs +1688 -0
- package/dist/components.mjs.map +1 -0
- package/dist/constants.cjs +5 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.d.ts +130 -0
- package/dist/constants.mjs +85 -0
- package/dist/constants.mjs.map +1 -0
- package/dist/events.cjs +5 -0
- package/dist/events.cjs.map +1 -0
- package/dist/events.d.ts +66 -0
- package/dist/events.mjs +31 -0
- package/dist/events.mjs.map +1 -0
- package/dist/hooks.cjs +5 -0
- package/dist/hooks.cjs.map +1 -0
- package/dist/hooks.d.ts +316 -0
- package/dist/hooks.mjs +107 -0
- package/dist/hooks.mjs.map +1 -0
- package/dist/icons.cjs +3 -0
- package/dist/icons.d.ts +218 -0
- package/dist/icons.mjs +76 -0
- package/dist/languages.cjs +5 -0
- package/dist/languages.cjs.map +1 -0
- package/dist/languages.d.ts +174 -0
- package/dist/languages.mjs +112 -0
- package/dist/languages.mjs.map +1 -0
- package/dist/layouts.cjs +5 -0
- package/dist/layouts.cjs.map +1 -0
- package/dist/layouts.d.ts +209 -0
- package/dist/layouts.mjs +460 -0
- package/dist/layouts.mjs.map +1 -0
- package/dist/navigations.cjs +5 -0
- package/dist/navigations.cjs.map +1 -0
- package/dist/navigations.d.ts +72 -0
- package/dist/navigations.mjs +30 -0
- package/dist/navigations.mjs.map +1 -0
- package/dist/preference.cjs +3 -0
- package/dist/preference.d.ts +94 -0
- package/dist/preference.mjs +14 -0
- package/dist/services.cjs +5 -0
- package/dist/services.cjs.map +1 -0
- package/dist/services.d.ts +8 -0
- package/dist/services.mjs +26 -0
- package/dist/services.mjs.map +1 -0
- package/dist/stores.cjs +5 -0
- package/dist/stores.cjs.map +1 -0
- package/dist/stores.d.ts +101 -0
- package/dist/stores.mjs +167 -0
- package/dist/stores.mjs.map +1 -0
- package/dist/themes.cjs +5 -0
- package/dist/themes.cjs.map +1 -0
- package/dist/themes.d.ts +229 -0
- package/dist/themes.mjs +894 -0
- package/dist/themes.mjs.map +1 -0
- package/dist/types.cjs +2 -0
- package/dist/types.d.ts +147 -0
- package/dist/types.mjs +2 -0
- package/dist/utils.cjs +5 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.ts +374 -0
- package/dist/utils.mjs +293 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +196 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.cjs","names":["memo","memo","React"],"sources":["../src/designs/components/Button/styles.module.css","../src/designs/components/Button/index.tsx","../src/designs/components/Dropdown/Dropdown.module.css","../src/designs/components/Dropdown/index.tsx","../src/designs/components/Icon/index.tsx","../src/designs/components/Input/styles.module.css","../src/designs/components/Input/index.tsx","../src/designs/components/KeyValueEditor/styles.module.css","../src/designs/components/KeyValueEditor/index.tsx","../src/designs/components/SearchInput/styles.module.css","../src/designs/components/SearchInput/index.tsx","../src/designs/components/ShowFilter/styles.module.css","../src/designs/components/ShowFilter/index.tsx","../src/designs/components/SlideDownSwitcher/styles.module.css","../src/designs/components/SlideDownSwitcher/index.tsx","../src/designs/components/ThemeSwitcher/index.tsx","../src/designs/components/LayoutSwitcher/index.tsx","../src/designs/components/Slider/styles.module.css","../src/designs/components/Slider/index.tsx","../src/designs/components/Suspense/styles.module.css","../src/designs/components/Suspense/SuspenseErrorBoundary.ts","../src/designs/components/Suspense/index.tsx","../src/designs/components/Textarea/styles.module.css","../src/designs/components/Textarea/index.tsx","../node_modules/@tanstack/virtual-core/dist/esm/utils.js","../node_modules/@tanstack/virtual-core/dist/esm/index.js","../node_modules/@tanstack/react-virtual/dist/esm/index.js","../src/designs/components/VirtualList/styles.module.css","../src/designs/components/VirtualList/index.tsx","../src/designs/components/VirtualWindowList/styles.module.css","../src/designs/components/VirtualWindowList/index.tsx"],"sourcesContent":[".button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n border: 1px solid transparent;\n border-radius: 0.5rem;\n font-family: inherit;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n outline: none;\n position: relative;\n}\n\n.button:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\n.button:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n/* Size variants */\n.button.small {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n min-height: 2rem;\n}\n\n.button.medium {\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n min-height: 2.5rem;\n}\n\n.button.large {\n padding: 1rem 2rem;\n font-size: 1rem;\n min-height: 3rem;\n}\n\n/* Variant styles */\n.button.primary {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: var(--color-primary-fg, #ffffff);\n}\n\n.button.primary:hover:not(:disabled) {\n background: var(--color-primary-light);\n border-color: var(--color-primary-light);\n transform: translateY(-1px);\n}\n\n.button.primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.button.secondary {\n background: var(--color-bg-2);\n border-color: var(--color-border-4);\n color: var(--color-fg-text);\n}\n\n.button.secondary:hover:not(:disabled) {\n background: var(--color-bg-3);\n border-color: var(--color-primary);\n}\n\n.button.outline {\n background: transparent;\n border-color: var(--color-border-4);\n color: var(--color-fg-text);\n}\n\n.button.outline:hover:not(:disabled) {\n background: var(--color-bg-2);\n border-color: var(--color-primary);\n}\n\n.button.ghost {\n background: transparent;\n border-color: transparent;\n color: var(--color-fg-text);\n}\n\n.button.ghost:hover:not(:disabled) {\n background: var(--color-bg-2);\n}\n\n.button.danger {\n background: var(--color-danger);\n border-color: var(--color-danger);\n color: #ffffff;\n}\n\n.button.danger:hover:not(:disabled) {\n background: var(--color-danger-light);\n border-color: var(--color-danger-light);\n transform: translateY(-1px);\n}\n\n.button.danger:active:not(:disabled) {\n transform: translateY(0);\n}\n\n/* Full width */\n.button.fullWidth {\n width: 100%;\n}\n\n/* Loading state */\n.button.loading {\n pointer-events: none;\n}\n\n.spinner {\n width: 1rem;\n height: 1rem;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n flex-shrink: 0;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.button.small .spinner {\n width: 0.875rem;\n height: 0.875rem;\n border-width: 1.5px;\n}\n\n.button.large .spinner {\n width: 1.25rem;\n height: 1.25rem;\n border-width: 2.5px;\n}\n\n.content {\n display: flex;\n align-items: center;\n}\n\n.leftIcon,\n.rightIcon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n.leftIcon {\n margin-right: -0.25rem;\n}\n\n.rightIcon {\n margin-left: -0.25rem;\n}\n\n/* Icon-only (square) */\n.button.iconOnly {\n aspect-ratio: 1;\n padding: 0;\n min-width: 2.5rem;\n min-height: 2.5rem;\n}\n\n.button.iconOnly.small {\n min-width: 2rem;\n min-height: 2rem;\n}\n\n.button.iconOnly.large {\n min-width: 3rem;\n min-height: 3rem;\n}\n\n.iconContainer {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n.layout {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.25rem;\n width: 100%;\n}\n\n.horizontal {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n width: 100%;\n}\n\n.topIcon,\n.bottomIcon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.iconOnly .iconContainer .leftIcon,\n.iconOnly .iconContainer .rightIcon {\n margin: 0;\n}\n","/**\n * 按钮组件:支持 variant、size、四向图标、iconOnly、loading、fullWidth。\n * Button with variant, size, top/right/bottom/left icon, iconOnly, loading, fullWidth.\n *\n * @example\n * ```tsx\n * <Button>保存</Button>\n * <Button leftIcon={<Save size={16} />} loading={isSubmitting}>提交</Button>\n * <Button leftIcon={<Trash2 size={16} />} iconOnly aria-label=\"删除\" />\n * ```\n */\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\n\nimport { cloneElement, forwardRef, isValidElement } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"size\"> {\n variant?: \"primary\" | \"secondary\" | \"outline\" | \"ghost\" | \"danger\";\n size?: \"small\" | \"medium\" | \"large\";\n fullWidth?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n /** 上方图标。Top icon. */\n topIcon?: ReactNode;\n /** 下方图标。Bottom icon. */\n bottomIcon?: ReactNode;\n /** 仅图标无文案。Icon only, no text. */\n iconOnly?: boolean;\n /** 图标尺寸覆盖。Override icon size. */\n iconSize?: number;\n loading?: boolean;\n children?: ReactNode;\n}\n\nfunction renderIcon(icon: ReactNode, iconSize?: number): ReactNode {\n if (!icon) return null;\n if (iconSize && isValidElement(icon) && typeof icon.type !== \"string\") {\n const existingProps = icon.props && typeof icon.props === \"object\" ? icon.props : {};\n return cloneElement(icon as React.ReactElement<{ size?: number }>, { ...existingProps, size: iconSize });\n }\n return icon;\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = \"primary\",\n size = \"medium\",\n fullWidth = false,\n leftIcon,\n rightIcon,\n topIcon,\n bottomIcon,\n iconOnly = false,\n iconSize,\n loading = false,\n disabled,\n children,\n className = \"\",\n ...props\n },\n ref,\n ) => {\n const hasIcons = leftIcon || rightIcon || topIcon || bottomIcon;\n const hasContent = !iconOnly && children;\n const useIconOnlyLayout = iconOnly && hasIcons && !hasContent;\n const useLayout = topIcon || bottomIcon || useIconOnlyLayout;\n\n const buttonClasses = [\n styles.button,\n styles[variant],\n styles[size],\n fullWidth && styles.fullWidth,\n loading && styles.loading,\n useIconOnlyLayout && styles.iconOnly,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n if (useIconOnlyLayout) {\n return (\n <button ref={ref} type=\"button\" className={buttonClasses} disabled={disabled || loading} {...props}>\n <span className={styles.iconContainer}>\n {topIcon && <span className={styles.topIcon}>{renderIcon(topIcon, iconSize)}</span>}\n {leftIcon && <span className={styles.leftIcon}>{renderIcon(leftIcon, iconSize)}</span>}\n {rightIcon && <span className={styles.rightIcon}>{renderIcon(rightIcon, iconSize)}</span>}\n {bottomIcon && <span className={styles.bottomIcon}>{renderIcon(bottomIcon, iconSize)}</span>}\n </span>\n </button>\n );\n }\n\n if (useLayout) {\n return (\n <button ref={ref} type=\"button\" className={buttonClasses} disabled={disabled || loading} {...props}>\n {loading && <span className={styles.spinner} />}\n {!loading && (\n <span className={styles.layout}>\n {topIcon && <span className={styles.topIcon}>{renderIcon(topIcon, iconSize)}</span>}\n <span className={styles.horizontal}>\n {leftIcon && <span className={styles.leftIcon}>{renderIcon(leftIcon, iconSize)}</span>}\n {hasContent && <span className={styles.content}>{children}</span>}\n {rightIcon && <span className={styles.rightIcon}>{renderIcon(rightIcon, iconSize)}</span>}\n </span>\n {bottomIcon && <span className={styles.bottomIcon}>{renderIcon(bottomIcon, iconSize)}</span>}\n </span>\n )}\n </button>\n );\n }\n\n return (\n <button ref={ref} type=\"button\" className={buttonClasses} disabled={disabled || loading} {...props}>\n {loading && <span className={styles.spinner} />}\n {leftIcon && !loading && <span className={styles.leftIcon}>{renderIcon(leftIcon, iconSize)}</span>}\n {children && <span className={styles.content}>{children}</span>}\n {rightIcon && !loading && <span className={styles.rightIcon}>{renderIcon(rightIcon, iconSize)}</span>}\n </button>\n );\n },\n);\n\nButton.displayName = \"Button\";\n\nexport default Button;\n","/* ===== Dropdown 基础样式 ===== */\r\n.dropdown {\r\n position: relative;\r\n display: inline-block;\r\n width: 100%;\r\n}\r\n\r\n.dropdownButton {\r\n position: relative;\r\n width: 100%;\r\n padding: 0.75rem 1rem;\r\n padding-right: 2.5rem;\r\n border: 1px solid var(--color-separator);\r\n border-radius: 8px;\r\n cursor: pointer;\r\n outline: none;\r\n transition: all 0.2s ease-in-out;\r\n text-align: left;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n font-family: inherit;\r\n font-size: 1rem;\r\n font-weight: 400;\r\n line-height: 1.5rem;\r\n background: var(--color-bg-2);\r\n color: var(--color-fg-text);\r\n}\r\n\r\n.dropdownButton:hover:not(:disabled) {\r\n border-color: var(--color-primary);\r\n background: var(--color-bg-1);\r\n}\r\n\r\n.dropdownButton:focus {\r\n border-color: var(--color-primary);\r\n background: var(--color-bg-1);\r\n box-shadow: 0 0 0 2px var(--color-primary-transparent);\r\n}\r\n\r\n.dropdownButton.disabled {\r\n cursor: not-allowed;\r\n opacity: 0.6;\r\n background: var(--color-bg-3);\r\n}\r\n\r\n.dropdownButton.error {\r\n border-color: #ef4444;\r\n}\r\n\r\n.buttonText {\r\n flex: 1;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n}\r\n\r\n.chevronIcon {\r\n position: absolute;\r\n right: 1rem;\r\n transition: transform 0.15s ease;\r\n flex-shrink: 0;\r\n color: var(--color-fg-highlight);\r\n}\r\n\r\n.chevronIcon.open {\r\n transform: rotate(180deg);\r\n}\r\n\r\n/* ===== 下拉菜单 ===== */\r\n.dropdownMenu {\r\n position: absolute;\r\n top: calc(100% + 0.5rem);\r\n left: 0;\r\n right: 0;\r\n min-width: 100%;\r\n background: var(--color-bg);\r\n border: 1px solid var(--color-border-4);\r\n border-radius: 8px;\r\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.175);\r\n z-index: 1000;\r\n overflow: hidden;\r\n animation: slideDown 0.15s ease-out;\r\n}\r\n\r\n@keyframes slideDown {\r\n from {\r\n opacity: 0;\r\n transform: translateY(-0.5rem);\r\n }\r\n\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n}\r\n\r\n.optionsList {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0.5rem 0;\r\n}\r\n\r\n.option {\r\n padding: 0.75rem 1rem;\r\n cursor: pointer;\r\n transition: all 0.15s ease;\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-fg-text);\r\n font-size: 0.875rem;\r\n}\r\n\r\n.option:hover {\r\n background-color: var(--color-bg-2);\r\n}\r\n\r\n.option.selected {\r\n background-color: var(--color-bg-3);\r\n color: var(--color-fg-highlight);\r\n font-weight: 600;\r\n}\r\n\r\n/* ===== 响应式 ===== */\r\n@media (max-width: 768px) {\r\n .dropdownButton {\r\n padding: 0.625rem 0.875rem;\r\n padding-right: 2.25rem;\r\n font-size: 0.875rem;\r\n }\r\n\r\n .chevronIcon {\r\n right: 0.875rem;\r\n }\r\n\r\n .option {\r\n padding: 0.625rem 0.875rem;\r\n font-size: 0.8125rem;\r\n }\r\n}","/**\n * 下拉选择:options 为 { value, label } 列表,受控 value/onChange。Dropdown select; options as { value, label }, controlled value/onChange.\n *\n * @example\n * ```tsx\n * * 受控选择\n * const [value, setValue] = useState(\"\");\n * <Dropdown\n * options={[{ value: \"a\", label: \"选项 A\" }, { value: \"b\", label: \"选项 B\" }]}\n * value={value}\n * onChange={setValue}\n * placeholder=\"请选择\"\n * />\n * ```\n */\nimport { memo, useEffect, useRef, useState } from \"react\";\n\nimport { ChevronDown } from \"@/icons/lucide\";\n\nimport styles from \"./Dropdown.module.css\";\n\nexport interface DropdownOption {\n /** 选项值。Option value. */\n value: string;\n /** 选项展示文案。Option label. */\n label: string;\n}\n\nexport interface DropdownProps {\n /** 选项列表。Options list. */\n options: DropdownOption[];\n /** 当前选中值。Current value. */\n value: string;\n /** 选中回调。Change callback. */\n onChange: (value: string) => void;\n /** 占位符。Placeholder. */\n placeholder?: string;\n /** 是否禁用。Disabled. */\n disabled?: boolean;\n /** 是否错误态。Error state. */\n error?: boolean;\n /** 容器 className。Container className. */\n className?: string;\n}\n\nconst Dropdown = memo<DropdownProps>(({ options, value, onChange, placeholder = \"Select an option\", disabled = false, error = false, className = \"\" }) => {\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n // 点击外部关闭下拉菜单\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n const selectedOption = options.find((option) => option.value === value);\n const displayText = selectedOption ? selectedOption.label : placeholder;\n\n const handleOptionClick = (optionValue: string) => {\n onChange(optionValue);\n setIsOpen(false);\n };\n\n return (\n <div className={`${styles.dropdown} ${className}`} ref={dropdownRef}>\n <button\n type=\"button\"\n className={`${styles.dropdownButton} ${error ? styles.error : \"\"} ${disabled ? styles.disabled : \"\"}`}\n onClick={() => !disabled && setIsOpen(!isOpen)}\n disabled={disabled}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n <span className={styles.buttonText}>{displayText}</span>\n <ChevronDown size={16} className={`${styles.chevronIcon} ${isOpen ? styles.open : \"\"}`} />\n </button>\n\n {isOpen && !disabled && (\n <div className={styles.dropdownMenu}>\n <ul className={styles.optionsList} role=\"listbox\">\n {options.map((option) => (\n <li\n key={option.value}\n className={`${styles.option} ${option.value === value ? styles.selected : \"\"}`}\n onClick={() => handleOptionClick(option.value)}\n role=\"option\"\n aria-selected={option.value === value}\n >\n {option.label}\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n );\n});\n\nDropdown.displayName = \"Dropdown\";\n\nexport default Dropdown;\n","/**\n * 图标组件:基于 lucide-react,通过 name 渲染对应图标。Icon component; renders lucide icon by name.\n *\n * @example\n * ```tsx\n * * 使用已注册的图标名\n * <Icon name=\"ChevronDown\" size={20} />\n * * 带 className\n * <Icon name=\"Search\" className={styles.searchIcon} />\n * ```\n */\nimport type { LucideProps } from \"lucide-react\";\n\nimport { memo } from \"react\";\n\nimport * as LucideIcons from \"@/icons/lucide\";\n\nexport type IconName = keyof Omit<typeof LucideIcons, \"LucideIcon\">;\n\nexport interface IconProps extends LucideProps {\n /** 图标名(lucide 注册名)。Icon name (lucide registered name). */\n name: IconName;\n}\n\nconst Icon = memo(({ name, ...props }: IconProps) => {\n const LucideIcon = LucideIcons[name] as React.ComponentType<LucideProps> | undefined;\n\n if (!LucideIcon) {\n console.warn(`Icon \"${name}\" not found in lucide-react`);\n return null;\n }\n\n return <LucideIcon {...props} />;\n});\n\nIcon.displayName = \"Icon\";\n\nexport default Icon;\n",".wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.wrapper.fullWidth {\n width: 100%;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-heading);\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.required {\n color: var(--color-danger);\n}\n\n.inputContainer {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n.input {\n width: 100%;\n border: 1px solid var(--color-border-4);\n border-radius: 0.5rem;\n background: var(--color-bg);\n color: var(--color-fg-text);\n font-size: 0.875rem;\n font-family: inherit;\n transition: all 0.2s ease;\n outline: none;\n}\n\n/* 隐藏浏览器默认的密码可见性切换图标 */\n/* Chrome/Edge/Safari: 隐藏密码可见性切换按钮 */\n.input[type=\"password\"]::-webkit-credentials-auto-fill-button {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n pointer-events: none !important;\n -webkit-appearance: none !important;\n appearance: none !important;\n position: absolute !important;\n left: -9999px !important;\n}\n\n.input[type=\"password\"]::-webkit-strong-password-toggle-button {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n pointer-events: none !important;\n -webkit-appearance: none !important;\n appearance: none !important;\n margin: 0 !important;\n padding: 0 !important;\n width: 0 !important;\n height: 0 !important;\n position: absolute !important;\n left: -9999px !important;\n}\n\n/* Edge 浏览器额外处理 */\n.input[type=\"password\"]::-ms-reveal,\n.input[type=\"password\"]::-ms-clear {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n pointer-events: none !important;\n width: 0 !important;\n height: 0 !important;\n position: absolute !important;\n left: -9999px !important;\n}\n\n.input:focus {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb, 102, 126, 234), 0.1);\n}\n\n.input::placeholder {\n color: var(--color-fg-muted, var(--color-fg-text));\n opacity: 0.5;\n}\n\n/* Size variants */\n.input.small {\n padding: 0.5rem 0.75rem;\n font-size: 0.8125rem;\n}\n\n.input.medium {\n padding: 0.75rem;\n font-size: 0.875rem;\n}\n\n.input.large {\n padding: 1rem;\n font-size: 1rem;\n}\n\n/* Variant styles */\n.input.default {\n background: var(--color-bg);\n border-color: var(--color-border-4);\n}\n\n.input.filled {\n background: var(--color-bg-2);\n border-color: var(--color-border-3);\n}\n\n/* With icons - handled via className in component */\n.inputContainer.withLeftIcon .input {\n padding-left: 2.5rem;\n}\n\n.inputContainer.withRightIcon .input {\n padding-right: 2.5rem;\n}\n\n.inputContainer.withLeftIcon .input.small {\n padding-left: 2rem;\n}\n\n.inputContainer.withRightIcon .input.small {\n padding-right: 2rem;\n}\n\n.inputContainer.withLeftIcon .input.large {\n padding-left: 3rem;\n}\n\n.inputContainer.withRightIcon .input.large {\n padding-right: 3rem;\n}\n\n.leftIcon,\n.rightIcon {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-fg-muted, var(--color-fg-text));\n pointer-events: none;\n z-index: 1;\n}\n\n.leftIcon {\n left: 0.75rem;\n}\n\n.rightIcon {\n right: 0.75rem;\n}\n\n.rightIcon.rightIconInteractive {\n pointer-events: auto;\n}\n\n.inputContainer.containerSmall .leftIcon {\n left: 0.5rem;\n}\n\n.inputContainer.containerSmall .rightIcon {\n right: 0.5rem;\n}\n\n.inputContainer.containerLarge .leftIcon {\n left: 1rem;\n}\n\n.inputContainer.containerLarge .rightIcon {\n right: 1rem;\n}\n\n/* Error state */\n.input.error {\n border-color: var(--color-danger);\n}\n\n.input.error:focus {\n border-color: var(--color-danger);\n box-shadow: 0 0 0 3px rgba(var(--color-danger-rgb, 244, 67, 54), 0.1);\n}\n\n/* Disabled state */\n.input.disabled {\n background: var(--color-bg-3);\n border-color: var(--color-border-5);\n color: var(--color-fg-muted);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.errorMessage {\n font-size: 0.75rem;\n color: var(--color-danger);\n margin: 0;\n}\n\n.helperText {\n font-size: 0.75rem;\n color: var(--color-fg-muted);\n margin: 0;\n}\n","/**\n * 输入框:支持 label、error、helperText、左右图标与 rightIconInteractive。Input with label, error, helperText, left/right icon.\n *\n * @example\n * ```tsx\n * * 带标签与错误态\n * <Input label=\"用户名\" error={errors.name} value={name} onChange={(e) => setName(e.target.value)} />\n * * 右侧可点击图标(如清除)\n * <Input rightIcon={<X size={16} />} rightIconInteractive onRightIconClick={clear} />\n * ```\n */\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\n\nimport { forwardRef } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\"> {\n /** 标签文案。Label text. */\n label?: string;\n /** 错误信息。Error message. */\n error?: string;\n /** 辅助说明。Helper text. */\n helperText?: string;\n /** 左侧图标。Left icon. */\n leftIcon?: ReactNode;\n /** 右侧图标。Right icon. */\n rightIcon?: ReactNode;\n /** 为 true 时 rightIcon 可点击(如密码切换、清除按钮)。When true, right icon is clickable (e.g. password toggle, clear). */\n rightIconInteractive?: boolean;\n /** 尺寸。Size. */\n size?: \"small\" | \"medium\" | \"large\";\n /** 视觉变体。Variant. */\n variant?: \"default\" | \"filled\";\n /** 是否占满宽度。Full width. */\n fullWidth?: boolean;\n}\n\nconst Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n label,\n error,\n helperText,\n leftIcon,\n rightIcon,\n rightIconInteractive = false,\n size = \"medium\",\n variant = \"default\",\n fullWidth = false,\n className = \"\",\n disabled,\n ...props\n },\n ref,\n ) => {\n const inputClasses = [styles.input, styles[size], styles[variant], error && styles.error, disabled && styles.disabled, className].filter(Boolean).join(\" \");\n\n const wrapperClasses = [styles.wrapper, fullWidth && styles.fullWidth].filter(Boolean).join(\" \");\n\n const containerClasses = [\n styles.inputContainer,\n leftIcon && styles.withLeftIcon,\n rightIcon && styles.withRightIcon,\n size && styles[`container${size.charAt(0).toUpperCase() + size.slice(1)}`],\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={wrapperClasses}>\n {label && (\n <label className={styles.label}>\n {label}\n {props.required && <span className={styles.required}>*</span>}\n </label>\n )}\n <div className={containerClasses}>\n {leftIcon && <div className={styles.leftIcon}>{leftIcon}</div>}\n <input ref={ref} className={inputClasses} disabled={disabled} {...props} />\n {rightIcon && <div className={`${styles.rightIcon} ${rightIconInteractive ? styles.rightIconInteractive : \"\"}`}>{rightIcon}</div>}\n </div>\n {error && <p className={styles.errorMessage}>{error}</p>}\n {helperText && !error && <p className={styles.helperText}>{helperText}</p>}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n\nexport default Input;\n",".container {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-text);\n}\n\n.error {\n font-size: 0.875rem;\n color: var(--color-error);\n}\n\n.pairs {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.pair {\n display: grid;\n grid-template-columns: 1fr 2fr auto;\n gap: 0.75rem;\n align-items: start;\n}\n\n.keyInput,\n.valueInput {\n flex: 1;\n}\n\n.removeButton {\n padding: 0.5rem;\n min-width: auto;\n color: var(--color-error);\n}\n\n.removeButton:hover {\n background-color: var(--color-error);\n color: white;\n}\n\n.addButton {\n align-self: flex-start;\n}\n\n@media (max-width: 768px) {\n .pair {\n grid-template-columns: 1fr;\n }\n\n .removeButton {\n align-self: flex-end;\n }\n}\n","/**\n * 键值对编辑器:动态增删 key-value 行,支持 string 或 array 值类型。Key-value pair editor; add/remove rows, valueType string or array.\n *\n * @example\n * ```tsx\n * * 字符串值\n * const [pairs, setPairs] = useState<KeyValuePair[]>([{ key: \"env\", value: \"prod\" }]);\n * <KeyValueEditor label=\"环境变量\" pairs={pairs} onChange={setPairs} />\n * * 数组值(逗号分隔)\n * <KeyValueEditor label=\"标签\" pairs={pairs} onChange={setPairs} valueType=\"array\" />\n * ```\n */\nimport { memo, useEffect, useState } from \"react\";\n\nimport Button from \"@/designs/components/Button\";\nimport Input from \"@/designs/components/Input\";\nimport { Plus, Trash2 } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface KeyValuePair {\n /** 键。Key. */\n key: string;\n /** 值(字符串或字符串数组)。Value (string or string[]). */\n value: string | string[];\n}\n\nexport interface KeyValueEditorProps {\n /** 表单项标签。Field label. */\n label: string;\n /** 键值对列表。Key-value pairs. */\n pairs: KeyValuePair[];\n /** 列表变化回调。Change callback. */\n onChange: (pairs: KeyValuePair[]) => void;\n /** 值类型:string 或 array。Value type: string or array. */\n valueType?: \"string\" | \"array\";\n /** 键占位符。Key placeholder. */\n keyPlaceholder?: string;\n /** 值占位符(string 模式)。Value placeholder (string mode). */\n valuePlaceholder?: string;\n /** 值占位符(array 模式)。Value placeholder (array mode). */\n valueArrayPlaceholder?: string;\n /** 删除按钮 aria-label。Remove button aria-label. */\n removeAriaLabel?: string;\n /** 新增按钮文案。Add button label. */\n addLabel?: string;\n /** 错误信息。Error message. */\n error?: string;\n}\n\nconst KeyValueEditor = memo(\n ({\n label,\n pairs,\n onChange,\n valueType = \"string\",\n keyPlaceholder = \"Key\",\n valuePlaceholder = \"Value\",\n valueArrayPlaceholder = \"Value (comma-separated)\",\n removeAriaLabel = \"Remove row\",\n addLabel = \"Add\",\n error,\n }: KeyValueEditorProps) => {\n const effectiveValuePlaceholder = valueType === \"array\" ? valueArrayPlaceholder : valuePlaceholder;\n const [localPairs, setLocalPairs] = useState<KeyValuePair[]>(pairs);\n\n // Sync with external pairs changes\n useEffect(() => {\n setLocalPairs(pairs);\n }, [pairs]);\n\n const handleAdd = () => {\n const newPairs = [...localPairs, { key: \"\", value: valueType === \"array\" ? [] : \"\" }];\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const handleRemove = (index: number) => {\n const newPairs = localPairs.filter((_, i) => i !== index);\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const handleKeyChange = (index: number, key: string) => {\n const newPairs = [...localPairs];\n newPairs[index] = { ...newPairs[index], key };\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const handleValueChange = (index: number, value: string) => {\n const newPairs = [...localPairs];\n if (valueType === \"array\") {\n // Split by comma and trim\n const arrayValue = value\n .split(\",\")\n .map((v) => v.trim())\n .filter((v) => v.length > 0);\n newPairs[index] = { ...newPairs[index], value: arrayValue };\n } else {\n newPairs[index] = { ...newPairs[index], value };\n }\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const getDisplayValue = (value: string | string[]): string => {\n if (Array.isArray(value)) {\n return value.join(\", \");\n }\n return value;\n };\n\n return (\n <div className={styles.container}>\n <label className={styles.label}>{label}</label>\n {error && <div className={styles.error}>{error}</div>}\n <div className={styles.pairs}>\n {localPairs.map((pair, index) => (\n <div key={index} className={styles.pair}>\n <Input placeholder={keyPlaceholder} value={pair.key} onChange={(e) => handleKeyChange(index, e.target.value)} className={styles.keyInput} />\n <Input\n placeholder={effectiveValuePlaceholder}\n value={getDisplayValue(pair.value)}\n onChange={(e) => handleValueChange(index, e.target.value)}\n className={styles.valueInput}\n />\n <Button type=\"button\" variant=\"ghost\" onClick={() => handleRemove(index)} className={styles.removeButton} aria-label={removeAriaLabel}>\n <Trash2 size={16} />\n </Button>\n </div>\n ))}\n </div>\n <Button type=\"button\" variant=\"secondary\" onClick={handleAdd} className={styles.addButton}>\n <Plus size={16} />\n {addLabel}\n </Button>\n </div>\n );\n },\n);\n\nKeyValueEditor.displayName = \"KeyValueEditor\";\n\nexport default KeyValueEditor;\n",".searchContainer {\r\n position: relative;\r\n width: 100%;\r\n max-width: 400px;\r\n}\r\n\r\n.searchIcon {\r\n position: absolute;\r\n left: 1rem;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n color: var(--color-fg-muted);\r\n pointer-events: none;\r\n}\r\n\r\n.searchInput {\r\n width: 100%;\r\n padding: 0.75rem 3rem 0.75rem 3rem;\r\n border: 1px solid var(--color-border);\r\n border-radius: 0.5rem;\r\n font-size: 1rem;\r\n color: var(--color-fg-text);\r\n background: var(--color-bg-2);\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.searchInput:focus {\r\n outline: none;\r\n border-color: var(--color-primary);\r\n box-shadow: 0 0 0 3px var(--color-primary-bg);\r\n}\r\n\r\n.searchInput::placeholder {\r\n color: var(--color-fg-muted);\r\n}\r\n\r\n.clearBtn {\r\n position: absolute;\r\n right: 0.75rem;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 1.5rem;\r\n height: 1.5rem;\r\n padding: 0;\r\n background: none;\r\n border: none;\r\n color: var(--color-fg-muted);\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.clearBtn:hover {\r\n color: var(--color-fg-text);\r\n}\r\n\r\n@media (max-width: 768px) {\r\n .searchContainer {\r\n max-width: 100%;\r\n }\r\n}\r\n\r\n","/**\n * 搜索输入框:带搜索图标与清除按钮;文案由调用方传入。Search input with search icon and clear button; labels passed as props.\n *\n * @example\n * ```tsx\n * * 受控,文案由上层 i18n 传入\n * const { t } = useTranslation(\"components\");\n * <SearchInput value={keyword} onChange={setKeyword} placeholder={t(\"searchInput.placeholder\")} clearButtonAriaLabel={t(\"searchInput.clearSearch\")} />\n * ```\n */\nimport { memo } from \"react\";\n\nimport { Search, X } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface SearchInputProps {\n /** 当前输入值。Current value. */\n value: string;\n /** 值变化回调。Change callback. */\n onChange: (value: string) => void;\n /** 占位符,由调用方传入。Placeholder; pass from caller. */\n placeholder?: string;\n /** 清除按钮 aria-label;由调用方传入(可来自 i18n)。Clear button aria-label; pass from caller. */\n clearButtonAriaLabel?: string;\n}\n\nconst SearchInput = memo(({ value, onChange, placeholder, clearButtonAriaLabel = \"Clear search\" }: SearchInputProps) => {\n const handleClear = () => onChange(\"\");\n\n return (\n <div className={styles.searchContainer}>\n <Search size={18} className={styles.searchIcon} />\n <input type=\"text\" value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} className={styles.searchInput} />\n {value && (\n <button onClick={handleClear} className={styles.clearBtn} aria-label={clearButtonAriaLabel}>\n <X size={16} />\n </button>\n )}\n </div>\n );\n});\n\nSearchInput.displayName = \"SearchInput\";\n\nexport default SearchInput;\n",".container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.75rem;\r\n}\r\n\r\n.toggleContainer {\r\n display: flex;\r\n align-items: center;\r\n}\r\n\r\n.toggleButton {\r\n display: flex;\r\n align-items: center;\r\n gap: 0.5rem;\r\n padding: 0.5rem 1rem;\r\n border: 1px solid var(--color-border-4);\r\n border-radius: 0.5rem;\r\n background: var(--color-bg);\r\n color: var(--color-fg-muted);\r\n font-size: 0.875rem;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.toggleButton:hover {\r\n background: var(--color-bg-2);\r\n border-color: var(--color-border-3);\r\n}\r\n\r\n.toggleButton.enabled {\r\n background: var(--color-primary);\r\n color: white;\r\n border-color: var(--color-primary);\r\n}\r\n\r\n.toggleButton.enabled:hover {\r\n background: var(--color-primary-hover);\r\n border-color: var(--color-primary-hover);\r\n}\r\n\r\n.optionsContainer {\r\n display: flex;\r\n gap: 0.5rem;\r\n padding: 0.5rem;\r\n background: var(--color-bg-2);\r\n border-radius: 0.5rem;\r\n border: 1px solid var(--color-border-4);\r\n}\r\n\r\n.option {\r\n display: flex;\r\n align-items: center;\r\n gap: 0.375rem;\r\n padding: 0.5rem 0.875rem;\r\n border: 1px solid var(--color-border-4);\r\n border-radius: 0.375rem;\r\n background: var(--color-bg);\r\n color: var(--color-fg);\r\n font-size: 0.875rem;\r\n font-weight: 500;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n flex: 1;\r\n justify-content: center;\r\n}\r\n\r\n.option:hover {\r\n background: var(--color-bg-3);\r\n border-color: var(--color-border-3);\r\n}\r\n\r\n.option.active {\r\n background: var(--color-primary);\r\n color: white;\r\n border-color: var(--color-primary);\r\n}\r\n\r\n.option.active:hover {\r\n background: var(--color-primary-hover);\r\n border-color: var(--color-primary-hover);\r\n}\r\n\r\n","/**\n * 显示/隐藏筛选器:开关 + 全部/显示/隐藏选项;文案由调用方传入。Show/hide filter; labels passed as props.\n *\n * @example\n * ```tsx\n * * 受控,不传文案则用默认英文;可传 i18n\n * <ShowFilter value={filter} onChange={setFilter} />\n * <ShowFilter value={filter} onChange={setFilter} all={t(\"showFilter.all\")} show={t(\"showFilter.show\")} hide={t(\"showFilter.hide\")} />\n * ```\n */\nimport { memo } from \"react\";\n\nimport { Eye, EyeOff, Filter } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface ShowFilterValue {\n /** 筛选是否启用。Whether filter is enabled. */\n enabled: boolean;\n /** 显示/隐藏:null=全部,true=显示,false=隐藏。Show/hide: null=all, true=show, false=hide. */\n value: boolean | null;\n}\n\nexport interface ShowFilterProps {\n /** 当前值。Current value. */\n value: ShowFilterValue;\n /** 值变化回调。Change callback. */\n onChange: (value: ShowFilterValue) => void;\n /** 筛选开启时的按钮文案。Label when filter enabled. */\n filterEnabled?: string;\n /** 筛选关闭时的按钮文案。Label when filter disabled. */\n filterDisabled?: string;\n /** 开启筛选按钮的 aria-label。Aria-label for enable filter button. */\n enableFilterAriaLabel?: string;\n /** 关闭筛选按钮的 aria-label。Aria-label for disable filter button. */\n disableFilterAriaLabel?: string;\n /** 「全部」选项文案。Label for \"all\" option. */\n all?: string;\n /** 「显示」选项文案。Label for \"show\" option. */\n show?: string;\n /** 「隐藏」选项文案。Label for \"hide\" option. */\n hide?: string;\n}\n\nconst ShowFilter = memo(\n ({\n value,\n onChange,\n filterEnabled = \"Filter on\",\n filterDisabled = \"Filter\",\n enableFilterAriaLabel = \"Enable filter\",\n disableFilterAriaLabel = \"Disable filter\",\n all = \"All\",\n show = \"Show\",\n hide = \"Hide\",\n }: ShowFilterProps) => {\n const handleToggleEnabled = () => {\n onChange({ ...value, enabled: !value.enabled });\n };\n\n const handleSelectValue = (filterValue: boolean | null) => {\n onChange({ ...value, value: filterValue });\n };\n\n return (\n <div className={styles.container}>\n <div className={styles.toggleContainer}>\n <button\n type=\"button\"\n className={`${styles.toggleButton} ${value.enabled ? styles.enabled : \"\"}`}\n onClick={handleToggleEnabled}\n aria-label={value.enabled ? disableFilterAriaLabel : enableFilterAriaLabel}\n >\n <Filter size={16} />\n <span>{value.enabled ? filterEnabled : filterDisabled}</span>\n </button>\n </div>\n\n {value.enabled && (\n <div className={styles.optionsContainer}>\n <button type=\"button\" className={`${styles.option} ${value.value === null ? styles.active : \"\"}`} onClick={() => handleSelectValue(null)}>\n {all}\n </button>\n <button type=\"button\" className={`${styles.option} ${value.value === true ? styles.active : \"\"}`} onClick={() => handleSelectValue(true)}>\n <Eye size={16} />\n <span>{show}</span>\n </button>\n <button type=\"button\" className={`${styles.option} ${value.value === false ? styles.active : \"\"}`} onClick={() => handleSelectValue(false)}>\n <EyeOff size={16} />\n <span>{hide}</span>\n </button>\n </div>\n )}\n </div>\n );\n },\n);\n\nShowFilter.displayName = \"ShowFilter\";\n\nexport default ShowFilter;\n","/* ===== Nebular Select 样式模仿(下拉滑出) ===== */\n\n.nbSelect {\n display: inline-block;\n position: relative;\n font-family: inherit;\n font-size: 0.9375rem;\n line-height: 1.5rem;\n font-weight: 600;\n}\n\n.selectButton {\n position: relative;\n width: 100%;\n min-width: 8rem;\n padding: 0.4375rem 2.2rem 0.4375rem 1.125rem;\n border: 1px solid;\n border-radius: 0.25rem;\n cursor: pointer;\n outline: none;\n transition: all 0.15s ease-in-out;\n text-align: left;\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-family: inherit;\n font-size: inherit;\n font-weight: inherit;\n line-height: inherit;\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n}\n\n.selectButton.primary {\n background-color: var(--color-primary);\n border-color: var(--color-primary);\n color: var(--color-primary-fg);\n}\n\n.selectButton.primary:hover:not(:disabled) {\n background-color: var(--color-primary-light);\n border-color: var(--color-primary-light);\n}\n\n.selectButton.primary:focus,\n.selectButton.primary.open {\n background-color: var(--color-primary-light);\n border-color: var(--color-primary-light);\n box-shadow: 0 0 0 0.125rem rgba(143, 155, 179, 0.25);\n}\n\n.selectButton.default {\n background-color: var(--color-bg);\n border-color: var(--color-border-4);\n color: var(--color-fg-text);\n}\n\n.selectButton.default:hover:not(:disabled) {\n background-color: var(--color-bg-2);\n border-color: var(--color-primary);\n}\n\n.selectButton.default:focus,\n.selectButton.default.open {\n background-color: var(--color-bg-2);\n border-color: var(--color-primary);\n box-shadow: 0 0 0 0.125rem rgba(143, 155, 179, 0.25);\n}\n\n.selectButton:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.buttonText {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.chevronIcon {\n position: absolute;\n right: 0.41rem;\n width: 1.5rem;\n height: 1.5rem;\n transition: transform 0.15s ease;\n flex-shrink: 0;\n}\n\n.selectButton.primary .chevronIcon {\n color: var(--color-primary-fg);\n}\n\n.selectButton.default .chevronIcon {\n color: var(--color-fg);\n}\n\n.chevronIcon.open {\n transform: rotate(180deg);\n}\n\n.optionsPanel {\n position: absolute;\n top: calc(100% + 0.5rem);\n left: 0;\n right: 0;\n min-width: 100%;\n background-color: var(--color-bg);\n border: 1px solid var(--color-border-4);\n border-radius: 0.25rem;\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n z-index: 1000;\n overflow: hidden;\n transform-origin: top;\n visibility: hidden;\n pointer-events: none;\n}\n\n.optionsPanel.open {\n visibility: visible;\n pointer-events: auto;\n animation: expandDown 0.25s ease-out;\n}\n\n.optionsPanel.closed {\n visibility: hidden;\n pointer-events: none;\n animation: collapseUp 0.25s ease-out;\n}\n\n@keyframes expandDown {\n from {\n opacity: 0;\n transform: scaleY(0);\n }\n to {\n opacity: 1;\n transform: scaleY(1);\n }\n}\n\n@keyframes collapseUp {\n from {\n opacity: 1;\n transform: scaleY(1);\n }\n to {\n opacity: 0;\n transform: scaleY(0);\n }\n}\n\n.optionsPanel.primary {\n border-color: var(--color-primary);\n}\n\n.optionsPanel.default {\n border-color: var(--color-border-4);\n}\n\n.optionsList {\n list-style: none;\n margin: 0;\n padding: 0.5rem 0;\n}\n\n.option {\n padding: 0.75rem 1.125rem;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: space-between;\n color: var(--color-fg-text);\n}\n\n.option:hover {\n background-color: var(--color-bg-2);\n}\n\n.option.selected {\n background-color: var(--color-primary);\n color: var(--color-primary-fg);\n font-weight: 700;\n}\n\n@media (prefers-color-scheme: dark) {\n .optionsPanel {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.3);\n }\n}\n","/**\n * 下滑切换器:选项列表下拉选择,支持泛型 T(如 enum)。Dropdown switcher with options; generic T (e.g. enum).\n *\n * @example\n * ```tsx\n * * 与 enum 配合\n * type Status = \"all\" | \"active\" | \"archived\";\n * <SlideDownSwitcher<Status>\n * value={filter}\n * options={[\"all\", \"active\", \"archived\"]}\n * getDisplayName={(v) => ({ all: \"全部\", active: \"启用\", archived: \"归档\" }[v])}\n * onChange={setFilter}\n * />\n * ```\n */\nimport { memo, useEffect, useRef, useState } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface SlideDownSwitcherProps<T extends string> {\n /** 当前选中的值(enum 或 string) */\n value: T;\n /** 可选项列表(如 Object.values(SomeEnum)) */\n options: readonly T[];\n /** 选项展示文案 */\n getDisplayName: (value: T) => string;\n /** 选中后回调 */\n onChange: (value: T) => void;\n status?: \"primary\" | \"default\";\n}\n\nconst SlideDownSwitcherInner = <T extends string>({ value, options, getDisplayName, onChange, status = \"primary\" }: SlideDownSwitcherProps<T>) => {\n const [isOpen, setIsOpen] = useState(false);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, []);\n\n const handleSelect = (option: T) => {\n onChange(option);\n setIsOpen(false);\n };\n\n return (\n <div className={styles.nbSelect} ref={wrapperRef}>\n <button\n type=\"button\"\n className={`${styles.selectButton} ${styles[status]}`}\n onClick={() => setIsOpen(!isOpen)}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n <span className={styles.buttonText}>{getDisplayName(value)}</span>\n <svg\n className={`${styles.chevronIcon} ${isOpen ? styles.open : \"\"}`}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"m6 9 6 6 6-6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n\n <div className={`${styles.optionsPanel} ${styles[status]} ${isOpen ? styles.open : styles.closed}`} role=\"listbox\">\n <ul className={styles.optionsList}>\n {options.map((option) => (\n <li\n key={option}\n className={`${styles.option} ${option === value ? styles.selected : \"\"}`}\n onClick={() => handleSelect(option)}\n role=\"option\"\n aria-selected={option === value}\n >\n <span>{getDisplayName(option)}</span>\n {option === value && (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M20 6L9 17l-5-5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n </li>\n ))}\n </ul>\n </div>\n </div>\n );\n};\n\nconst SlideDownSwitcher = memo(SlideDownSwitcherInner) as typeof SlideDownSwitcherInner & {\n displayName?: string;\n};\nSlideDownSwitcher.displayName = \"SlideDownSwitcher\";\n\nexport default SlideDownSwitcher;\n","import type { ThemeEnum, ThemeSwitcherProps } from \"@/themes/types\";\n\nimport { memo } from \"react\";\n\nimport { useTheme } from \"@/themes/hooks/useTheme\";\n\nimport SlideDownSwitcher from \"../SlideDownSwitcher\";\n\nconst ThemeSwitcher = memo(({ status = \"primary\", getThemeDisplayName, handleChangeTheme }: ThemeSwitcherProps) => {\n const { themeName, setTheme, availableThemes } = useTheme();\n\n const getDisplayName = getThemeDisplayName ?? ((theme: ThemeEnum) => theme);\n\n const handleChange = (theme: ThemeEnum) => {\n setTheme(theme);\n handleChangeTheme?.(theme);\n };\n\n return <SlideDownSwitcher value={themeName} options={availableThemes} getDisplayName={getDisplayName} onChange={handleChange} status={status} />;\n});\n\nThemeSwitcher.displayName = \"ThemeSwitcher\";\n\nexport default ThemeSwitcher;\n","import type { LayoutSwitcherProps } from \"@/designs/layouts/types\";\n\nimport { memo } from \"react\";\n\nimport useLayout from \"@/designs/layouts/hooks/useLayout\";\nimport { LAYOUT_MODE_VALUES, LayoutModeEnum } from \"@/designs/layouts/types\";\n\nimport SlideDownSwitcher from \"../SlideDownSwitcher\";\n\nconst LayoutSwitcher = memo(({ status = \"primary\", getLayoutDisplayName, handleChangeLayoutMode }: LayoutSwitcherProps) => {\n const { layoutMode, setLayoutMode } = useLayout();\n\n const getDisplayName = getLayoutDisplayName ?? ((mode: LayoutModeEnum) => mode);\n\n const handleChange = (mode: LayoutModeEnum) => {\n setLayoutMode(mode);\n handleChangeLayoutMode?.(mode);\n };\n\n return <SlideDownSwitcher value={layoutMode} options={LAYOUT_MODE_VALUES} getDisplayName={getDisplayName} onChange={handleChange} status={status} />;\n});\n\nLayoutSwitcher.displayName = \"LayoutSwitcher\";\n\nexport default LayoutSwitcher;\n",".sliderContainer {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.sliderContainer.fullWidth {\n width: 100%;\n}\n\n.labelRow {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.5rem;\n min-height: 1.5rem;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-text);\n}\n\n.required {\n color: var(--color-danger);\n margin-left: 0.25rem;\n}\n\n.sliderWrapper {\n display: flex;\n width: 100%;\n touch-action: none;\n user-select: none;\n align-items: center;\n justify-content: center;\n gap: 0.75rem;\n}\n\n.sliderRoot {\n position: relative;\n display: flex;\n width: 100%;\n flex-grow: 1;\n cursor: grab;\n touch-action: none;\n user-select: none;\n align-items: center;\n padding: 0.75rem 0;\n}\n\n.sliderRoot:active {\n cursor: grabbing;\n}\n\n.sliderTrackWrapper {\n display: flex;\n flex-grow: 1;\n position: relative;\n}\n\n.sliderTrack {\n position: relative;\n height: 0.375rem;\n width: 100%;\n overflow: hidden;\n border-radius: 9999px;\n background-color: var(--color-bg-3);\n}\n\n.sliderRange {\n position: absolute;\n height: 100%;\n background-color: var(--color-primary);\n border-radius: 9999px;\n}\n\n.valueIndicator {\n color: var(--color-primary);\n font-size: 0.875rem;\n font-weight: 600;\n min-width: 2rem;\n text-align: center;\n flex-shrink: 0;\n line-height: 1;\n}\n\n.iconWrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.icon {\n width: 20px;\n height: 20px;\n color: var(--color-fg-muted);\n}\n\n.errorMessage {\n font-size: 0.75rem;\n color: var(--color-danger);\n margin: 0;\n}\n\n.helperText {\n font-size: 0.75rem;\n color: var(--color-fg-muted);\n margin: 0;\n}\n","/**\n * 滑块:受控 value/onChange,支持 min/max/step、label、error、overflow 动效。Slider; controlled value/onChange, min/max/step, label, error.\n *\n * @example\n * ```tsx\n * * 基础\n * <Slider value={volume} onChange={setVolume} min={0} max={100} />\n * * 带标签与辅助文案\n * <Slider label=\"音量\" value={volume} onChange={setVolume} showValue helperText=\"0-100\" />\n * ```\n */\nimport { forwardRef, memo, useEffect, useRef, useState } from \"react\";\nimport { animate, motion, useMotionValue, useMotionValueEvent, useTransform } from \"motion/react\";\n\nimport { ChevronLeft, ChevronRight } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nconst MAX_OVERFLOW = 50;\n\nexport interface SliderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n /** 当前值。Current value. */\n value: number;\n /** 值变化回调。Change callback. */\n onChange: (value: number) => void;\n /** 最小值。Minimum. */\n min?: number;\n /** 最大值。Maximum. */\n max?: number;\n /** 步长。Step. */\n step?: number;\n /** 是否显示数值。Show value. */\n showValue?: boolean;\n /** 是否占满宽度。Full width. */\n fullWidth?: boolean;\n /** 标签文案。Label text. */\n label?: string;\n /** 错误信息。Error message. */\n error?: string;\n /** 辅助说明。Helper text. */\n helperText?: string;\n /** 是否必填。Required. */\n required?: boolean;\n}\n\nconst Slider = memo(\n forwardRef<HTMLDivElement, SliderProps>(\n (\n {\n value: controlledValue,\n onChange,\n min = 0,\n max = 10,\n step = 1,\n showValue = true,\n fullWidth = false,\n label,\n error,\n helperText,\n required = false,\n className = \"\",\n ...props\n },\n ref,\n ) => {\n const [value, setValue] = useState<number>(controlledValue);\n const sliderRef = useRef<HTMLDivElement>(null);\n const [region, setRegion] = useState<\"left\" | \"middle\" | \"right\">(\"middle\");\n const clientX = useMotionValue(0);\n const overflow = useMotionValue(0);\n\n useEffect(() => {\n setValue(controlledValue);\n }, [controlledValue]);\n\n useMotionValueEvent(clientX, \"change\", (latest: number) => {\n if (sliderRef.current) {\n const { left, right } = sliderRef.current.getBoundingClientRect();\n let newValue: number;\n if (latest < left) {\n setRegion(\"left\");\n newValue = left - latest;\n } else if (latest > right) {\n setRegion(\"right\");\n newValue = latest - right;\n } else {\n setRegion(\"middle\");\n newValue = 0;\n }\n overflow.jump(decay(newValue, MAX_OVERFLOW));\n }\n });\n\n const handlePointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n if (e.buttons > 0 && sliderRef.current) {\n const { left, width } = sliderRef.current.getBoundingClientRect();\n let newValue = min + ((e.clientX - left) / width) * (max - min);\n if (step > 0) {\n newValue = Math.round(newValue / step) * step;\n }\n newValue = Math.min(Math.max(newValue, min), max);\n setValue(newValue);\n onChange(newValue);\n clientX.jump(e.clientX);\n }\n };\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n handlePointerMove(e);\n e.currentTarget.setPointerCapture(e.pointerId);\n };\n\n const handlePointerUp = () => {\n animate(overflow, 0, { type: \"spring\", bounce: 0.5 });\n };\n\n const getRangePercentage = (): number => {\n const totalRange = max - min;\n if (totalRange === 0) return 0;\n return ((value - min) / totalRange) * 100;\n };\n\n const wrapperClasses = [styles.sliderContainer, fullWidth && styles.fullWidth, className].filter(Boolean).join(\" \");\n\n return (\n <div ref={ref} className={wrapperClasses} {...props}>\n {label && (\n <div className={styles.labelRow}>\n <label className={styles.label}>\n {label}\n {required && <span className={styles.required}>*</span>}\n </label>\n </div>\n )}\n <motion.div className={styles.sliderWrapper}>\n <motion.div\n animate={{\n scale: region === \"left\" ? [1, 1.4, 1] : 1,\n transition: { duration: 0.25 },\n }}\n style={{\n x: useTransform(() => (region === \"left\" ? -overflow.get() : 0)),\n }}\n className={styles.iconWrapper}\n >\n <ChevronLeft size={20} className={styles.icon} />\n </motion.div>\n\n <div\n ref={sliderRef}\n className={styles.sliderRoot}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n >\n <motion.div\n style={{\n scaleX: useTransform(() => {\n if (sliderRef.current) {\n const { width } = sliderRef.current.getBoundingClientRect();\n return 1 + overflow.get() / width;\n }\n return 1;\n }),\n scaleY: useTransform(overflow, [0, MAX_OVERFLOW], [1, 0.8]),\n transformOrigin: useTransform(() => {\n if (sliderRef.current) {\n const { left, width } = sliderRef.current.getBoundingClientRect();\n return clientX.get() < left + width / 2 ? \"right\" : \"left\";\n }\n return \"center\";\n }),\n }}\n className={styles.sliderTrackWrapper}\n >\n <div className={styles.sliderTrack}>\n <motion.div\n className={styles.sliderRange}\n initial={false}\n animate={{ width: `${getRangePercentage()}%` }}\n transition={{ type: \"spring\", stiffness: 300, damping: 30 }}\n />\n </div>\n </motion.div>\n </div>\n\n <motion.div\n animate={{\n scale: region === \"right\" ? [1, 1.4, 1] : 1,\n transition: { duration: 0.25 },\n }}\n style={{\n x: useTransform(() => (region === \"right\" ? overflow.get() : 0)),\n }}\n className={styles.iconWrapper}\n >\n <ChevronRight size={20} className={styles.icon} />\n </motion.div>\n {showValue && !label && <span className={styles.valueIndicator}>{Math.round(value)}</span>}\n </motion.div>\n {error && <p className={styles.errorMessage}>{error}</p>}\n {helperText && !error && <p className={styles.helperText}>{helperText}</p>}\n </div>\n );\n },\n ),\n);\n\nfunction decay(value: number, max: number): number {\n if (max === 0) {\n return 0;\n }\n const entry = value / max;\n const sigmoid = 2 * (1 / (1 + Math.exp(-entry)) - 0.5);\n return sigmoid * max;\n}\n\nSlider.displayName = \"Slider\";\n\nexport default Slider;\n",".loadingContainer {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n min-height: 60vh;\r\n gap: 1.5rem;\r\n}\r\n\r\n.loadingText {\r\n color: var(--color-fg-muted);\r\n font-size: 1rem;\r\n}\r\n\r\n.errorContainer {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n min-height: 60vh;\r\n gap: 2rem;\r\n padding: 3rem 2rem;\r\n text-align: center;\r\n color: var(--color-fg-text);\r\n}\r\n\r\n.errorIconWrapper {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 120px;\r\n height: 120px;\r\n border-radius: 50%;\r\n background: linear-gradient(135deg, rgba(var(--color-error-rgb, 239, 68, 68), 0.1), rgba(var(--color-error-rgb, 239, 68, 68), 0.05));\r\n border: 2px solid rgba(var(--color-error-rgb, 239, 68, 68), 0.2);\r\n animation: pulse 2s ease-in-out infinite;\r\n}\r\n\r\n@keyframes pulse {\r\n 0%, 100% {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n 50% {\r\n transform: scale(1.05);\r\n opacity: 0.9;\r\n }\r\n}\r\n\r\n.errorIcon {\r\n color: var(--color-error, #ef4444);\r\n stroke-width: 1.5;\r\n}\r\n\r\n.errorContent {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 1rem;\r\n max-width: 600px;\r\n width: 100%;\r\n}\r\n\r\n.errorTitle {\r\n margin: 0;\r\n font-size: 1.75rem;\r\n font-weight: 700;\r\n color: var(--color-fg-heading);\r\n letter-spacing: -0.02em;\r\n line-height: 1.2;\r\n}\r\n\r\n.errorDescription {\r\n margin: 0;\r\n color: var(--color-fg-muted);\r\n font-size: 1rem;\r\n line-height: 1.6;\r\n max-width: 480px;\r\n}\r\n\r\n.errorDetailsWrapper {\r\n width: 100%;\r\n max-width: 600px;\r\n margin-top: 0.5rem;\r\n}\r\n\r\n.errorDetailsContainer {\r\n width: 100%;\r\n text-align: left;\r\n border: 1px solid var(--color-border, rgba(0, 0, 0, 0.1));\r\n border-radius: 0.75rem;\r\n background: var(--color-bg-2, rgba(0, 0, 0, 0.02));\r\n overflow: hidden;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.errorDetailsContainer:hover {\r\n border-color: var(--color-border-hover, rgba(0, 0, 0, 0.15));\r\n background: var(--color-bg-3, rgba(0, 0, 0, 0.03));\r\n}\r\n\r\n.errorDetailsSummary {\r\n padding: 0.875rem 1.25rem;\r\n cursor: pointer;\r\n font-size: 0.875rem;\r\n font-weight: 500;\r\n color: var(--color-fg-muted);\r\n user-select: none;\r\n list-style: none;\r\n transition: color 0.2s ease;\r\n}\r\n\r\n.errorDetailsSummary:hover {\r\n color: var(--color-fg-text);\r\n}\r\n\r\n.errorDetailsSummary::-webkit-details-marker {\r\n display: none;\r\n}\r\n\r\n.errorDetailsSummary::before {\r\n content: \"▶\";\r\n display: inline-block;\r\n margin-right: 0.5rem;\r\n font-size: 0.75rem;\r\n transition: transform 0.2s ease;\r\n}\r\n\r\n.errorDetailsContainer[open] .errorDetailsSummary::before {\r\n transform: rotate(90deg);\r\n}\r\n\r\n.errorDetails {\r\n max-width: 100%;\r\n padding: 1rem 1.25rem;\r\n margin: 0;\r\n background: var(--color-bg-3, rgba(0, 0, 0, 0.03));\r\n border-top: 1px solid var(--color-border, rgba(0, 0, 0, 0.1));\r\n color: var(--color-fg-muted);\r\n font-size: 0.8125rem;\r\n font-family: \"Monaco\", \"Menlo\", \"Ubuntu Mono\", \"Consolas\", \"source-code-pro\", monospace;\r\n line-height: 1.6;\r\n overflow-x: auto;\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n.errorActions {\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.75rem;\r\n margin-top: 1rem;\r\n}\r\n\r\n.retryButton {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.5rem;\r\n padding: 0.75rem 2rem;\r\n border-radius: 0.5rem;\r\n background: var(--color-primary);\r\n color: var(--color-primary-fg);\r\n border: none;\r\n cursor: pointer;\r\n font-size: 0.9375rem;\r\n font-weight: 500;\r\n transition: all 0.2s ease;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.retryButton:hover {\r\n transform: translateY(-2px);\r\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\r\n background: var(--color-primary-hover, var(--color-primary));\r\n}\r\n\r\n.retryButton:active {\r\n transform: translateY(0);\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.retryButtonIcon {\r\n display: inline-block;\r\n font-size: 1.125rem;\r\n line-height: 1;\r\n transition: transform 0.3s ease;\r\n}\r\n\r\n.retryButton:hover .retryButtonIcon {\r\n transform: rotate(180deg);\r\n}\r\n\r\n.clearLocalDataButton {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 0.75rem 1.5rem;\r\n border-radius: 0.5rem;\r\n background: transparent;\r\n color: var(--color-fg-muted);\r\n border: 1px solid var(--color-border-4);\r\n cursor: pointer;\r\n font-size: 0.9375rem;\r\n font-weight: 500;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.clearLocalDataButton:hover {\r\n color: var(--color-fg-text);\r\n border-color: var(--color-border-3);\r\n background: var(--color-bg-secondary);\r\n}","import type { ReactNode } from \"react\";\n\nimport { Component } from \"react\";\n\ninterface SuspenseErrorBoundaryProps {\n children: ReactNode;\n fallbackRender: (args: { error: Error | null; retry: () => void }) => ReactNode;\n onReset?: () => void;\n}\n\ninterface SuspenseErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nclass SuspenseErrorBoundary extends Component<SuspenseErrorBoundaryProps, SuspenseErrorBoundaryState> {\n state: SuspenseErrorBoundaryState = {\n hasError: false,\n error: null,\n };\n\n static getDerivedStateFromError(error: Error): SuspenseErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error) {\n if (import.meta.env.DEV) {\n console.error(\"SuspenseErrorBoundary captured error:\", error);\n }\n }\n\n private handleReset = () => {\n this.setState({ hasError: false, error: null }, () => {\n this.props.onReset?.();\n });\n };\n\n render() {\n if (this.state.hasError) {\n return this.props.fallbackRender({ error: this.state.error, retry: this.handleReset });\n }\n\n return this.props.children;\n }\n}\n\nexport default SuspenseErrorBoundary;\n","/**\n * 统一 Suspense 包装:QueryErrorResetBoundary + 自定义 Loading/Error 样式,支持 loadingType、errorFallback。Suspense wrapper with QueryErrorResetBoundary, custom loading/error UI.\n *\n * @example\n * ```tsx\n * * 包裹懒加载内容\n * <Suspense fallback={null}>\n * <LazyPage />\n * </Suspense>\n * * 自定义 loading 类型\n * <Suspense loadingType=\"bounce\" loadingShape=\"circle\">...</Suspense>\n * ```\n */\nimport type { QueryErrorResetBoundaryProps } from \"@tanstack/react-query\";\nimport type { ReactNode, SuspenseProps as ReactSuspenseProps } from \"react\";\n\nimport { memo, Suspense as ReactSuspense } from \"react\";\nimport { QueryErrorResetBoundary } from \"@tanstack/react-query\";\n\nimport BounceLoading from \"@/designs/animations/BounceLoading\";\nimport ECGLoading from \"@/designs/animations/ECGLoading\";\nimport TruckLoading from \"@/designs/animations/TruckLoading\";\nimport { AlertCircle } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\nimport SuspenseErrorBoundary from \"./SuspenseErrorBoundary\";\n\ninterface LoadingFallbackProps {\n /** 自定义 fallback 节点。Custom fallback node. */\n fallback?: ReactNode;\n /** 加载动画类型。Loading animation type. */\n loadingType?: \"ecg\" | \"truck\" | \"bounce\";\n /** 加载图形形状。Loading shape. */\n loadingShape?: \"square\" | \"circle\";\n /** 加载中文案。Loading text. */\n loadingText?: string;\n /** 加载图尺寸。Loading size. */\n loadingSize?: \"small\" | \"medium\" | \"large\";\n /** 容器 className。Container className. */\n loadingContainerClassName?: string;\n /** 文案 className。Text className. */\n loadingTextClassName?: string;\n /** 加载图 className。Loading className. */\n loadingClassName?: string;\n}\n\ninterface ErrorFallbackProps {\n /** 错误对象。Error object. */\n error: Error | null;\n /** 重试函数。Retry function. */\n retry: () => void;\n /** 自定义错误 UI。Custom error UI. */\n errorFallback?: (args: { error: Error | null; retry: () => void }) => ReactNode;\n /** 错误标题。Error title. */\n errorTitle?: string;\n /** 错误描述。Error description. */\n errorDescription?: string;\n /** 重试按钮文案。Retry button text. */\n retryText?: string;\n /** 详情折叠文案。Error details summary text. */\n errorDetailsText?: string;\n /** 清除本地数据按钮文案。Clear local data button text. */\n clearLocalDataText?: string;\n /** 点击「清除本地数据」后执行(如跳转登录页),由调用方传入。Called after clear local data (e.g. navigate to login); pass from caller. */\n onClearLocalData?: () => void;\n /** 错误容器 className。Error container className. */\n errorContainerClassName?: string;\n /** 错误详情 className。Error details className. */\n errorDetailsClassName?: string;\n /** 是否展示错误详情。Show error details. */\n showErrorDetails?: boolean;\n}\n\nexport interface SuspenseProps extends Omit<ReactSuspenseProps, \"fallback\">, Omit<QueryErrorResetBoundaryProps, \"children\"> {\n /** 自定义 fallback。Custom fallback. */\n fallback?: ReactNode;\n /** 测试用:始终挂起。Test: always suspend. */\n test?: boolean;\n /** 加载动画类型。Loading type. */\n loadingType?: \"ecg\" | \"truck\" | \"bounce\";\n /** 加载图形形状。Loading shape. */\n loadingShape?: \"square\" | \"circle\";\n /** 加载中文案,由调用方传入。Loading text; pass from caller (e.g. i18n). */\n loadingText?: string;\n /** 加载图尺寸。Loading size. */\n loadingSize?: \"small\" | \"medium\" | \"large\";\n /** 加载容器 className。Loading container className. */\n loadingContainerClassName?: string;\n /** 加载文案 className。Loading text className. */\n loadingTextClassName?: string;\n /** 加载图 className。Loading className. */\n loadingClassName?: string;\n /** 自定义错误 UI。Custom error fallback. */\n errorFallback?: (args: { error: Error | null; retry: () => void }) => ReactNode;\n /** 错误标题,由调用方传入。Error title; pass from caller. */\n errorTitle?: string;\n /** 错误描述,由调用方传入。Error description; pass from caller. */\n errorDescription?: string;\n /** 重试按钮文案,由调用方传入。Retry text; pass from caller. */\n retryText?: string;\n /** 错误详情折叠文案。Error details text. */\n errorDetailsText?: string;\n /** 清除本地数据按钮文案。Clear local data text. */\n clearLocalDataText?: string;\n /** 点击「清除本地数据」后执行(如跳转登录页),由调用方传入。Called after clear local data (e.g. navigate to login); pass from caller. */\n onClearLocalData?: () => void;\n /** 错误容器 className。Error container className. */\n errorContainerClassName?: string;\n /** 错误详情 className。Error details className. */\n errorDetailsClassName?: string;\n /** 是否展示错误详情。Show error details. */\n showErrorDetails?: boolean;\n}\n\nconst LoadingFallback = memo(\n ({\n fallback,\n loadingType = \"ecg\",\n loadingShape = \"square\",\n loadingText = \"Loading...\",\n loadingSize = \"medium\",\n loadingContainerClassName,\n loadingTextClassName,\n loadingClassName,\n }: LoadingFallbackProps) => {\n if (fallback) {\n return <>{fallback}</>;\n }\n\n const renderLoading = () => {\n switch (loadingType) {\n case \"ecg\":\n return <ECGLoading size={loadingSize} className={loadingClassName} />;\n case \"truck\":\n return <TruckLoading size={loadingSize} className={loadingClassName} />;\n case \"bounce\":\n return <BounceLoading size={loadingSize} shape={loadingShape} className={loadingClassName} />;\n default:\n return <ECGLoading size={loadingSize} className={loadingClassName} />;\n }\n };\n\n return (\n <div className={`${styles.loadingContainer} ${loadingContainerClassName || \"\"}`}>\n {renderLoading()}\n <p className={`${styles.loadingText} ${loadingTextClassName || \"\"}`}>{loadingText}</p>\n </div>\n );\n },\n);\n\nLoadingFallback.displayName = \"LoadingFallback\";\n\nconst ErrorFallback = memo(\n ({\n error,\n retry,\n errorFallback,\n errorTitle = \"Error\",\n errorDescription = \"Something went wrong. Please try again.\",\n retryText = \"Retry\",\n errorDetailsText = \"Details\",\n clearLocalDataText = \"Clear local data\",\n onClearLocalData,\n errorContainerClassName,\n errorDetailsClassName,\n showErrorDetails = import.meta.env.DEV,\n }: ErrorFallbackProps) => {\n const handleClearLocalData = () => {\n try {\n sessionStorage.clear();\n } catch {\n // ignore\n } finally {\n onClearLocalData?.();\n }\n };\n\n if (errorFallback) {\n return <>{errorFallback({ error, retry })}</>;\n }\n\n return (\n <div className={`${styles.errorContainer} ${errorContainerClassName || \"\"}`}>\n <div className={styles.errorIconWrapper}>\n <AlertCircle className={styles.errorIcon} size={64} />\n </div>\n <div className={styles.errorContent}>\n <h3 className={styles.errorTitle}>{errorTitle}</h3>\n <p className={styles.errorDescription}>{errorDescription}</p>\n {showErrorDetails && error && (\n <div className={styles.errorDetailsWrapper}>\n <details className={styles.errorDetailsContainer}>\n <summary className={styles.errorDetailsSummary}>{errorDetailsText}</summary>\n <pre className={`${styles.errorDetails} ${errorDetailsClassName || \"\"}`}>{error.message}</pre>\n </details>\n </div>\n )}\n <div className={styles.errorActions}>\n <button type=\"button\" className={styles.retryButton} onClick={retry}>\n <span className={styles.retryButtonIcon}>↻</span>\n <span>{retryText}</span>\n </button>\n <button type=\"button\" className={styles.clearLocalDataButton} onClick={handleClearLocalData}>\n <span>{clearLocalDataText}</span>\n </button>\n </div>\n </div>\n </div>\n );\n },\n);\n\nErrorFallback.displayName = \"ErrorFallback\";\n\nconst Suspense = memo(\n ({\n fallback,\n test,\n loadingType = \"ecg\",\n loadingShape = \"square\",\n loadingClassName,\n loadingText,\n loadingSize = \"medium\",\n loadingContainerClassName,\n loadingTextClassName,\n children,\n errorFallback,\n errorTitle,\n errorDescription,\n retryText,\n errorDetailsText,\n clearLocalDataText,\n onClearLocalData,\n errorContainerClassName,\n errorDetailsClassName,\n showErrorDetails = import.meta.env.DEV,\n ...restProps\n }: SuspenseProps) => {\n return (\n <QueryErrorResetBoundary {...restProps}>\n {({ reset }) => (\n <SuspenseErrorBoundary\n onReset={reset}\n fallbackRender={({ error, retry }) => (\n <ErrorFallback\n error={error}\n retry={retry}\n errorFallback={errorFallback}\n errorTitle={errorTitle}\n errorDescription={errorDescription}\n retryText={retryText}\n errorDetailsText={errorDetailsText}\n clearLocalDataText={clearLocalDataText}\n onClearLocalData={onClearLocalData}\n errorContainerClassName={errorContainerClassName}\n errorDetailsClassName={errorDetailsClassName}\n showErrorDetails={showErrorDetails}\n />\n )}\n >\n <ReactSuspense\n fallback={\n <LoadingFallback\n fallback={fallback}\n loadingType={loadingType}\n loadingShape={loadingShape}\n loadingText={loadingText}\n loadingSize={loadingSize}\n loadingContainerClassName={loadingContainerClassName}\n loadingTextClassName={loadingTextClassName}\n loadingClassName={loadingClassName}\n />\n }\n {...restProps}\n >\n {test ? <AlwaysPending /> : children}\n </ReactSuspense>\n </SuspenseErrorBoundary>\n )}\n </QueryErrorResetBoundary>\n );\n },\n);\n\nSuspense.displayName = \"Suspense\";\nexport default Suspense;\n\nconst AlwaysPending = () => {\n throw new Promise(() => {}); // 永不 resolve 的 Promise\n};\n",".wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.wrapper.fullWidth {\n width: 100%;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-heading);\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.required {\n color: var(--color-danger);\n}\n\n.inputContainer {\n position: relative;\n display: flex;\n align-items: flex-start;\n width: 100%;\n}\n\n.textarea {\n width: 100%;\n border: 1px solid var(--color-border-4);\n border-radius: 0.5rem;\n background: var(--color-bg);\n color: var(--color-fg-text);\n font-size: 0.875rem;\n font-family: inherit;\n transition: all 0.2s ease;\n outline: none;\n resize: vertical;\n min-height: 4rem;\n}\n\n.textarea:focus {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb, 102, 126, 234), 0.1);\n}\n\n.textarea::placeholder {\n color: var(--color-fg-muted, var(--color-fg-text));\n opacity: 0.5;\n}\n\n/* Size variants */\n.textarea.small {\n padding: 0.5rem 0.75rem;\n font-size: 0.8125rem;\n min-height: 3rem;\n}\n\n.textarea.medium {\n padding: 0.75rem;\n font-size: 0.875rem;\n min-height: 4rem;\n}\n\n.textarea.large {\n padding: 1rem;\n font-size: 1rem;\n min-height: 5rem;\n}\n\n/* Variant styles */\n.textarea.default {\n background: var(--color-bg);\n border-color: var(--color-border-4);\n}\n\n.textarea.filled {\n background: var(--color-bg-2);\n border-color: var(--color-border-3);\n}\n\n/* With icons */\n.inputContainer .leftIcon {\n position: absolute;\n left: 0.75rem;\n top: 0.75rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-fg-muted, var(--color-fg-text));\n pointer-events: none;\n z-index: 1;\n}\n\n.inputContainer .rightIcon {\n position: absolute;\n right: 0.75rem;\n top: 0.75rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-fg-muted, var(--color-fg-text));\n pointer-events: none;\n z-index: 1;\n}\n\n.inputContainer .textarea.small + .leftIcon,\n.inputContainer .textarea.small + .rightIcon {\n top: 0.5rem;\n}\n\n.inputContainer .textarea.large + .leftIcon,\n.inputContainer .textarea.large + .rightIcon {\n top: 1rem;\n}\n\n/* Error state */\n.textarea.error {\n border-color: var(--color-danger);\n}\n\n.textarea.error:focus {\n border-color: var(--color-danger);\n box-shadow: 0 0 0 3px rgba(var(--color-danger-rgb, 244, 67, 54), 0.1);\n}\n\n/* Disabled state */\n.textarea.disabled {\n background: var(--color-bg-3);\n border-color: var(--color-border-5);\n color: var(--color-fg-muted);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.errorText {\n font-size: 0.75rem;\n color: var(--color-danger);\n margin: 0;\n}\n\n.helperText {\n font-size: 0.75rem;\n color: var(--color-fg-muted);\n margin: 0;\n}\n","/**\n * 多行文本框:支持 label、error、helperText、左右图标与 size/variant。Textarea with label, error, helperText, left/right icon.\n *\n * @example\n * ```tsx\n * * 基础用法\n * <Textarea label=\"备注\" value={note} onChange={(e) => setNote(e.target.value)} rows={4} />\n * * 错误态\n * <Textarea error={errors.note} helperText=\"选填\" />\n * ```\n */\nimport type { ReactNode, TextareaHTMLAttributes } from \"react\";\n\nimport { forwardRef } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, \"size\"> {\n /** 标签文案。Label text. */\n label?: string;\n /** 错误信息。Error message. */\n error?: string;\n /** 辅助说明。Helper text. */\n helperText?: string;\n /** 左侧图标。Left icon. */\n leftIcon?: ReactNode;\n /** 右侧图标。Right icon. */\n rightIcon?: ReactNode;\n /** 尺寸。Size. */\n size?: \"small\" | \"medium\" | \"large\";\n /** 视觉变体。Variant. */\n variant?: \"default\" | \"filled\";\n /** 是否占满宽度。Full width. */\n fullWidth?: boolean;\n}\n\nconst Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ label, error, helperText, leftIcon, rightIcon, size = \"medium\", variant = \"default\", fullWidth = false, className = \"\", disabled, ...props }, ref) => {\n const textareaClasses = [styles.textarea, styles[size], styles[variant], error && styles.error, disabled && styles.disabled, className]\n .filter(Boolean)\n .join(\" \");\n\n const wrapperClasses = [styles.wrapper, fullWidth && styles.fullWidth].filter(Boolean).join(\" \");\n\n return (\n <div className={wrapperClasses}>\n {label && (\n <label className={styles.label}>\n {label}\n {props.required && <span className={styles.required}>*</span>}\n </label>\n )}\n <div className={styles.inputContainer}>\n {leftIcon && <div className={styles.leftIcon}>{leftIcon}</div>}\n <textarea ref={ref} className={textareaClasses} disabled={disabled} {...props} />\n {rightIcon && <div className={styles.rightIcon}>{rightIcon}</div>}\n </div>\n {error && <span className={styles.errorText}>{error}</span>}\n {helperText && !error && <span className={styles.helperText}>{helperText}</span>}\n </div>\n );\n },\n);\n\nTextarea.displayName = \"Textarea\";\n\nexport default Textarea;\n","function memo(getDeps, fn, opts) {\n let deps = opts.initialDeps ?? [];\n let result;\n let isInitial = true;\n function memoizedFunction() {\n var _a, _b, _c;\n let depTime;\n if (opts.key && ((_a = opts.debug) == null ? void 0 : _a.call(opts))) depTime = Date.now();\n const newDeps = getDeps();\n const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);\n if (!depsChanged) {\n return result;\n }\n deps = newDeps;\n let resultTime;\n if (opts.key && ((_b = opts.debug) == null ? void 0 : _b.call(opts))) resultTime = Date.now();\n result = fn(...newDeps);\n if (opts.key && ((_c = opts.debug) == null ? void 0 : _c.call(opts))) {\n const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;\n const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;\n const resultFpsPercentage = resultEndTime / 16;\n const pad = (str, num) => {\n str = String(str);\n while (str.length < num) {\n str = \" \" + str;\n }\n return str;\n };\n console.info(\n `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n `\n font-size: .6rem;\n font-weight: bold;\n color: hsl(${Math.max(\n 0,\n Math.min(120 - 120 * resultFpsPercentage, 120)\n )}deg 100% 31%);`,\n opts == null ? void 0 : opts.key\n );\n }\n if ((opts == null ? void 0 : opts.onChange) && !(isInitial && opts.skipInitialOnChange)) {\n opts.onChange(result);\n }\n isInitial = false;\n return result;\n }\n memoizedFunction.updateDeps = (newDeps) => {\n deps = newDeps;\n };\n return memoizedFunction;\n}\nfunction notUndefined(value, msg) {\n if (value === void 0) {\n throw new Error(`Unexpected undefined${msg ? `: ${msg}` : \"\"}`);\n } else {\n return value;\n }\n}\nconst approxEqual = (a, b) => Math.abs(a - b) < 1.01;\nconst debounce = (targetWindow, fn, ms) => {\n let timeoutId;\n return function(...args) {\n targetWindow.clearTimeout(timeoutId);\n timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms);\n };\n};\nexport {\n approxEqual,\n debounce,\n memo,\n notUndefined\n};\n//# sourceMappingURL=utils.js.map\n","import { debounce, memo, notUndefined, approxEqual } from \"./utils.js\";\nconst getRect = (element) => {\n const { offsetWidth, offsetHeight } = element;\n return { width: offsetWidth, height: offsetHeight };\n};\nconst defaultKeyExtractor = (index) => index;\nconst defaultRangeExtractor = (range) => {\n const start = Math.max(range.startIndex - range.overscan, 0);\n const end = Math.min(range.endIndex + range.overscan, range.count - 1);\n const arr = [];\n for (let i = start; i <= end; i++) {\n arr.push(i);\n }\n return arr;\n};\nconst observeElementRect = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n const handler = (rect) => {\n const { width, height } = rect;\n cb({ width: Math.round(width), height: Math.round(height) });\n };\n handler(getRect(element));\n if (!targetWindow.ResizeObserver) {\n return () => {\n };\n }\n const observer = new targetWindow.ResizeObserver((entries) => {\n const run = () => {\n const entry = entries[0];\n if (entry == null ? void 0 : entry.borderBoxSize) {\n const box = entry.borderBoxSize[0];\n if (box) {\n handler({ width: box.inlineSize, height: box.blockSize });\n return;\n }\n }\n handler(getRect(element));\n };\n instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();\n });\n observer.observe(element, { box: \"border-box\" });\n return () => {\n observer.unobserve(element);\n };\n};\nconst addEventListenerOptions = {\n passive: true\n};\nconst observeWindowRect = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const handler = () => {\n cb({ width: element.innerWidth, height: element.innerHeight });\n };\n handler();\n element.addEventListener(\"resize\", handler, addEventListenerOptions);\n return () => {\n element.removeEventListener(\"resize\", handler);\n };\n};\nconst supportsScrollend = typeof window == \"undefined\" ? true : \"onscrollend\" in window;\nconst observeElementOffset = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n let offset = 0;\n const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(\n targetWindow,\n () => {\n cb(offset, false);\n },\n instance.options.isScrollingResetDelay\n );\n const createHandler = (isScrolling) => () => {\n const { horizontal, isRtl } = instance.options;\n offset = horizontal ? element[\"scrollLeft\"] * (isRtl && -1 || 1) : element[\"scrollTop\"];\n fallback();\n cb(offset, isScrolling);\n };\n const handler = createHandler(true);\n const endHandler = createHandler(false);\n element.addEventListener(\"scroll\", handler, addEventListenerOptions);\n const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;\n if (registerScrollendEvent) {\n element.addEventListener(\"scrollend\", endHandler, addEventListenerOptions);\n }\n return () => {\n element.removeEventListener(\"scroll\", handler);\n if (registerScrollendEvent) {\n element.removeEventListener(\"scrollend\", endHandler);\n }\n };\n};\nconst observeWindowOffset = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n let offset = 0;\n const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(\n targetWindow,\n () => {\n cb(offset, false);\n },\n instance.options.isScrollingResetDelay\n );\n const createHandler = (isScrolling) => () => {\n offset = element[instance.options.horizontal ? \"scrollX\" : \"scrollY\"];\n fallback();\n cb(offset, isScrolling);\n };\n const handler = createHandler(true);\n const endHandler = createHandler(false);\n element.addEventListener(\"scroll\", handler, addEventListenerOptions);\n const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;\n if (registerScrollendEvent) {\n element.addEventListener(\"scrollend\", endHandler, addEventListenerOptions);\n }\n return () => {\n element.removeEventListener(\"scroll\", handler);\n if (registerScrollendEvent) {\n element.removeEventListener(\"scrollend\", endHandler);\n }\n };\n};\nconst measureElement = (element, entry, instance) => {\n if (entry == null ? void 0 : entry.borderBoxSize) {\n const box = entry.borderBoxSize[0];\n if (box) {\n const size = Math.round(\n box[instance.options.horizontal ? \"inlineSize\" : \"blockSize\"]\n );\n return size;\n }\n }\n return element[instance.options.horizontal ? \"offsetWidth\" : \"offsetHeight\"];\n};\nconst windowScroll = (offset, {\n adjustments = 0,\n behavior\n}, instance) => {\n var _a, _b;\n const toOffset = offset + adjustments;\n (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {\n [instance.options.horizontal ? \"left\" : \"top\"]: toOffset,\n behavior\n });\n};\nconst elementScroll = (offset, {\n adjustments = 0,\n behavior\n}, instance) => {\n var _a, _b;\n const toOffset = offset + adjustments;\n (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {\n [instance.options.horizontal ? \"left\" : \"top\"]: toOffset,\n behavior\n });\n};\nclass Virtualizer {\n constructor(opts) {\n this.unsubs = [];\n this.scrollElement = null;\n this.targetWindow = null;\n this.isScrolling = false;\n this.currentScrollToIndex = null;\n this.measurementsCache = [];\n this.itemSizeCache = /* @__PURE__ */ new Map();\n this.laneAssignments = /* @__PURE__ */ new Map();\n this.pendingMeasuredCacheIndexes = [];\n this.prevLanes = void 0;\n this.lanesChangedFlag = false;\n this.lanesSettling = false;\n this.scrollRect = null;\n this.scrollOffset = null;\n this.scrollDirection = null;\n this.scrollAdjustments = 0;\n this.elementsCache = /* @__PURE__ */ new Map();\n this.observer = /* @__PURE__ */ (() => {\n let _ro = null;\n const get = () => {\n if (_ro) {\n return _ro;\n }\n if (!this.targetWindow || !this.targetWindow.ResizeObserver) {\n return null;\n }\n return _ro = new this.targetWindow.ResizeObserver((entries) => {\n entries.forEach((entry) => {\n const run = () => {\n this._measureElement(entry.target, entry);\n };\n this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();\n });\n });\n };\n return {\n disconnect: () => {\n var _a;\n (_a = get()) == null ? void 0 : _a.disconnect();\n _ro = null;\n },\n observe: (target) => {\n var _a;\n return (_a = get()) == null ? void 0 : _a.observe(target, { box: \"border-box\" });\n },\n unobserve: (target) => {\n var _a;\n return (_a = get()) == null ? void 0 : _a.unobserve(target);\n }\n };\n })();\n this.range = null;\n this.setOptions = (opts2) => {\n Object.entries(opts2).forEach(([key, value]) => {\n if (typeof value === \"undefined\") delete opts2[key];\n });\n this.options = {\n debug: false,\n initialOffset: 0,\n overscan: 1,\n paddingStart: 0,\n paddingEnd: 0,\n scrollPaddingStart: 0,\n scrollPaddingEnd: 0,\n horizontal: false,\n getItemKey: defaultKeyExtractor,\n rangeExtractor: defaultRangeExtractor,\n onChange: () => {\n },\n measureElement,\n initialRect: { width: 0, height: 0 },\n scrollMargin: 0,\n gap: 0,\n indexAttribute: \"data-index\",\n initialMeasurementsCache: [],\n lanes: 1,\n isScrollingResetDelay: 150,\n enabled: true,\n isRtl: false,\n useScrollendEvent: false,\n useAnimationFrameWithResizeObserver: false,\n ...opts2\n };\n };\n this.notify = (sync) => {\n var _a, _b;\n (_b = (_a = this.options).onChange) == null ? void 0 : _b.call(_a, this, sync);\n };\n this.maybeNotify = memo(\n () => {\n this.calculateRange();\n return [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null\n ];\n },\n (isScrolling) => {\n this.notify(isScrolling);\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"maybeNotify\",\n debug: () => this.options.debug,\n initialDeps: [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null\n ]\n }\n );\n this.cleanup = () => {\n this.unsubs.filter(Boolean).forEach((d) => d());\n this.unsubs = [];\n this.observer.disconnect();\n this.scrollElement = null;\n this.targetWindow = null;\n };\n this._didMount = () => {\n return () => {\n this.cleanup();\n };\n };\n this._willUpdate = () => {\n var _a;\n const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;\n if (this.scrollElement !== scrollElement) {\n this.cleanup();\n if (!scrollElement) {\n this.maybeNotify();\n return;\n }\n this.scrollElement = scrollElement;\n if (this.scrollElement && \"ownerDocument\" in this.scrollElement) {\n this.targetWindow = this.scrollElement.ownerDocument.defaultView;\n } else {\n this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;\n }\n this.elementsCache.forEach((cached) => {\n this.observer.observe(cached);\n });\n this.unsubs.push(\n this.options.observeElementRect(this, (rect) => {\n this.scrollRect = rect;\n this.maybeNotify();\n })\n );\n this.unsubs.push(\n this.options.observeElementOffset(this, (offset, isScrolling) => {\n this.scrollAdjustments = 0;\n this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? \"forward\" : \"backward\" : null;\n this.scrollOffset = offset;\n this.isScrolling = isScrolling;\n this.maybeNotify();\n })\n );\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: void 0,\n behavior: void 0\n });\n }\n };\n this.getSize = () => {\n if (!this.options.enabled) {\n this.scrollRect = null;\n return 0;\n }\n this.scrollRect = this.scrollRect ?? this.options.initialRect;\n return this.scrollRect[this.options.horizontal ? \"width\" : \"height\"];\n };\n this.getScrollOffset = () => {\n if (!this.options.enabled) {\n this.scrollOffset = null;\n return 0;\n }\n this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset === \"function\" ? this.options.initialOffset() : this.options.initialOffset);\n return this.scrollOffset;\n };\n this.getFurthestMeasurement = (measurements, index) => {\n const furthestMeasurementsFound = /* @__PURE__ */ new Map();\n const furthestMeasurements = /* @__PURE__ */ new Map();\n for (let m = index - 1; m >= 0; m--) {\n const measurement = measurements[m];\n if (furthestMeasurementsFound.has(measurement.lane)) {\n continue;\n }\n const previousFurthestMeasurement = furthestMeasurements.get(\n measurement.lane\n );\n if (previousFurthestMeasurement == null || measurement.end > previousFurthestMeasurement.end) {\n furthestMeasurements.set(measurement.lane, measurement);\n } else if (measurement.end < previousFurthestMeasurement.end) {\n furthestMeasurementsFound.set(measurement.lane, true);\n }\n if (furthestMeasurementsFound.size === this.options.lanes) {\n break;\n }\n }\n return furthestMeasurements.size === this.options.lanes ? Array.from(furthestMeasurements.values()).sort((a, b) => {\n if (a.end === b.end) {\n return a.index - b.index;\n }\n return a.end - b.end;\n })[0] : void 0;\n };\n this.getMeasurementOptions = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.scrollMargin,\n this.options.getItemKey,\n this.options.enabled,\n this.options.lanes\n ],\n (count, paddingStart, scrollMargin, getItemKey, enabled, lanes) => {\n const lanesChanged = this.prevLanes !== void 0 && this.prevLanes !== lanes;\n if (lanesChanged) {\n this.lanesChangedFlag = true;\n }\n this.prevLanes = lanes;\n this.pendingMeasuredCacheIndexes = [];\n return {\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n enabled,\n lanes\n };\n },\n {\n key: false\n }\n );\n this.getMeasurements = memo(\n () => [this.getMeasurementOptions(), this.itemSizeCache],\n ({ count, paddingStart, scrollMargin, getItemKey, enabled, lanes }, itemSizeCache) => {\n if (!enabled) {\n this.measurementsCache = [];\n this.itemSizeCache.clear();\n this.laneAssignments.clear();\n return [];\n }\n if (this.laneAssignments.size > count) {\n for (const index of this.laneAssignments.keys()) {\n if (index >= count) {\n this.laneAssignments.delete(index);\n }\n }\n }\n if (this.lanesChangedFlag) {\n this.lanesChangedFlag = false;\n this.lanesSettling = true;\n this.measurementsCache = [];\n this.itemSizeCache.clear();\n this.laneAssignments.clear();\n this.pendingMeasuredCacheIndexes = [];\n }\n if (this.measurementsCache.length === 0 && !this.lanesSettling) {\n this.measurementsCache = this.options.initialMeasurementsCache;\n this.measurementsCache.forEach((item) => {\n this.itemSizeCache.set(item.key, item.size);\n });\n }\n const min = this.lanesSettling ? 0 : this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;\n this.pendingMeasuredCacheIndexes = [];\n if (this.lanesSettling && this.measurementsCache.length === count) {\n this.lanesSettling = false;\n }\n const measurements = this.measurementsCache.slice(0, min);\n const laneLastIndex = new Array(lanes).fill(\n void 0\n );\n for (let m = 0; m < min; m++) {\n const item = measurements[m];\n if (item) {\n laneLastIndex[item.lane] = m;\n }\n }\n for (let i = min; i < count; i++) {\n const key = getItemKey(i);\n const cachedLane = this.laneAssignments.get(i);\n let lane;\n let start;\n if (cachedLane !== void 0 && this.options.lanes > 1) {\n lane = cachedLane;\n const prevIndex = laneLastIndex[lane];\n const prevInLane = prevIndex !== void 0 ? measurements[prevIndex] : void 0;\n start = prevInLane ? prevInLane.end + this.options.gap : paddingStart + scrollMargin;\n } else {\n const furthestMeasurement = this.options.lanes === 1 ? measurements[i - 1] : this.getFurthestMeasurement(measurements, i);\n start = furthestMeasurement ? furthestMeasurement.end + this.options.gap : paddingStart + scrollMargin;\n lane = furthestMeasurement ? furthestMeasurement.lane : i % this.options.lanes;\n if (this.options.lanes > 1) {\n this.laneAssignments.set(i, lane);\n }\n }\n const measuredSize = itemSizeCache.get(key);\n const size = typeof measuredSize === \"number\" ? measuredSize : this.options.estimateSize(i);\n const end = start + size;\n measurements[i] = {\n index: i,\n start,\n size,\n end,\n key,\n lane\n };\n laneLastIndex[lane] = i;\n }\n this.measurementsCache = measurements;\n return measurements;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getMeasurements\",\n debug: () => this.options.debug\n }\n );\n this.calculateRange = memo(\n () => [\n this.getMeasurements(),\n this.getSize(),\n this.getScrollOffset(),\n this.options.lanes\n ],\n (measurements, outerSize, scrollOffset, lanes) => {\n return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n lanes\n }) : null;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"calculateRange\",\n debug: () => this.options.debug\n }\n );\n this.getVirtualIndexes = memo(\n () => {\n let startIndex = null;\n let endIndex = null;\n const range = this.calculateRange();\n if (range) {\n startIndex = range.startIndex;\n endIndex = range.endIndex;\n }\n this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex]);\n return [\n this.options.rangeExtractor,\n this.options.overscan,\n this.options.count,\n startIndex,\n endIndex\n ];\n },\n (rangeExtractor, overscan, count, startIndex, endIndex) => {\n return startIndex === null || endIndex === null ? [] : rangeExtractor({\n startIndex,\n endIndex,\n overscan,\n count\n });\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getVirtualIndexes\",\n debug: () => this.options.debug\n }\n );\n this.indexFromElement = (node) => {\n const attributeName = this.options.indexAttribute;\n const indexStr = node.getAttribute(attributeName);\n if (!indexStr) {\n console.warn(\n `Missing attribute name '${attributeName}={index}' on measured element.`\n );\n return -1;\n }\n return parseInt(indexStr, 10);\n };\n this._measureElement = (node, entry) => {\n const index = this.indexFromElement(node);\n const item = this.measurementsCache[index];\n if (!item) {\n return;\n }\n const key = item.key;\n const prevNode = this.elementsCache.get(key);\n if (prevNode !== node) {\n if (prevNode) {\n this.observer.unobserve(prevNode);\n }\n this.observer.observe(node);\n this.elementsCache.set(key, node);\n }\n if (node.isConnected) {\n this.resizeItem(index, this.options.measureElement(node, entry, this));\n }\n };\n this.resizeItem = (index, size) => {\n const item = this.measurementsCache[index];\n if (!item) {\n return;\n }\n const itemSize = this.itemSizeCache.get(item.key) ?? item.size;\n const delta = size - itemSize;\n if (delta !== 0) {\n if (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this) : item.start < this.getScrollOffset() + this.scrollAdjustments) {\n if (process.env.NODE_ENV !== \"production\" && this.options.debug) {\n console.info(\"correction\", delta);\n }\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: this.scrollAdjustments += delta,\n behavior: void 0\n });\n }\n this.pendingMeasuredCacheIndexes.push(item.index);\n this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));\n this.notify(false);\n }\n };\n this.measureElement = (node) => {\n if (!node) {\n this.elementsCache.forEach((cached, key) => {\n if (!cached.isConnected) {\n this.observer.unobserve(cached);\n this.elementsCache.delete(key);\n }\n });\n return;\n }\n this._measureElement(node, void 0);\n };\n this.getVirtualItems = memo(\n () => [this.getVirtualIndexes(), this.getMeasurements()],\n (indexes, measurements) => {\n const virtualItems = [];\n for (let k = 0, len = indexes.length; k < len; k++) {\n const i = indexes[k];\n const measurement = measurements[i];\n virtualItems.push(measurement);\n }\n return virtualItems;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getVirtualItems\",\n debug: () => this.options.debug\n }\n );\n this.getVirtualItemForOffset = (offset) => {\n const measurements = this.getMeasurements();\n if (measurements.length === 0) {\n return void 0;\n }\n return notUndefined(\n measurements[findNearestBinarySearch(\n 0,\n measurements.length - 1,\n (index) => notUndefined(measurements[index]).start,\n offset\n )]\n );\n };\n this.getMaxScrollOffset = () => {\n if (!this.scrollElement) return 0;\n if (\"scrollHeight\" in this.scrollElement) {\n return this.options.horizontal ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth : this.scrollElement.scrollHeight - this.scrollElement.clientHeight;\n } else {\n const doc = this.scrollElement.document.documentElement;\n return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;\n }\n };\n this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {\n if (!this.scrollElement) return 0;\n const size = this.getSize();\n const scrollOffset = this.getScrollOffset();\n if (align === \"auto\") {\n align = toOffset >= scrollOffset + size ? \"end\" : \"start\";\n }\n if (align === \"center\") {\n toOffset += (itemSize - size) / 2;\n } else if (align === \"end\") {\n toOffset -= size;\n }\n const maxOffset = this.getMaxScrollOffset();\n return Math.max(Math.min(maxOffset, toOffset), 0);\n };\n this.getOffsetForIndex = (index, align = \"auto\") => {\n index = Math.max(0, Math.min(index, this.options.count - 1));\n const item = this.measurementsCache[index];\n if (!item) {\n return void 0;\n }\n const size = this.getSize();\n const scrollOffset = this.getScrollOffset();\n if (align === \"auto\") {\n if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {\n align = \"end\";\n } else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {\n align = \"start\";\n } else {\n return [scrollOffset, align];\n }\n }\n if (align === \"end\" && index === this.options.count - 1) {\n return [this.getMaxScrollOffset(), align];\n }\n const toOffset = align === \"end\" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;\n return [\n this.getOffsetForAlignment(toOffset, align, item.size),\n align\n ];\n };\n this.isDynamicMode = () => this.elementsCache.size > 0;\n this.scrollToOffset = (toOffset, { align = \"start\", behavior } = {}) => {\n if (behavior === \"smooth\" && this.isDynamicMode()) {\n console.warn(\n \"The `smooth` scroll behavior is not fully supported with dynamic size.\"\n );\n }\n this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), {\n adjustments: void 0,\n behavior\n });\n };\n this.scrollToIndex = (index, { align: initialAlign = \"auto\", behavior } = {}) => {\n if (behavior === \"smooth\" && this.isDynamicMode()) {\n console.warn(\n \"The `smooth` scroll behavior is not fully supported with dynamic size.\"\n );\n }\n index = Math.max(0, Math.min(index, this.options.count - 1));\n this.currentScrollToIndex = index;\n let attempts = 0;\n const maxAttempts = 10;\n const tryScroll = (currentAlign) => {\n if (!this.targetWindow) return;\n const offsetInfo = this.getOffsetForIndex(index, currentAlign);\n if (!offsetInfo) {\n console.warn(\"Failed to get offset for index:\", index);\n return;\n }\n const [offset, align] = offsetInfo;\n this._scrollToOffset(offset, { adjustments: void 0, behavior });\n this.targetWindow.requestAnimationFrame(() => {\n if (!this.targetWindow) return;\n const verify = () => {\n if (this.currentScrollToIndex !== index) return;\n const currentOffset = this.getScrollOffset();\n const afterInfo = this.getOffsetForIndex(index, align);\n if (!afterInfo) {\n console.warn(\"Failed to get offset for index:\", index);\n return;\n }\n if (!approxEqual(afterInfo[0], currentOffset)) {\n scheduleRetry(align);\n }\n };\n if (this.isDynamicMode()) {\n this.targetWindow.requestAnimationFrame(verify);\n } else {\n verify();\n }\n });\n };\n const scheduleRetry = (align) => {\n if (!this.targetWindow) return;\n if (this.currentScrollToIndex !== index) return;\n attempts++;\n if (attempts < maxAttempts) {\n if (process.env.NODE_ENV !== \"production\" && this.options.debug) {\n console.info(\"Schedule retry\", attempts, maxAttempts);\n }\n this.targetWindow.requestAnimationFrame(() => tryScroll(align));\n } else {\n console.warn(\n `Failed to scroll to index ${index} after ${maxAttempts} attempts.`\n );\n }\n };\n tryScroll(initialAlign);\n };\n this.scrollBy = (delta, { behavior } = {}) => {\n if (behavior === \"smooth\" && this.isDynamicMode()) {\n console.warn(\n \"The `smooth` scroll behavior is not fully supported with dynamic size.\"\n );\n }\n this._scrollToOffset(this.getScrollOffset() + delta, {\n adjustments: void 0,\n behavior\n });\n };\n this.getTotalSize = () => {\n var _a;\n const measurements = this.getMeasurements();\n let end;\n if (measurements.length === 0) {\n end = this.options.paddingStart;\n } else if (this.options.lanes === 1) {\n end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;\n } else {\n const endByLane = Array(this.options.lanes).fill(null);\n let endIndex = measurements.length - 1;\n while (endIndex >= 0 && endByLane.some((val) => val === null)) {\n const item = measurements[endIndex];\n if (endByLane[item.lane] === null) {\n endByLane[item.lane] = item.end;\n }\n endIndex--;\n }\n end = Math.max(...endByLane.filter((val) => val !== null));\n }\n return Math.max(\n end - this.options.scrollMargin + this.options.paddingEnd,\n 0\n );\n };\n this._scrollToOffset = (offset, {\n adjustments,\n behavior\n }) => {\n this.options.scrollToFn(offset, { behavior, adjustments }, this);\n };\n this.measure = () => {\n this.itemSizeCache = /* @__PURE__ */ new Map();\n this.laneAssignments = /* @__PURE__ */ new Map();\n this.notify(false);\n };\n this.setOptions(opts);\n }\n}\nconst findNearestBinarySearch = (low, high, getCurrentValue, value) => {\n while (low <= high) {\n const middle = (low + high) / 2 | 0;\n const currentValue = getCurrentValue(middle);\n if (currentValue < value) {\n low = middle + 1;\n } else if (currentValue > value) {\n high = middle - 1;\n } else {\n return middle;\n }\n }\n if (low > 0) {\n return low - 1;\n } else {\n return 0;\n }\n};\nfunction calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n lanes\n}) {\n const lastIndex = measurements.length - 1;\n const getOffset = (index) => measurements[index].start;\n if (measurements.length <= lanes) {\n return {\n startIndex: 0,\n endIndex: lastIndex\n };\n }\n let startIndex = findNearestBinarySearch(\n 0,\n lastIndex,\n getOffset,\n scrollOffset\n );\n let endIndex = startIndex;\n if (lanes === 1) {\n while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) {\n endIndex++;\n }\n } else if (lanes > 1) {\n const endPerLane = Array(lanes).fill(0);\n while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {\n const item = measurements[endIndex];\n endPerLane[item.lane] = item.end;\n endIndex++;\n }\n const startPerLane = Array(lanes).fill(scrollOffset + outerSize);\n while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {\n const item = measurements[startIndex];\n startPerLane[item.lane] = item.start;\n startIndex--;\n }\n startIndex = Math.max(0, startIndex - startIndex % lanes);\n endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));\n }\n return { startIndex, endIndex };\n}\nexport {\n Virtualizer,\n approxEqual,\n debounce,\n defaultKeyExtractor,\n defaultRangeExtractor,\n elementScroll,\n measureElement,\n memo,\n notUndefined,\n observeElementOffset,\n observeElementRect,\n observeWindowOffset,\n observeWindowRect,\n windowScroll\n};\n//# sourceMappingURL=index.js.map\n","import * as React from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { Virtualizer, elementScroll, observeElementOffset, observeElementRect, windowScroll, observeWindowOffset, observeWindowRect } from \"@tanstack/virtual-core\";\nexport * from \"@tanstack/virtual-core\";\nconst useIsomorphicLayoutEffect = typeof document !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\nfunction useVirtualizerBase({\n useFlushSync = true,\n ...options\n}) {\n const rerender = React.useReducer(() => ({}), {})[1];\n const resolvedOptions = {\n ...options,\n onChange: (instance2, sync) => {\n var _a;\n if (useFlushSync && sync) {\n flushSync(rerender);\n } else {\n rerender();\n }\n (_a = options.onChange) == null ? void 0 : _a.call(options, instance2, sync);\n }\n };\n const [instance] = React.useState(\n () => new Virtualizer(resolvedOptions)\n );\n instance.setOptions(resolvedOptions);\n useIsomorphicLayoutEffect(() => {\n return instance._didMount();\n }, []);\n useIsomorphicLayoutEffect(() => {\n return instance._willUpdate();\n });\n return instance;\n}\nfunction useVirtualizer(options) {\n return useVirtualizerBase({\n observeElementRect,\n observeElementOffset,\n scrollToFn: elementScroll,\n ...options\n });\n}\nfunction useWindowVirtualizer(options) {\n return useVirtualizerBase({\n getScrollElement: () => typeof document !== \"undefined\" ? window : null,\n observeElementRect: observeWindowRect,\n observeElementOffset: observeWindowOffset,\n scrollToFn: windowScroll,\n initialOffset: () => typeof document !== \"undefined\" ? window.scrollY : 0,\n ...options\n });\n}\nexport {\n useVirtualizer,\n useWindowVirtualizer\n};\n//# sourceMappingURL=index.js.map\n","/* Virtual List Container */\r\n.virtualList {\r\n position: relative;\r\n overflow: auto;\r\n contain: strict;\r\n width: 100%;\r\n padding-bottom: 300px;\r\n}\r\n\r\n/* Empty State Container */\r\n.emptyContainer {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n color: var(--color-fg-muted);\r\n}\r\n\r\n/* Virtual List Inner Container */\r\n.virtualListInner {\r\n width: 100%;\r\n position: relative;\r\n}\r\n\r\n/* Virtual List Items Wrapper */\r\n.virtualListItems {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n}\r\n\r\n/* Loading More Indicator */\r\n.loadingMore {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.75rem;\r\n padding: 2rem 0;\r\n color: var(--color-fg-muted);\r\n font-size: 0.875rem;\r\n}\r\n\r\n/* End of List Indicator */\r\n.endOfList {\r\n display: flex;\r\n justify-content: center;\r\n padding: 2rem 0;\r\n color: var(--color-fg-muted);\r\n font-size: 0.875rem;\r\n border-top: 1px solid var(--color-border-3);\r\n margin-top: 1rem;\r\n}\r\n\r\n.endOfList span {\r\n padding: 0.5rem 1rem;\r\n background-color: var(--color-bg-2);\r\n border-radius: 0.25rem;\r\n}","/**\n * 虚拟列表:基于 @tanstack/react-virtual,支持无限滚动 fetchNextPage。Virtual list; @tanstack/react-virtual, fetchNextPage.\n *\n * @example\n * ```tsx\n * * 与 useInfiniteQuery 配合,data 为 pages 拍平后的 items\n * <VirtualList data={items} getItemKey={(i) => i.id} renderItem={(i) => <Row item={i} />} hasNextPage fetchNextPage={fetchNextPage} />\n * ```\n */\nimport type { VirtualizerOptions } from \"@tanstack/react-virtual\";\nimport type { ReactNode } from \"react\";\n\nimport { memo, useCallback, useEffect, useRef } from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface VirtualListProps<T> extends Partial<\n Omit<\n VirtualizerOptions<HTMLDivElement, Element>,\n \"count\" | \"getScrollElement\" | \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\" | \"getItemKey\" | \"estimateSize\"\n >\n> {\n /** 数据列表。Data array. */\n data: T[];\n /** 是否有下一页。Has next page. */\n hasNextPage?: boolean;\n /** 是否正在拉取下一页。Is fetching next page. */\n isFetchingNextPage?: boolean;\n /** 拉取下一页。Fetch next page. */\n fetchNextPage?: () => void;\n /** 单项渲染。Render item. */\n renderItem: (item: T, index: number) => ReactNode;\n /** 单项高度估计。Estimate item size. */\n estimateSize?: number | ((index: number) => number);\n /** 列表高度。List height. */\n height?: string | number;\n /** 单项 key。Get item key. */\n getItemKey: (item: T, index: number) => string | number;\n /** 空状态自定义节点。Empty state node. */\n emptyState?: ReactNode;\n /** 加载更多指示器。Loading indicator node. */\n loadingIndicator?: ReactNode;\n /** 列表底指示器。End of list indicator node. */\n endOfListIndicator?: ReactNode;\n /** 当未提供 emptyState 时使用的文案,由调用方传入。Text when no data; used when emptyState not provided. */\n emptyText?: string;\n /** 当未提供 loadingIndicator 时使用的文案。Text when loading more. */\n loadingMoreText?: string;\n /** 当未提供 endOfListIndicator 时使用的文案。Text at end of list. */\n endOfListText?: string;\n /** 列表项容器 className。Flex container class. */\n flexClass?: string;\n /** 外层容器 className。Outer class. */\n outerClass?: string;\n /** 内层容器 className。Inner class. */\n innerClass?: string;\n}\n\nfunction VirtualListComponent<T>({\n data,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n renderItem,\n estimateSize = 200,\n overscan = 5,\n height = \"600px\",\n getItemKey,\n emptyState,\n loadingIndicator,\n endOfListIndicator,\n emptyText = \"No data\",\n loadingMoreText = \"Loading more...\",\n endOfListText = \"No more items\",\n flexClass,\n outerClass,\n innerClass,\n ...virtualizerOptions\n}: VirtualListProps<T>) {\n const parentRef = useRef<HTMLDivElement>(null);\n\n // 防御性检查:确保 data 是数组\n const safeData = Array.isArray(data) ? data : [];\n const dataLength = safeData.length;\n\n // Setup virtualizer\n // eslint-disable-next-line react-hooks/incompatible-library\n const rowVirtualizer = useVirtualizer({\n count: hasNextPage ? dataLength + 1 : dataLength,\n getScrollElement: () => parentRef.current,\n estimateSize: typeof estimateSize === \"number\" ? () => estimateSize : estimateSize,\n overscan,\n ...virtualizerOptions,\n });\n\n const items = rowVirtualizer.getVirtualItems();\n\n // Auto-fetch when scrolling near bottom (following official pattern)\n useEffect(() => {\n const [lastItem] = [...items].reverse();\n\n if (!lastItem) {\n return;\n }\n\n if (lastItem.index >= dataLength - 1 && hasNextPage && !isFetchingNextPage && fetchNextPage) {\n fetchNextPage();\n }\n }, [hasNextPage, fetchNextPage, dataLength, isFetchingNextPage, items]);\n\n const renderEmptyState = useCallback(() => {\n return (\n <div\n className={styles.virtualList}\n style={{\n height: typeof height === \"number\" ? `${height}px` : height,\n }}\n >\n {emptyState ?? (\n <div className={styles.emptyContainer}>\n <span>{emptyText}</span>\n </div>\n )}\n </div>\n );\n }, [emptyState, height, emptyText]);\n\n const renderLoadingIndicator = useCallback(() => {\n if (loadingIndicator) return loadingIndicator;\n return (\n <div className={styles.loadingMore}>\n <span>{loadingMoreText}</span>\n </div>\n );\n }, [loadingIndicator, loadingMoreText]);\n\n const renderEndOfListIndicator = useCallback(() => {\n if (endOfListIndicator) return endOfListIndicator;\n return (\n <div className={styles.endOfList}>\n <span>{endOfListText}</span>\n </div>\n );\n }, [endOfListIndicator, endOfListText]);\n\n // Show empty state if no data\n if (dataLength === 0) return renderEmptyState();\n\n return (\n <div\n ref={parentRef}\n className={`${styles.virtualList} ${outerClass ?? \"\"}`}\n style={{\n height: typeof height === \"number\" ? `${height}px` : height,\n }}\n >\n <div\n className={`${styles.virtualListInner} ${innerClass ?? \"\"}`}\n style={{\n height: `${rowVirtualizer.getTotalSize()}px`,\n }}\n >\n <div\n className={`${styles.virtualListItems} ${flexClass ?? \"\"}`}\n style={{\n transform: `translateY(${items[0]?.start ?? 0}px)`,\n paddingTop: `2px`,\n }}\n >\n {items.map((virtualRow) => {\n const isLoaderRow = virtualRow.index > dataLength - 1;\n const item = safeData[virtualRow.index];\n\n return (\n <div key={virtualRow.key} data-index={virtualRow.index} ref={rowVirtualizer.measureElement}>\n {isLoaderRow ? (\n hasNextPage ? (\n renderLoadingIndicator()\n ) : (\n renderEndOfListIndicator()\n )\n ) : (\n <div key={getItemKey(item, virtualRow.index)}>{renderItem(item, virtualRow.index)}</div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n\n// Use memo with generic type\nconst VirtualList = memo(VirtualListComponent) as typeof VirtualListComponent;\nexport default VirtualList;\n","/* 外层容器 */\r\n.virtualList {\r\n width: 100%;\r\n position: relative;\r\n overflow: visible; /* ✅ window 滚动,不是列表滚动 */\r\n padding-bottom: 300px;\r\n }\r\n \r\n /* 内层:撑出总高度 */\r\n .virtualListInner {\r\n width: 100%;\r\n position: relative;\r\n }\r\n \r\n /* 基于 translateY 的内容容器 */\r\n .virtualListItems {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n }\r\n \r\n /* 行样式(你不一定用得上,但可选) */\r\n .virtualListRow {\r\n width: 100%;\r\n }\r\n \r\n /* 无数据 */\r\n .emptyContainer {\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: 2rem 0;\r\n color: var(--color-fg-muted);\r\n }\r\n \r\n /* 加载中 */\r\n .loadingMore {\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: 1.5rem 0;\r\n color: var(--color-fg-muted);\r\n }\r\n \r\n /* 末尾提示 */\r\n .endOfList {\r\n display: flex;\r\n justify-content: center;\r\n padding: 1.5rem 0;\r\n color: var(--color-fg-muted);\r\n border-top: 1px solid var(--color-border-3);\r\n }\r\n ","/**\n * 窗口虚拟列表:基于 useWindowVirtualizer,相对视口滚动。Window virtual list; uses useWindowVirtualizer, scroll relative to viewport.\n *\n * @example\n * ```tsx\n * * 与无限列表数据配合\n * <VirtualWindowList\n * data={items}\n * getItemKey={(item) => item.id}\n * renderItem={(item) => <Row item={item} />}\n * hasNextPage={hasNextPage}\n * fetchNextPage={fetchNextPage}\n * />\n * ```\n */\nimport type { VirtualizerOptions } from \"@tanstack/react-virtual\";\nimport type { ReactNode } from \"react\";\n\nimport { memo, useCallback, useEffect } from \"react\";\nimport { useWindowVirtualizer } from \"@tanstack/react-virtual\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface VirtualWindowListProps<T> extends Partial<\n Omit<\n VirtualizerOptions<Window, Element>,\n \"count\" | \"getScrollElement\" | \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\" | \"estimateSize\" | \"getItemKey\"\n >\n> {\n /** 数据列表。Data array. */\n data: T[];\n /** 是否有下一页。Has next page. */\n hasNextPage?: boolean;\n /** 是否正在拉取下一页。Is fetching next page. */\n isFetchingNextPage?: boolean;\n /** 拉取下一页。Fetch next page. */\n fetchNextPage?: () => void;\n /** 单项渲染。Render item. */\n renderItem: (item: T, index: number) => ReactNode;\n /** 单项高度估计。Estimate item size. */\n estimateSize?: number | ((index: number) => number);\n /** 列表高度。List height. */\n height?: string | number;\n /** 单项 key。Get item key. */\n getItemKey: (item: T, index: number) => string | number;\n /** 空状态自定义节点。Empty state node. */\n emptyState?: ReactNode;\n /** 加载更多指示器。Loading indicator node. */\n loadingIndicator?: ReactNode;\n /** 列表底指示器。End of list indicator node. */\n endOfListIndicator?: ReactNode;\n /** 空状态文案(未提供 emptyState 时)。Empty text. */\n emptyText?: string;\n /** 加载更多文案。Loading more text. */\n loadingMoreText?: string;\n /** 列表底文案。End of list text. */\n endOfListText?: string;\n /** 列表项容器 className。Flex container class. */\n flexClass?: string;\n /** 外层容器 className。Outer class. */\n outerClass?: string;\n /** 内层容器 className。Inner class. */\n innerClass?: string;\n}\n\n/* -------------------------------------------\n ✅ MAIN COMPONENT\n-------------------------------------------- */\nfunction VirtualWindowListComponent<T>({\n data,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n renderItem,\n estimateSize = 200,\n overscan = 5,\n height,\n getItemKey,\n\n emptyState,\n loadingIndicator,\n endOfListIndicator,\n emptyText = \"No data\",\n loadingMoreText = \"Loading more...\",\n endOfListText = \"No more items\",\n flexClass,\n outerClass,\n innerClass,\n ...virtualizerOptions\n}: VirtualWindowListProps<T>) {\n /* ✅ 防御性检查:确保 data 是数组 */\n const safeData = Array.isArray(data) ? data : [];\n const dataLength = safeData.length;\n\n /* ✅ 真正的 window 虚拟滚动器 */\n const virtualizer = useWindowVirtualizer({\n count: hasNextPage ? dataLength + 1 : dataLength,\n estimateSize: typeof estimateSize === \"number\" ? () => estimateSize : estimateSize,\n overscan,\n ...virtualizerOptions,\n });\n\n const items = virtualizer.getVirtualItems();\n\n /* ✅ 自动加载更多 */\n useEffect(() => {\n const last = items[items.length - 1];\n if (!last) return;\n\n const isLoaderRow = last.index >= dataLength;\n\n if (isLoaderRow && hasNextPage && !isFetchingNextPage && fetchNextPage) {\n fetchNextPage();\n }\n }, [items, hasNextPage, isFetchingNextPage, fetchNextPage, dataLength]);\n\n const renderEmptyState = useCallback(() => {\n return (\n <div\n className={styles.virtualList}\n style={{\n height: typeof height === \"number\" ? `${height}px` : (height ?? \"auto\"),\n }}\n >\n {emptyState ?? (\n <div className={styles.emptyContainer}>\n <span>{emptyText}</span>\n </div>\n )}\n </div>\n );\n }, [emptyState, height, emptyText]);\n\n const renderLoadingIndicator = useCallback(() => {\n return (\n loadingIndicator ?? (\n <div className={styles.loadingMore}>\n <span>{loadingMoreText}</span>\n </div>\n )\n );\n }, [loadingIndicator, loadingMoreText]);\n\n const renderEndOfListIndicator = useCallback(() => {\n return (\n endOfListIndicator ?? (\n <div className={styles.endOfList}>\n <span>{endOfListText}</span>\n </div>\n )\n );\n }, [endOfListIndicator, endOfListText]);\n\n /* ✅ 无数据情况 */\n if (dataLength === 0) return renderEmptyState();\n\n /* ✅ 正常渲染 */\n return (\n <div className={`${styles.virtualList} ${outerClass ?? \"\"}`}>\n <div\n className={`${styles.virtualListInner} ${innerClass ?? \"\"}`}\n style={{\n height: virtualizer.getTotalSize(),\n }}\n >\n <div\n className={`${styles.virtualListItems} ${flexClass ?? \"\"}`}\n style={{\n transform: `translateY(${items[0]?.start ?? 0}px)`,\n }}\n >\n {items.map((row) => {\n const isLoaderRow = row.index >= dataLength;\n const item = safeData[row.index];\n\n return (\n <div key={row.key} data-index={row.index} ref={virtualizer.measureElement}>\n {isLoaderRow ? (\n hasNextPage ? (\n renderLoadingIndicator()\n ) : (\n renderEndOfListIndicator()\n )\n ) : item == null ? (\n <div key={`missing-${row.index}`} />\n ) : (\n <div key={getItemKey(item, row.index)}>{renderItem(item, row.index)}</div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n\nconst VirtualWindowList = memo(VirtualWindowListComponent) as typeof VirtualWindowListComponent;\n\nexport default VirtualWindowList;\n"],"x_google_ignoreList":[24,25,26],"mappings":"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"}
|