@fangxinyan/lumina 0.6.6 → 0.6.8

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 (231) hide show
  1. package/dist/Alert.cjs +3 -3
  2. package/dist/Alert.js +2 -2
  3. package/dist/AppShell.cjs +5 -5
  4. package/dist/AppShell.js +1 -1
  5. package/dist/AutoComplete.cjs +5 -5
  6. package/dist/AutoComplete.js +4 -4
  7. package/dist/Avatar.cjs +2 -2
  8. package/dist/Avatar.js +1 -1
  9. package/dist/Badge.cjs +2 -2
  10. package/dist/Badge.js +1 -1
  11. package/dist/Button.cjs +7 -3
  12. package/dist/Button.d.cts +13 -1
  13. package/dist/Button.d.ts +13 -1
  14. package/dist/Button.js +2 -2
  15. package/dist/Calendar.cjs +3 -3
  16. package/dist/Calendar.js +2 -2
  17. package/dist/{Card-MA6SV7D5.css → Card-M6UMBDD2.css} +41 -1
  18. package/dist/Card.cjs +3 -2
  19. package/dist/Card.d.cts +18 -0
  20. package/dist/Card.d.ts +18 -0
  21. package/dist/Card.js +2 -1
  22. package/dist/Cascader.cjs +5 -5
  23. package/dist/Cascader.js +4 -4
  24. package/dist/Checkbox.cjs +3 -3
  25. package/dist/Checkbox.js +2 -2
  26. package/dist/Collapse.cjs +3 -3
  27. package/dist/Collapse.js +2 -2
  28. package/dist/ColorPicker.cjs +2 -2
  29. package/dist/ColorPicker.js +1 -1
  30. package/dist/CommandPalette.cjs +5 -5
  31. package/dist/CommandPalette.js +4 -4
  32. package/dist/ContextMenu.cjs +2 -2
  33. package/dist/ContextMenu.js +1 -1
  34. package/dist/Divider.cjs +2 -2
  35. package/dist/Divider.js +1 -1
  36. package/dist/Drawer.cjs +3 -3
  37. package/dist/Drawer.js +2 -2
  38. package/dist/Empty.cjs +2 -2
  39. package/dist/Empty.js +1 -1
  40. package/dist/Form.cjs +4 -4
  41. package/dist/Form.js +1 -1
  42. package/dist/Icon.cjs +49 -49
  43. package/dist/Icon.js +1 -1
  44. package/dist/Image.cjs +6 -6
  45. package/dist/Image.js +2 -2
  46. package/dist/Input.cjs +5 -5
  47. package/dist/Input.js +3 -3
  48. package/dist/InputNumber.cjs +5 -5
  49. package/dist/InputNumber.js +4 -4
  50. package/dist/List.cjs +2 -2
  51. package/dist/List.js +1 -1
  52. package/dist/Message.cjs +6 -6
  53. package/dist/Message.js +2 -2
  54. package/dist/Modal.cjs +4 -4
  55. package/dist/Modal.d.cts +12 -0
  56. package/dist/Modal.d.ts +12 -0
  57. package/dist/Modal.js +3 -3
  58. package/dist/Pagination.cjs +7 -7
  59. package/dist/Pagination.js +6 -6
  60. package/dist/Popover.cjs +2 -2
  61. package/dist/Popover.js +1 -1
  62. package/dist/Progress.cjs +2 -2
  63. package/dist/Progress.js +1 -1
  64. package/dist/Radio.cjs +3 -3
  65. package/dist/Radio.js +1 -1
  66. package/dist/Select.cjs +6 -6
  67. package/dist/Select.js +5 -5
  68. package/dist/Skeleton.cjs +2 -2
  69. package/dist/Skeleton.js +1 -1
  70. package/dist/Slider.cjs +2 -2
  71. package/dist/Slider.js +1 -1
  72. package/dist/Spin.cjs +2 -2
  73. package/dist/Spin.js +1 -1
  74. package/dist/Splitter.cjs +2 -2
  75. package/dist/Splitter.js +1 -1
  76. package/dist/StatusBar.cjs +3 -3
  77. package/dist/StatusBar.js +1 -1
  78. package/dist/Surface.cjs +4 -4
  79. package/dist/Surface.js +2 -2
  80. package/dist/Switch.cjs +2 -2
  81. package/dist/Switch.js +1 -1
  82. package/dist/Table.cjs +9 -9
  83. package/dist/Table.js +8 -8
  84. package/dist/TablePro.cjs +10 -10
  85. package/dist/TablePro.d.cts +11 -7
  86. package/dist/TablePro.d.ts +11 -7
  87. package/dist/TablePro.js +9 -9
  88. package/dist/Tabs.cjs +2 -2
  89. package/dist/Tabs.js +1 -1
  90. package/dist/Tag.cjs +3 -3
  91. package/dist/Tag.js +2 -2
  92. package/dist/Textarea.cjs +4 -4
  93. package/dist/Textarea.js +2 -2
  94. package/dist/Theme.cjs +11 -11
  95. package/dist/Theme.js +1 -1
  96. package/dist/{ThemePanel-76LB3YA5.css → ThemePanel-TEHB2JCQ.css} +68 -0
  97. package/dist/ThemePanel.cjs +13 -13
  98. package/dist/ThemePanel.d.cts +12 -2
  99. package/dist/ThemePanel.d.ts +12 -2
  100. package/dist/ThemePanel.js +10 -10
  101. package/dist/{Timeline-ZIM7QFQC.css → Timeline-CRFZ3I2W.css} +4 -1
  102. package/dist/Timeline.cjs +3 -3
  103. package/dist/Timeline.d.cts +38 -0
  104. package/dist/Timeline.d.ts +38 -0
  105. package/dist/Timeline.js +2 -2
  106. package/dist/Tooltip.cjs +2 -2
  107. package/dist/Tooltip.js +1 -1
  108. package/dist/Typography.cjs +7 -7
  109. package/dist/Typography.js +2 -2
  110. package/dist/{chunk-MOMLQP7B.cjs → chunk-2EY34PPA.cjs} +1 -1
  111. package/dist/{chunk-IHK2FRTS.cjs → chunk-2LM5UYNU.cjs} +1 -1
  112. package/dist/{chunk-Y5F7ZTBH.js → chunk-3GJZRYTD.js} +1 -1
  113. package/dist/{chunk-D5PCIVID.cjs → chunk-3HPHQV2L.cjs} +3 -3
  114. package/dist/{chunk-DYHNOYRC.cjs → chunk-3NSBPQBT.cjs} +6 -6
  115. package/dist/{chunk-LI4XJTEA.js → chunk-3VXBSLPT.js} +3 -3
  116. package/dist/{chunk-YVTLHTG6.js → chunk-44WHEN76.js} +1 -1
  117. package/dist/{chunk-NT6CJYI3.cjs → chunk-4LOOWTRX.cjs} +4 -4
  118. package/dist/{chunk-U2H4DRMV.cjs → chunk-4N64ZL5M.cjs} +1 -1
  119. package/dist/{chunk-6XVLERA3.cjs → chunk-5C3ZSOKF.cjs} +1 -1
  120. package/dist/{chunk-2ZFJTMEF.js → chunk-5CWTC3I2.js} +3 -3
  121. package/dist/{chunk-ZPKHGKVL.cjs → chunk-5KGGB3EH.cjs} +3 -3
  122. package/dist/{chunk-W5CJC7S7.js → chunk-62RPBEAW.js} +2 -2
  123. package/dist/{chunk-NE7IUGMK.js → chunk-64ZQHLHL.js} +2 -2
  124. package/dist/{chunk-YJEXAO2I.js → chunk-6VSNO7IH.js} +1 -1
  125. package/dist/{chunk-3YP7CBJT.js → chunk-762NV3E4.js} +2 -2
  126. package/dist/{chunk-SYWTT5TY.cjs → chunk-76OH42CM.cjs} +4 -4
  127. package/dist/{chunk-56PHETWO.js → chunk-7DNK5JB2.js} +2 -2
  128. package/dist/chunk-7IWYBQAE.js +151 -0
  129. package/dist/{chunk-VAXWWJJP.cjs → chunk-7OYMY22O.cjs} +8 -8
  130. package/dist/{chunk-L27C5O4W.cjs → chunk-7UCXY4T5.cjs} +3 -3
  131. package/dist/{chunk-7NZ2A4MA.js → chunk-7ZCTEIOW.js} +1 -1
  132. package/dist/{chunk-QY76WTO5.cjs → chunk-AA2FRQUQ.cjs} +8 -8
  133. package/dist/{chunk-SABWUELE.js → chunk-ACZA7HHP.js} +1 -1
  134. package/dist/{chunk-GZCU6HXD.js → chunk-AHS2AFTD.js} +1 -1
  135. package/dist/{chunk-YSCIMHOI.cjs → chunk-AYZ4BWHG.cjs} +4 -4
  136. package/dist/{chunk-WEJKY3DF.js → chunk-BKI7JY4Z.js} +24 -5
  137. package/dist/{chunk-NFXHIO3G.js → chunk-BY2YW5XN.js} +1 -1
  138. package/dist/{chunk-OGPDCBPD.cjs → chunk-CPBFUKSX.cjs} +11 -11
  139. package/dist/{chunk-R74TZKJS.cjs → chunk-D56CNYUP.cjs} +3 -3
  140. package/dist/{chunk-4UKM4KAC.cjs → chunk-DDCAHAAE.cjs} +1 -1
  141. package/dist/{chunk-N2COYOXE.cjs → chunk-DGB6KVU3.cjs} +1 -1
  142. package/dist/{chunk-PNZJFLMY.js → chunk-EXN64ADJ.js} +2 -2
  143. package/dist/{chunk-LFTCK2VM.cjs → chunk-F3DN2JGE.cjs} +489 -238
  144. package/dist/{chunk-IDJCFYPP.cjs → chunk-F65KYGPX.cjs} +14 -14
  145. package/dist/{chunk-RIUDYPRB.cjs → chunk-FJHFUES7.cjs} +1 -1
  146. package/dist/{chunk-66GXZQKL.cjs → chunk-FL25IGIG.cjs} +3 -3
  147. package/dist/{chunk-REMJWNAT.js → chunk-FPII6I52.js} +3 -3
  148. package/dist/{chunk-YSXD344H.js → chunk-FZITSOKH.js} +4 -4
  149. package/dist/{chunk-2NT5QKEX.js → chunk-GEANNF4T.js} +2 -2
  150. package/dist/{chunk-6LARTGLP.cjs → chunk-GJAEGIPM.cjs} +1 -1
  151. package/dist/chunk-GT34KAMX.cjs +173 -0
  152. package/dist/{chunk-TVUBGXWA.js → chunk-GVPGJXZT.js} +1 -1
  153. package/dist/{chunk-6GQPF3EI.cjs → chunk-HFM4YKM5.cjs} +1 -1
  154. package/dist/{chunk-2SCXQ7QS.js → chunk-HR5QBBIS.js} +1 -1
  155. package/dist/{chunk-ACQSRMLF.cjs → chunk-HTW62OMX.cjs} +4 -4
  156. package/dist/{chunk-VNNQYJLT.js → chunk-I5XCHN67.js} +2 -2
  157. package/dist/{chunk-N3OLFKV5.cjs → chunk-IMAGOTLP.cjs} +1 -1
  158. package/dist/{chunk-Z4PZ2ZHI.cjs → chunk-J2R3BEEH.cjs} +1 -1
  159. package/dist/{chunk-PEJLXJQD.js → chunk-JPAYPF6H.js} +1 -1
  160. package/dist/{chunk-YNCDTKAE.cjs → chunk-JWZ6HJIF.cjs} +1 -1
  161. package/dist/{chunk-S6OKX4H7.cjs → chunk-KOY7GNP3.cjs} +1 -1
  162. package/dist/{chunk-NDO22RER.cjs → chunk-LF3ATJFY.cjs} +1 -1
  163. package/dist/{chunk-5NFSDFBB.cjs → chunk-LW6Z2WDZ.cjs} +3 -3
  164. package/dist/{chunk-YUKXNWVE.cjs → chunk-MLOT2AGK.cjs} +1 -1
  165. package/dist/{chunk-7D76MI37.js → chunk-MOLKLUSQ.js} +4 -4
  166. package/dist/{chunk-SG42F5VB.cjs → chunk-MZCKPLHQ.cjs} +1 -1
  167. package/dist/chunk-N24KHD5B.js +84 -0
  168. package/dist/{chunk-C24W6PTJ.cjs → chunk-N4JH6HHA.cjs} +1 -1
  169. package/dist/{chunk-5JNDDWFZ.js → chunk-NUF3EA7T.js} +2 -2
  170. package/dist/chunk-NUNPFMCM.cjs +106 -0
  171. package/dist/{chunk-AJH2O4WC.js → chunk-OVTB7FQQ.js} +2 -2
  172. package/dist/{chunk-HFUHQUPQ.js → chunk-P434GBHP.js} +1 -1
  173. package/dist/{chunk-66T76GII.cjs → chunk-PEFIXNAV.cjs} +6 -6
  174. package/dist/{chunk-WXWFMWWF.js → chunk-PHONNUK2.js} +2 -2
  175. package/dist/{chunk-MYRLCN6V.js → chunk-PWPL3DRN.js} +1 -1
  176. package/dist/{chunk-HU7T64Y3.js → chunk-Q5KHJ32P.js} +1 -1
  177. package/dist/{chunk-OHFZ7L4T.js → chunk-Q77BWQNG.js} +1 -1
  178. package/dist/{chunk-XVP7IKLZ.js → chunk-QDXBI3PV.js} +3 -3
  179. package/dist/{chunk-PKHITACT.js → chunk-QKWRN2JL.js} +1 -1
  180. package/dist/{chunk-7ZNGHWVS.js → chunk-R53WIZY5.js} +1 -1
  181. package/dist/{chunk-LQLOOUS3.js → chunk-RYRBNMCC.js} +1 -1
  182. package/dist/{chunk-2ZADGBUN.cjs → chunk-S4CZ3VO6.cjs} +9 -4
  183. package/dist/{chunk-OHIFKN4E.js → chunk-SGNDIRZC.js} +17 -4
  184. package/dist/{chunk-YT5NLCRC.js → chunk-SNX4FZYB.js} +1 -1
  185. package/dist/{chunk-CBKJXKVI.cjs → chunk-TDYJ5ECR.cjs} +24 -5
  186. package/dist/{chunk-KMG7OMOS.js → chunk-TJB7U72Z.js} +1 -1
  187. package/dist/{chunk-SFAGHPBT.js → chunk-TWJAYAK2.js} +1 -1
  188. package/dist/{chunk-JFQ53MO4.cjs → chunk-VM6CJYP6.cjs} +1 -1
  189. package/dist/{chunk-CNGKJYGZ.js → chunk-VRA4CQCJ.js} +7 -3
  190. package/dist/{chunk-YU5JK247.cjs → chunk-VUTCNATX.cjs} +6 -6
  191. package/dist/{chunk-CEZ2DR4R.js → chunk-W72IIGOV.js} +2 -2
  192. package/dist/{chunk-QP7RXZES.js → chunk-WIBAYFBB.js} +1 -1
  193. package/dist/{chunk-O43DOE7V.js → chunk-WIZVOZNO.js} +2 -2
  194. package/dist/{chunk-SQIWPU6V.js → chunk-XN52S7PT.js} +1 -1
  195. package/dist/{chunk-O4BOBOYV.cjs → chunk-XOYMBL5R.cjs} +1 -1
  196. package/dist/{chunk-MYHBC3HA.cjs → chunk-XPV672EI.cjs} +1 -1
  197. package/dist/{chunk-DYSGXQUK.cjs → chunk-XVDD6JEU.cjs} +6 -6
  198. package/dist/{chunk-ZWCDB5PP.cjs → chunk-XWRQ7ZLT.cjs} +1 -1
  199. package/dist/{chunk-N2BTMKF2.cjs → chunk-Z35Q432P.cjs} +4 -4
  200. package/dist/{chunk-VSUMJX6Z.cjs → chunk-ZC5VDX4W.cjs} +1 -1
  201. package/dist/{chunk-ZPP7LTHP.js → chunk-ZCMFLRZS.js} +2 -2
  202. package/dist/{chunk-GBKUGKIY.cjs → chunk-ZGDAYWWC.cjs} +24 -11
  203. package/dist/{chunk-NJCHFXGC.js → chunk-ZTIECMCF.js} +455 -204
  204. package/dist/index.cjs +180 -176
  205. package/dist/index.d.cts +3 -3
  206. package/dist/index.d.ts +3 -3
  207. package/dist/index.js +48 -48
  208. package/dist/styles.css +118 -1
  209. package/dist/{tokens-EF34LSWI.css → tokens-RGFJKRC7.css} +21 -0
  210. package/dist/tokens.css +21 -0
  211. package/docs/llms/autocomplete.md +6 -0
  212. package/docs/llms/button.md +16 -4
  213. package/docs/llms/card.md +32 -0
  214. package/docs/llms/commandpalette.md +6 -0
  215. package/docs/llms/contextmenu.md +6 -0
  216. package/docs/llms/form.md +6 -0
  217. package/docs/llms/inputnumber.md +6 -0
  218. package/docs/llms/modal.md +19 -0
  219. package/docs/llms/splitter.md +6 -0
  220. package/docs/llms/statusbar.md +6 -0
  221. package/docs/llms/tablepro.md +2 -0
  222. package/docs/llms/textarea.md +83 -0
  223. package/docs/llms/themepanel.md +26 -5
  224. package/docs/llms/timeline.md +35 -0
  225. package/docs/llms/typography.md +1 -1
  226. package/docs/llms.md +2 -1
  227. package/package.json +51 -1
  228. package/dist/chunk-BJ6WUVEG.cjs +0 -106
  229. package/dist/chunk-D64IPDUE.cjs +0 -28
  230. package/dist/chunk-GUZ2DNDC.js +0 -26
  231. package/dist/chunk-OQU3TJCF.js +0 -84
