dishui 0.0.45 → 0.0.46

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.
Files changed (60) hide show
  1. package/dist/chart.js +46 -0
  2. package/dist/components/Chart/Chart.d.ts +17 -0
  3. package/dist/components/Chart/Chart.js +29 -0
  4. package/dist/components/Chart/Chart.js.map +1 -0
  5. package/dist/components/Chart/index.d.ts +15 -0
  6. package/dist/components/Input/index.js +2 -2
  7. package/dist/components/Input/index.js.map +1 -1
  8. package/dist/components/Select/index.js +1 -1
  9. package/dist/components/Select/index.js.map +1 -1
  10. package/dist/components/pro/Flow/Flow.js +492 -392
  11. package/dist/components/pro/Flow/Flow.js.map +1 -1
  12. package/dist/components/pro/Flow/FlowCanvas.js +895 -864
  13. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  14. package/dist/components/pro/Flow/context/FlowUIContext.d.ts +2 -0
  15. package/dist/components/pro/Flow/context/FlowUIContext.js +68 -65
  16. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  17. package/dist/components/pro/Flow/edges/edgePaths.js +234 -216
  18. package/dist/components/pro/Flow/edges/edgePaths.js.map +1 -1
  19. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js +21 -10
  20. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js.map +1 -1
  21. package/dist/components/pro/Flow/hooks/useMindMap.js +138 -134
  22. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  23. package/dist/components/pro/Flow/index.d.ts +1 -1
  24. package/dist/components/pro/Flow/nodes/MediaContent.js +47 -25
  25. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  26. package/dist/components/pro/Flow/nodes/Model3DView.d.ts +7 -0
  27. package/dist/components/pro/Flow/nodes/Model3DView.js +118 -0
  28. package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -0
  29. package/dist/components/pro/Flow/nodes/NodeHandles.d.ts +2 -1
  30. package/dist/components/pro/Flow/nodes/NodeHandles.js +4 -2
  31. package/dist/components/pro/Flow/nodes/NodeHandles.js.map +1 -1
  32. package/dist/components/pro/Flow/nodes/NodeRenderer.d.ts +2 -0
  33. package/dist/components/pro/Flow/nodes/NodeRenderer.js +115 -113
  34. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  35. package/dist/components/pro/Flow/nodes/NodeText.d.ts +3 -0
  36. package/dist/components/pro/Flow/nodes/NodeText.js +26 -17
  37. package/dist/components/pro/Flow/nodes/NodeText.js.map +1 -1
  38. package/dist/components/pro/Flow/panels/FlowToolbar.js +85 -79
  39. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  40. package/dist/components/pro/Flow/panels/InspectorPanel.js +618 -488
  41. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  42. package/dist/components/pro/Flow/panels/OutlinePanel.js +15 -15
  43. package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
  44. package/dist/components/pro/Flow/panels/ShapePalette.js +71 -55
  45. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  46. package/dist/components/pro/Flow/panels/toolbarIcons.d.ts +1 -0
  47. package/dist/components/pro/Flow/panels/toolbarIcons.js +59 -41
  48. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  49. package/dist/components/pro/Flow/types.d.ts +13 -4
  50. package/dist/components/pro/Flow/types.js.map +1 -1
  51. package/dist/dishui.css +1 -1
  52. package/dist/index-nostyled.d.ts +3 -1
  53. package/dist/index.d.ts +3 -1
  54. package/dist/index.js +145 -143
  55. package/dist/utils/i18n.d.ts +1 -0
  56. package/dist/utils/i18n.js +200 -6
  57. package/dist/utils/i18n.js.map +1 -1
  58. package/dist/utils/menu.js +26 -10
  59. package/dist/utils/menu.js.map +1 -1
  60. package/package.json +14 -3
