dishui 0.0.64 → 0.0.65

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 (177) hide show
  1. package/dist/components/Badge/index.js +12 -9
  2. package/dist/components/Badge/index.js.map +1 -1
  3. package/dist/components/Button/index.js +43 -40
  4. package/dist/components/Button/index.js.map +1 -1
  5. package/dist/components/Card/index.d.ts +11 -0
  6. package/dist/components/Card/index.js +62 -37
  7. package/dist/components/Card/index.js.map +1 -1
  8. package/dist/components/Chart/Chart.js.map +1 -1
  9. package/dist/components/Checkbox/index.js +32 -30
  10. package/dist/components/Checkbox/index.js.map +1 -1
  11. package/dist/components/Demo/index.js.map +1 -1
  12. package/dist/components/EmptyState/index.d.ts +4 -1
  13. package/dist/components/EmptyState/index.js +3 -3
  14. package/dist/components/EmptyState/index.js.map +1 -1
  15. package/dist/components/FileUploader/DropZone.js.map +1 -1
  16. package/dist/components/FileUploader/FileItem.js.map +1 -1
  17. package/dist/components/FileUploader/FileUploader.js.map +1 -1
  18. package/dist/components/FileUploader/UploadQueue.js.map +1 -1
  19. package/dist/components/Input/index.js +30 -30
  20. package/dist/components/Input/index.js.map +1 -1
  21. package/dist/components/Label/index.js +41 -40
  22. package/dist/components/Label/index.js.map +1 -1
  23. package/dist/components/List/index.js +47 -32
  24. package/dist/components/List/index.js.map +1 -1
  25. package/dist/components/Markdown/Markdown.js +61 -57
  26. package/dist/components/Markdown/Markdown.js.map +1 -1
  27. package/dist/components/Markdown/markdownComponents.js +49 -49
  28. package/dist/components/Markdown/markdownComponents.js.map +1 -1
  29. package/dist/components/Modal/index.d.ts +7 -3
  30. package/dist/components/Modal/index.js +77 -65
  31. package/dist/components/Modal/index.js.map +1 -1
  32. package/dist/components/Page/index.d.ts +58 -0
  33. package/dist/components/Page/index.js +74 -0
  34. package/dist/components/Page/index.js.map +1 -0
  35. package/dist/components/PageHeader/index.js.map +1 -1
  36. package/dist/components/Select/index.js +0 -3
  37. package/dist/components/Select/index.js.map +1 -1
  38. package/dist/components/SidebarToggleButton/index.js.map +1 -1
  39. package/dist/components/StatCard/index.d.ts +3 -1
  40. package/dist/components/StatCard/index.js +39 -11
  41. package/dist/components/StatCard/index.js.map +1 -1
  42. package/dist/components/Table/index.js +103 -85
  43. package/dist/components/Table/index.js.map +1 -1
  44. package/dist/components/Tabs/index.d.ts +19 -5
  45. package/dist/components/Tabs/index.js +32 -13
  46. package/dist/components/Tabs/index.js.map +1 -1
  47. package/dist/components/Tree/Tree.js.map +1 -1
  48. package/dist/components/pro/ArticleContextMenu/index.js.map +1 -1
  49. package/dist/components/pro/ArticleControl/ArticleControl2.js.map +1 -1
  50. package/dist/components/pro/CodeEditor/editors/CodeEditor.js +141 -134
  51. package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
  52. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js +81 -78
  53. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js.map +1 -1
  54. package/dist/components/pro/CodeEditor/panels/FootnotePanel.js.map +1 -1
  55. package/dist/components/pro/CodeEditor/panels/HistoryPanel.js.map +1 -1
  56. package/dist/components/pro/CodeEditor/panels/OutlinePanel.js.map +1 -1
  57. package/dist/components/pro/CodeEditor/panels/TableOfContentsPanel.js.map +1 -1
  58. package/dist/components/pro/CodeEditor/panels/VariablePanel.js.map +1 -1
  59. package/dist/components/pro/CodeEditor/themes.js +59 -59
  60. package/dist/components/pro/CodeEditor/themes.js.map +1 -1
  61. package/dist/components/pro/DataTable/DataTable.js +49 -48
  62. package/dist/components/pro/DataTable/DataTable.js.map +1 -1
  63. package/dist/components/pro/DataTable/Filters.js +42 -42
  64. package/dist/components/pro/DataTable/Filters.js.map +1 -1
  65. package/dist/components/pro/DataTable/PivotPanel.js.map +1 -1
  66. package/dist/components/pro/DataTable/PivotView.js +35 -32
  67. package/dist/components/pro/DataTable/PivotView.js.map +1 -1
  68. package/dist/components/pro/DataTable/components/BulkActions.js.map +1 -1
  69. package/dist/components/pro/DataTable/components/ColumnSelector.js.map +1 -1
  70. package/dist/components/pro/DataTable/components/FilterBar.js.map +1 -1
  71. package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
  72. package/dist/components/pro/DataTable/components/TableHeader.js.map +1 -1
  73. package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
  74. package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
  75. package/dist/components/pro/DataTable/pivotExtension.js.map +1 -1
  76. package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
  77. package/dist/components/pro/DataTable/tanstack-table.js +37 -37
  78. package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
  79. package/dist/components/pro/FileExplorer/Breadcrumb.js +53 -53
  80. package/dist/components/pro/FileExplorer/Breadcrumb.js.map +1 -1
  81. package/dist/components/pro/FileExplorer/CreateDialog.js.map +1 -1
  82. package/dist/components/pro/FileExplorer/FileExplorer.js.map +1 -1
  83. package/dist/components/pro/FileExplorer/FileIcon.js +22 -22
  84. package/dist/components/pro/FileExplorer/FileIcon.js.map +1 -1
  85. package/dist/components/pro/FileExplorer/GridView.js.map +1 -1
  86. package/dist/components/pro/FileExplorer/ListView.js.map +1 -1
  87. package/dist/components/pro/FileExplorer/Toolbar.js.map +1 -1
  88. package/dist/components/pro/Flow/Flow.js +496 -494
  89. package/dist/components/pro/Flow/Flow.js.map +1 -1
  90. package/dist/components/pro/Flow/FlowCanvas.js +916 -917
  91. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  92. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  93. package/dist/components/pro/Flow/edges/EdgeRenderer.js +59 -59
  94. package/dist/components/pro/Flow/edges/EdgeRenderer.js.map +1 -1
  95. package/dist/components/pro/Flow/hooks/useClipboard.js.map +1 -1
  96. package/dist/components/pro/Flow/hooks/useDeleteSelection.js.map +1 -1
  97. package/dist/components/pro/Flow/hooks/useEdgeMutations.js.map +1 -1
  98. package/dist/components/pro/Flow/hooks/useLayoutActions.js +9 -11
  99. package/dist/components/pro/Flow/hooks/useLayoutActions.js.map +1 -1
  100. package/dist/components/pro/Flow/hooks/useLineMutations.js.map +1 -1
  101. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  102. package/dist/components/pro/Flow/hooks/useNodeMutations.js.map +1 -1
  103. package/dist/components/pro/Flow/lines/FreehandTool.js +9 -9
  104. package/dist/components/pro/Flow/lines/FreehandTool.js.map +1 -1
  105. package/dist/components/pro/Flow/lines/LineRenderer.js +5 -5
  106. package/dist/components/pro/Flow/lines/LineRenderer.js.map +1 -1
  107. package/dist/components/pro/Flow/nodes/DataNodeView.js +113 -93
  108. package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
  109. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  110. package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
  111. package/dist/components/pro/Flow/nodes/Model3DView.js +1 -1
  112. package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
  113. package/dist/components/pro/Flow/nodes/NodeRenderer.js +118 -118
  114. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  115. package/dist/components/pro/Flow/nodes/dataUtils.js.map +1 -1
  116. package/dist/components/pro/Flow/nodes/shapes.js +1 -3
  117. package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
  118. package/dist/components/pro/Flow/panels/AIPanel.js.map +1 -1
  119. package/dist/components/pro/Flow/panels/Breadcrumb.js.map +1 -1
  120. package/dist/components/pro/Flow/panels/ContextMenu.js.map +1 -1
  121. package/dist/components/pro/Flow/panels/DataInspectorSection.js.map +1 -1
  122. package/dist/components/pro/Flow/panels/ExpandableTextarea.js.map +1 -1
  123. package/dist/components/pro/Flow/panels/FlowPanelGroup.js.map +1 -1
  124. package/dist/components/pro/Flow/panels/FlowToolbar.js +97 -97
  125. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  126. package/dist/components/pro/Flow/panels/InspectorPanel.js +57 -57
  127. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  128. package/dist/components/pro/Flow/panels/OutlinePanel.js +26 -22
  129. package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
  130. package/dist/components/pro/Flow/panels/PresentationMode.js +18 -16
  131. package/dist/components/pro/Flow/panels/PresentationMode.js.map +1 -1
  132. package/dist/components/pro/Flow/panels/ProjectTitle.js.map +1 -1
  133. package/dist/components/pro/Flow/panels/ShapePalette.js +109 -104
  134. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  135. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  136. package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
  137. package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
  138. package/dist/components/pro/RichTextEditor/BubbleToolbar.js.map +1 -1
  139. package/dist/components/pro/RichTextEditor/CommentDialog.js.map +1 -1
  140. package/dist/components/pro/RichTextEditor/CommentPanel.js.map +1 -1
  141. package/dist/components/pro/RichTextEditor/CommentPopover.js.map +1 -1
  142. package/dist/components/pro/RichTextEditor/ContextMenu.js.map +1 -1
  143. package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
  144. package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
  145. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
  146. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
  147. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
  148. package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.js.map +1 -1
  149. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
  150. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
  151. package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
  152. package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js.map +1 -1
  153. package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.js.map +1 -1
  154. package/dist/contexts/AppContext.js.map +1 -1
  155. package/dist/dishui.css +1 -1
  156. package/dist/hooks/useTableColumns.js +7 -8
  157. package/dist/hooks/useTableColumns.js.map +1 -1
  158. package/dist/index.d.ts +2 -0
  159. package/dist/index.js +227 -221
  160. package/dist/layouts/MainLayout.js +22 -22
  161. package/dist/layouts/MainLayout.js.map +1 -1
  162. package/dist/layouts/Navbar.js.map +1 -1
  163. package/dist/layouts/Sidebar.js +94 -73
  164. package/dist/layouts/Sidebar.js.map +1 -1
  165. package/dist/layouts/headbar/Headbar.js.map +1 -1
  166. package/dist/layouts/headbar/HeadbarLangSwitcher.js.map +1 -1
  167. package/dist/layouts/headbar/HeadbarSearch.js.map +1 -1
  168. package/dist/layouts/headbar/HeadbarThemeSwitcher.js +11 -11
  169. package/dist/layouts/headbar/HeadbarThemeSwitcher.js.map +1 -1
  170. package/dist/layouts/headbar/HeadbarTitle.js.map +1 -1
  171. package/dist/utils/i18n.js +10 -10
  172. package/dist/utils/i18n.js.map +1 -1
  173. package/dist/utils/menu.js.map +1 -1
  174. package/dist/utils/routerBuilder.js +17 -15
  175. package/dist/utils/routerBuilder.js.map +1 -1
  176. package/dist/utils/themes.js.map +1 -1
  177. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"markdownComponents.js","names":[],"sources":["../../../src/components/Markdown/markdownComponents.tsx"],"sourcesContent":["import React from 'react';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { parseCodeBlockMeta } from './parseCodeBlockMeta';\nimport { resolveMetaTheme } from './codeThemes';\n\nfunction highlightMarkdown(text: string) {\n const lines = text.split('\\n');\n return lines.map((line, index) => {\n if (/^#{1,6}\\s/.test(line)) {\n const match = line.match(/^(#{1,6})(\\s+.*)$/);\n if (match) {\n return (\n <div key={index}>\n <span style={{ color: '#569cd6' }}>{match[1]}</span>\n <span style={{ color: '#dcdcaa' }}>{match[2]}</span>\n </div>\n );\n }\n }\n\n if (/^(\\s*)([-*+]|\\d+\\.)\\s/.test(line)) {\n const match = line.match(/^(\\s*)([-*+]|\\d+\\.)(\\s+.*)$/);\n if (match) {\n return (\n <div key={index}>\n <span>{match[1]}</span>\n <span style={{ color: '#c586c0' }}>{match[2]}</span>\n <span>{match[3]}</span>\n </div>\n );\n }\n }\n\n if (/^```/.test(line)) {\n return (\n <div key={index}>\n <span style={{ color: '#4ec9b0' }}>{line}</span>\n </div>\n );\n }\n\n if (/^>\\s/.test(line)) {\n return (\n <div key={index}>\n <span style={{ color: '#608b4e' }}>{line}</span>\n </div>\n );\n }\n\n const processInlineStyles = (text: string) => {\n const parts: React.ReactNode[] = [];\n let lastIndex = 0;\n const regex = /(\\*\\*[^*]+\\*\\*|\\*[^*]+\\*|`[^`]+`|\\[([^\\]]+)\\]\\(([^)]+)\\))/g;\n let match;\n\n while ((match = regex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n parts.push(text.substring(lastIndex, match.index));\n }\n const matched = match[1];\n if (matched.startsWith('**')) {\n parts.push(<span key={match.index} style={{ color: '#ce9178', fontWeight: 'bold' }}>{matched}</span>);\n } else if (matched.startsWith('*')) {\n parts.push(<span key={match.index} style={{ color: '#ce9178', fontStyle: 'italic' }}>{matched}</span>);\n } else if (matched.startsWith('`')) {\n parts.push(<span key={match.index} style={{ color: '#d16969' }}>{matched}</span>);\n } else if (matched.startsWith('[')) {\n parts.push(<span key={match.index} style={{ color: '#4ec9b0' }}>{matched}</span>);\n }\n lastIndex = regex.lastIndex;\n }\n\n if (lastIndex < text.length) {\n parts.push(text.substring(lastIndex));\n }\n\n return parts.length > 0 ? parts : text;\n };\n\n return (\n <div key={index}>\n {processInlineStyles(line)}\n </div>\n );\n }).filter(Boolean);\n}\n\nconst MONO_FONT = 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace';\n\ninterface CreateMarkdownComponentsOpts {\n enableMermaid: boolean;\n enableMarkmap: boolean;\n showLineNumbers: boolean;\n codeStyle: any;\n}\n\nexport function createMarkdownComponents(opts: CreateMarkdownComponentsOpts) {\n const { enableMermaid, enableMarkmap, showLineNumbers, codeStyle } = opts;\n\n return {\n code({ node, className, children, ...props }: any) {\n const fullClassName = className || '';\n const match = /language-(\\w+)/.exec(fullClassName);\n const inline = props.inline;\n const language = match ? match[1] : '';\n\n const metaString = (props as any).dataMeta ||\n (props as any)['data-meta'] || '';\n\n const codeMeta = parseCodeBlockMeta(metaString, fullClassName);\n\n if (!inline && language === 'mermaid' && enableMermaid) {\n return (\n <div className=\"mermaid-diagram my-4\">\n {String(children).replace(/\\n$/, '')}\n </div>\n );\n }\n\n if (!inline && language === 'markmap' && enableMarkmap) {\n return (\n <div\n className=\"markmap-diagram my-4 border border-base-300 rounded-lg overflow-hidden\"\n data-markmap-content={String(children).replace(/\\n$/, '')}\n />\n );\n }\n\n if (!inline && match && language === 'markdown') {\n const code = String(children).replace(/\\n$/, '');\n return (\n <pre\n style={{\n fontFamily: MONO_FONT,\n fontSize: '0.875em',\n borderRadius: '0.5rem',\n padding: '1em',\n margin: 0,\n backgroundColor: 'rgb(30, 30, 30)',\n color: 'rgb(212, 212, 212)',\n overflow: 'auto',\n lineHeight: '1.5',\n }}\n >\n <code style={{ fontFamily: MONO_FONT }}>\n {highlightMarkdown(code)}\n </code>\n </pre>\n );\n }\n\n if (!inline && match) {\n const selectedStyle = resolveMetaTheme(codeMeta.theme, codeStyle);\n\n let shouldShowLineNumbers: boolean | undefined;\n let lineNumbersToShow: number[] | undefined;\n\n if (Array.isArray(codeMeta.showLineNumbers)) {\n shouldShowLineNumbers = true;\n lineNumbersToShow = codeMeta.showLineNumbers;\n } else if (codeMeta.showLineNumbers !== undefined) {\n shouldShowLineNumbers = codeMeta.showLineNumbers as boolean;\n } else {\n shouldShowLineNumbers = showLineNumbers;\n }\n\n const startingLineNumber = codeMeta.startLineNumber || 1;\n const wrapLines = (codeMeta.highlightLines && codeMeta.highlightLines.length > 0) ||\n (lineNumbersToShow && lineNumbersToShow.length > 0);\n\n const codeBlock = (\n <SyntaxHighlighter\n style={selectedStyle as any}\n language={language}\n PreTag=\"div\"\n showLineNumbers={shouldShowLineNumbers}\n startingLineNumber={startingLineNumber}\n customStyle={{\n fontFamily: MONO_FONT,\n fontSize: '0.875em',\n borderRadius: codeMeta.title ? '0 0 0.5rem 0.5rem' : '0.5rem',\n borderTop: codeMeta.title ? 'none' : undefined,\n padding: '1em',\n margin: 0,\n border: 'none',\n boxShadow: 'none',\n lineHeight: '1.5',\n }}\n codeTagProps={{\n style: { fontFamily: MONO_FONT }\n }}\n lineNumberStyle={(lineNumber: number) => {\n const baseStyle: React.CSSProperties = {\n minWidth: '3em',\n paddingRight: '1em',\n userSelect: 'none',\n border: 'none',\n };\n if (lineNumbersToShow) {\n if (lineNumbersToShow.includes(lineNumber)) {\n baseStyle.opacity = 0.5;\n } else {\n baseStyle.opacity = 0;\n baseStyle.visibility = 'hidden';\n }\n } else {\n baseStyle.opacity = 0.5;\n }\n return baseStyle;\n }}\n wrapLines={wrapLines}\n lineProps={(lineNumber: number) => {\n const style: React.CSSProperties = {\n display: 'block',\n border: 'none',\n boxShadow: 'none',\n outline: 'none',\n margin: 0,\n padding: 0,\n };\n if (codeMeta.highlightLines && codeMeta.highlightLines.includes(lineNumber)) {\n style.backgroundColor = 'rgba(255, 255, 0, 0.1)';\n style.display = 'block';\n style.width = '100%';\n }\n return { style };\n }}\n {...props}\n >\n {String(children).replace(/\\n$/, '')}\n </SyntaxHighlighter>\n );\n\n if (codeMeta.title) {\n return (\n <div className=\"my-4\">\n <div\n className=\"px-4 py-2 text-sm font-mono text-base-content bg-base-200 rounded-t-lg border-b border-base-300\"\n style={{ fontFamily: MONO_FONT }}\n >\n {codeMeta.title}\n </div>\n {codeBlock}\n </div>\n );\n }\n\n return codeBlock;\n }\n\n return (\n <code className={className} {...props}>\n {children}\n </code>\n );\n },\n\n table({ node, children, ...props }: any) {\n return (\n <div className=\"overflow-x-auto my-6\">\n <table className=\"table-auto border-collapse w-full\" {...props}>\n {children}\n </table>\n </div>\n );\n },\n thead({ node, children, ...props }: any) {\n return <thead className=\"bg-base-200\" {...props}>{children}</thead>;\n },\n tbody({ node, children, ...props }: any) {\n return <tbody {...props}>{children}</tbody>;\n },\n tr({ node, children, ...props }: any) {\n return <tr className=\"border-b border-base-300 hover:bg-base-100 transition-colors\" {...props}>{children}</tr>;\n },\n th({ node, children, ...props }: any) {\n return <th className=\"px-4 py-3 text-left font-semibold text-base-content border-b-2 border-base-300\" {...props}>{children}</th>;\n },\n td({ node, children, ...props }: any) {\n return <td className=\"px-4 py-3 text-base-content\" {...props}>{children}</td>;\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"markdownComponents.js","names":[],"sources":["../../../src/components/Markdown/markdownComponents.tsx"],"sourcesContent":["import React from 'react';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { parseCodeBlockMeta } from './parseCodeBlockMeta';\nimport { resolveMetaTheme } from './codeThemes';\n\nfunction highlightMarkdown(text: string) {\n const lines = text.split('\\n');\n return lines.map((line, index) => {\n if (/^#{1,6}\\s/.test(line)) {\n const match = line.match(/^(#{1,6})(\\s+.*)$/);\n if (match) {\n return (\n <div key={index}>\n <span style={{ color: '#569cd6' }}>{match[1]}</span>\n <span style={{ color: '#dcdcaa' }}>{match[2]}</span>\n </div>\n );\n }\n }\n\n if (/^(\\s*)([-*+]|\\d+\\.)\\s/.test(line)) {\n const match = line.match(/^(\\s*)([-*+]|\\d+\\.)(\\s+.*)$/);\n if (match) {\n return (\n <div key={index}>\n <span>{match[1]}</span>\n <span style={{ color: '#c586c0' }}>{match[2]}</span>\n <span>{match[3]}</span>\n </div>\n );\n }\n }\n\n if (/^```/.test(line)) {\n return (\n <div key={index}>\n <span style={{ color: '#4ec9b0' }}>{line}</span>\n </div>\n );\n }\n\n if (/^>\\s/.test(line)) {\n return (\n <div key={index}>\n <span style={{ color: '#608b4e' }}>{line}</span>\n </div>\n );\n }\n\n const processInlineStyles = (text: string) => {\n const parts: React.ReactNode[] = [];\n let lastIndex = 0;\n const regex = /(\\*\\*[^*]+\\*\\*|\\*[^*]+\\*|`[^`]+`|\\[([^\\]]+)\\]\\(([^)]+)\\))/g;\n let match;\n\n while ((match = regex.exec(text)) !== null) {\n if (match.index > lastIndex) {\n parts.push(text.substring(lastIndex, match.index));\n }\n const matched = match[1];\n if (matched.startsWith('**')) {\n parts.push(<span key={match.index} style={{ color: '#ce9178', fontWeight: 'bold' }}>{matched}</span>);\n } else if (matched.startsWith('*')) {\n parts.push(<span key={match.index} style={{ color: '#ce9178', fontStyle: 'italic' }}>{matched}</span>);\n } else if (matched.startsWith('`')) {\n parts.push(<span key={match.index} style={{ color: '#d16969' }}>{matched}</span>);\n } else if (matched.startsWith('[')) {\n parts.push(<span key={match.index} style={{ color: '#4ec9b0' }}>{matched}</span>);\n }\n lastIndex = regex.lastIndex;\n }\n\n if (lastIndex < text.length) {\n parts.push(text.substring(lastIndex));\n }\n\n return parts.length > 0 ? parts : text;\n };\n\n return (\n <div key={index}>\n {processInlineStyles(line)}\n </div>\n );\n }).filter(Boolean);\n}\n\nconst MONO_FONT = 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace';\n\ninterface CreateMarkdownComponentsOpts {\n enableMermaid: boolean;\n enableMarkmap: boolean;\n showLineNumbers: boolean;\n codeStyle: any;\n}\n\nexport function createMarkdownComponents(opts: CreateMarkdownComponentsOpts) {\n const { enableMermaid, enableMarkmap, showLineNumbers, codeStyle } = opts;\n\n return {\n code({ node, className, children, ...props }: any) {\n const fullClassName = className || '';\n const match = /language-(\\w+)/.exec(fullClassName);\n const inline = props.inline;\n const language = match ? match[1] : '';\n\n const metaString = (props as any).dataMeta ||\n (props as any)['data-meta'] || '';\n\n const codeMeta = parseCodeBlockMeta(metaString, fullClassName);\n\n if (!inline && language === 'mermaid' && enableMermaid) {\n return (\n <div className=\"mermaid-diagram my-4\">\n {String(children).replace(/\\n$/, '')}\n </div>\n );\n }\n\n if (!inline && language === 'markmap' && enableMarkmap) {\n return (\n <div\n className=\"markmap-diagram my-4 border border-base-300 rounded-lg overflow-hidden\"\n data-markmap-content={String(children).replace(/\\n$/, '')}\n />\n );\n }\n\n if (!inline && match && language === 'markdown') {\n const code = String(children).replace(/\\n$/, '');\n return (\n <pre\n style={{\n fontFamily: MONO_FONT,\n fontSize: '0.875em',\n borderRadius: '0.5rem',\n padding: '1em',\n margin: 0,\n backgroundColor: 'rgb(30, 30, 30)',\n color: 'rgb(212, 212, 212)',\n overflow: 'auto',\n lineHeight: '1.5',\n }}\n >\n <code style={{ fontFamily: MONO_FONT }}>\n {highlightMarkdown(code)}\n </code>\n </pre>\n );\n }\n\n if (!inline && match) {\n const selectedStyle = resolveMetaTheme(codeMeta.theme, codeStyle);\n\n let shouldShowLineNumbers: boolean | undefined;\n let lineNumbersToShow: number[] | undefined;\n\n if (Array.isArray(codeMeta.showLineNumbers)) {\n shouldShowLineNumbers = true;\n lineNumbersToShow = codeMeta.showLineNumbers;\n } else if (codeMeta.showLineNumbers !== undefined) {\n shouldShowLineNumbers = codeMeta.showLineNumbers as boolean;\n } else {\n shouldShowLineNumbers = showLineNumbers;\n }\n\n const startingLineNumber = codeMeta.startLineNumber || 1;\n const wrapLines = (codeMeta.highlightLines && codeMeta.highlightLines.length > 0) ||\n (lineNumbersToShow && lineNumbersToShow.length > 0);\n\n const codeBlock = (\n <SyntaxHighlighter\n style={selectedStyle as any}\n language={language}\n PreTag=\"div\"\n showLineNumbers={shouldShowLineNumbers}\n startingLineNumber={startingLineNumber}\n customStyle={{\n fontFamily: MONO_FONT,\n fontSize: '0.875em',\n borderRadius: codeMeta.title ? '0 0 0.5rem 0.5rem' : '0.5rem',\n borderTop: codeMeta.title ? 'none' : undefined,\n padding: '1em',\n margin: 0,\n border: 'none',\n boxShadow: 'none',\n lineHeight: '1.5',\n }}\n codeTagProps={{\n style: { fontFamily: MONO_FONT }\n }}\n lineNumberStyle={(lineNumber: number) => {\n const baseStyle: React.CSSProperties = {\n minWidth: '3em',\n paddingRight: '1em',\n userSelect: 'none',\n border: 'none',\n };\n if (lineNumbersToShow) {\n if (lineNumbersToShow.includes(lineNumber)) {\n baseStyle.opacity = 0.5;\n } else {\n baseStyle.opacity = 0;\n baseStyle.visibility = 'hidden';\n }\n } else {\n baseStyle.opacity = 0.5;\n }\n return baseStyle;\n }}\n wrapLines={wrapLines}\n lineProps={(lineNumber: number) => {\n const style: React.CSSProperties = {\n display: 'block',\n border: 'none',\n boxShadow: 'none',\n outline: 'none',\n margin: 0,\n padding: 0,\n };\n if (codeMeta.highlightLines && codeMeta.highlightLines.includes(lineNumber)) {\n style.backgroundColor = 'rgba(255, 255, 0, 0.1)';\n style.display = 'block';\n style.width = '100%';\n }\n return { style };\n }}\n {...props}\n >\n {String(children).replace(/\\n$/, '')}\n </SyntaxHighlighter>\n );\n\n if (codeMeta.title) {\n return (\n <div className=\"my-4\">\n <div\n className=\"px-4 py-2 text-sm font-mono text-base-content bg-base-200 rounded-t-lg border-b border-base-300\"\n style={{ fontFamily: MONO_FONT }}\n >\n {codeMeta.title}\n </div>\n {codeBlock}\n </div>\n );\n }\n\n return codeBlock;\n }\n\n return (\n <code className={className} {...props}>\n {children}\n </code>\n );\n },\n\n table({ node, children, ...props }: any) {\n return (\n <div className=\"overflow-x-auto my-6\">\n <table className=\"table-auto border-collapse w-full\" {...props}>\n {children}\n </table>\n </div>\n );\n },\n thead({ node, children, ...props }: any) {\n return <thead className=\"bg-base-200\" {...props}>{children}</thead>;\n },\n tbody({ node, children, ...props }: any) {\n return <tbody {...props}>{children}</tbody>;\n },\n tr({ node, children, ...props }: any) {\n return <tr className=\"border-b border-base-300 hover:bg-base-100 transition-colors\" {...props}>{children}</tr>;\n },\n th({ node, children, ...props }: any) {\n return <th className=\"px-4 py-3 text-left font-semibold text-base-content border-b-2 border-base-300\" {...props}>{children}</th>;\n },\n td({ node, children, ...props }: any) {\n return <td className=\"px-4 py-3 text-base-content\" {...props}>{children}</td>;\n },\n };\n}\n"],"mappings":"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"}
@@ -12,8 +12,12 @@ export type ModalProps = {
12
12
  children?: React.ReactNode;
13
13
  /** 底部操作区(默认右对齐) */
14
14
  footer?: React.ReactNode;
15
- /** 尺寸 */
16
- size?: 'sm' | 'md' | 'lg';
15
+ /** 尺寸(预设):sm / md / lg / xl / full */
16
+ size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
17
+ /** 自定义宽度:支持百分比/像素等 CSS 长度(如 "80%"、640)。优先于 size。 */
18
+ width?: number | string;
19
+ /** 自定义高度:支持百分比/像素等 CSS 长度(如 "80%"、480)。 */
20
+ height?: number | string;
17
21
  /** 点击遮罩是否关闭(默认 true) */
18
22
  closeOnOverlay?: boolean;
19
23
  /** 是否显示右上角关闭按钮(默认 true) */
@@ -23,5 +27,5 @@ export type ModalProps = {
23
27
  /**
24
28
  * 轻量模态框:遮罩 + 居中面板,支持 Esc 关闭、遮罩点击关闭与滚动锁定。
25
29
  */
26
- declare const Modal: ({ open, onClose, title, description, children, footer, size, closeOnOverlay, showClose, className, }: ModalProps) => React.JSX.Element | null;
30
+ declare const Modal: ({ open, onClose, title, description, children, footer, size, width, height, closeOnOverlay, showClose, className, }: ModalProps) => React.JSX.Element | null;
27
31
  export default Modal;
@@ -1,73 +1,85 @@
1
- import { useEffect as x } from "react";
1
+ import { useEffect as N } from "react";
2
2
  import { jsx as e, jsxs as r } from "react/jsx-runtime";
3
- var f = {
3
+ var g = {
4
4
  sm: "max-w-sm",
5
5
  md: "max-w-lg",
6
- lg: "max-w-2xl"
7
- }, p = ({ open: a, onClose: t, title: s, description: n, children: i, footer: o, size: c = "md", closeOnOverlay: m = !0, showClose: d = !0, className: u = "" }) => (x(() => {
8
- if (!a) return;
9
- const l = (v) => {
10
- v.key === "Escape" && t();
11
- };
12
- window.addEventListener("keydown", l);
13
- const b = document.body.style.overflow;
14
- return document.body.style.overflow = "hidden", () => {
15
- window.removeEventListener("keydown", l), document.body.style.overflow = b;
16
- };
17
- }, [a, t]), a ? /* @__PURE__ */ r("div", {
18
- className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4",
19
- children: [/* @__PURE__ */ e("div", {
20
- className: "absolute inset-0",
21
- onClick: m ? t : void 0,
22
- "aria-hidden": !0
23
- }), /* @__PURE__ */ r("div", {
24
- role: "dialog",
25
- "aria-modal": "true",
26
- className: `card relative w-full bg-base-100 shadow-xl ${f[c]} ${u}`.trim(),
27
- children: [
28
- (s || d) && /* @__PURE__ */ r("div", {
29
- className: "flex items-start justify-between gap-3 border-b border-base-300 px-5 py-3.5",
30
- children: [/* @__PURE__ */ r("div", {
31
- className: "min-w-0",
32
- children: [s && /* @__PURE__ */ e("h3", {
33
- className: "truncate text-sm font-semibold text-base-content",
34
- children: s
35
- }), n && /* @__PURE__ */ e("p", {
36
- className: "mt-0.5 text-xs text-base-content/60",
37
- children: n
38
- })]
39
- }), d && /* @__PURE__ */ e("button", {
40
- type: "button",
41
- onClick: t,
42
- "aria-label": "Close",
43
- className: "shrink-0 rounded-md p-1 text-base-content/50 transition-colors hover:bg-base-200 hover:text-base-content",
44
- children: /* @__PURE__ */ e("svg", {
45
- className: "h-4 w-4",
46
- fill: "none",
47
- viewBox: "0 0 24 24",
48
- stroke: "currentColor",
49
- strokeWidth: 2,
50
- children: /* @__PURE__ */ e("path", {
51
- strokeLinecap: "round",
52
- strokeLinejoin: "round",
53
- d: "M6 18L18 6M6 6l12 12"
6
+ lg: "max-w-2xl",
7
+ xl: "max-w-5xl",
8
+ full: "max-w-[95vw]"
9
+ }, x = (t) => typeof t == "number" ? `${t}px` : t, E = ({ open: t, onClose: s, title: a, description: n, children: v, footer: l, size: u = "md", width: i, height: d, closeOnOverlay: b = !0, showClose: c = !0, className: f = "" }) => {
10
+ if (N(() => {
11
+ if (!t) return;
12
+ const m = (k) => {
13
+ k.key === "Escape" && s();
14
+ };
15
+ window.addEventListener("keydown", m);
16
+ const p = document.body.style.overflow;
17
+ return document.body.style.overflow = "hidden", () => {
18
+ window.removeEventListener("keydown", m), document.body.style.overflow = p;
19
+ };
20
+ }, [t, s]), !t) return null;
21
+ const o = i !== void 0, h = {
22
+ width: o ? x(i) : void 0,
23
+ maxWidth: o ? "95vw" : void 0,
24
+ height: x(d),
25
+ maxHeight: "92vh"
26
+ }, w = o ? "" : g[u], y = d !== void 0 ? "min-h-0 flex-1 overflow-y-auto px-5 py-4" : "max-h-[70vh] overflow-y-auto px-5 py-4";
27
+ return /* @__PURE__ */ r("div", {
28
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4",
29
+ children: [/* @__PURE__ */ e("div", {
30
+ className: "absolute inset-0",
31
+ onClick: b ? s : void 0,
32
+ "aria-hidden": !0
33
+ }), /* @__PURE__ */ r("div", {
34
+ role: "dialog",
35
+ "aria-modal": "true",
36
+ className: `card relative flex w-full flex-col bg-base-100 shadow-xl ${w} ${f}`.trim(),
37
+ style: h,
38
+ children: [
39
+ (a || c) && /* @__PURE__ */ r("div", {
40
+ className: "flex shrink-0 items-start justify-between gap-3 border-b border-base-300 px-5 py-3.5",
41
+ children: [/* @__PURE__ */ r("div", {
42
+ className: "min-w-0",
43
+ children: [a && /* @__PURE__ */ e("h3", {
44
+ className: "truncate text-sm font-semibold text-base-content",
45
+ children: a
46
+ }), n && /* @__PURE__ */ e("p", {
47
+ className: "mt-0.5 text-xs text-base-content/60",
48
+ children: n
49
+ })]
50
+ }), c && /* @__PURE__ */ e("button", {
51
+ type: "button",
52
+ onClick: s,
53
+ "aria-label": "Close",
54
+ className: "shrink-0 rounded-md p-1 text-base-content/50 transition-colors hover:bg-base-200 hover:text-base-content",
55
+ children: /* @__PURE__ */ e("svg", {
56
+ className: "h-4 w-4",
57
+ fill: "none",
58
+ viewBox: "0 0 24 24",
59
+ stroke: "currentColor",
60
+ strokeWidth: 2,
61
+ children: /* @__PURE__ */ e("path", {
62
+ strokeLinecap: "round",
63
+ strokeLinejoin: "round",
64
+ d: "M6 18L18 6M6 6l12 12"
65
+ })
54
66
  })
55
- })
56
- })]
57
- }),
58
- /* @__PURE__ */ e("div", {
59
- className: "max-h-[70vh] overflow-y-auto px-5 py-4",
60
- children: i
61
- }),
62
- o && /* @__PURE__ */ e("div", {
63
- className: "flex justify-end gap-2 border-t border-base-300 px-5 py-3.5",
64
- children: o
65
- })
66
- ]
67
- })]
68
- }) : null);
67
+ })]
68
+ }),
69
+ /* @__PURE__ */ e("div", {
70
+ className: y,
71
+ children: v
72
+ }),
73
+ l && /* @__PURE__ */ e("div", {
74
+ className: "flex shrink-0 justify-end gap-2 border-t border-base-300 px-5 py-3.5",
75
+ children: l
76
+ })
77
+ ]
78
+ })]
79
+ });
80
+ };
69
81
  export {
70
- p as default
82
+ E as default
71
83
  };
72
84
 
73
85
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Modal/index.tsx"],"sourcesContent":["import React, { useEffect } from 'react';\n\nexport type ModalProps = {\n /** 是否打开 */\n open: boolean;\n /** 关闭回调(遮罩点击 / Esc / 关闭按钮触发) */\n onClose: () => void;\n /** 标题 */\n title?: React.ReactNode;\n /** 标题下的说明文字 */\n description?: React.ReactNode;\n /** 正文内容 */\n children?: React.ReactNode;\n /** 底部操作区(默认右对齐) */\n footer?: React.ReactNode;\n /** 尺寸 */\n size?: 'sm' | 'md' | 'lg';\n /** 点击遮罩是否关闭(默认 true) */\n closeOnOverlay?: boolean;\n /** 是否显示右上角关闭按钮(默认 true) */\n showClose?: boolean;\n className?: string;\n};\n\nconst SIZE_CLASS: Record<NonNullable<ModalProps['size']>, string> = {\n sm: 'max-w-sm',\n md: 'max-w-lg',\n lg: 'max-w-2xl',\n};\n\n/**\n * 轻量模态框:遮罩 + 居中面板,支持 Esc 关闭、遮罩点击关闭与滚动锁定。\n */\nconst Modal = ({\n open,\n onClose,\n title,\n description,\n children,\n footer,\n size = 'md',\n closeOnOverlay = true,\n showClose = true,\n className = '',\n}: ModalProps) => {\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', onKey);\n const prevOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => {\n window.removeEventListener('keydown', onKey);\n document.body.style.overflow = prevOverflow;\n };\n }, [open, onClose]);\n\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\n <div\n className=\"absolute inset-0\"\n onClick={closeOnOverlay ? onClose : undefined}\n aria-hidden\n />\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n className={`card relative w-full bg-base-100 shadow-xl ${SIZE_CLASS[size]} ${className}`.trim()}\n >\n {(title || showClose) && (\n <div className=\"flex items-start justify-between gap-3 border-b border-base-300 px-5 py-3.5\">\n <div className=\"min-w-0\">\n {title && (\n <h3 className=\"truncate text-sm font-semibold text-base-content\">\n {title}\n </h3>\n )}\n {description && (\n <p className=\"mt-0.5 text-xs text-base-content/60\">{description}</p>\n )}\n </div>\n {showClose && (\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close\"\n className=\"shrink-0 rounded-md p-1 text-base-content/50 transition-colors hover:bg-base-200 hover:text-base-content\"\n >\n <svg\n className=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n )}\n </div>\n )}\n <div className=\"max-h-[70vh] overflow-y-auto px-5 py-4\">{children}</div>\n {footer && (\n <div className=\"flex justify-end gap-2 border-t border-base-300 px-5 py-3.5\">\n {footer}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default Modal;\n"],"mappings":";;AAwBA,IAAM,IAA8D;AAAA,EAChE,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACR,GAKM,IAAA,CAAS,EACX,MAAA,GACA,SAAA,GACA,OAAA,GACA,aAAA,GACA,UAAA,GACA,QAAA,GACA,MAAA,IAAO,MACP,gBAAA,IAAiB,IACjB,WAAA,IAAY,IACZ,WAAA,IAAY,GAAA,OAEZ,EAAA,MAAgB;AACZ,MAAI,CAAC,EAAM;AACX,QAAM,IAAA,CAAS,MAAqB;AAChC,IAAI,EAAE,QAAQ,YAAU,EAAQ;AAAA,EACpC;AACA,SAAO,iBAAiB,WAAW,CAAK;AACxC,QAAM,IAAe,SAAS,KAAK,MAAM;AACzC,kBAAS,KAAK,MAAM,WAAW,UAC/B,MAAa;AACT,WAAO,oBAAoB,WAAW,CAAK,GAC3C,SAAS,KAAK,MAAM,WAAW;AAAA,EACnC;AACJ,GAAG,CAAC,GAAM,CAAO,CAAC,GAEb,IAGD,gBAAA,EAAC,OAAD;AAAA,EAAK,WAAU;AAAA,YAAf,CACI,gBAAA,EAAC,OAAD;AAAA,IACI,WAAU;AAAA,IACV,SAAS,IAAiB,IAAU;AAAA,IACpC,eAAA;AAAA,EACH,CAAA,GACD,gBAAA,EAAC,OAAD;AAAA,IACI,MAAK;AAAA,IACL,cAAW;AAAA,IACX,WAAW,8CAA8C,EAAW,CAAA,CAAA,IAAS,CAAA,GAAY,KAAK;AAAA,cAHlG;AAAA,OAKM,KAAS,MACP,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,kBAAf,CACI,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,oBAAf,CACK,KACG,gBAAA,EAAC,MAAD;AAAA,YAAI,WAAU;AAAA,sBACT;AAAA,UACD,CAAA,GAEP,KACG,gBAAA,EAAC,KAAD;AAAA,YAAG,WAAU;AAAA,sBAAuC;AAAA,UAAe,CAAA,CAEtE;AAAA,YACJ,KACG,gBAAA,EAAC,UAAD;AAAA,UACI,MAAK;AAAA,UACL,SAAS;AAAA,UACT,cAAW;AAAA,UACX,WAAU;AAAA,oBAEV,gBAAA,EAAC,OAAD;AAAA,YACI,WAAU;AAAA,YACV,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,QAAO;AAAA,YACP,aAAa;AAAA,sBAEb,gBAAA,EAAC,QAAD;AAAA,cACI,eAAc;AAAA,cACd,gBAAe;AAAA,cACf,GAAE;AAAA,YACL,CAAA;AAAA,UACA,CAAA;AAAA,QACD,CAAA,CAEX;AAAA;MAET,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,QAA0C,UAAA;AAAA,MAAc,CAAA;AAAA,MACtE,KACG,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,kBACV;AAAA,MACA,CAAA;AAAA,IAER;AAAA,IACJ;KAzDS"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Modal/index.tsx"],"sourcesContent":["import React, { useEffect } from 'react';\n\nexport type ModalProps = {\n /** 是否打开 */\n open: boolean;\n /** 关闭回调(遮罩点击 / Esc / 关闭按钮触发) */\n onClose: () => void;\n /** 标题 */\n title?: React.ReactNode;\n /** 标题下的说明文字 */\n description?: React.ReactNode;\n /** 正文内容 */\n children?: React.ReactNode;\n /** 底部操作区(默认右对齐) */\n footer?: React.ReactNode;\n /** 尺寸(预设):sm / md / lg / xl / full */\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n /** 自定义宽度:支持百分比/像素等 CSS 长度(如 \"80%\"、640)。优先于 size。 */\n width?: number | string;\n /** 自定义高度:支持百分比/像素等 CSS 长度(如 \"80%\"、480)。 */\n height?: number | string;\n /** 点击遮罩是否关闭(默认 true) */\n closeOnOverlay?: boolean;\n /** 是否显示右上角关闭按钮(默认 true) */\n showClose?: boolean;\n className?: string;\n};\n\nconst SIZE_CLASS: Record<NonNullable<ModalProps['size']>, string> = {\n sm: 'max-w-sm',\n md: 'max-w-lg',\n lg: 'max-w-2xl',\n xl: 'max-w-5xl',\n full: 'max-w-[95vw]',\n};\n\nconst toCssSize = (value: number | string | undefined): string | undefined =>\n typeof value === 'number' ? `${value}px` : value;\n\n/**\n * 轻量模态框:遮罩 + 居中面板,支持 Esc 关闭、遮罩点击关闭与滚动锁定。\n */\nconst Modal = ({\n open,\n onClose,\n title,\n description,\n children,\n footer,\n size = 'md',\n width,\n height,\n closeOnOverlay = true,\n showClose = true,\n className = '',\n}: ModalProps) => {\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n window.addEventListener('keydown', onKey);\n const prevOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => {\n window.removeEventListener('keydown', onKey);\n document.body.style.overflow = prevOverflow;\n };\n }, [open, onClose]);\n\n if (!open) return null;\n\n // 自定义宽高:传入时优先于 size 预设;支持百分比。\n const hasCustomWidth = width !== undefined;\n const panelStyle: React.CSSProperties = {\n width: hasCustomWidth ? toCssSize(width) : undefined,\n maxWidth: hasCustomWidth ? '95vw' : undefined,\n height: toCssSize(height),\n maxHeight: '92vh',\n };\n // 面板尺寸类:未自定义宽度时才应用 max-w-* 预设。\n const sizeClass = hasCustomWidth ? '' : SIZE_CLASS[size];\n // 正文区:固定高度时自适应充满并内部滚动;否则限制最大高度。\n const bodyClass = height !== undefined\n ? 'min-h-0 flex-1 overflow-y-auto px-5 py-4'\n : 'max-h-[70vh] overflow-y-auto px-5 py-4';\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\n <div\n className=\"absolute inset-0\"\n onClick={closeOnOverlay ? onClose : undefined}\n aria-hidden\n />\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n className={`card relative flex w-full flex-col bg-base-100 shadow-xl ${sizeClass} ${className}`.trim()}\n style={panelStyle}\n >\n {(title || showClose) && (\n <div className=\"flex shrink-0 items-start justify-between gap-3 border-b border-base-300 px-5 py-3.5\">\n <div className=\"min-w-0\">\n {title && (\n <h3 className=\"truncate text-sm font-semibold text-base-content\">\n {title}\n </h3>\n )}\n {description && (\n <p className=\"mt-0.5 text-xs text-base-content/60\">{description}</p>\n )}\n </div>\n {showClose && (\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close\"\n className=\"shrink-0 rounded-md p-1 text-base-content/50 transition-colors hover:bg-base-200 hover:text-base-content\"\n >\n <svg\n className=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n )}\n </div>\n )}\n <div className={bodyClass}>{children}</div>\n {footer && (\n <div className=\"flex shrink-0 justify-end gap-2 border-t border-base-300 px-5 py-3.5\">\n {footer}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default Modal;\n"],"mappings":";;AA4BA,IAAM,IAA8D;AAAA,EAChE,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACV,GAEM,IAAA,CAAa,MACf,OAAO,KAAU,WAAW,GAAG,CAAA,OAAY,GAKzC,IAAA,CAAS,EACX,MAAA,GACA,SAAA,GACA,OAAA,GACA,aAAA,GACA,UAAA,GACA,QAAA,GACA,MAAA,IAAO,MACP,OAAA,GACA,QAAA,GACA,gBAAA,IAAiB,IACjB,WAAA,IAAY,IACZ,WAAA,IAAY,GAAA,MACE;AAed,MAdA,EAAA,MAAgB;AACZ,QAAI,CAAC,EAAM;AACX,UAAM,IAAA,CAAS,MAAqB;AAChC,MAAI,EAAE,QAAQ,YAAU,EAAQ;AAAA,IACpC;AACA,WAAO,iBAAiB,WAAW,CAAK;AACxC,UAAM,IAAe,SAAS,KAAK,MAAM;AACzC,oBAAS,KAAK,MAAM,WAAW,UAC/B,MAAa;AACT,aAAO,oBAAoB,WAAW,CAAK,GAC3C,SAAS,KAAK,MAAM,WAAW;AAAA,IACnC;AAAA,EACJ,GAAG,CAAC,GAAM,CAAO,CAAC,GAEd,CAAC,EAAM,QAAO;AAGlB,QAAM,IAAiB,MAAU,QAC3B,IAAkC;AAAA,IACpC,OAAO,IAAiB,EAAU,CAAK,IAAI;AAAA,IAC3C,UAAU,IAAiB,SAAS;AAAA,IACpC,QAAQ,EAAU,CAAM;AAAA,IACxB,WAAW;AAAA,EACf,GAEM,IAAY,IAAiB,KAAK,EAAW,CAAA,GAE7C,IAAY,MAAW,SACvB,6CACA;AAEN,SACI,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAU;AAAA,IAAf,UAAA,CACI,gBAAA,EAAC,OAAD;AAAA,MACI,WAAU;AAAA,MACV,SAAS,IAAiB,IAAU;AAAA,MACpC,eAAA;AAAA,IACH,CAAA,GACD,gBAAA,EAAC,OAAD;AAAA,MACI,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAW,4DAA4D,CAAA,IAAa,CAAA,GAAY,KAAK;AAAA,MACrG,OAAO;AAAA,MAJX,UAAA;AAAA,SAMM,KAAS,MACP,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,UAAf,UAAA,CACI,gBAAA,EAAC,OAAD;AAAA,YAAK,WAAU;AAAA,YAAf,UAAA,CACK,KACG,gBAAA,EAAC,MAAD;AAAA,cAAI,WAAU;AAAA,cACT,UAAA;AAAA,YACD,CAAA,GAEP,KACG,gBAAA,EAAC,KAAD;AAAA,cAAG,WAAU;AAAA,cAAuC,UAAA;AAAA,YAAe,CAAA,CAEtE;AAAA,UACJ,CAAA,GAAA,KACG,gBAAA,EAAC,UAAD;AAAA,YACI,MAAK;AAAA,YACL,SAAS;AAAA,YACT,cAAW;AAAA,YACX,WAAU;AAAA,YAEV,UAAA,gBAAA,EAAC,OAAD;AAAA,cACI,WAAU;AAAA,cACV,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,QAAO;AAAA,cACP,aAAa;AAAA,cAEb,UAAA,gBAAA,EAAC,QAAD;AAAA,gBACI,eAAc;AAAA,gBACd,gBAAe;AAAA,gBACf,GAAE;AAAA,cACL,CAAA;AAAA,YACA,CAAA;AAAA,UACD,CAAA,CAEX;AAAA;QAET,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAW;AAAA,UAAY,UAAA;AAAA,QAAc,CAAA;AAAA,QACzC,KACG,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,UACV,UAAA;AAAA,QACA,CAAA;AAAA,MAER;AAAA,IACJ,CAAA,CAAA;AAAA;AAEb"}
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import { PageHeaderProps } from '../PageHeader';
3
+ /**
4
+ * Page 布局脚手架
5
+ * ----------------------------------------------------------------------------
6
+ * 为管理后台等页面提供统一的「页头 + 主体 + 左右侧栏」骨架,配合 PageHeader、
7
+ * StatCard 等组件使用。所有区域都是可选的,可按需组合。
8
+ *
9
+ * 典型结构:
10
+ * <Page fullHeight>
11
+ * <Page.Header title="用户管理" actions={<Button>新建</Button>} />
12
+ * <Page.Body scroll>
13
+ * <Page.Left width={240}>筛选器</Page.Left>
14
+ * <Page.Main scroll>主内容</Page.Main>
15
+ * <Page.Right width={320}>详情</Page.Right>
16
+ * </Page.Body>
17
+ * </Page>
18
+ */
19
+ export type PageProps = React.HTMLAttributes<HTMLDivElement> & {
20
+ /** 是否占满父容器高度并启用内部滚动(主体区滚动,页头固定) */
21
+ fullHeight?: boolean;
22
+ };
23
+ export type PageBodyProps = React.HTMLAttributes<HTMLDivElement> & {
24
+ /** 主体内的间距(left/main/right 之间),数字按 px 处理,默认 16 */
25
+ gap?: number | string;
26
+ /** 是否让主体区在剩余空间内滚动(配合 Page fullHeight 使用) */
27
+ scroll?: boolean;
28
+ };
29
+ export type PageAsideProps = React.HTMLAttributes<HTMLDivElement> & {
30
+ /** 侧栏宽度,数字按 px 处理,默认 260 */
31
+ width?: number | string;
32
+ /** 是否显示分隔边框 */
33
+ bordered?: boolean;
34
+ /** 侧栏内部纵向滚动自适应 */
35
+ scroll?: boolean;
36
+ /** 小屏(<768px)下是否隐藏(侧栏通常在移动端折叠) */
37
+ hideOnMobile?: boolean;
38
+ };
39
+ export type PageMainProps = React.HTMLAttributes<HTMLDivElement> & {
40
+ /** 主内容区是否在剩余空间内纵向滚动 */
41
+ scroll?: boolean;
42
+ };
43
+ /** 页头:直接复用 PageHeader,作为 Page.Header 使用 */
44
+ declare const PageHeaderSlot: (props: PageHeaderProps) => React.JSX.Element;
45
+ declare const PageBody: ({ gap, scroll, className, style, children, ...rest }: PageBodyProps) => React.JSX.Element;
46
+ declare const PageLeft: ({ width, bordered, scroll, hideOnMobile, className, style, children, ...rest }: PageAsideProps) => React.JSX.Element;
47
+ declare const PageRight: ({ width, bordered, scroll, hideOnMobile, className, style, children, ...rest }: PageAsideProps) => React.JSX.Element;
48
+ declare const PageMain: ({ scroll, className, children, ...rest }: PageMainProps) => React.JSX.Element;
49
+ interface PageCompound extends React.FC<PageProps> {
50
+ Header: typeof PageHeaderSlot;
51
+ Body: typeof PageBody;
52
+ Left: typeof PageLeft;
53
+ Right: typeof PageRight;
54
+ Main: typeof PageMain;
55
+ }
56
+ declare const PageWithCompounds: PageCompound;
57
+ export { PageBody, PageLeft, PageRight, PageMain };
58
+ export default PageWithCompounds;
@@ -0,0 +1,74 @@
1
+ import n from "../PageHeader/index.js";
2
+ import "react";
3
+ import { jsx as d } from "react/jsx-runtime";
4
+ var t = (e) => typeof e == "number" ? `${e}px` : e, h = ({ fullHeight: e = !1, className: a = "", children: i, ...l }) => /* @__PURE__ */ d("div", {
5
+ className: [
6
+ "dishui-page flex w-full flex-col",
7
+ e ? "h-full min-h-0" : "",
8
+ a
9
+ ].filter(Boolean).join(" "),
10
+ ...l,
11
+ children: i
12
+ }), u = (e) => /* @__PURE__ */ d(n, { ...e }), g = ({ gap: e = 16, scroll: a = !1, className: i = "", style: l, children: o, ...r }) => /* @__PURE__ */ d("div", {
13
+ className: [
14
+ "dishui-page-body flex w-full flex-col md:flex-row",
15
+ a ? "min-h-0 flex-1" : "",
16
+ i
17
+ ].filter(Boolean).join(" "),
18
+ style: {
19
+ gap: t(e),
20
+ ...l
21
+ },
22
+ ...r,
23
+ children: o
24
+ }), p = ({ width: e = 260, bordered: a = !0, scroll: i = !0, hideOnMobile: l = !1, className: o = "", style: r, children: m, ...f }) => /* @__PURE__ */ d("aside", {
25
+ className: [
26
+ "dishui-page-left w-full shrink-0 md:w-(--dishui-aside-w)",
27
+ a ? "md:border-r md:border-base-300 md:pr-4" : "",
28
+ i ? "md:min-h-0 md:overflow-y-auto" : "",
29
+ l ? "hidden md:block" : "",
30
+ o
31
+ ].filter(Boolean).join(" "),
32
+ style: {
33
+ "--dishui-aside-w": t(e),
34
+ ...r
35
+ },
36
+ ...f,
37
+ children: m
38
+ }), w = ({ width: e = 320, bordered: a = !0, scroll: i = !0, hideOnMobile: l = !1, className: o = "", style: r, children: m, ...f }) => /* @__PURE__ */ d("aside", {
39
+ className: [
40
+ "dishui-page-right w-full shrink-0 md:w-(--dishui-aside-w)",
41
+ a ? "md:border-l md:border-base-300 md:pl-4" : "",
42
+ i ? "md:min-h-0 md:overflow-y-auto" : "",
43
+ l ? "hidden md:block" : "",
44
+ o
45
+ ].filter(Boolean).join(" "),
46
+ style: {
47
+ "--dishui-aside-w": t(e),
48
+ ...r
49
+ },
50
+ ...f,
51
+ children: m
52
+ }), v = ({ scroll: e = !1, className: a = "", children: i, ...l }) => /* @__PURE__ */ d("main", {
53
+ className: [
54
+ "dishui-page-main min-w-0 flex-1",
55
+ e ? "min-h-0 overflow-y-auto" : "",
56
+ a
57
+ ].filter(Boolean).join(" "),
58
+ ...l,
59
+ children: i
60
+ }), s = h;
61
+ s.Header = u;
62
+ s.Body = g;
63
+ s.Left = p;
64
+ s.Right = w;
65
+ s.Main = v;
66
+ export {
67
+ g as PageBody,
68
+ p as PageLeft,
69
+ v as PageMain,
70
+ w as PageRight,
71
+ s as default
72
+ };
73
+
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Page/index.tsx"],"sourcesContent":["import React from 'react';\nimport PageHeader, { PageHeaderProps } from '../PageHeader';\n\n/**\n * Page 布局脚手架\n * ----------------------------------------------------------------------------\n * 为管理后台等页面提供统一的「页头 + 主体 + 左右侧栏」骨架,配合 PageHeader、\n * StatCard 等组件使用。所有区域都是可选的,可按需组合。\n *\n * 典型结构:\n * <Page fullHeight>\n * <Page.Header title=\"用户管理\" actions={<Button>新建</Button>} />\n * <Page.Body scroll>\n * <Page.Left width={240}>筛选器</Page.Left>\n * <Page.Main scroll>主内容</Page.Main>\n * <Page.Right width={320}>详情</Page.Right>\n * </Page.Body>\n * </Page>\n */\n\nexport type PageProps = React.HTMLAttributes<HTMLDivElement> & {\n /** 是否占满父容器高度并启用内部滚动(主体区滚动,页头固定) */\n fullHeight?: boolean;\n};\n\nexport type PageBodyProps = React.HTMLAttributes<HTMLDivElement> & {\n /** 主体内的间距(left/main/right 之间),数字按 px 处理,默认 16 */\n gap?: number | string;\n /** 是否让主体区在剩余空间内滚动(配合 Page fullHeight 使用) */\n scroll?: boolean;\n};\n\nexport type PageAsideProps = React.HTMLAttributes<HTMLDivElement> & {\n /** 侧栏宽度,数字按 px 处理,默认 260 */\n width?: number | string;\n /** 是否显示分隔边框 */\n bordered?: boolean;\n /** 侧栏内部纵向滚动自适应 */\n scroll?: boolean;\n /** 小屏(<768px)下是否隐藏(侧栏通常在移动端折叠) */\n hideOnMobile?: boolean;\n};\n\nexport type PageMainProps = React.HTMLAttributes<HTMLDivElement> & {\n /** 主内容区是否在剩余空间内纵向滚动 */\n scroll?: boolean;\n};\n\nconst toCssSize = (value: number | string | undefined): string | undefined =>\n typeof value === 'number' ? `${value}px` : value;\n\nconst Page = ({ fullHeight = false, className = '', children, ...rest }: PageProps) => (\n <div\n className={[\n 'dishui-page flex w-full flex-col',\n fullHeight ? 'h-full min-h-0' : '',\n className,\n ].filter(Boolean).join(' ')}\n {...rest}\n >\n {children}\n </div>\n);\n\n/** 页头:直接复用 PageHeader,作为 Page.Header 使用 */\nconst PageHeaderSlot = (props: PageHeaderProps) => <PageHeader {...props} />;\n\nconst PageBody = ({ gap = 16, scroll = false, className = '', style, children, ...rest }: PageBodyProps) => (\n <div\n className={[\n 'dishui-page-body flex w-full flex-col md:flex-row',\n scroll ? 'min-h-0 flex-1' : '',\n className,\n ].filter(Boolean).join(' ')}\n style={{ gap: toCssSize(gap), ...style }}\n {...rest}\n >\n {children}\n </div>\n);\n\nconst PageLeft = ({\n width = 260,\n bordered = true,\n scroll = true,\n hideOnMobile = false,\n className = '',\n style,\n children,\n ...rest\n}: PageAsideProps) => (\n <aside\n className={[\n 'dishui-page-left w-full shrink-0 md:w-(--dishui-aside-w)',\n bordered ? 'md:border-r md:border-base-300 md:pr-4' : '',\n scroll ? 'md:min-h-0 md:overflow-y-auto' : '',\n hideOnMobile ? 'hidden md:block' : '',\n className,\n ].filter(Boolean).join(' ')}\n style={{ ['--dishui-aside-w' as string]: toCssSize(width), ...style }}\n {...rest}\n >\n {children}\n </aside>\n);\n\nconst PageRight = ({\n width = 320,\n bordered = true,\n scroll = true,\n hideOnMobile = false,\n className = '',\n style,\n children,\n ...rest\n}: PageAsideProps) => (\n <aside\n className={[\n 'dishui-page-right w-full shrink-0 md:w-(--dishui-aside-w)',\n bordered ? 'md:border-l md:border-base-300 md:pl-4' : '',\n scroll ? 'md:min-h-0 md:overflow-y-auto' : '',\n hideOnMobile ? 'hidden md:block' : '',\n className,\n ].filter(Boolean).join(' ')}\n style={{ ['--dishui-aside-w' as string]: toCssSize(width), ...style }}\n {...rest}\n >\n {children}\n </aside>\n);\n\nconst PageMain = ({ scroll = false, className = '', children, ...rest }: PageMainProps) => (\n <main\n className={[\n 'dishui-page-main min-w-0 flex-1',\n scroll ? 'min-h-0 overflow-y-auto' : '',\n className,\n ].filter(Boolean).join(' ')}\n {...rest}\n >\n {children}\n </main>\n);\n\ninterface PageCompound extends React.FC<PageProps> {\n Header: typeof PageHeaderSlot;\n Body: typeof PageBody;\n Left: typeof PageLeft;\n Right: typeof PageRight;\n Main: typeof PageMain;\n}\n\nconst PageWithCompounds = Page as PageCompound;\nPageWithCompounds.Header = PageHeaderSlot;\nPageWithCompounds.Body = PageBody;\nPageWithCompounds.Left = PageLeft;\nPageWithCompounds.Right = PageRight;\nPageWithCompounds.Main = PageMain;\n\nexport { PageBody, PageLeft, PageRight, PageMain };\nexport default PageWithCompounds;\n"],"mappings":";;;AAgDA,IAAM,IAAA,CAAa,MACf,OAAO,KAAU,WAAW,GAAG,CAAA,OAAY,GAEzC,IAAA,CAAQ,EAAE,YAAA,IAAa,IAAO,WAAA,IAAY,IAAI,UAAA,GAAU,GAAG,EAAA,MAC7D,gBAAA,EAAC,OAAD;AAAA,EACI,WAAW;AAAA,IACP;AAAA,IACA,IAAa,mBAAmB;AAAA,IAChC;AAAA,EACJ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,EAC1B,GAAI;AAAA,EAEH,UAAA;AACA,CAAA,GAIH,IAAA,CAAkB,MAA2B,gBAAA,EAAC,GAAD,EAAY,GAAI,EAAQ,CAAA,GAErE,IAAA,CAAY,EAAE,KAAA,IAAM,IAAI,QAAA,IAAS,IAAO,WAAA,IAAY,IAAI,OAAA,GAAO,UAAA,GAAU,GAAG,EAAA,MAC9E,gBAAA,EAAC,OAAD;AAAA,EACI,WAAW;AAAA,IACP;AAAA,IACA,IAAS,mBAAmB;AAAA,IAC5B;AAAA,EACJ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,EAC1B,OAAO;AAAA,IAAE,KAAK,EAAU,CAAG;AAAA,IAAG,GAAG;AAAA,EAAM;AAAA,EACvC,GAAI;AAAA,EAEH,UAAA;AACA,CAAA,GAGH,IAAA,CAAY,EACd,OAAA,IAAQ,KACR,UAAA,IAAW,IACX,QAAA,IAAS,IACT,cAAA,IAAe,IACf,WAAA,IAAY,IACZ,OAAA,GACA,UAAA,GACA,GAAG,EAAA,MAEH,gBAAA,EAAC,SAAD;AAAA,EACI,WAAW;AAAA,IACP;AAAA,IACA,IAAW,2CAA2C;AAAA,IACtD,IAAS,kCAAkC;AAAA,IAC3C,IAAe,oBAAoB;AAAA,IACnC;AAAA,EACJ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,EAC1B,OAAO;AAAA,IAAG,oBAA+B,EAAU,CAAK;AAAA,IAAG,GAAG;AAAA,EAAM;AAAA,EACpE,GAAI;AAAA,EAEH,UAAA;AACE,CAAA,GAGL,IAAA,CAAa,EACf,OAAA,IAAQ,KACR,UAAA,IAAW,IACX,QAAA,IAAS,IACT,cAAA,IAAe,IACf,WAAA,IAAY,IACZ,OAAA,GACA,UAAA,GACA,GAAG,EAAA,MAEH,gBAAA,EAAC,SAAD;AAAA,EACI,WAAW;AAAA,IACP;AAAA,IACA,IAAW,2CAA2C;AAAA,IACtD,IAAS,kCAAkC;AAAA,IAC3C,IAAe,oBAAoB;AAAA,IACnC;AAAA,EACJ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,EAC1B,OAAO;AAAA,IAAG,oBAA+B,EAAU,CAAK;AAAA,IAAG,GAAG;AAAA,EAAM;AAAA,EACpE,GAAI;AAAA,EAEH,UAAA;AACE,CAAA,GAGL,IAAA,CAAY,EAAE,QAAA,IAAS,IAAO,WAAA,IAAY,IAAI,UAAA,GAAU,GAAG,EAAA,MAC7D,gBAAA,EAAC,QAAD;AAAA,EACI,WAAW;AAAA,IACP;AAAA,IACA,IAAS,4BAA4B;AAAA,IACrC;AAAA,EACJ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,EAC1B,GAAI;AAAA,EAEH,UAAA;AACC,CAAA,GAWJ,IAAoB;AAC1B,EAAkB,SAAS;AAC3B,EAAkB,OAAO;AACzB,EAAkB,OAAO;AACzB,EAAkB,QAAQ;AAC1B,EAAkB,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/PageHeader/index.tsx"],"sourcesContent":["import React from 'react';\n\nexport type PageHeaderProps = {\n /** 页面标题 */\n title: React.ReactNode;\n /** 标题下方的描述文字 */\n description?: React.ReactNode;\n /** 标题左侧的图标(通常为 lucide 图标) */\n icon?: React.ReactNode;\n /** 右侧操作区(按钮组等) */\n actions?: React.ReactNode;\n /** 紧凑模式:标题与间距更小 */\n compact?: boolean;\n className?: string;\n};\n\n/**\n * 页面头部:统一管理后台等页面的标题 / 描述 / 操作区排版。\n * 相比页面内手写的 `text-3xl` 标题,默认字号更精致(text-lg)。\n */\nconst PageHeader = ({\n title,\n description,\n icon,\n actions,\n compact = true,\n className = '',\n}: PageHeaderProps) => {\n const titleSize = compact ? 'text-lg' : 'text-2xl';\n const iconSize = compact ? '[&>svg]:h-5 [&>svg]:w-5' : '[&>svg]:h-6 [&>svg]:w-6';\n const spacing = compact ? 'mb-5' : 'mb-8';\n\n return (\n <div className={`flex flex-wrap items-start justify-between gap-3 ${spacing} ${className}`.trim()}>\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2.5\">\n {icon && (\n <span className={`shrink-0 text-primary ${iconSize}`}>{icon}</span>\n )}\n <h1 className={`truncate font-bold text-base-content ${titleSize}`}>{title}</h1>\n </div>\n {description && (\n <p className=\"mt-0.5 text-xs text-base-content/60\">{description}</p>\n )}\n </div>\n {actions && <div className=\"flex shrink-0 items-center gap-2\">{actions}</div>}\n </div>\n );\n};\n\nexport default PageHeader;\n"],"mappings":";;AAoBA,IAAM,IAAA,CAAc,EAChB,OAAA,GACA,aAAA,GACA,MAAA,GACA,SAAA,GACA,SAAA,IAAU,IACV,WAAA,IAAY,GAAA,MACO;AACnB,QAAM,IAAY,IAAU,YAAY,YAClC,IAAW,IAAU,4BAA4B;AAGvD,SACI,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,oDAHJ,IAAU,SAAS,MAAA,IAGgD,CAAA,GAAY,KAAK;AAAA,cAAhG,CACI,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAf,CACI,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,kBAAf,CACK,KACG,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,yBAAyB,CAAA;AAAA,oBAAa;AAAA,QAAW,CAAA,GAEtE,gBAAA,EAAC,MAAD;AAAA,UAAI,WAAW,wCAAwC,CAAA;AAAA,oBAAc;AAAA,QAAU,CAAA,CAC9E;AAAA,UACJ,KACG,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAU;AAAA,kBAAuC;AAAA,MAAe,CAAA,CAEtE;AAAA,QACJ,KAAW,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,gBAAoC;AAAA,IAAa,CAAA,CAC3E;AAAA;AAEb"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/PageHeader/index.tsx"],"sourcesContent":["import React from 'react';\n\nexport type PageHeaderProps = {\n /** 页面标题 */\n title: React.ReactNode;\n /** 标题下方的描述文字 */\n description?: React.ReactNode;\n /** 标题左侧的图标(通常为 lucide 图标) */\n icon?: React.ReactNode;\n /** 右侧操作区(按钮组等) */\n actions?: React.ReactNode;\n /** 紧凑模式:标题与间距更小 */\n compact?: boolean;\n className?: string;\n};\n\n/**\n * 页面头部:统一管理后台等页面的标题 / 描述 / 操作区排版。\n * 相比页面内手写的 `text-3xl` 标题,默认字号更精致(text-lg)。\n */\nconst PageHeader = ({\n title,\n description,\n icon,\n actions,\n compact = true,\n className = '',\n}: PageHeaderProps) => {\n const titleSize = compact ? 'text-lg' : 'text-2xl';\n const iconSize = compact ? '[&>svg]:h-5 [&>svg]:w-5' : '[&>svg]:h-6 [&>svg]:w-6';\n const spacing = compact ? 'mb-5' : 'mb-8';\n\n return (\n <div className={`flex flex-wrap items-start justify-between gap-3 ${spacing} ${className}`.trim()}>\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2.5\">\n {icon && (\n <span className={`shrink-0 text-primary ${iconSize}`}>{icon}</span>\n )}\n <h1 className={`truncate font-bold text-base-content ${titleSize}`}>{title}</h1>\n </div>\n {description && (\n <p className=\"mt-0.5 text-xs text-base-content/60\">{description}</p>\n )}\n </div>\n {actions && <div className=\"flex shrink-0 items-center gap-2\">{actions}</div>}\n </div>\n );\n};\n\nexport default PageHeader;\n"],"mappings":";;AAoBA,IAAM,IAAA,CAAc,EAChB,OAAA,GACA,aAAA,GACA,MAAA,GACA,SAAA,GACA,SAAA,IAAU,IACV,WAAA,IAAY,GAAA,MACO;AACnB,QAAM,IAAY,IAAU,YAAY,YAClC,IAAW,IAAU,4BAA4B;AAGvD,SACI,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,oDAHJ,IAAU,SAAS,MAAA,IAGgD,CAAA,GAAY,KAAK;AAAA,IAAhG,UAAA,CACI,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,MAAf,UAAA,CACI,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,QAAf,UAAA,CACK,KACG,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,yBAAyB,CAAA;AAAA,UAAa,UAAA;AAAA,QAAW,CAAA,GAEtE,gBAAA,EAAC,MAAD;AAAA,UAAI,WAAW,wCAAwC,CAAA;AAAA,UAAc,UAAA;AAAA,QAAU,CAAA,CAC9E;AAAA,MACJ,CAAA,GAAA,KACG,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAU;AAAA,QAAuC,UAAA;AAAA,MAAe,CAAA,CAEtE;AAAA,IACJ,CAAA,GAAA,KAAW,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,MAAoC,UAAA;AAAA,IAAa,CAAA,CAC3E;AAAA;AAEb"}
@@ -86,9 +86,6 @@ var Y = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
86
86
  break;
87
87
  case "Escape":
88
88
  u(!1);
89
- break;
90
- default:
91
- break;
92
89
  }
93
90
  };
94
91
  return document.addEventListener("keydown", e), () => {
@@ -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 // Tracks a touch/pen press on an option so a tap selects while a drag scrolls.\n // (pointerdown on touch must NOT preventDefault — that blocks native scrolling.)\n const touchPressRef = useRef<{ pointerId: number; x: number; y: number } | null>(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 // Mouse: select immediately on press (existing desktop behavior).\n // Touch/pen: only record the press — selection happens on pointerup if the\n // gesture turned out to be a tap rather than a scroll. preventDefault() on a\n // touch pointerdown suppresses the browser's native pan gesture, which made\n // long dropdowns impossible to scroll on mobile (and every scroll attempt\n // selected an option instead).\n const handleOptionPointerDown = (event: React.PointerEvent<HTMLLIElement>, option: Option) => {\n if (event.pointerType === 'mouse') {\n event.preventDefault();\n event.stopPropagation();\n handleOptionClick(option);\n return;\n }\n event.stopPropagation();\n touchPressRef.current = { pointerId: event.pointerId, x: event.clientX, y: event.clientY };\n };\n\n const handleOptionPointerUp = (event: React.PointerEvent<HTMLLIElement>, option: Option) => {\n const press = touchPressRef.current;\n touchPressRef.current = null;\n if (!press || event.pointerId !== press.pointerId) return;\n // Select only if the finger did not move much — otherwise it was a scroll.\n const moved = Math.hypot(event.clientX - press.x, event.clientY - press.y);\n if (moved < 10) {\n event.stopPropagation();\n handleOptionClick(option);\n }\n };\n\n const handleOptionPointerCancel = () => {\n touchPressRef.current = null;\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, touchAction: 'pan-y' }}\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) => handleOptionPointerDown(event, option)}\n onPointerUp={(event) => handleOptionPointerUp(event, option)}\n onPointerCancel={handleOptionPointerCancel}\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 // Tracks a touch/pen press on an option so a tap selects while a drag scrolls.\n // (pointerdown on touch must NOT preventDefault — that blocks native scrolling.)\n const touchPressRef = useRef<{ pointerId: number; x: number; y: number } | null>(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 // Mouse: select immediately on press (existing desktop behavior).\n // Touch/pen: only record the press — selection happens on pointerup if the\n // gesture turned out to be a tap rather than a scroll. preventDefault() on a\n // touch pointerdown suppresses the browser's native pan gesture, which made\n // long dropdowns impossible to scroll on mobile (and every scroll attempt\n // selected an option instead).\n const handleOptionPointerDown = (event: React.PointerEvent<HTMLLIElement>, option: Option) => {\n if (event.pointerType === 'mouse') {\n event.preventDefault();\n event.stopPropagation();\n handleOptionClick(option);\n return;\n }\n event.stopPropagation();\n touchPressRef.current = { pointerId: event.pointerId, x: event.clientX, y: event.clientY };\n };\n\n const handleOptionPointerUp = (event: React.PointerEvent<HTMLLIElement>, option: Option) => {\n const press = touchPressRef.current;\n touchPressRef.current = null;\n if (!press || event.pointerId !== press.pointerId) return;\n // Select only if the finger did not move much — otherwise it was a scroll.\n const moved = Math.hypot(event.clientX - press.x, event.clientY - press.y);\n if (moved < 10) {\n event.stopPropagation();\n handleOptionClick(option);\n }\n };\n\n const handleOptionPointerCancel = () => {\n touchPressRef.current = null;\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, touchAction: 'pan-y' }}\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) => handleOptionPointerDown(event, option)}\n onPointerUp={(event) => handleOptionPointerUp(event, option)}\n onPointerCancel={handleOptionPointerCancel}\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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"}