@@ -0,0 +1,83 @@
1
+ # Textarea 多行输入
2
+
3
+ > 多行文本输入域,支持清除、字数统计、错误态和原生 textarea 属性。
4
+
5
+ ## 导入
6
+
7
+ ```tsx
8
+ import { Textarea, TextArea, Input } from "@fangxinyan/lumina";
9
+ ```
10
+
11
+ ## 示例
12
+
13
+ ### 基础用法
14
+
15
+ Textarea 直接暴露原生 textarea ref 和常用原生属性。
16
+
17
+ ```tsx
18
+ const [notes, setNotes] = useState("");
19
+
20
+ <Textarea
21
+ value={notes}
22
+ onValueChange={setNotes}
23
+ rows={4}
24
+ placeholder="写点什么..."
25
+ />
26
+ ```
27
+
28
+ ### 可清除与字数统计
29
+
30
+ allowClear、maxLength、showCount 可组合使用,适合受限文本输入。
31
+
32
+ ```tsx
33
+ <Textarea
34
+ value={feedback}
35
+ onValueChange={setFeedback}
36
+ allowClear
37
+ maxLength={160}
38
+ showCount
39
+ placeholder="最多输入 160 个字"
40
+ />
41
+ ```
42
+
43
+ ### 错误与禁用
44
+
45
+ invalid 只负责视觉状态;错误文案通常交给 Field 或 Form.Item 展示。
46
+
47
+ ```tsx
48
+ <Textarea invalid defaultValue="太短" />
49
+ <Textarea disabled defaultValue="只读说明..." />
50
+ ```
51
+
52
+ ### Input.TextArea 别名
53
+
54
+ 当表单统一从 Input 命名空间取控件时,Input.TextArea 与 Textarea 等价。
55
+
56
+ ```tsx
57
+ <Input.TextArea
58
+ defaultValue="Input.TextArea 与 Textarea 使用同一套能力"
59
+ allowClear
60
+ showCount
61
+ />
62
+ ```
63
+
64
+ ## API
65
+
66
+ **Textarea / TextArea / Input.TextArea**
67
+
68
+ | Prop | 类型 | 默认 | 说明 |
69
+ | --- | --- | --- | --- |
70
+ | value / defaultValue | `string` | — | 受控值 / 初值 |
71
+ | onChange | `(event) => void` | — | 变更回调,传入 React 原生事件 |
72
+ | onValueChange | `(value: string, event) => void` | — | 值回调便捷写法 |
73
+ | allowClear | `boolean` | `false` | 右上角显示清除按钮 |
74
+ | maxLength | `number` | — | 最大字符数,透传至原生 textarea |
75
+ | showCount | `boolean` | `false` | 显示字数统计;有 maxLength 时显示 N / max |
76
+ | invalid | `boolean` | `false` | 错误态 |
77
+ | disabled | `boolean` | `false` | 禁用 |
78
+ | rows | `number` | — | 文本域可见行数,透传至原生 textarea |
79
+ | className / style / id / data-* / aria-* | `native attrs` | — | 透传至原生 textarea |
80
+
81
+
82
+ ---
83
+ [← 回到索引](../llms.md)
@@ -12,7 +12,7 @@ import { ThemeProvider, ThemePanel, THEME_PANEL_DEFAULT_PRESET_OPTIONS, THEME_PA
12
12
 
13
13
  ### 完整面板
14
14
 
15
- 默认包含浅色、深色、瓷白、助手、助手暗五个主题卡片,并提供简洁/深度两档新建主题入口;其余控制项直接驱动 useTheme。
15
+ 默认包含浅色、深色、瓷白、助手、助手暗五个主题卡片,并提供简洁/深度两档新建主题入口;高级调整区可编辑当前主题的 token、palette 和自定义字体,默认主题另存时可填写新主题名和副标题,非默认主题可直接改名、修改副标题后保存。
16
16
 
17
17
  ```tsx
18
18
  <ThemeProvider>
@@ -22,7 +22,7 @@ import { ThemeProvider, ThemePanel, THEME_PANEL_DEFAULT_PRESET_OPTIONS, THEME_PA
22
22
 
23
23
  ### 外部保存与回灌
24
24
 
25
- onCreateTheme / onDeleteTheme 会把新建和删除事件交给业务侧;业务侧保存后通过 ThemeProvider themes 回灌。
25
+ onCreateTheme / onUpdateTheme / onDeleteTheme 会把新建、另存为、更新和删除事件交给业务侧;主题名和卡片第二行副标题会分别通过 payload.label / payload.description 传出,业务侧保存后通过 ThemeProvider themes 回灌。
26
26
 
27
27
  ```tsx
28
28
  import { ThemeProvider, ThemePanel, type ThemePresets } from "lumina";
@@ -45,6 +45,13 @@ const [themes, setThemes] = React.useState<ThemePresets>({});
45
45
  });