package/dist/chart.js ADDED
@@ -0,0 +1,46 @@
1
+ import o from "./components/Chart/Chart.js";
2
+ import { areaX as e, areaY as i, barY as t, cell as m, colorGradientLegend as p, colorLegend as l, defineChart as n, dot as f, group as d, lineY as c, linearRegressionY as s, link as g, rect as L, stack as k, text as Y } from "@tanstack/charts";
3
+ import { scaleBand as u } from "@tanstack/charts/scales/band";
4
+ import { scaleLinear as y } from "@tanstack/charts/scales/linear";
5
+ import { scalePoint as D } from "@tanstack/charts/scales/point";
6
+ import { scaleOrdinal as A } from "@tanstack/charts/scales/ordinal";
7
+ import { geoShape as G } from "@tanstack/charts/geo";
8
+ import { treemap as P } from "@tanstack/charts/hierarchy/treemap";
9
+ import { delaunayLink as S } from "@tanstack/charts/spatial/delaunay";
10
+ import { pie as j, polar as q, radialArc as v, radialDot as w, radialLine as z } from "@tanstack/charts/polar";
11
+ import { sankeyDiagram as F } from "@tanstack/charts/network/sankey";
12
+ import { tooltip as I } from "@tanstack/charts/tooltip";
13
+ export * from "@tanstack/react-charts";
14
+ export {
15
+ o as Chart,
16
+ e as areaX,
17
+ i as areaY,
18
+ t as barY,
19
+ m as cell,
20
+ p as colorGradientLegend,
21
+ l as colorLegend,
22
+ o as default,
23
+ n as defineChart,
24
+ S as delaunayLink,
25
+ f as dot,
26
+ G as geoShape,
27
+ d as group,
28
+ c as lineY,
29
+ s as linearRegressionY,
30
+ g as link,
31
+ j as pie,
32
+ q as polar,
33
+ v as radialArc,
34
+ w as radialDot,
35
+ z as radialLine,
36
+ L as rect,
37
+ F as sankeyDiagram,
38
+ u as scaleBand,
39
+ y as scaleLinear,
40
+ A as scaleOrdinal,
41
+ D as scalePoint,
42
+ k as stack,
43
+ Y as text,
44
+ I as tooltip,
45
+ P as treemap
46
+ };
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import type { DomChartDefinition } from '@tanstack/charts';
3
+ export interface ChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
4
+ /** TanStack Charts declarative chart definition. */
5
+ definition: DomChartDefinition<any, any, any>;
6
+ /** Wrapper height. TanStack Charts fills the available space. */
7
+ height?: number | string;
8
+ /** Additional wrapper class name. */
9
+ className?: string;
10
+ /** Additional wrapper style. */
11
+ style?: React.CSSProperties;
12
+ /** Optional empty state controlled by the caller. */
13
+ empty?: boolean;
14
+ emptyContent?: React.ReactNode;
15
+ }
16
+ declare const Chart: React.ForwardRefExoticComponent<ChartProps & React.RefAttributes<HTMLDivElement>>;
17
+ export default Chart;
@@ -0,0 +1,29 @@
1
+ import n from "react";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ import { Chart as m } from "@tanstack/react-charts/tooltip";
4
+ var v = n.forwardRef(function({ height: e = 360, className: a = "", style: o, empty: l = !1, emptyContent: i = "No chart data", definition: s, ...r }, d) {
5
+ const f = typeof e == "number" ? Math.max(1, e - 26) : void 0;
6
+ return /* @__PURE__ */ t("div", {
7
+ ref: d,
8
+ className: `relative w-full overflow-hidden rounded-xl border border-base-300 bg-base-100 p-3 ${a}`,
9
+ style: {
10
+ height: e,
11
+ ...o
12
+ },
13
+ ...r,
14
+ children: l ? /* @__PURE__ */ t("div", {
15
+ className: "flex h-full items-center justify-center p-6 text-sm text-base-content/50",
16
+ children: i
17
+ }) : /* @__PURE__ */ t(m, {
18
+ definition: s,
19
+ ariaLabel: r["aria-label"] || "Chart",
20
+ height: f,
21
+ style: typeof e == "string" ? { height: "100%" } : void 0
22
+ })
23
+ });
24
+ });
25
+ export {
26
+ v as default
27
+ };
28
+
29
+ //# sourceMappingURL=Chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Chart.js","names":[],"sources":["../../../src/components/Chart/Chart.tsx"],"sourcesContent":["import React from 'react';\nimport { Chart as TanStackChart } from '@tanstack/react-charts/tooltip';\nimport type { DomChartDefinition } from '@tanstack/charts';\n\nexport interface ChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** TanStack Charts declarative chart definition. */\n definition: DomChartDefinition<any, any, any>;\n\n /** Wrapper height. TanStack Charts fills the available space. */\n height?: number | string;\n /** Additional wrapper class name. */\n className?: string;\n /** Additional wrapper style. */\n style?: React.CSSProperties;\n /** Optional empty state controlled by the caller. */\n empty?: boolean;\n emptyContent?: React.ReactNode;\n}\n\nconst Chart = React.forwardRef<HTMLDivElement, ChartProps>(function Chart({\n height = 360,\n className = '',\n style,\n empty = false,\n emptyContent = 'No chart data',\n definition,\n ...wrapperProps\n}, ref) {\n const numericChartHeight = typeof height === 'number' ? Math.max(1, height - 26) : undefined;\n\n return (\n <div\n ref={ref}\n className={`relative w-full overflow-hidden rounded-xl border border-base-300 bg-base-100 p-3 ${className}`}\n style={{ height, ...style }}\n {...wrapperProps}\n >\n {empty ? (\n <div className=\"flex h-full items-center justify-center p-6 text-sm text-base-content/50\">\n {emptyContent}\n </div>\n ) : (\n <TanStackChart\n definition={definition}\n ariaLabel={wrapperProps['aria-label'] || 'Chart'}\n height={numericChartHeight}\n style={typeof height === 'string' ? { height: '100%' } : undefined}\n />\n )}\n </div>\n );\n});\n\nexport default Chart;\n"],"mappings":";;;AAmBA,IAAM,IAAQ,EAAM,WAAuC,SAAe,EACxE,QAAA,IAAS,KACT,WAAA,IAAY,IACZ,OAAA,GACA,OAAA,IAAQ,IACR,cAAA,IAAe,iBACf,YAAA,GACA,GAAG,EAAA,GACF,GAAK;AACN,QAAM,IAAqB,OAAO,KAAW,WAAW,KAAK,IAAI,GAAG,IAAS,EAAE,IAAI;AAEnF,SACE,gBAAA,EAAC,OAAD;AAAA,IACO,KAAA;AAAA,IACL,WAAW,qFAAqF,CAAA;AAAA,IAChG,OAAO;AAAA,MAAE,QAAA;AAAA,MAAQ,GAAG;AAAA,IAAM;AAAA,IAC1B,GAAI;AAAA,cAEH,IACC,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBACZ;AAAA,IACE,CAAA,IAEL,gBAAA,EAAC,GAAD;AAAA,MACc,YAAA;AAAA,MACZ,WAAW,EAAa,YAAA,KAAiB;AAAA,MACzC,QAAQ;AAAA,MACR,OAAO,OAAO,KAAW,WAAW,EAAE,QAAQ,OAAO,IAAI;AAAA,IAC1D,CAAA;AAAA,EAEA,CAAA;AAET,CAAC"}
@@ -0,0 +1,15 @@
1
+ export { default } from './Chart';
2
+ export { default as Chart } from './Chart';
3
+ export type { ChartProps } from './Chart';
4
+ export * from '@tanstack/react-charts';
5
+ export { areaX, areaY, barY, cell, colorGradientLegend, colorLegend, defineChart, dot, group, linearRegressionY, lineY, link, rect, stack, text, } from '@tanstack/charts';
6
+ export { scaleBand } from '@tanstack/charts/scales/band';
7
+ export { scaleLinear } from '@tanstack/charts/scales/linear';
8
+ export { scalePoint } from '@tanstack/charts/scales/point';
9
+ export { scaleOrdinal } from '@tanstack/charts/scales/ordinal';
10
+ export { geoShape } from '@tanstack/charts/geo';
11
+ export { treemap } from '@tanstack/charts/hierarchy/treemap';
12
+ export { delaunayLink } from '@tanstack/charts/spatial/delaunay';
13
+ export { polar, pie, radialArc, radialDot, radialLine } from '@tanstack/charts/polar';
14
+ export { sankeyDiagram } from '@tanstack/charts/network/sankey';
15
+ export { tooltip } from '@tanstack/charts/tooltip';
@@ -130,7 +130,7 @@ var S = ({ placeholder: x, value: d, onChange: A, type: n = "text", variant: B,
130
130
  })
131
131
  ]