46
46
  deleteThemeFromServerOrStorage(payload);
47
47
  }}
48
+ onUpdateTheme={(payload) => {
49
+ setThemes((current) => ({
50
+ ...current,
51
+ [String(payload.key)]: payload.preset,
52
+ }));
53
+ saveThemeToServerOrStorage(payload);
54
+ }}
48
55
  />
49
56
  </ThemeProvider>
50
57
  ```
@@ -71,16 +78,18 @@ const [themes, setThemes] = React.useState<ThemePresets>({});
71
78
  | --- | --- | --- | --- |
72
79
  | title | `ReactNode` | `"主题"` | 面板标题;传 null 可隐藏标题文本 |
73
80
  | description | `ReactNode` | `"快速调整当前 Lumina 主题"` | 面板副标题 |
74
- | sections | `ThemePanelSection[]` | — | 展示的控制区及顺序;shadow 区同时控制 intensity / shadow-scale / shadow-float-scale |
81
+ | sections | `ThemePanelSection[]` | — | 展示的控制区及顺序;advanced 区提供完整 token / palette 编辑,shadow 区同时控制 intensity / shadow-scale / shadow-float-scale |
75
82
  | modeOptions | `ThemePanelModeOption[]` | — | 模式切换项 |
76
83
  | presetOptions | `ThemePanelPresetOption[]` | — | 命名主题预设卡片;不传时使用浅色/深色/瓷白/助手/助手暗 + theme.themes,也可完全由业务侧控制 |
77
84
  | defaultCustomAccent | `string` | `"#845ef7"` | 自定义强调色初始值 |
78
85
  | allowCreateTheme | `boolean` | `true` | 在预设区显示新建主题流程 |
79
86
  | defaultCreateThemeName | `string` | `"我的主题"` | 新建主题的默认名称 |
80
87
  | createThemeKeyPrefix | `string` | `"user"` | 生成自建主题 mode key 时使用的前缀 |
81
- | onCreateTheme | `(payload: ThemePanelCreateThemePayload) => void` | — | 保存自建主题后的回调,业务侧可把 payload.preset 存起来并通过 ThemeProvider themes 回灌 |
88
+ | onCreateTheme | `(payload: ThemePanelCreateThemePayload) => void` | — | 保存自建主题或高级区命名另存为后的回调;主题名和副标题通过 payload.label / payload.description 传出,业务侧可把 payload.preset 存起来并通过 ThemeProvider themes 回灌 |
82
89
  | allowDeleteTheme | `boolean` | `true` | 为非默认主题显示删除按钮;默认主题不会显示删除入口 |
83
90
  | onDeleteTheme | `(payload: ThemePanelDeleteThemePayload) => void` | — | 删除非默认主题后的回调,业务侧可同步删除外部存储 |
91
+ | allowUpdateTheme | `boolean` | `true` | 在高级调整区为非默认主题显示保存修改能力;默认主题保存时会另存为新主题 |
92
+ | onUpdateTheme | `(payload: ThemePanelUpdateThemePayload) => void` | — | 覆盖保存非默认主题修改后的回调;名称和副标题修改通过 payload.label / payload.description 传出,另存为仍走 onCreateTheme |
84
93
  | showReset | `boolean` | `true` | 显示重置按钮 |
85
94
  | compact | `boolean` | `false` | 紧凑布局 |
86
95
 
@@ -109,11 +118,23 @@ const [themes, setThemes] = React.useState<ThemePresets>({});
109
118
  | --- | --- | --- | --- |
110
119
  | key | `ThemeMode` | — | 保存后注册到 ThemeProvider 的 mode key |
111
120
  | label | `string` | — | 用户输入的主题名称 |
112
- | description | `string` | — | ThemePanel 生成的说明文案,如自建亮/自建暗 |
121
+ | description | `string` | — | 用户输入的主题副标题,会显示在主题卡片第二行 |
113
122
  | preset | `ThemePreset` | — | 最终保存到 theme.themes 的主题配置 |
114
123
  | presetOption | `ThemePanelPresetOption` | — | 可直接追加到受控 presetOptions 的卡片配置 |
115
124
 
116
125
 
126
+ **ThemePanelUpdateThemePayload**
127
+
128
+ | Prop | 类型 | 默认 | 说明 |
129
+ | --- | --- | --- | --- |
130
+ | key | `ThemeMode` | — | 被更新的主题 mode key |
131
+ | label | `string` | — | 被更新主题的展示名称 |
132
+ | description | `string` | — | 被更新主题的副标题,会显示在主题卡片第二行 |
133
+ | preset | `ThemePreset` | — | 从当前面板状态生成的新主题配置 |
134
+ | previousPreset | `ThemePreset` | — | 更新前的主题配置 |
135
+ | presetOption | `ThemePanelPresetOption` | — | 可直接回灌到受控 presetOptions 的卡片配置 |
136
+
137
+
117
138
  **ThemePanelDeleteThemePayload**
118
139
 
119
140
  | Prop | 类型 | 默认 | 说明 |
@@ -2,6 +2,12 @@
2
2
 
3
3
  > 垂直时间线,支持等待状态、自定义圆点、交替布局
4
4
 
5
+ ## 导入
6
+
7
+ ```tsx
8
+ import { Timeline } from "@fangxinyan/lumina";
9
+ ```
10
+
5
11
  ## 示例
6
12
 
7
13
  ### 基础用法
@@ -112,6 +118,24 @@ reverse 属性将时间线反转,最新的事件在最上面
112
118
  />
113
119
  ```
114
120
 
121
+ ### 槽位样式
122
+
123
+ item / content / dot / label 都可以拿到样式入口;content 默认 min-width: 0,长内容能在弹性容器里正确收缩。
124
+
125
+ ```tsx
126
+ <Timeline
127
+ contentMinWidth={0}
128
+ dotOffset={4}
129
+ items={[
130
+ {
131
+ children: "很长的任务标题...",
132
+ contentStyle: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
133
+ dotStyle: { boxShadow: "var(--neu-shadow-lift)" },
134
+ },
135
+ ]}
136
+ />
137
+ ```
138
+
115
139
  ## API
116
140
 
117
141
  **Timeline**
@@ -123,6 +147,13 @@ reverse 属性将时间线反转,最新的事件在最上面
123
147
  | pendingContent | `ReactNode` | `"加载中..."` | 等待节点的文字内容 |
124
148
  | mode | `"left" | "right" | "alternate"` | `"left"` | 布局模式 |
125
149
  | reverse | `boolean` | `false` | 反转节点顺序 |
150
+ | itemClassName / itemStyle | `string / CSSProperties` | — | 透传到每个节点外层 |
151
+ | contentClassName / contentStyle | `string / CSSProperties` | — | 透传到每个内容槽 |
152
+ | contentMinWidth | `CSSProperties['minWidth']` | `0` | 内容槽最小宽度,默认允许在 flex/grid 中收缩 |
153
+ | dotClassName / dotStyle | `string / CSSProperties` | — | 透传到每个圆点槽 |
154
+ | dotOffset | `CSSProperties['marginTop']` | `4` | 圆点垂直偏移 |
155
+ | dotAlign | `"start" | "center" | "end"` | `"center"` | 圆点在 head 列中的横向对齐 |
156
+ | labelClassName / labelStyle | `string / CSSProperties` | — | 透传到每个标签槽 |
126
157
 