132
132
  }) : /* @__PURE__ */ t("div", {
133
- className: `relative ${$}`,
133
+ className: `relative w-full ${$}`,
134
134
  onMouseEnter: y,
135
135
  onMouseLeave: k,
136
136
  children: [
@@ -167,7 +167,7 @@ var S = ({ placeholder: x, value: d, onChange: A, type: n = "text", variant: B,
167
167
  })
168
168
  ]
169
169
  }) : /* @__PURE__ */ t("div", {
170
- className: `relative ${$}`,
170
+ className: `relative w-full ${$}`,
171
171
  onMouseEnter: y,
172
172
  onMouseLeave: k,
173
173
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Input/index.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\n\nexport type InputProps = {\n placeholder?: string;\n value?: string;\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n type?: string;\n variant?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'ghost';\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n disabled?: boolean;\n required?: boolean;\n label?: string;\n labelPosition?: 'inline' | 'top';\n leftSection?: React.ReactNode;\n rightSection?: React.ReactNode;\n pattern?: string;\n className?: string;\n validator?: boolean;\n validatorHint?: string;\n validationRules?: {\n pattern: RegExp;\n message: string;\n }[];\n};\n\nconst Input = ({\n placeholder,\n value,\n onChange,\n type = 'text',\n variant,\n size = 'sm',\n disabled = false,\n required = false,\n label,\n labelPosition = 'inline',\n leftSection,\n rightSection,\n pattern,\n className = '',\n validator = false,\n validatorHint,\n validationRules = [],\n}: InputProps) => {\n // 密码显示/隐藏状态\n const [showPassword, setShowPassword] = useState(false);\n // 追踪最近输入的字符\n const [recentInput, setRecentInput] = useState('');\n // 表单验证状态\n const [isValid, setIsValid] = useState<boolean | null>(null);\n // 显示验证提示\n const [showValidationHint, setShowValidationHint] = useState(false);\n // 验证失败的规则消息\n const [failedRules, setFailedRules] = useState<string[]>([]);\n \n // 输入框引用,用于焦点和验证\n const inputRef = useRef<HTMLInputElement>(null);\n \n // 确定实际使用的输入类型\n const actualType = type === 'password' && showPassword ? 'text' : type;\n \n // 处理输入变化,包括密码字符延迟遮罩和验证\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n \n // 处理密码输入的特殊效果\n if (type === 'password' && newValue.length > (value || '').length) {\n // 获取新输入的字符\n const newChar = newValue.slice((value || '').length);\n setRecentInput(newChar);\n \n // 设置定时器延迟清除最近输入的字符\n setTimeout(() => {\n setRecentInput('');\n }, 1000); // 1秒后隐藏\n }\n \n // 验证输入\n if (validator && inputRef.current) {\n validateInput(newValue);\n }\n \n // 调用原始的onChange处理函数\n if (onChange) {\n onChange(e);\n }\n };\n \n // 验证输入值\n const validateInput = (inputValue: string) => {\n if (!inputRef.current) return;\n \n // 使用HTML5自带的验证\n const isNativeValid = inputRef.current.checkValidity();\n \n // 检查自定义验证规则\n const failedMessages: string[] = [];\n \n if (validationRules.length > 0) {\n validationRules.forEach(rule => {\n if (!rule.pattern.test(inputValue)) {\n failedMessages.push(rule.message);\n }\n });\n }\n \n setFailedRules(failedMessages);\n setIsValid(isNativeValid && failedMessages.length === 0);\n };\n \n // 切换密码显示/隐藏\n const togglePasswordVisibility = () => {\n setShowPassword(!showPassword);\n };\n \n // 鼠标悬停事件处理\n const handleMouseEnter = () => {\n if (validator && !isValid) {\n setShowValidationHint(true);\n }\n };\n \n const handleMouseLeave = () => {\n setShowValidationHint(false);\n };\n \n // 验证状态相关的类名\n let validationStateClass = '';\n if (validator && isValid !== null) {\n validationStateClass = isValid ? 'input-success' : 'input-error';\n }\n \n const baseClass = 'input border border-base-content/30 bg-base-100 hover:border-base-content/50 focus:border-primary';\n const variantClass = variant && !validationStateClass ? `input-${variant}` : '';\n const sizeClass = size ? `input-${size}` : '';\n const validatorClass = validator ? 'validator' : '';\n \n\n // 密码可见性切换按钮\n const passwordToggle = type === 'password' && (\n <span \n className=\"cursor-pointer opacity-70 hover:opacity-100\"\n onClick={togglePasswordVisibility}\n >\n {showPassword ? (\n // 眼睛关闭图标\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n <path d=\"M1 1l22 22\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n </svg>\n ) : (\n // 眼睛打开图标\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n )}\n </span>\n );\n \n // 构建验证提示悬浮框\n const validationTooltip = (\n <div className=\"validation-tooltip\">\n {failedRules.length > 0 ? (\n <ul className=\"text-xs list-disc pl-4 py-1\">\n {failedRules.map((rule, index) => (\n <li key={index}>{rule}</li>\n ))}\n </ul>\n ) : validatorHint ? (\n <p className=\"text-xs py-1\">{validatorHint}</p>\n ) : null}\n </div>\n );\n\n // 如果有label,则使用label作为容器\n if (label || leftSection || rightSection || type === 'password') {\n // labelPosition === 'top': label above the input field\n if (label && labelPosition === 'top') {\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <span className=\"text-sm font-medium mb-1 block\">{label}</span>\n <label className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full flex items-center gap-2`}>\n {leftSection && <span>{leftSection}</span>}\n <input\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className=\"grow\"\n pattern={pattern}\n />\n {type === 'password' ? (\n <span className=\"cursor-pointer opacity-70 hover:opacity-100\" onClick={togglePasswordVisibility}>\n {showPassword ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n <path d=\"M1 1l22 22\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n </svg>\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n )}\n </span>\n ) : rightSection ? (\n <span>{rightSection}</span>\n ) : null}\n </label>\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n }\n\n // Default: inline label\n return (\n <div className={`relative ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <label className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full flex items-center gap-2`}>\n {leftSection && <span>{leftSection}</span>}\n {label && <span>{label}</span>}\n <input\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className=\"grow\"\n pattern={pattern}\n />\n {/* 显示最近输入的字符,仅针对密码字段 */}\n {type === 'password' && recentInput && (\n <span className=\"password-recent absolute right-10 font-mono\">\n {recentInput}\n </span>\n )}\n {/* 加入密码切换按钮或其他右侧元素 */}\n {type === 'password' ? (\n <span>{passwordToggle}</span>\n ) : rightSection ? (\n <span>{rightSection}</span>\n ) : null}\n </label>\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n }\n\n // 如果没有label,则直接返回input\n return (\n <div className={`relative ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <input\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full`}\n pattern={pattern}\n />\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n};\n\nexport default Input; "],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Input/index.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\n\nexport type InputProps = {\n placeholder?: string;\n value?: string;\n onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n type?: string;\n variant?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'ghost';\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n disabled?: boolean;\n required?: boolean;\n label?: string;\n labelPosition?: 'inline' | 'top';\n leftSection?: React.ReactNode;\n rightSection?: React.ReactNode;\n pattern?: string;\n className?: string;\n validator?: boolean;\n validatorHint?: string;\n validationRules?: {\n pattern: RegExp;\n message: string;\n }[];\n};\n\nconst Input = ({\n placeholder,\n value,\n onChange,\n type = 'text',\n variant,\n size = 'sm',\n disabled = false,\n required = false,\n label,\n labelPosition = 'inline',\n leftSection,\n rightSection,\n pattern,\n className = '',\n validator = false,\n validatorHint,\n validationRules = [],\n}: InputProps) => {\n // 密码显示/隐藏状态\n const [showPassword, setShowPassword] = useState(false);\n // 追踪最近输入的字符\n const [recentInput, setRecentInput] = useState('');\n // 表单验证状态\n const [isValid, setIsValid] = useState<boolean | null>(null);\n // 显示验证提示\n const [showValidationHint, setShowValidationHint] = useState(false);\n // 验证失败的规则消息\n const [failedRules, setFailedRules] = useState<string[]>([]);\n \n // 输入框引用,用于焦点和验证\n const inputRef = useRef<HTMLInputElement>(null);\n \n // 确定实际使用的输入类型\n const actualType = type === 'password' && showPassword ? 'text' : type;\n \n // 处理输入变化,包括密码字符延迟遮罩和验证\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n \n // 处理密码输入的特殊效果\n if (type === 'password' && newValue.length > (value || '').length) {\n // 获取新输入的字符\n const newChar = newValue.slice((value || '').length);\n setRecentInput(newChar);\n \n // 设置定时器延迟清除最近输入的字符\n setTimeout(() => {\n setRecentInput('');\n }, 1000); // 1秒后隐藏\n }\n \n // 验证输入\n if (validator && inputRef.current) {\n validateInput(newValue);\n }\n \n // 调用原始的onChange处理函数\n if (onChange) {\n onChange(e);\n }\n };\n \n // 验证输入值\n const validateInput = (inputValue: string) => {\n if (!inputRef.current) return;\n \n // 使用HTML5自带的验证\n const isNativeValid = inputRef.current.checkValidity();\n \n // 检查自定义验证规则\n const failedMessages: string[] = [];\n \n if (validationRules.length > 0) {\n validationRules.forEach(rule => {\n if (!rule.pattern.test(inputValue)) {\n failedMessages.push(rule.message);\n }\n });\n }\n \n setFailedRules(failedMessages);\n setIsValid(isNativeValid && failedMessages.length === 0);\n };\n \n // 切换密码显示/隐藏\n const togglePasswordVisibility = () => {\n setShowPassword(!showPassword);\n };\n \n // 鼠标悬停事件处理\n const handleMouseEnter = () => {\n if (validator && !isValid) {\n setShowValidationHint(true);\n }\n };\n \n const handleMouseLeave = () => {\n setShowValidationHint(false);\n };\n \n // 验证状态相关的类名\n let validationStateClass = '';\n if (validator && isValid !== null) {\n validationStateClass = isValid ? 'input-success' : 'input-error';\n }\n \n const baseClass = 'input border border-base-content/30 bg-base-100 hover:border-base-content/50 focus:border-primary';\n const variantClass = variant && !validationStateClass ? `input-${variant}` : '';\n const sizeClass = size ? `input-${size}` : '';\n const validatorClass = validator ? 'validator' : '';\n \n\n // 密码可见性切换按钮\n const passwordToggle = type === 'password' && (\n <span \n className=\"cursor-pointer opacity-70 hover:opacity-100\"\n onClick={togglePasswordVisibility}\n >\n {showPassword ? (\n // 眼睛关闭图标\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n <path d=\"M1 1l22 22\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n </svg>\n ) : (\n // 眼睛打开图标\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n )}\n </span>\n );\n \n // 构建验证提示悬浮框\n const validationTooltip = (\n <div className=\"validation-tooltip\">\n {failedRules.length > 0 ? (\n <ul className=\"text-xs list-disc pl-4 py-1\">\n {failedRules.map((rule, index) => (\n <li key={index}>{rule}</li>\n ))}\n </ul>\n ) : validatorHint ? (\n <p className=\"text-xs py-1\">{validatorHint}</p>\n ) : null}\n </div>\n );\n\n // 如果有label,则使用label作为容器\n if (label || leftSection || rightSection || type === 'password') {\n // labelPosition === 'top': label above the input field\n if (label && labelPosition === 'top') {\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <span className=\"text-sm font-medium mb-1 block\">{label}</span>\n <label className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full flex items-center gap-2`}>\n {leftSection && <span>{leftSection}</span>}\n <input\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className=\"grow\"\n pattern={pattern}\n />\n {type === 'password' ? (\n <span className=\"cursor-pointer opacity-70 hover:opacity-100\" onClick={togglePasswordVisibility}>\n {showPassword ? (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\" />\n <path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n <path d=\"M1 1l22 22\" />\n <path d=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\" />\n </svg>\n ) : (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n )}\n </span>\n ) : rightSection ? (\n <span>{rightSection}</span>\n ) : null}\n </label>\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n }\n\n // Default: inline label\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <label className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full flex items-center gap-2`}>\n {leftSection && <span>{leftSection}</span>}\n {label && <span>{label}</span>}\n <input\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className=\"grow\"\n pattern={pattern}\n />\n {/* 显示最近输入的字符,仅针对密码字段 */}\n {type === 'password' && recentInput && (\n <span className=\"password-recent absolute right-10 font-mono\">\n {recentInput}\n </span>\n )}\n {/* 加入密码切换按钮或其他右侧元素 */}\n {type === 'password' ? (\n <span>{passwordToggle}</span>\n ) : rightSection ? (\n <span>{rightSection}</span>\n ) : null}\n </label>\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n }\n\n // 如果没有label,则直接返回input\n return (\n <div className={`relative w-full ${className}`} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <input\n ref={inputRef}\n type={actualType}\n placeholder={placeholder}\n value={value}\n onChange={handleInputChange}\n disabled={disabled}\n required={required}\n className={`${baseClass} ${variantClass} ${sizeClass} ${validatorClass} ${validationStateClass} w-full`}\n pattern={pattern}\n />\n {validator && validatorHint && !showValidationHint && (\n <p className=\"validator-hint text-xs mt-1 opacity-70\">{validatorHint}</p>\n )}\n {showValidationHint && validator && !isValid && (\n <div className=\"absolute z-10 mt-1 bg-base-200 border border-error rounded shadow-lg text-error px-3 py-1\">\n {validationTooltip}\n </div>\n )}\n </div>\n );\n};\n\nexport default Input; "],"mappings":"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"}
@@ -183,7 +183,7 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
183
183
  return /* @__PURE__ */ E("div", {
184
184
  ref: h,
185
185
  style: I,
186
- className: `relative w-52 font-sans select-none ${O || ""}`,
186
+ className: `relative w-full font-sans select-none ${O || ""}`,
187
187
  children: [/* @__PURE__ */ E("div", {
188
188
  tabIndex: 0,
189
189
  className: T,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Select/index.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useClickOutside } from '../../hooks/useClickOutside';\n\nexport interface Option {\n value: string | number;\n label: string;\n}\n\nexport interface SelectProps {\n options: Option[];\n value?: string | number | (string | number)[];\n onChange: (value: string | number | (string | number)[]) => void;\n placeholder?: string;\n multiple?: boolean;\n fixedHeight?: boolean;\n style?: React.CSSProperties; // Allow passing inline styles\n className?: string; // Allow passing CSS classes for the wrapper\n}\n\n// SVG component for the dropdown arrow\nconst DropdownArrow: React.FC<{ isOpen: boolean }> = ({ isOpen }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n style={{\n display: 'block',\n width: 16,\n height: 16,\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 200ms ease-in-out',\n }}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n);\n\n// SVG component for the remove button 'x'\nconst RemoveIcon: React.FC = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n);\n\n// Select Component Implementation using daisyUI/Tailwind\nconst Select: React.FC<SelectProps> = ({\n options,\n value,\n onChange,\n placeholder = 'Select...',\n multiple = false,\n fixedHeight = false,\n style,\n className // This className applies to the wrapper\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const [tooltipText, setTooltipText] = useState('');\n const [showArrow, setShowArrow] = useState(true);\n const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({});\n const wrapperRef = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null); // Ref for the header div\n const optionsListRef = useRef<HTMLUListElement>(null);\n\n useEffect(() => {\n if (!isOpen) return;\n const handlePointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (wrapperRef.current?.contains(target) || optionsListRef.current?.contains(target)) return;\n setIsOpen(false);\n };\n document.addEventListener('pointerdown', handlePointerDown);\n document.addEventListener('mousedown', handlePointerDown);\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown);\n document.removeEventListener('mousedown', handlePointerDown);\n };\n }, [isOpen]);\n\n const selectedValuesArray = Array.isArray(value) ? value : (value !== undefined && value !== null ? [value] : []);\n\n // Close dropdown when clicking outside\n useClickOutside(wrapperRef, useCallback(() => setIsOpen(false), []));\n\n const updateDropdownPosition = useCallback(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n const estimatedHeight = Math.min(options.length, 8) * 36 + 8;\n const fitsBelow = rect.bottom + 4 + estimatedHeight <= window.innerHeight;\n setDropdownStyle({\n position: 'fixed',\n left: rect.left,\n top: fitsBelow ? rect.bottom + 4 : Math.max(8, rect.top - estimatedHeight - 4),\n width: rect.width,\n zIndex: 10000,\n });\n }, [options.length]);\n\n useEffect(() => {\n if (!isOpen) return;\n updateDropdownPosition();\n window.addEventListener('resize', updateDropdownPosition);\n window.addEventListener('scroll', updateDropdownPosition, true);\n return () => {\n window.removeEventListener('resize', updateDropdownPosition);\n window.removeEventListener('scroll', updateDropdownPosition, true);\n };\n }, [isOpen, updateDropdownPosition]);\n\n // Hide the decorative arrow when the control becomes too narrow to reserve\n // space for both it and a useful amount of label text.\n useEffect(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n const update = () => setShowArrow(wrapper.clientWidth >= 88);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(wrapper);\n return () => observer.disconnect();\n }, []);\n\n // Keyboard navigation\n useEffect(() => {\n if (!isOpen) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setHighlightedIndex(prev => (prev < options.length - 1 ? prev + 1 : 0));\n scrollToHighlightedOption();\n break;\n case 'ArrowUp':\n event.preventDefault();\n setHighlightedIndex(prev => (prev > 0 ? prev - 1 : options.length - 1));\n scrollToHighlightedOption();\n break;\n case 'Enter':\n case ' ': // Space key\n event.preventDefault();\n if (highlightedIndex >= 0 && highlightedIndex < options.length) {\n handleOptionClick(options[highlightedIndex]);\n if (!multiple) setIsOpen(false); // Close dropdown on selection if single mode\n } else if (!multiple) {\n setIsOpen(false); // Close dropdown if Enter/Space is pressed without a highlighted option in single mode\n }\n break;\n case 'Escape':\n setIsOpen(false);\n break;\n default:\n // Optional: Implement type-ahead find\n break;\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, highlightedIndex, options, multiple]); // Added multiple to dependencies\n\n const scrollToHighlightedOption = useCallback(() => {\n if (optionsListRef.current && highlightedIndex >= 0) {\n const list = optionsListRef.current;\n const optionElement = list.children[highlightedIndex] as HTMLLIElement;\n if (optionElement) {\n const listRect = list.getBoundingClientRect();\n const optionRect = optionElement.getBoundingClientRect();\n\n if (optionRect.bottom > listRect.bottom) {\n list.scrollTop += optionRect.bottom - listRect.bottom;\n } else if (optionRect.top < listRect.top) {\n list.scrollTop -= listRect.top - optionRect.top;\n }\n }\n }\n }, [highlightedIndex]);\n\n const toggleDropdown = () => {\n const next = !isOpen;\n setIsOpen(next);\n setHighlightedIndex(next ? 0 : -1); // Reset or set initial highlight\n if (next) updateDropdownPosition();\n };\n\n const handleOptionClick = (option: Option) => {\n if (multiple) {\n const currentValues = Array.isArray(value) ? value : [];\n let newValue;\n if (currentValues.includes(option.value)) {\n newValue = currentValues.filter(v => v !== option.value);\n } else {\n newValue = [...currentValues, option.value];\n }\n onChange(newValue);\n } else {\n onChange(option.value);\n setIsOpen(false); // Close dropdown on single select\n }\n // Keep highlight on the selected item in multi-select? Maybe not.\n // setHighlightedIndex(options.findIndex(o => o.value === option.value));\n };\n\n const handleRemoveItem = (e: React.MouseEvent, itemValue: string | number) => {\n e.stopPropagation(); // Prevent dropdown from opening/closing\n const currentValues = Array.isArray(value) ? value : [];\n onChange(currentValues.filter(v => v !== itemValue));\n };\n\n // Update tooltip text and check for overflow\n useEffect(() => {\n if (multiple && headerRef.current) {\n const header = headerRef.current;\n const selectedLabels = options\n .filter(opt => selectedValuesArray.includes(opt.value))\n .map(opt => opt.label)\n .join(', ');\n\n // Check if the content (scrollWidth) exceeds the visible area (clientWidth)\n const isOverflowing = header.scrollWidth > header.clientWidth;\n setTooltipText(isOverflowing ? selectedLabels : ''); // Only set text if overflowing\n } else {\n setTooltipText(''); // Clear tooltip for single select or empty multi-select\n }\n }, [value, multiple, options, selectedValuesArray]);\n\n\n const renderSelectedValue = () => {\n if (selectedValuesArray.length === 0) {\n return <span className=\"text-base-content/60 italic\">{placeholder}</span>;\n }\n\n const selectedOptions = options.filter(opt => selectedValuesArray.includes(opt.value));\n\n if (multiple) {\n const isFixed = fixedHeight;\n // Apply overflow-x-auto for horizontal scrolling in fixedHeight mode\n const containerClasses = `\n flex gap-1 \n ${isFixed ? 'flex-nowrap overflow-x-auto overflow-y-hidden' : 'flex-wrap overflow-hidden'} // Enable horizontal scroll, hide vertical scrollbar if any\n ${tooltipText ? 'tooltip tooltip-bottom' : ''} // Keep tooltip for overflow\n `;\n // Removed showEllipsisPrefix\n\n return (\n <div\n ref={headerRef}\n className={containerClasses}\n data-tip={tooltipText ? tooltipText : undefined} // Keep tooltip logic\n // Add scrollbar styling if desired (e.g., using ::-webkit-scrollbar pseudo-element via CSS or a utility)\n style={{\n scrollbarWidth: 'thin',\n // 为固定高度模式添加右侧内边距,避免与下拉图标重叠\n ...(isFixed ? { paddingRight: '1.75rem' } : {})\n }}\n >\n {/* Removed wrapper for ellipsis and its popup */}\n\n {/* Render the badges */}\n {selectedOptions.map(option => (\n <span key={option.value} className=\"badge badge-ghost gap-1 text-xs items-center whitespace-nowrap flex-shrink-0\">\n {option.label}\n <button\n type=\"button\"\n onClick={(e) => handleRemoveItem(e, option.value)}\n className=\"btn btn-xs btn-ghost btn-circle p-0 m-0 hover:bg-error hover:text-error-content\"\n aria-label={`Remove ${option.label}`}\n >\n <RemoveIcon />\n </button>\n </span>\n ))}\n </div>\n );\n } else {\n const selectedOption = options.find(opt => opt.value === selectedValuesArray[0]);\n return selectedOption ? <span className=\"truncate\">{selectedOption.label}</span> : <span className=\"text-base-content/60 italic\">{placeholder}</span>;\n }\n };\n\n // Match the default control height to a normal line of form text. Multi-select\n // may still grow when wrapping tags unless fixedHeight is requested.\n const selectClasses = `\n relative border border-base-300 rounded-lg bg-base-100 w-full\n flex justify-between items-center cursor-pointer px-3 text-sm\n focus:outline-none focus:ring-2 focus:ring-primary focus:ring-opacity-50\n hover:border-base-content/30\n ${multiple\n ? (fixedHeight ? 'h-8' : 'min-h-8 h-auto py-1')\n : 'h-8'}\n `;\n\n return (\n <div\n ref={wrapperRef}\n style={style}\n className={`relative w-52 font-sans select-none ${className || ''}`}\n >\n {/* Header */}\n <div\n tabIndex={0}\n className={selectClasses}\n onClick={toggleDropdown}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') toggleDropdown(); }}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n >\n <div\n className=\"flex-1 min-w-0 overflow-hidden\"\n style={{ paddingRight: showArrow ? 28 : 0 }}\n >\n {renderSelectedValue()}\n </div>\n {/* Inline positioning avoids utility CSS/theme overrides moving the icon. */}\n {showArrow && (\n <div\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n right: 10,\n top: '50%',\n transform: 'translateY(-50%)',\n pointerEvents: 'none',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n }}\n >\n <DropdownArrow isOpen={isOpen} />\n </div>\n )}\n </div>\n\n {/* Dropdown Options */}\n {isOpen && typeof document !== 'undefined' && createPortal(\n <ul\n ref={optionsListRef}\n className=\"bg-base-100 border border-base-300 rounded-md shadow-lg list-none p-0 m-0 max-h-60 overflow-y-auto focus:outline-none\"\n style={dropdownStyle}\n onPointerDown={(event) => event.stopPropagation()}\n role=\"listbox\" // ARIA role\n aria-activedescendant={highlightedIndex >= 0 ? `option-${options[highlightedIndex]?.value}` : undefined} // For screen readers\n tabIndex={-1} // Allows focus programmatically but not via tab\n >\n {options.length > 0 ? (\n options.map((option, index) => (\n <li\n key={option.value}\n id={`option-${option.value}`} // ID for aria-activedescendant\n className={`p-2 cursor-pointer whitespace-nowrap overflow-hidden text-ellipsis hover:bg-base-200 ${index === highlightedIndex ? 'bg-base-300' : '' // Highlight style\n } ${selectedValuesArray.includes(option.value) && !multiple ? 'font-semibold bg-base-200' : '' // Style for selected single item\n } ${selectedValuesArray.includes(option.value) && multiple ? 'font-semibold' : '' // Style for selected multi items (less prominent background)\n }`}\n onPointerDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleOptionClick(option);\n }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onMouseEnter={() => setHighlightedIndex(index)} // Highlight on hover\n role=\"option\" // ARIA role\n aria-selected={selectedValuesArray.includes(option.value)}\n >\n {/* Optional: Add a checkmark or similar for selected items, especially in multi-select */}\n {option.label}\n </li>\n ))\n ) : (\n <li className=\"p-2 text-base-content/60 italic\">\n No options available\n </li>\n )}\n </ul>,\n document.body,\n )}\n </div>\n );\n};\n\nexport default Select; "],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Select/index.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useClickOutside } from '../../hooks/useClickOutside';\n\nexport interface Option {\n value: string | number;\n label: string;\n}\n\nexport interface SelectProps {\n options: Option[];\n value?: string | number | (string | number)[];\n onChange: (value: string | number | (string | number)[]) => void;\n placeholder?: string;\n multiple?: boolean;\n fixedHeight?: boolean;\n style?: React.CSSProperties; // Allow passing inline styles\n className?: string; // Allow passing CSS classes for the wrapper\n}\n\n// SVG component for the dropdown arrow\nconst DropdownArrow: React.FC<{ isOpen: boolean }> = ({ isOpen }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n style={{\n display: 'block',\n width: 16,\n height: 16,\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 200ms ease-in-out',\n }}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n);\n\n// SVG component for the remove button 'x'\nconst RemoveIcon: React.FC = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n);\n\n// Select Component Implementation using daisyUI/Tailwind\nconst Select: React.FC<SelectProps> = ({\n options,\n value,\n onChange,\n placeholder = 'Select...',\n multiple = false,\n fixedHeight = false,\n style,\n className // This className applies to the wrapper\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const [tooltipText, setTooltipText] = useState('');\n const [showArrow, setShowArrow] = useState(true);\n const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({});\n const wrapperRef = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null); // Ref for the header div\n const optionsListRef = useRef<HTMLUListElement>(null);\n\n useEffect(() => {\n if (!isOpen) return;\n const handlePointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (wrapperRef.current?.contains(target) || optionsListRef.current?.contains(target)) return;\n setIsOpen(false);\n };\n document.addEventListener('pointerdown', handlePointerDown);\n document.addEventListener('mousedown', handlePointerDown);\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown);\n document.removeEventListener('mousedown', handlePointerDown);\n };\n }, [isOpen]);\n\n const selectedValuesArray = Array.isArray(value) ? value : (value !== undefined && value !== null ? [value] : []);\n\n // Close dropdown when clicking outside\n useClickOutside(wrapperRef, useCallback(() => setIsOpen(false), []));\n\n const updateDropdownPosition = useCallback(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n const estimatedHeight = Math.min(options.length, 8) * 36 + 8;\n const fitsBelow = rect.bottom + 4 + estimatedHeight <= window.innerHeight;\n setDropdownStyle({\n position: 'fixed',\n left: rect.left,\n top: fitsBelow ? rect.bottom + 4 : Math.max(8, rect.top - estimatedHeight - 4),\n width: rect.width,\n zIndex: 10000,\n });\n }, [options.length]);\n\n useEffect(() => {\n if (!isOpen) return;\n updateDropdownPosition();\n window.addEventListener('resize', updateDropdownPosition);\n window.addEventListener('scroll', updateDropdownPosition, true);\n return () => {\n window.removeEventListener('resize', updateDropdownPosition);\n window.removeEventListener('scroll', updateDropdownPosition, true);\n };\n }, [isOpen, updateDropdownPosition]);\n\n // Hide the decorative arrow when the control becomes too narrow to reserve\n // space for both it and a useful amount of label text.\n useEffect(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n const update = () => setShowArrow(wrapper.clientWidth >= 88);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(wrapper);\n return () => observer.disconnect();\n }, []);\n\n // Keyboard navigation\n useEffect(() => {\n if (!isOpen) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setHighlightedIndex(prev => (prev < options.length - 1 ? prev + 1 : 0));\n scrollToHighlightedOption();\n break;\n case 'ArrowUp':\n event.preventDefault();\n setHighlightedIndex(prev => (prev > 0 ? prev - 1 : options.length - 1));\n scrollToHighlightedOption();\n break;\n case 'Enter':\n case ' ': // Space key\n event.preventDefault();\n if (highlightedIndex >= 0 && highlightedIndex < options.length) {\n handleOptionClick(options[highlightedIndex]);\n if (!multiple) setIsOpen(false); // Close dropdown on selection if single mode\n } else if (!multiple) {\n setIsOpen(false); // Close dropdown if Enter/Space is pressed without a highlighted option in single mode\n }\n break;\n case 'Escape':\n setIsOpen(false);\n break;\n default:\n // Optional: Implement type-ahead find\n break;\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, highlightedIndex, options, multiple]); // Added multiple to dependencies\n\n const scrollToHighlightedOption = useCallback(() => {\n if (optionsListRef.current && highlightedIndex >= 0) {\n const list = optionsListRef.current;\n const optionElement = list.children[highlightedIndex] as HTMLLIElement;\n if (optionElement) {\n const listRect = list.getBoundingClientRect();\n const optionRect = optionElement.getBoundingClientRect();\n\n if (optionRect.bottom > listRect.bottom) {\n list.scrollTop += optionRect.bottom - listRect.bottom;\n } else if (optionRect.top < listRect.top) {\n list.scrollTop -= listRect.top - optionRect.top;\n }\n }\n }\n }, [highlightedIndex]);\n\n const toggleDropdown = () => {\n const next = !isOpen;\n setIsOpen(next);\n setHighlightedIndex(next ? 0 : -1); // Reset or set initial highlight\n if (next) updateDropdownPosition();\n };\n\n const handleOptionClick = (option: Option) => {\n if (multiple) {\n const currentValues = Array.isArray(value) ? value : [];\n let newValue;\n if (currentValues.includes(option.value)) {\n newValue = currentValues.filter(v => v !== option.value);\n } else {\n newValue = [...currentValues, option.value];\n }\n onChange(newValue);\n } else {\n onChange(option.value);\n setIsOpen(false); // Close dropdown on single select\n }\n // Keep highlight on the selected item in multi-select? Maybe not.\n // setHighlightedIndex(options.findIndex(o => o.value === option.value));\n };\n\n const handleRemoveItem = (e: React.MouseEvent, itemValue: string | number) => {\n e.stopPropagation(); // Prevent dropdown from opening/closing\n const currentValues = Array.isArray(value) ? value : [];\n onChange(currentValues.filter(v => v !== itemValue));\n };\n\n // Update tooltip text and check for overflow\n useEffect(() => {\n if (multiple && headerRef.current) {\n const header = headerRef.current;\n const selectedLabels = options\n .filter(opt => selectedValuesArray.includes(opt.value))\n .map(opt => opt.label)\n .join(', ');\n\n // Check if the content (scrollWidth) exceeds the visible area (clientWidth)\n const isOverflowing = header.scrollWidth > header.clientWidth;\n setTooltipText(isOverflowing ? selectedLabels : ''); // Only set text if overflowing\n } else {\n setTooltipText(''); // Clear tooltip for single select or empty multi-select\n }\n }, [value, multiple, options, selectedValuesArray]);\n\n\n const renderSelectedValue = () => {\n if (selectedValuesArray.length === 0) {\n return <span className=\"text-base-content/60 italic\">{placeholder}</span>;\n }\n\n const selectedOptions = options.filter(opt => selectedValuesArray.includes(opt.value));\n\n if (multiple) {\n const isFixed = fixedHeight;\n // Apply overflow-x-auto for horizontal scrolling in fixedHeight mode\n const containerClasses = `\n flex gap-1 \n ${isFixed ? 'flex-nowrap overflow-x-auto overflow-y-hidden' : 'flex-wrap overflow-hidden'} // Enable horizontal scroll, hide vertical scrollbar if any\n ${tooltipText ? 'tooltip tooltip-bottom' : ''} // Keep tooltip for overflow\n `;\n // Removed showEllipsisPrefix\n\n return (\n <div\n ref={headerRef}\n className={containerClasses}\n data-tip={tooltipText ? tooltipText : undefined} // Keep tooltip logic\n // Add scrollbar styling if desired (e.g., using ::-webkit-scrollbar pseudo-element via CSS or a utility)\n style={{\n scrollbarWidth: 'thin',\n // 为固定高度模式添加右侧内边距,避免与下拉图标重叠\n ...(isFixed ? { paddingRight: '1.75rem' } : {})\n }}\n >\n {/* Removed wrapper for ellipsis and its popup */}\n\n {/* Render the badges */}\n {selectedOptions.map(option => (\n <span key={option.value} className=\"badge badge-ghost gap-1 text-xs items-center whitespace-nowrap flex-shrink-0\">\n {option.label}\n <button\n type=\"button\"\n onClick={(e) => handleRemoveItem(e, option.value)}\n className=\"btn btn-xs btn-ghost btn-circle p-0 m-0 hover:bg-error hover:text-error-content\"\n aria-label={`Remove ${option.label}`}\n >\n <RemoveIcon />\n </button>\n </span>\n ))}\n </div>\n );\n } else {\n const selectedOption = options.find(opt => opt.value === selectedValuesArray[0]);\n return selectedOption ? <span className=\"truncate\">{selectedOption.label}</span> : <span className=\"text-base-content/60 italic\">{placeholder}</span>;\n }\n };\n\n // Match the default control height to a normal line of form text. Multi-select\n // may still grow when wrapping tags unless fixedHeight is requested.\n const selectClasses = `\n relative border border-base-300 rounded-lg bg-base-100 w-full\n flex justify-between items-center cursor-pointer px-3 text-sm\n focus:outline-none focus:ring-2 focus:ring-primary focus:ring-opacity-50\n hover:border-base-content/30\n ${multiple\n ? (fixedHeight ? 'h-8' : 'min-h-8 h-auto py-1')\n : 'h-8'}\n `;\n\n return (\n <div\n ref={wrapperRef}\n style={style}\n className={`relative w-full font-sans select-none ${className || ''}`}\n >\n {/* Header */}\n <div\n tabIndex={0}\n className={selectClasses}\n onClick={toggleDropdown}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') toggleDropdown(); }}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n >\n <div\n className=\"flex-1 min-w-0 overflow-hidden\"\n style={{ paddingRight: showArrow ? 28 : 0 }}\n >\n {renderSelectedValue()}\n </div>\n {/* Inline positioning avoids utility CSS/theme overrides moving the icon. */}\n {showArrow && (\n <div\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n right: 10,\n top: '50%',\n transform: 'translateY(-50%)',\n pointerEvents: 'none',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n }}\n >\n <DropdownArrow isOpen={isOpen} />\n </div>\n )}\n </div>\n\n {/* Dropdown Options */}\n {isOpen && typeof document !== 'undefined' && createPortal(\n <ul\n ref={optionsListRef}\n className=\"bg-base-100 border border-base-300 rounded-md shadow-lg list-none p-0 m-0 max-h-60 overflow-y-auto focus:outline-none\"\n style={dropdownStyle}\n onPointerDown={(event) => event.stopPropagation()}\n role=\"listbox\" // ARIA role\n aria-activedescendant={highlightedIndex >= 0 ? `option-${options[highlightedIndex]?.value}` : undefined} // For screen readers\n tabIndex={-1} // Allows focus programmatically but not via tab\n >\n {options.length > 0 ? (\n options.map((option, index) => (\n <li\n key={option.value}\n id={`option-${option.value}`} // ID for aria-activedescendant\n className={`p-2 cursor-pointer whitespace-nowrap overflow-hidden text-ellipsis hover:bg-base-200 ${index === highlightedIndex ? 'bg-base-300' : '' // Highlight style\n } ${selectedValuesArray.includes(option.value) && !multiple ? 'font-semibold bg-base-200' : '' // Style for selected single item\n } ${selectedValuesArray.includes(option.value) && multiple ? 'font-semibold' : '' // Style for selected multi items (less prominent background)\n }`}\n onPointerDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleOptionClick(option);\n }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onMouseEnter={() => setHighlightedIndex(index)} // Highlight on hover\n role=\"option\" // ARIA role\n aria-selected={selectedValuesArray.includes(option.value)}\n >\n {/* Optional: Add a checkmark or similar for selected items, especially in multi-select */}\n {option.label}\n </li>\n ))\n ) : (\n <li className=\"p-2 text-base-content/60 italic\">\n No options available\n </li>\n )}\n </ul>,\n document.body,\n )}\n </div>\n );\n};\n\nexport default Select; "],"mappings":"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"}