127
158
 
128
159
  **TimelineItemConfig**
@@ -134,6 +165,10 @@ reverse 属性将时间线反转,最新的事件在最上面
134
165
  | label | `ReactNode` | — | 对侧标签(alternate 模式下使用) |
135
166
  | color | `"accent" | "success" | "warning" | "danger" | "info" | "muted"` | `"accent"` | 圆点颜色 |
136
167
  | dot | `ReactNode` | — | 自定义圆点内容 |
168
+ | className / style | `string / CSSProperties` | — | 节点外层样式槽 |
169
+ | contentClassName / contentStyle | `string / CSSProperties` | — | 内容槽样式 |
170
+ | dotClassName / dotStyle | `string / CSSProperties` | — | 圆点槽样式 |
171
+ | labelClassName / labelStyle | `string / CSSProperties` | — | 标签槽样式 |
137
172
 
138
173
 
139
174
  ---
@@ -5,7 +5,7 @@
5
5
  ## 导入
6
6
 
7
7
  ```tsx
8
- import { Typography } from "@fangxinyan/lumina";
8
+ import { Typography, Title, Text, Paragraph, Link } from "@fangxinyan/lumina";
9
9
  ```
10
10
 
11
11
  ## 示例
package/docs/llms.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > 拟态风格的 React 18 组件库,目标是 Electron 桌面应用。**写给 AI 编程助手**的按需文档 —— 每个组件单独一个 `.md`,避免一次性读取全部。示例源自 playground 的 demo,可直接复制运行。
4
4
 
5
5
  - **包名**: `@fangxinyan/lumina`
6
- - **版本**: `0.6.6`
6
+ - **版本**: `0.6.8`
7
7
  - **React 最低版本**: 18
8
8
  - **环境**: 带打包器的 React 工程(Vite / Next.js / Webpack / Remix / Electron + Vite 等)
9
9
  - **零运行时依赖**: 只依赖 `react` / `react-dom` (peer deps)
@@ -55,6 +55,7 @@
55
55
  ### 表单
56
56
 
57
57
  - [Input 输入框](./llms/input.md) — 凹陷凹槽式输入域,支持前后置图标、错误态、禁用态。
58
+ - [Textarea 多行输入](./llms/textarea.md) — 多行文本输入域,支持清除、字数统计、错误态和原生 textarea 属性。
58
59
  - [InputNumber 数字输入](./llms/inputnumber.md) — 带步进按钮的数字输入框。
59
60
  - [Switch 开关](./llms/switch.md) — 二元状态切换器。
60
61
  - [Checkbox 复选框](./llms/checkbox.md) — 在一组选项中进行多项选择,或独立切换某个开关项。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fangxinyan/lumina",
3
- "version": "0.6.6",
3
+ "version": "0.6.8",
4
4
  "description": "Lumina — Neumorphic component library for Electron & React apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -27,6 +27,56 @@
27
27
  "import": "./dist/AppShell.js",
28
28
  "require": "./dist/AppShell.cjs"
29
29
  },
30
+ "./IconButton": {
31
+ "types": "./dist/Button.d.ts",
32
+ "import": "./dist/Button.js",
33
+ "require": "./dist/Button.cjs"
34
+ },
35
+ "./InputPassword": {
36
+ "types": "./dist/Input.d.ts",
37
+ "import": "./dist/Input.js",
38
+ "require": "./dist/Input.cjs"
39
+ },
40
+ "./TextArea": {
41
+ "types": "./dist/Textarea.d.ts",
42
+ "import": "./dist/Textarea.js",
43
+ "require": "./dist/Textarea.cjs"
44
+ },
45
+ "./RadioGroup": {
46
+ "types": "./dist/Radio.d.ts",
47
+ "import": "./dist/Radio.js",
48
+ "require": "./dist/Radio.cjs"
49
+ },
50
+ "./FormItem": {
51
+ "types": "./dist/Form.d.ts",
52
+ "import": "./dist/Form.js",
53
+ "require": "./dist/Form.cjs"
54
+ },
55
+ "./ThemeProvider": {
56
+ "types": "./dist/Theme.d.ts",
57
+ "import": "./dist/Theme.js",
58
+ "require": "./dist/Theme.cjs"
59
+ },
60
+ "./Title": {
61
+ "types": "./dist/Typography.d.ts",
62
+ "import": "./dist/Typography.js",
63
+ "require": "./dist/Typography.cjs"
64
+ },
65
+ "./Text": {
66
+ "types": "./dist/Typography.d.ts",
67
+ "import": "./dist/Typography.js",
68
+ "require": "./dist/Typography.cjs"
69
+ },
70
+ "./Paragraph": {
71
+ "types": "./dist/Typography.d.ts",
72
+ "import": "./dist/Typography.js",
73
+ "require": "./dist/Typography.cjs"
74
+ },
75
+ "./Link": {
76
+ "types": "./dist/Typography.d.ts",
77
+ "import": "./dist/Typography.js",
78
+ "require": "./dist/Typography.cjs"
79
+ },
30
80
  "./Sidebar": {
31
81
  "types": "./dist/AppShell.d.ts",
32
82
  "import": "./dist/AppShell.js",
@@ -1,106 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkSG42F5VB_cjs = require('./chunk-SG42F5VB.cjs');
4
- require('./tokens-EF34LSWI.css');
5
- require('./shared-NJHRNLRH.css');
6
- require('./Timeline-ZIM7QFQC.css');
7
- var React = require('react');
8
- var jsxRuntime = require('react/jsx-runtime');
9
-
10
- function _interopNamespace(e) {
11
- if (e && e.__esModule) return e;
12
- var n = Object.create(null);
13
- if (e) {
14
- Object.keys(e).forEach(function (k) {
15
- if (k !== 'default') {
16
- var d = Object.getOwnPropertyDescriptor(e, k);
17
- Object.defineProperty(n, k, d.get ? d : {
18
- enumerable: true,
19
- get: function () { return e[k]; }
20
- });
21
- }
22
- });
23
- }
24
- n.default = e;
25
- return Object.freeze(n);
26
- }
27
-
28
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
29
-
30
- var Timeline = React__namespace.forwardRef(
31
- ({
32
- items,
33
- pending = false,
34
- pendingContent = "\u52A0\u8F7D\u4E2D...",
35
- mode = "left",
36
- reverse = false,
37
- className = "",
38
- ...rest
39
- }, ref) => {
40
- const displayItems = [...items];
41
- if (reverse) displayItems.reverse();
42
- const hasPending = pending !== false;
43
- return /* @__PURE__ */ jsxRuntime.jsxs(
44
- "div",
45
- {
46
- ref,
47
- className: `timeline timeline-${mode} ${className}`,
48
- ...rest,
49
- children: [
50
- displayItems.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(
51
- TimelineItem,
52
- {
53
- item,
54
- isLast: !hasPending && i === displayItems.length - 1,
55
- position: getPosition(mode, i)
56
- },
57
- item.key ?? i
58
- )),
59
- hasPending && /* @__PURE__ */ jsxRuntime.jsx(
60
- TimelineItem,
61
- {
62
- item: {
63
- children: pendingContent,
64
- dot: typeof pending === "boolean" ? void 0 : pending,
65
- color: "muted"
66
- },
67
- isLast: true,
68
- isPending: true,
69
- position: getPosition(mode, displayItems.length)
70
- }
71
- )
72
- ]
73
- }
74
- );
75
- }
76
- );
77
- Timeline.displayName = "Timeline";
78
- function getPosition(mode, index) {
79
- if (mode === "left") return "left";
80
- if (mode === "right") return "right";
81
- return index % 2 === 0 ? "left" : "right";
82
- }
83
- var TimelineItem = ({
84
- item,
85
- isLast,
86
- isPending,
87
- position
88
- }) => {
89
- const color = item.color ?? "accent";
90
- const cls = [
91
- "timeline-item",
92
- `timeline-item-${position}`,
93
- isLast ? "timeline-item-last" : "",
94
- isPending ? "timeline-item-pending" : ""
95
- ].filter(Boolean).join(" ");
96
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cls, children: [
97
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "timeline-item-label", children: item.label }),
98
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "timeline-item-head", children: [
99
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `timeline-item-dot ${color} ${isPending ? "pending" : ""}`, children: item.dot ?? (isPending && /* @__PURE__ */ jsxRuntime.jsx(chunkSG42F5VB_cjs.Spin, { size: 14 })) }),
100
- !isLast && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "timeline-item-tail" })
101
- ] }),
102
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "timeline-item-content", children: item.children })
103
- ] });
104
- };
105
-
106
- exports.Timeline = Timeline;
@@ -1,28 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkOGPDCBPD_cjs = require('./chunk-OGPDCBPD.cjs');
4
- require('./tokens-EF34LSWI.css');
5
- require('./shared-NJHRNLRH.css');
6
- require('./TablePro-JRSBPXB5.css');
7
- var jsxRuntime = require('react/jsx-runtime');
8
-
9
- function TablePro({
10
- toolbar,
11
- actions,
12
- footer,
13
- title,
14
- className = "",
15
- ...tableProps
16
- }) {
17
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `table-card ${className}`, children: [
18
- (title || toolbar || actions) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "table-toolbar", children: [
19
- title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "table-title", children: title }),
20
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "table-toolbar-main", children: toolbar }),
21
- actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "table-toolbar-actions", children: actions })
22
- ] }),
23
- /* @__PURE__ */ jsxRuntime.jsx(chunkOGPDCBPD_cjs.Table, { ...tableProps, className: "joined" }),
24
- footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "table-footer", children: footer })
25
- ] });
26
- }
27
-
28
- exports.TablePro = TablePro;
@@ -1,26 +0,0 @@
1
- import { Table } from './chunk-YSXD344H.js';
2
- import './tokens-EF34LSWI.css';
3
- import './shared-NJHRNLRH.css';
4
- import './TablePro-JRSBPXB5.css';
5
- import { jsxs, jsx } from 'react/jsx-runtime';
6
-
7
- function TablePro({
8
- toolbar,
9
- actions,
10
- footer,
11
- title,
12
- className = "",
13
- ...tableProps
14
- }) {
15
- return /* @__PURE__ */ jsxs("div", { className: `table-card ${className}`, children: [
16
- (title || toolbar || actions) && /* @__PURE__ */ jsxs("div", { className: "table-toolbar", children: [
17
- title && /* @__PURE__ */ jsx("div", { className: "table-title", children: title }),
18
- /* @__PURE__ */ jsx("div", { className: "table-toolbar-main", children: toolbar }),
19
- actions && /* @__PURE__ */ jsx("div", { className: "table-toolbar-actions", children: actions })
20
- ] }),
21
- /* @__PURE__ */ jsx(Table, { ...tableProps, className: "joined" }),
22
- footer && /* @__PURE__ */ jsx("div", { className: "table-footer", children: footer })
23
- ] });
24
- }
25
-
26
- export { TablePro };
@@ -1,84 +0,0 @@
1
- import { Spin } from './chunk-Y5F7ZTBH.js';
2
- import './tokens-EF34LSWI.css';
3
- import './shared-NJHRNLRH.css';
4
- import './Timeline-ZIM7QFQC.css';
5
- import * as React from 'react';
6
- import { jsxs, jsx } from 'react/jsx-runtime';
7
-
8
- var Timeline = React.forwardRef(
9
- ({
10
- items,
11
- pending = false,
12
- pendingContent = "\u52A0\u8F7D\u4E2D...",
13
- mode = "left",
14
- reverse = false,
15
- className = "",
16
- ...rest
17
- }, ref) => {
18
- const displayItems = [...items];
19
- if (reverse) displayItems.reverse();
20
- const hasPending = pending !== false;
21
- return /* @__PURE__ */ jsxs(
22
- "div",
23
- {
24
- ref,
25
- className: `timeline timeline-${mode} ${className}`,
26
- ...rest,
27
- children: [
28
- displayItems.map((item, i) => /* @__PURE__ */ jsx(
29
- TimelineItem,
30
- {
31
- item,
32
- isLast: !hasPending && i === displayItems.length - 1,
33
- position: getPosition(mode, i)
34
- },
35
- item.key ?? i
36
- )),
37
- hasPending && /* @__PURE__ */ jsx(
38
- TimelineItem,
39
- {
40
- item: {
41
- children: pendingContent,
42
- dot: typeof pending === "boolean" ? void 0 : pending,
43
- color: "muted"
44
- },
45
- isLast: true,
46
- isPending: true,
47
- position: getPosition(mode, displayItems.length)
48
- }
49
- )
50
- ]
51
- }
52
- );
53
- }
54
- );
55
- Timeline.displayName = "Timeline";
56
- function getPosition(mode, index) {
57
- if (mode === "left") return "left";
58
- if (mode === "right") return "right";
59
- return index % 2 === 0 ? "left" : "right";
60
- }
61
- var TimelineItem = ({
62
- item,
63
- isLast,
64
- isPending,
65
- position
66
- }) => {
67
- const color = item.color ?? "accent";
68
- const cls = [
69
- "timeline-item",
70
- `timeline-item-${position}`,
71
- isLast ? "timeline-item-last" : "",
72
- isPending ? "timeline-item-pending" : ""
73
- ].filter(Boolean).join(" ");
74
- return /* @__PURE__ */ jsxs("div", { className: cls, children: [
75
- /* @__PURE__ */ jsx("div", { className: "timeline-item-label", children: item.label }),
76
- /* @__PURE__ */ jsxs("div", { className: "timeline-item-head", children: [
77
- /* @__PURE__ */ jsx("div", { className: `timeline-item-dot ${color} ${isPending ? "pending" : ""}`, children: item.dot ?? (isPending && /* @__PURE__ */ jsx(Spin, { size: 14 })) }),
78
- !isLast && /* @__PURE__ */ jsx("div", { className: "timeline-item-tail" })
79
- ] }),
80
- /* @__PURE__ */ jsx("div", { className: "timeline-item-content", children: item.children })
81
- ] });
82
- };
83
-
84
- export { Timeline };