@lobehub/ui 6.0.0-beta.4 → 6.0.0-beta.6

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 (286) hide show
  1. package/es/ActionIcon/style.mjs +1 -1
  2. package/es/ActionIcon/style.mjs.map +1 -1
  3. package/es/Anchor/Anchor.mjs +2 -2
  4. package/es/Anchor/Anchor.mjs.map +1 -1
  5. package/es/Carousel/Carousel.mjs +1 -1
  6. package/es/Carousel/Carousel.mjs.map +1 -1
  7. package/es/CodeDiff/CodeDiff.mjs.map +1 -1
  8. package/es/CodeDiff/PatchDiff.mjs.map +1 -1
  9. package/es/CodeDiff/theme.mjs.map +1 -1
  10. package/es/CodeDiff/type.d.mts +2 -2
  11. package/es/CodeEditor/CodeEditor.mjs +1 -1
  12. package/es/CodeEditor/CodeEditor.mjs.map +1 -1
  13. package/es/ColorPicker/ColorPicker.mjs +1 -1
  14. package/es/ColorPicker/ColorPicker.mjs.map +1 -1
  15. package/es/ColorSwatches/ColorSwatches.mjs +18 -23
  16. package/es/ColorSwatches/ColorSwatches.mjs.map +1 -1
  17. package/es/ColorSwatches/CustomPicker.mjs +101 -0
  18. package/es/ColorSwatches/CustomPicker.mjs.map +1 -0
  19. package/es/ColorSwatches/index.d.mts +2 -2
  20. package/es/ColorSwatches/marker.stylex.mjs +9 -0
  21. package/es/ColorSwatches/marker.stylex.mjs.map +1 -0
  22. package/es/ColorSwatches/style.mjs +36 -0
  23. package/es/ColorSwatches/style.mjs.map +1 -1
  24. package/es/ColorSwatches/type.d.mts +9 -0
  25. package/es/ConfigProvider/cdnAssets.mjs +6 -0
  26. package/es/ConfigProvider/cdnAssets.mjs.map +1 -0
  27. package/es/ConfigProvider/index.mjs +2 -1
  28. package/es/ConfigProvider/index.mjs.map +1 -1
  29. package/es/ContextMenu/store.d.mts +0 -1
  30. package/es/ContextMenu/store.mjs.map +1 -1
  31. package/es/DatePicker/DatePicker.mjs +1 -1
  32. package/es/DatePicker/DatePicker.mjs.map +1 -1
  33. package/es/DatePicker/DateRangePicker.mjs +1 -1
  34. package/es/DatePicker/DateRangePicker.mjs.map +1 -1
  35. package/es/DraggablePanel/atoms.mjs +1 -1
  36. package/es/DraggablePanel/atoms.mjs.map +1 -1
  37. package/es/DraggableSideNav/DraggableSideNav.mjs +2 -2
  38. package/es/DraggableSideNav/DraggableSideNav.mjs.map +1 -1
  39. package/es/Drawer/atoms.mjs +1 -1
  40. package/es/Drawer/atoms.mjs.map +1 -1
  41. package/es/DropdownMenu/atoms.mjs +1 -1
  42. package/es/DropdownMenu/atoms.mjs.map +1 -1
  43. package/es/EditableText/ControlInput.mjs +42 -29
  44. package/es/EditableText/ControlInput.mjs.map +1 -1
  45. package/es/EditableText/EditableText.mjs +1 -1
  46. package/es/EditableText/EditableText.mjs.map +1 -1
  47. package/es/EmojiPicker/EmojiPicker.mjs +3 -9
  48. package/es/EmojiPicker/EmojiPicker.mjs.map +1 -1
  49. package/es/EmojiPicker/useEmojiMartI18n.mjs +37 -0
  50. package/es/EmojiPicker/useEmojiMartI18n.mjs.map +1 -0
  51. package/es/FormKit/engine/tanstack.mjs +1 -1
  52. package/es/FormKit/engine/tanstack.mjs.map +1 -1
  53. package/es/Grid/style.mjs +1 -1
  54. package/es/Grid/style.mjs.map +1 -1
  55. package/es/HotkeyInput/HotkeyInput.mjs +1 -1
  56. package/es/HotkeyInput/HotkeyInput.mjs.map +1 -1
  57. package/es/Image/type.d.mts +1 -0
  58. package/es/Image/viewer/ImageViewer.mjs +2 -1
  59. package/es/Image/viewer/ImageViewer.mjs.map +1 -1
  60. package/es/Image/viewer/Toolbar.mjs +19 -6
  61. package/es/Image/viewer/Toolbar.mjs.map +1 -1
  62. package/es/Image/viewer/ViewerChrome.mjs.map +1 -1
  63. package/es/ImageSelect/ImageSelect.mjs +1 -1
  64. package/es/ImageSelect/ImageSelect.mjs.map +1 -1
  65. package/es/Input/Input.mjs +7 -5
  66. package/es/Input/Input.mjs.map +1 -1
  67. package/es/Input/TextArea.mjs +1 -1
  68. package/es/Input/TextArea.mjs.map +1 -1
  69. package/es/Input/style.mjs +3 -3
  70. package/es/Input/style.mjs.map +1 -1
  71. package/es/Modal/atoms.mjs +3 -3
  72. package/es/Modal/atoms.mjs.map +1 -1
  73. package/es/Pagination/Pagination.mjs +1 -1
  74. package/es/Pagination/Pagination.mjs.map +1 -1
  75. package/es/Popover/PopoverInGroup.mjs +1 -1
  76. package/es/Popover/PopoverInGroup.mjs.map +1 -1
  77. package/es/Popover/atoms.mjs +1 -1
  78. package/es/Popover/atoms.mjs.map +1 -1
  79. package/es/Rate/Rate.mjs +1 -1
  80. package/es/Rate/Rate.mjs.map +1 -1
  81. package/es/ScrollShadow/ScrollShadow.mjs +1 -1
  82. package/es/ScrollShadow/ScrollShadow.mjs.map +1 -1
  83. package/es/SearchBar/SearchBar.mjs +31 -25
  84. package/es/SearchBar/SearchBar.mjs.map +1 -1
  85. package/es/Segmented/Segmented.mjs +1 -1
  86. package/es/Segmented/Segmented.mjs.map +1 -1
  87. package/es/Select/atoms.mjs +1 -1
  88. package/es/Select/atoms.mjs.map +1 -1
  89. package/es/Switch/atoms.mjs +1 -1
  90. package/es/Switch/atoms.mjs.map +1 -1
  91. package/es/Tabs/Tabs.mjs +35 -21
  92. package/es/Tabs/Tabs.mjs.map +1 -1
  93. package/es/ToggleGroup/ToggleGroup.mjs +1 -1
  94. package/es/ToggleGroup/ToggleGroup.mjs.map +1 -1
  95. package/es/Tooltip/TooltipInGroup.mjs +1 -1
  96. package/es/Tooltip/TooltipInGroup.mjs.map +1 -1
  97. package/es/Tooltip/TooltipStandalone.mjs +1 -1
  98. package/es/Tooltip/TooltipStandalone.mjs.map +1 -1
  99. package/es/Tree/Tree.mjs +1 -1
  100. package/es/Tree/Tree.mjs.map +1 -1
  101. package/es/awesome/Giscus/style.mjs +9 -9
  102. package/es/awesome/Giscus/style.mjs.map +1 -1
  103. package/es/awesome/Grainient/Grainient.d.mts +11 -0
  104. package/es/awesome/Grainient/Grainient.mjs +314 -0
  105. package/es/awesome/Grainient/Grainient.mjs.map +1 -0
  106. package/es/awesome/Grainient/index.d.mts +3 -0
  107. package/es/awesome/Grainient/style.mjs +23 -0
  108. package/es/awesome/Grainient/style.mjs.map +1 -0
  109. package/es/awesome/Grainient/type.d.mts +121 -0
  110. package/es/awesome/GridBackground/GridBackground.mjs +1 -1
  111. package/es/awesome/GridBackground/GridBackground.mjs.map +1 -1
  112. package/es/awesome/GridBackground/GridShowcase.mjs +4 -4
  113. package/es/awesome/GridBackground/GridShowcase.mjs.map +1 -1
  114. package/es/awesome/Spline/ParentSize.mjs +1 -1
  115. package/es/awesome/Spline/ParentSize.mjs.map +1 -1
  116. package/es/awesome/index.d.mts +4 -1
  117. package/es/awesome/index.mjs +2 -1
  118. package/es/chat/BackBottom/BackBottom.mjs +1 -1
  119. package/es/chat/BackBottom/BackBottom.mjs.map +1 -1
  120. package/es/chat/BackBottom/type.d.mts +2 -2
  121. package/es/chat/EditableMessage/EditableMessage.mjs +1 -1
  122. package/es/chat/EditableMessage/EditableMessage.mjs.map +1 -1
  123. package/es/chat/EditableMessageList/EditableMessageList.mjs +1 -1
  124. package/es/chat/EditableMessageList/EditableMessageList.mjs.map +1 -1
  125. package/es/chat/EditableMessageList/messageReducer.mjs +30 -23
  126. package/es/chat/EditableMessageList/messageReducer.mjs.map +1 -1
  127. package/es/chat/MessageModal/MessageModal.mjs +1 -1
  128. package/es/chat/MessageModal/MessageModal.mjs.map +1 -1
  129. package/es/chat/TokenTag/TokenTag.mjs +2 -3
  130. package/es/chat/TokenTag/TokenTag.mjs.map +1 -1
  131. package/es/dashboard/AuthLayout/Aside.d.mts +10 -0
  132. package/es/dashboard/AuthLayout/Aside.mjs +31 -0
  133. package/es/dashboard/AuthLayout/Aside.mjs.map +1 -0
  134. package/es/dashboard/AuthLayout/AuthLayout.d.mts +3 -1
  135. package/es/dashboard/AuthLayout/AuthLayout.mjs +93 -37
  136. package/es/dashboard/AuthLayout/AuthLayout.mjs.map +1 -1
  137. package/es/dashboard/AuthLayout/index.d.mts +3 -2
  138. package/es/dashboard/AuthLayout/style.mjs +98 -1
  139. package/es/dashboard/AuthLayout/style.mjs.map +1 -1
  140. package/es/dashboard/AuthLayout/type.d.mts +38 -2
  141. package/es/dashboard/AuthTools/AuthLocaleSwitch.d.mts +10 -0
  142. package/es/dashboard/AuthTools/AuthLocaleSwitch.mjs +33 -0
  143. package/es/dashboard/AuthTools/AuthLocaleSwitch.mjs.map +1 -0
  144. package/es/dashboard/AuthTools/AuthThemeSwitch.d.mts +10 -0
  145. package/es/dashboard/AuthTools/AuthThemeSwitch.mjs +59 -0
  146. package/es/dashboard/AuthTools/AuthThemeSwitch.mjs.map +1 -0
  147. package/es/dashboard/AuthTools/index.d.mts +4 -0
  148. package/es/dashboard/AuthTools/style.mjs +27 -0
  149. package/es/dashboard/AuthTools/style.mjs.map +1 -0
  150. package/es/dashboard/AuthTools/type.d.mts +29 -0
  151. package/es/dashboard/ChartGrid/ChartGrid.d.mts +10 -0
  152. package/es/dashboard/ChartGrid/ChartGrid.mjs +19 -0
  153. package/es/dashboard/ChartGrid/ChartGrid.mjs.map +1 -0
  154. package/es/dashboard/ChartGrid/index.d.mts +3 -0
  155. package/es/dashboard/ChartGrid/style.mjs +18 -0
  156. package/es/dashboard/ChartGrid/style.mjs.map +1 -0
  157. package/es/dashboard/ChartGrid/type.d.mts +8 -0
  158. package/es/dashboard/ConsoleNav/Skeleton.d.mts +15 -0
  159. package/es/dashboard/ConsoleNav/Skeleton.mjs +82 -0
  160. package/es/dashboard/ConsoleNav/Skeleton.mjs.map +1 -0
  161. package/es/dashboard/ConsoleNav/index.d.mts +3 -2
  162. package/es/dashboard/ConsoleNav/style.mjs +18 -0
  163. package/es/dashboard/ConsoleNav/style.mjs.map +1 -1
  164. package/es/dashboard/ConsoleNav/type.d.mts +13 -0
  165. package/es/dashboard/ConsoleShell/ConsoleShell.d.mts +1 -1
  166. package/es/dashboard/ConsoleShell/ConsoleShell.mjs +26 -6
  167. package/es/dashboard/ConsoleShell/ConsoleShell.mjs.map +1 -1
  168. package/es/dashboard/ConsoleShell/style.mjs +10 -0
  169. package/es/dashboard/ConsoleShell/style.mjs.map +1 -1
  170. package/es/dashboard/ConsoleShell/type.d.mts +11 -0
  171. package/es/dashboard/FilterSidebar/FilterSidebar.mjs +18 -17
  172. package/es/dashboard/FilterSidebar/FilterSidebar.mjs.map +1 -1
  173. package/es/dashboard/FilterStrip/FilterStrip.d.mts +11 -0
  174. package/es/dashboard/FilterStrip/FilterStrip.mjs +55 -0
  175. package/es/dashboard/FilterStrip/FilterStrip.mjs.map +1 -0
  176. package/es/dashboard/FilterStrip/index.d.mts +3 -0
  177. package/es/dashboard/FilterStrip/style.mjs +78 -0
  178. package/es/dashboard/FilterStrip/style.mjs.map +1 -0
  179. package/es/dashboard/FilterStrip/type.d.mts +25 -0
  180. package/es/dashboard/LabelWithKey/LabelWithKey.d.mts +10 -0
  181. package/es/dashboard/LabelWithKey/LabelWithKey.mjs +18 -0
  182. package/es/dashboard/LabelWithKey/LabelWithKey.mjs.map +1 -0
  183. package/es/dashboard/LabelWithKey/index.d.mts +3 -0
  184. package/es/dashboard/LabelWithKey/type.d.mts +11 -0
  185. package/es/dashboard/MetricStrip/MetricCell.mjs +81 -0
  186. package/es/dashboard/MetricStrip/MetricCell.mjs.map +1 -0
  187. package/es/dashboard/MetricStrip/MetricStrip.d.mts +13 -0
  188. package/es/dashboard/MetricStrip/MetricStrip.mjs +47 -0
  189. package/es/dashboard/MetricStrip/MetricStrip.mjs.map +1 -0
  190. package/es/dashboard/MetricStrip/index.d.mts +3 -0
  191. package/es/dashboard/MetricStrip/style.mjs +156 -0
  192. package/es/dashboard/MetricStrip/style.mjs.map +1 -0
  193. package/es/dashboard/MetricStrip/type.d.mts +36 -0
  194. package/es/dashboard/PageSkeleton/PageSkeleton.mjs +20 -18
  195. package/es/dashboard/PageSkeleton/PageSkeleton.mjs.map +1 -1
  196. package/es/dashboard/PageSkeleton/style.mjs +1 -1
  197. package/es/dashboard/PageSkeleton/style.mjs.map +1 -1
  198. package/es/dashboard/PageToolbar/PageToolbar.d.mts +10 -0
  199. package/es/dashboard/PageToolbar/PageToolbar.mjs +22 -0
  200. package/es/dashboard/PageToolbar/PageToolbar.mjs.map +1 -0
  201. package/es/dashboard/PageToolbar/index.d.mts +3 -0
  202. package/es/dashboard/PageToolbar/style.mjs +36 -0
  203. package/es/dashboard/PageToolbar/style.mjs.map +1 -0
  204. package/es/dashboard/PageToolbar/type.d.mts +11 -0
  205. package/es/dashboard/PanelSurface/PanelSurface.d.mts +10 -0
  206. package/es/dashboard/PanelSurface/PanelSurface.mjs +40 -0
  207. package/es/dashboard/PanelSurface/PanelSurface.mjs.map +1 -0
  208. package/es/dashboard/PanelSurface/index.d.mts +3 -0
  209. package/es/dashboard/PanelSurface/style.mjs +25 -0
  210. package/es/dashboard/PanelSurface/style.mjs.map +1 -0
  211. package/es/dashboard/PanelSurface/type.d.mts +17 -0
  212. package/es/dashboard/Section/Section.d.mts +10 -0
  213. package/es/dashboard/Section/Section.mjs +81 -0
  214. package/es/dashboard/Section/Section.mjs.map +1 -0
  215. package/es/dashboard/Section/index.d.mts +3 -0
  216. package/es/dashboard/Section/style.mjs +31 -0
  217. package/es/dashboard/Section/style.mjs.map +1 -0
  218. package/es/dashboard/Section/type.d.mts +23 -0
  219. package/es/dashboard/StatCard/StatCard.d.mts +2 -1
  220. package/es/dashboard/StatCard/StatCard.mjs +28 -91
  221. package/es/dashboard/StatCard/StatCard.mjs.map +1 -1
  222. package/es/dashboard/StatCard/type.d.mts +16 -5
  223. package/es/dashboard/Surface/Surface.d.mts +4 -3
  224. package/es/dashboard/Surface/Surface.mjs +91 -8
  225. package/es/dashboard/Surface/Surface.mjs.map +1 -1
  226. package/es/dashboard/Surface/index.d.mts +3 -2
  227. package/es/dashboard/Surface/link.d.mts +16 -0
  228. package/es/dashboard/Surface/link.mjs +40 -0
  229. package/es/dashboard/Surface/link.mjs.map +1 -0
  230. package/es/dashboard/Surface/marker.stylex.mjs +9 -0
  231. package/es/dashboard/Surface/marker.stylex.mjs.map +1 -0
  232. package/es/dashboard/Surface/style.d.mts +2 -0
  233. package/es/dashboard/Surface/style.mjs +155 -14
  234. package/es/dashboard/Surface/style.mjs.map +1 -1
  235. package/es/dashboard/Surface/type.d.mts +29 -1
  236. package/es/dashboard/TableIconActions/TableIconActions.d.mts +17 -0
  237. package/es/dashboard/TableIconActions/TableIconActions.mjs +39 -0
  238. package/es/dashboard/TableIconActions/TableIconActions.mjs.map +1 -0
  239. package/es/dashboard/TableIconActions/index.d.mts +3 -0
  240. package/es/dashboard/TableIconActions/type.d.mts +17 -0
  241. package/es/dashboard/TitleWithTips/TitleWithTips.d.mts +10 -0
  242. package/es/dashboard/TitleWithTips/TitleWithTips.mjs +28 -0
  243. package/es/dashboard/TitleWithTips/TitleWithTips.mjs.map +1 -0
  244. package/es/dashboard/TitleWithTips/index.d.mts +3 -0
  245. package/es/dashboard/TitleWithTips/type.d.mts +10 -0
  246. package/es/dashboard/index.d.mts +38 -4
  247. package/es/dashboard/index.mjs +17 -3
  248. package/es/hooks/useControlledState.mjs +20 -0
  249. package/es/hooks/useControlledState.mjs.map +1 -0
  250. package/es/hooks/useHighlight.mjs +2 -2
  251. package/es/hooks/useHighlight.mjs.map +1 -1
  252. package/es/hooks/useHover.mjs +22 -0
  253. package/es/hooks/useHover.mjs.map +1 -0
  254. package/es/hooks/useScroll.d.mts +8 -0
  255. package/es/hooks/useScroll.mjs +33 -0
  256. package/es/hooks/useScroll.mjs.map +1 -0
  257. package/es/hooks/useSize.mjs +26 -0
  258. package/es/hooks/useSize.mjs.map +1 -0
  259. package/es/internal/virtual/VirtualScrollArea.mjs +1 -1
  260. package/es/internal/virtual/VirtualScrollArea.mjs.map +1 -1
  261. package/es/mobile/ChatInputArea/ChatInputArea.mjs +1 -1
  262. package/es/mobile/ChatInputArea/ChatInputArea.mjs.map +1 -1
  263. package/es/mobile/TabBar/TabBar.mjs +1 -1
  264. package/es/mobile/TabBar/TabBar.mjs.map +1 -1
  265. package/es/node_modules/.pnpm/@eslint_core@1.2.1/node_modules/@eslint/core/dist/esm/types.d.mts +2 -46
  266. package/es/node_modules/.pnpm/@eslint_plugin-kit@0.7.3/node_modules/@eslint/plugin-kit/dist/cjs/index.d.mts +1 -1
  267. package/es/node_modules/.pnpm/@types_estree@1.0.9/node_modules/@types/estree/index.d.mts +1 -4
  268. package/es/node_modules/.pnpm/eslint@10.12.0_jiti@2.6.1_supports-color@10.2.2/node_modules/eslint/lib/types/index.d.mts +1 -1
  269. package/es/style.css +339 -32
  270. package/es/styles/theme/token/neutral.mjs +5 -5
  271. package/es/styles/theme/token/neutral.mjs.map +1 -1
  272. package/es/utils/colorMath.mjs +52 -0
  273. package/es/utils/colorMath.mjs.map +1 -0
  274. package/es/utils/formatNumber.mjs +7 -0
  275. package/es/utils/formatNumber.mjs.map +1 -0
  276. package/es/utils/genCdnUrl.mjs +6 -3
  277. package/es/utils/genCdnUrl.mjs.map +1 -1
  278. package/es/utils/hashString.mjs +19 -0
  279. package/es/utils/hashString.mjs.map +1 -0
  280. package/es/utils/mergeRefs.mjs +20 -0
  281. package/es/utils/mergeRefs.mjs.map +1 -0
  282. package/es/utils/placement.d.mts +5 -5
  283. package/es/utils/placement.mjs.map +1 -1
  284. package/package.json +16 -42
  285. package/es/dashboard/StatCard/style.mjs +0 -105
  286. package/es/dashboard/StatCard/style.mjs.map +0 -1
@@ -14,7 +14,7 @@ const styles = {
14
14
  $$css: true
15
15
  },
16
16
  dangerRoot: {
17
- kMwMTN: "lb53gy9q lby09ll3 lbuvp0lo",
17
+ kMwMTN: "lbnn15ax lby09ll3 lbuvp0lo",
18
18
  $$css: true
19
19
  },
20
20
  glass: {
@@ -1 +1 @@
1
- {"version":3,"file":"style.mjs","names":[],"sources":["../../src/ActionIcon/style.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\n\nimport { cssVar } from '@/styles/stylex/cssVar.stylex';\n\nconst hover = ':hover:not(:active)';\nconst pressed = ':active:not(:disabled, [aria-disabled=\"true\"])';\n\nexport const styles = stylex.create({\n active: {\n backgroundColor: cssVar.colorFillSecondary,\n },\n activeFill: {\n backgroundColor: { default: cssVar.colorFillSecondary, [pressed]: cssVar.colorFill },\n },\n activeOutlined: {\n backgroundColor: { 'default': cssVar.colorFillSecondary, ':hover': cssVar.colorFill },\n },\n dangerRoot: {\n color: {\n 'default': cssVar.colorTextTertiary,\n [hover]: cssVar.colorError,\n ':active': cssVar.colorErrorActive,\n },\n },\n glass: {\n backdropFilter: 'saturate(150%) blur(10px)',\n },\n root: {\n color: {\n 'default': cssVar.colorTextTertiary,\n [hover]: cssVar.colorTextSecondary,\n ':active': cssVar.colorText,\n },\n },\n shadow: {\n boxShadow: `0 1px 0 -1px ${cssVar.colorBorder}, 0 1px 2px -0.5px ${cssVar.colorBorder}, 0 2px 2px -1px ${cssVar.colorBorderSecondary}, 0 3px 6px -4px ${cssVar.colorBorderSecondary}`,\n },\n});\n\nexport const actionIconStyles = Object.fromEntries(\n Object.entries(styles).map(([key, value]) => [key, stylex.props(value).className ?? '']),\n) as Record<keyof typeof styles, string>;\n"],"mappings":";;AAKA,MAAa,SAAS;CACpB,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,OAAO;CACT;CACA,gBAAgB;EACd,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,OAAO;EACP,OAAO;CACT;CACA,MAAM;EACJ,QAAQ;EACR,OAAO;CACT;CACA,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;AACF;AACA,MAAa,mBAAmB,OAAO,YAAY,OAAO,QAAQ,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,OAAO,MAAM,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"style.mjs","names":[],"sources":["../../src/ActionIcon/style.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\n\nimport { cssVar } from '@/styles/stylex/cssVar.stylex';\n\nconst hover = ':hover:not(:active)';\nconst pressed = ':active:not(:disabled, [aria-disabled=\"true\"])';\n\nexport const styles = stylex.create({\n active: {\n backgroundColor: cssVar.colorFillSecondary,\n },\n activeFill: {\n backgroundColor: { default: cssVar.colorFillSecondary, [pressed]: cssVar.colorFill },\n },\n activeOutlined: {\n backgroundColor: { 'default': cssVar.colorFillSecondary, ':hover': cssVar.colorFill },\n },\n dangerRoot: {\n color: {\n 'default': `color-mix(in srgb, ${cssVar.colorError} 66%, transparent)`,\n [hover]: cssVar.colorError,\n ':active': cssVar.colorErrorActive,\n },\n },\n glass: {\n backdropFilter: 'saturate(150%) blur(10px)',\n },\n root: {\n color: {\n 'default': cssVar.colorTextTertiary,\n [hover]: cssVar.colorTextSecondary,\n ':active': cssVar.colorText,\n },\n },\n shadow: {\n boxShadow: `0 1px 0 -1px ${cssVar.colorBorder}, 0 1px 2px -0.5px ${cssVar.colorBorder}, 0 2px 2px -1px ${cssVar.colorBorderSecondary}, 0 3px 6px -4px ${cssVar.colorBorderSecondary}`,\n },\n});\n\nexport const actionIconStyles = Object.fromEntries(\n Object.entries(styles).map(([key, value]) => [key, stylex.props(value).className ?? '']),\n) as Record<keyof typeof styles, string>;\n"],"mappings":";;AAKA,MAAa,SAAS;CACpB,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,OAAO;CACT;CACA,gBAAgB;EACd,QAAQ;EACR,OAAO;CACT;CACA,YAAY;EACV,QAAQ;EACR,OAAO;CACT;CACA,OAAO;EACL,OAAO;EACP,OAAO;CACT;CACA,MAAM;EACJ,QAAQ;EACR,OAAO;CACT;CACA,QAAQ;EACN,QAAQ;EACR,OAAO;CACT;AACF;AACA,MAAa,mBAAmB,OAAO,YAAY,OAAO,QAAQ,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,OAAO,MAAM,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC"}
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import { styleProps } from "../styles/stylex/props.mjs";
3
+ import { useMergeRefs } from "../utils/mergeRefs.mjs";
3
4
  import { useEventCallback } from "../hooks/useEventCallback.mjs";
5
+ import { useControlledState } from "../hooks/useControlledState.mjs";
4
6
  import { styles } from "./style.mjs";
5
7
  import { memo, useEffect, useLayoutEffect, useRef, useState } from "react";
6
8
  import { jsx, jsxs } from "react/jsx-runtime";
7
9
  import * as stylex from "@stylexjs/stylex";
8
- import { useMergeRefs } from "react-merge-refs";
9
- import useControlledState from "use-merge-value";
10
10
  //#region src/Anchor/Anchor.tsx
11
11
  const SCROLL_LOCK_FALLBACK_MS = 1e3;
12
12
  const flatten = (items) => items.flatMap((item) => [item, ...flatten(item.children ?? [])]);
@@ -1 +1 @@
1
- {"version":3,"file":"Anchor.mjs","names":[],"sources":["../../src/Anchor/Anchor.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport {\n type CSSProperties,\n memo,\n type MouseEvent,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { useMergeRefs } from 'react-merge-refs';\nimport useControlledState from 'use-merge-value';\n\nimport { useEventCallback } from '@/hooks/useEventCallback';\nimport { styleProps } from '@/styles/stylex/props';\n\nimport { styles } from './style';\nimport type { AnchorItem, AnchorProps } from './type';\n\ntype ScrollContainer = HTMLElement | Window;\n\nconst SCROLL_LOCK_FALLBACK_MS = 1000;\n\nconst flatten = (items: AnchorItem[]): AnchorItem[] =>\n items.flatMap((item) => [item, ...flatten(item.children ?? [])]);\n\nconst getTarget = (href: string) => {\n const hash = href.split('#')[1];\n if (!hash) return null;\n try {\n return document.getElementById(decodeURIComponent(hash));\n } catch {\n return document.getElementById(hash);\n }\n};\n\nconst isWindow = (container: ScrollContainer): container is Window => container === window;\n\nconst getRelativeTop = (element: HTMLElement, container: ScrollContainer) =>\n element.getBoundingClientRect().top -\n (isWindow(container) ? 0 : container.getBoundingClientRect().top);\n\nconst getScrollTop = (container: ScrollContainer) =>\n isWindow(container) ? window.scrollY : container.scrollTop;\n\nconst getActiveKey = (\n items: AnchorItem[],\n container: ScrollContainer,\n offset: number,\n): string | null => {\n let activeKey: string | null = null;\n let activeTop = -Infinity;\n for (const item of flatten(items)) {\n const target = getTarget(item.href);\n if (!target) continue;\n const top = getRelativeTop(target, container);\n if (top <= offset + 1 && top >= activeTop) {\n activeKey = item.key;\n activeTop = top;\n }\n }\n return activeKey;\n};\n\nconst Anchor = memo<AnchorProps>(\n ({\n activeKey,\n className,\n getContainer,\n items,\n offset = 0,\n onChange,\n onClick,\n ref,\n style,\n ...rest\n }) => {\n const [mergedActiveKey, setMergedActiveKey] = useControlledState<string | null>(null, {\n onChange,\n value: activeKey,\n });\n const scrollLockRef = useRef(false);\n const navRef = useRef<HTMLElement>(null);\n const mergedRef = useMergeRefs([ref, navRef]);\n const [marker, setMarker] = useState<CSSProperties>();\n const lockTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const resolveContainer = useEventCallback((): ScrollContainer => getContainer?.() ?? window);\n const setActive = useEventCallback(setMergedActiveKey);\n const spy = useEventCallback(() => {\n if (scrollLockRef.current) return;\n setActive(getActiveKey(items, resolveContainer(), offset));\n });\n\n useEffect(() => {\n const container = resolveContainer();\n let frame = 0;\n const handleScroll = () => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(spy);\n };\n spy();\n container.addEventListener('scroll', handleScroll, { passive: true });\n return () => {\n cancelAnimationFrame(frame);\n container.removeEventListener('scroll', handleScroll);\n };\n }, [items, offset, resolveContainer, spy]);\n\n useEffect(() => () => clearTimeout(lockTimerRef.current), []);\n\n useLayoutEffect(() => {\n const nav = navRef.current;\n if (!nav) return;\n const place = () => {\n const link = [...nav.querySelectorAll<HTMLElement>('a[data-key]')].find(\n (element) => element.dataset.key === mergedActiveKey,\n );\n setMarker(\n link ? { height: link.offsetHeight, insetBlockStart: link.offsetTop } : undefined,\n );\n };\n place();\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(place);\n observer.observe(nav);\n return () => observer.disconnect();\n }, [items, mergedActiveKey]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>, item: AnchorItem) => {\n onClick?.(event, item);\n if (event.defaultPrevented || event.button !== 0) return;\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n\n const target = getTarget(item.href);\n if (!target) return;\n event.preventDefault();\n\n const container = resolveContainer();\n const top = getRelativeTop(target, container) + getScrollTop(container) - offset;\n const reduceMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\n\n // Smooth scrolling may never bring a heading near the page end up to the offset line, so the\n // clicked item is pinned as active until the scroll settles.\n const release = () => {\n scrollLockRef.current = false;\n };\n scrollLockRef.current = true;\n setActive(item.key);\n clearTimeout(lockTimerRef.current);\n lockTimerRef.current = setTimeout(release, SCROLL_LOCK_FALLBACK_MS);\n container.addEventListener('scrollend', release, { once: true });\n container.scrollTo({ behavior: reduceMotion ? 'auto' : 'smooth', top });\n };\n\n const renderList = (list: AnchorItem[], nested: boolean) => (\n <ul {...stylex.props(styles.list, nested && styles.listNested)}>\n {list.map((item) => (\n <li key={item.key}>\n <a\n aria-current={item.key === mergedActiveKey ? 'location' : undefined}\n {...stylex.props(styles.link, nested && styles.linkNested)}\n data-key={item.key}\n href={item.href}\n title={typeof item.title === 'string' ? item.title : undefined}\n onClick={(event) => handleClick(event, item)}\n >\n {item.title}\n </a>\n {item.children && item.children.length > 0 && renderList(item.children, true)}\n </li>\n ))}\n </ul>\n );\n\n return (\n <nav ref={mergedRef} {...rest} {...styleProps(styles.root, className, style)}>\n <span aria-hidden {...stylex.props(styles.marker)} hidden={!marker} style={marker} />\n {renderList(items, false)}\n </nav>\n );\n },\n);\n\nAnchor.displayName = 'Anchor';\n\nexport default Anchor;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Anchor.mjs","names":[],"sources":["../../src/Anchor/Anchor.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport {\n type CSSProperties,\n memo,\n type MouseEvent,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { useControlledState } from '@/hooks/useControlledState';\nimport { useEventCallback } from '@/hooks/useEventCallback';\nimport { styleProps } from '@/styles/stylex/props';\nimport { useMergeRefs } from '@/utils/mergeRefs';\n\nimport { styles } from './style';\nimport type { AnchorItem, AnchorProps } from './type';\n\ntype ScrollContainer = HTMLElement | Window;\n\nconst SCROLL_LOCK_FALLBACK_MS = 1000;\n\nconst flatten = (items: AnchorItem[]): AnchorItem[] =>\n items.flatMap((item) => [item, ...flatten(item.children ?? [])]);\n\nconst getTarget = (href: string) => {\n const hash = href.split('#')[1];\n if (!hash) return null;\n try {\n return document.getElementById(decodeURIComponent(hash));\n } catch {\n return document.getElementById(hash);\n }\n};\n\nconst isWindow = (container: ScrollContainer): container is Window => container === window;\n\nconst getRelativeTop = (element: HTMLElement, container: ScrollContainer) =>\n element.getBoundingClientRect().top -\n (isWindow(container) ? 0 : container.getBoundingClientRect().top);\n\nconst getScrollTop = (container: ScrollContainer) =>\n isWindow(container) ? window.scrollY : container.scrollTop;\n\nconst getActiveKey = (\n items: AnchorItem[],\n container: ScrollContainer,\n offset: number,\n): string | null => {\n let activeKey: string | null = null;\n let activeTop = -Infinity;\n for (const item of flatten(items)) {\n const target = getTarget(item.href);\n if (!target) continue;\n const top = getRelativeTop(target, container);\n if (top <= offset + 1 && top >= activeTop) {\n activeKey = item.key;\n activeTop = top;\n }\n }\n return activeKey;\n};\n\nconst Anchor = memo<AnchorProps>(\n ({\n activeKey,\n className,\n getContainer,\n items,\n offset = 0,\n onChange,\n onClick,\n ref,\n style,\n ...rest\n }) => {\n const [mergedActiveKey, setMergedActiveKey] = useControlledState<string | null>(null, {\n onChange,\n value: activeKey,\n });\n const scrollLockRef = useRef(false);\n const navRef = useRef<HTMLElement>(null);\n const mergedRef = useMergeRefs([ref, navRef]);\n const [marker, setMarker] = useState<CSSProperties>();\n const lockTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const resolveContainer = useEventCallback((): ScrollContainer => getContainer?.() ?? window);\n const setActive = useEventCallback(setMergedActiveKey);\n const spy = useEventCallback(() => {\n if (scrollLockRef.current) return;\n setActive(getActiveKey(items, resolveContainer(), offset));\n });\n\n useEffect(() => {\n const container = resolveContainer();\n let frame = 0;\n const handleScroll = () => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(spy);\n };\n spy();\n container.addEventListener('scroll', handleScroll, { passive: true });\n return () => {\n cancelAnimationFrame(frame);\n container.removeEventListener('scroll', handleScroll);\n };\n }, [items, offset, resolveContainer, spy]);\n\n useEffect(() => () => clearTimeout(lockTimerRef.current), []);\n\n useLayoutEffect(() => {\n const nav = navRef.current;\n if (!nav) return;\n const place = () => {\n const link = [...nav.querySelectorAll<HTMLElement>('a[data-key]')].find(\n (element) => element.dataset.key === mergedActiveKey,\n );\n setMarker(\n link ? { height: link.offsetHeight, insetBlockStart: link.offsetTop } : undefined,\n );\n };\n place();\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(place);\n observer.observe(nav);\n return () => observer.disconnect();\n }, [items, mergedActiveKey]);\n\n const handleClick = (event: MouseEvent<HTMLAnchorElement>, item: AnchorItem) => {\n onClick?.(event, item);\n if (event.defaultPrevented || event.button !== 0) return;\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n\n const target = getTarget(item.href);\n if (!target) return;\n event.preventDefault();\n\n const container = resolveContainer();\n const top = getRelativeTop(target, container) + getScrollTop(container) - offset;\n const reduceMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\n\n // Smooth scrolling may never bring a heading near the page end up to the offset line, so the\n // clicked item is pinned as active until the scroll settles.\n const release = () => {\n scrollLockRef.current = false;\n };\n scrollLockRef.current = true;\n setActive(item.key);\n clearTimeout(lockTimerRef.current);\n lockTimerRef.current = setTimeout(release, SCROLL_LOCK_FALLBACK_MS);\n container.addEventListener('scrollend', release, { once: true });\n container.scrollTo({ behavior: reduceMotion ? 'auto' : 'smooth', top });\n };\n\n const renderList = (list: AnchorItem[], nested: boolean) => (\n <ul {...stylex.props(styles.list, nested && styles.listNested)}>\n {list.map((item) => (\n <li key={item.key}>\n <a\n aria-current={item.key === mergedActiveKey ? 'location' : undefined}\n {...stylex.props(styles.link, nested && styles.linkNested)}\n data-key={item.key}\n href={item.href}\n title={typeof item.title === 'string' ? item.title : undefined}\n onClick={(event) => handleClick(event, item)}\n >\n {item.title}\n </a>\n {item.children && item.children.length > 0 && renderList(item.children, true)}\n </li>\n ))}\n </ul>\n );\n\n return (\n <nav ref={mergedRef} {...rest} {...styleProps(styles.root, className, style)}>\n <span aria-hidden {...stylex.props(styles.marker)} hidden={!marker} style={marker} />\n {renderList(items, false)}\n </nav>\n );\n },\n);\n\nAnchor.displayName = 'Anchor';\n\nexport default Anchor;\n"],"mappings":"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"}
@@ -2,12 +2,12 @@
2
2
  import { styleProps } from "../styles/stylex/props.mjs";
3
3
  import { ActionIconImpl } from "../ActionIcon/ActionIcon.mjs";
4
4
  import { useEventCallback } from "../hooks/useEventCallback.mjs";
5
+ import { useControlledState } from "../hooks/useControlledState.mjs";
5
6
  import { styles } from "./style.mjs";
6
7
  import { Children, createElement, isValidElement, memo, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
7
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
9
  import * as stylex from "@stylexjs/stylex";
9
10
  import { ChevronLeft, ChevronRight } from "lucide-react";
10
- import useControlledState from "use-merge-value";
11
11
  //#region src/Carousel/Carousel.tsx
12
12
  const DEFAULT_INTERVAL = 5e3;
13
13
  const SWIPE_THRESHOLD = 40;
@@ -1 +1 @@
1
- {"version":3,"file":"Carousel.mjs","names":["ActionIcon"],"sources":["../../src/Carousel/Carousel.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport {\n Children,\n isValidElement,\n memo,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport { ActionIconImpl as ActionIcon } from '@/ActionIcon/ActionIcon';\nimport { useEventCallback } from '@/hooks/useEventCallback';\nimport { styleProps } from '@/styles/stylex/props';\n\nimport { styles } from './style';\nimport type { CarouselProps } from './type';\n\nconst DEFAULT_INTERVAL = 5000;\nconst SWIPE_THRESHOLD = 40;\nconst ARROW_SIZE = { blockSize: 28, borderRadius: '50%', size: 16 };\n\nconst Carousel = memo<CarouselProps>(\n ({\n adaptiveHeight = false,\n arrows = false,\n autoplay = false,\n children,\n className,\n defaultIndex = 0,\n dots = true,\n index,\n loop = true,\n onIndexChange,\n onPointerEnter,\n onPointerLeave,\n pauseOnHover = true,\n ref,\n ...rest\n }) => {\n const slides = Children.toArray(children);\n const count = slides.length;\n const keys = slides.map((slide, slideIndex) =>\n isValidElement(slide) && slide.key !== null ? slide.key : slideIndex,\n );\n const [mergedIndex, setMergedIndex] = useControlledState(defaultIndex, {\n onChange: onIndexChange,\n value: index,\n });\n const current = Math.min(Math.max(mergedIndex, 0), Math.max(count - 1, 0));\n\n const [hovered, setHovered] = useState(false);\n const [height, setHeight] = useState<number>();\n const slidesRef = useRef<(HTMLDivElement | null)[]>([]);\n const swipeStartXRef = useRef<number | null>(null);\n\n const goTo = useEventCallback((target: number) => {\n if (count === 0) return;\n const next = loop\n ? ((target % count) + count) % count\n : Math.min(Math.max(target, 0), count - 1);\n if (next !== current) setMergedIndex(next);\n });\n const next = useEventCallback(() => goTo(current + 1));\n const prev = useEventCallback(() => goTo(current - 1));\n\n useImperativeHandle(ref, () => ({ goTo, next, prev }), [goTo, next, prev]);\n\n const interval = autoplay === true ? DEFAULT_INTERVAL : autoplay || 0;\n const paused = pauseOnHover && hovered;\n const atEnd = !loop && current >= count - 1;\n\n useEffect(() => {\n if (!interval || paused || count < 2 || atEnd) return;\n const timer = setTimeout(next, interval);\n return () => clearTimeout(timer);\n }, [interval, paused, count, atEnd, current, next]);\n\n useLayoutEffect(() => {\n const slide = slidesRef.current[current];\n if (!adaptiveHeight || !slide) return;\n setHeight(slide.offsetHeight);\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => setHeight(slide.offsetHeight));\n observer.observe(slide);\n return () => observer.disconnect();\n }, [adaptiveHeight, current, count]);\n\n return (\n <div\n aria-roledescription=\"carousel\"\n className={styleProps(styles.root, className).className}\n role=\"region\"\n onPointerEnter={(event) => {\n onPointerEnter?.(event);\n setHovered(true);\n }}\n onPointerLeave={(event) => {\n onPointerLeave?.(event);\n setHovered(false);\n }}\n {...rest}\n >\n <div\n {...stylex.props(styles.viewport)}\n style={adaptiveHeight && height !== undefined ? { height } : undefined}\n onPointerCancel={() => {\n swipeStartXRef.current = null;\n }}\n onPointerDown={(event) => {\n if (event.pointerType !== 'mouse') swipeStartXRef.current = event.clientX;\n }}\n onPointerUp={(event) => {\n if (swipeStartXRef.current === null) return;\n const delta = event.clientX - swipeStartXRef.current;\n swipeStartXRef.current = null;\n if (Math.abs(delta) < SWIPE_THRESHOLD) return;\n if (delta < 0) next();\n else prev();\n }}\n >\n <div\n aria-live={interval && !paused ? 'off' : 'polite'}\n {...stylex.props(styles.track, adaptiveHeight && styles.trackAdaptive)}\n style={{ transform: `translateX(-${current * 100}%)` }}\n >\n {slides.map((slide, slideIndex) => {\n const active = slideIndex === current;\n return (\n <div\n aria-hidden={!active || undefined}\n aria-label={`${slideIndex + 1} of ${count}`}\n aria-roledescription=\"slide\"\n {...stylex.props(styles.slide)}\n inert={!active}\n key={keys[slideIndex]}\n role=\"group\"\n ref={(node) => {\n slidesRef.current[slideIndex] = node;\n }}\n >\n {slide}\n </div>\n );\n })}\n </div>\n {arrows && count > 1 && (\n <>\n <ActionIcon\n aria-label=\"Previous slide\"\n disabled={!loop && current === 0}\n icon={ChevronLeft}\n size={ARROW_SIZE}\n style={{ insetInlineStart: 8 }}\n xstyle={styles.arrow}\n onClick={prev}\n />\n <ActionIcon\n aria-label=\"Next slide\"\n disabled={atEnd}\n icon={ChevronRight}\n size={ARROW_SIZE}\n style={{ insetInlineEnd: 8 }}\n xstyle={styles.arrow}\n onClick={next}\n />\n </>\n )}\n </div>\n {dots && count > 1 && (\n <div {...stylex.props(styles.dots)}>\n {slides.map((_, dotIndex) => (\n <button\n aria-current={dotIndex === current || undefined}\n aria-label={`Go to slide ${dotIndex + 1}`}\n {...stylex.props(styles.dot)}\n key={keys[dotIndex]}\n type=\"button\"\n onClick={() => goTo(dotIndex)}\n />\n ))}\n </div>\n )}\n </div>\n );\n },\n);\n\nCarousel.displayName = 'Carousel';\n\nexport default Carousel;\n"],"mappings":";;;;;;;;;;;AAWA,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,aAAa;CACjB,WAAW;CACX,cAAc;CACd,MAAM;AACR;AACA,MAAM,WAAW,MAAqB,EACpC,iBAAiB,OACjB,SAAS,OACT,WAAW,OACX,UACA,WACA,eAAe,GACf,OAAO,MACP,OACA,OAAO,MACP,eACA,gBACA,gBACA,eAAe,MACf,KACA,GAAG,WACC;CACJ,MAAM,SAAS,SAAS,QAAQ,QAAQ;CACxC,MAAM,QAAQ,OAAO;CACrB,MAAM,OAAO,OAAO,KAAK,OAAO,eAAe,eAAe,KAAK,KAAK,MAAM,QAAQ,OAAO,MAAM,MAAM,UAAU;CACnH,MAAM,CAAC,aAAa,kBAAkB,mBAAmB,cAAc;EACrE,UAAU;EACV,OAAO;CACT,CAAC;CACD,MAAM,UAAU,KAAK,IAAI,KAAK,IAAI,aAAa,CAAC,GAAG,KAAK,IAAI,QAAQ,GAAG,CAAC,CAAC;CACzE,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,CAAC,QAAQ,aAAa,SAAiB;CAC7C,MAAM,YAAY,OAAkC,CAAC,CAAC;CACtD,MAAM,iBAAiB,OAAsB,IAAI;CACjD,MAAM,OAAO,kBAAkB,WAAmB;EAChD,IAAI,UAAU,GAAG;EACjB,MAAM,OAAO,QAAQ,SAAS,QAAQ,SAAS,QAAQ,KAAK,IAAI,KAAK,IAAI,QAAQ,CAAC,GAAG,QAAQ,CAAC;EAC9F,IAAI,SAAS,SAAS,eAAe,IAAI;CAC3C,CAAC;CACD,MAAM,OAAO,uBAAuB,KAAK,UAAU,CAAC,CAAC;CACrD,MAAM,OAAO,uBAAuB,KAAK,UAAU,CAAC,CAAC;CACrD,oBAAoB,YAAY;EAC9B;EACA;EACA;CACF,IAAI;EAAC;EAAM;EAAM;CAAI,CAAC;CACtB,MAAM,WAAW,aAAa,OAAO,mBAAmB,YAAY;CACpE,MAAM,SAAS,gBAAgB;CAC/B,MAAM,QAAQ,CAAC,QAAQ,WAAW,QAAQ;CAC1C,gBAAgB;EACd,IAAI,CAAC,YAAY,UAAU,QAAQ,KAAK,OAAO;EAC/C,MAAM,QAAQ,WAAW,MAAM,QAAQ;EACvC,aAAa,aAAa,KAAK;CACjC,GAAG;EAAC;EAAU;EAAQ;EAAO;EAAO;EAAS;CAAI,CAAC;CAClD,sBAAsB;EACpB,MAAM,QAAQ,UAAU,QAAQ;EAChC,IAAI,CAAC,kBAAkB,CAAC,OAAO;EAC/B,UAAU,MAAM,YAAY;EAC5B,IAAI,OAAO,mBAAmB,aAAa;EAC3C,MAAM,WAAW,IAAI,qBAAqB,UAAU,MAAM,YAAY,CAAC;EACvE,SAAS,QAAQ,KAAK;EACtB,aAAa,SAAS,WAAW;CACnC,GAAG;EAAC;EAAgB;EAAS;CAAK,CAAC;CACnC,OAAO,qBAAC,OAAD;EAAK,wBAAqB;EAAW,WAAW,WAAW,OAAO,MAAM,SAAS,CAAC,CAAC;EAAW,MAAK;EAAS,iBAAgB,UAAS;GAC1I,iBAAiB,KAAK;GACtB,WAAW,IAAI;EACjB;EAAG,iBAAgB,UAAS;GAC1B,iBAAiB,KAAK;GACtB,WAAW,KAAK;EAClB;EAAG,GAAI;EANA,UAAA,CAOD,qBAAC,OAAD;GAAK,GAAI,OAAO,MAAM,OAAO,QAAQ;GAAG,OAAO,kBAAkB,WAAW,KAAA,IAAY,EAC1F,OACF,IAAI,KAAA;GAAW,uBAAuB;IACpC,eAAe,UAAU;GAC3B;GAAG,gBAAe,UAAS;IACzB,IAAI,MAAM,gBAAgB,SAAS,eAAe,UAAU,MAAM;GACpE;GAAG,cAAa,UAAS;IACvB,IAAI,eAAe,YAAY,MAAM;IACrC,MAAM,QAAQ,MAAM,UAAU,eAAe;IAC7C,eAAe,UAAU;IACzB,IAAI,KAAK,IAAI,KAAK,IAAI,iBAAiB;IACvC,IAAI,QAAQ,GAAG,KAAK;SAAO,KAAK;GAClC;GAZI,UAAA,CAaE,oBAAC,OAAD;IAAK,aAAW,YAAY,CAAC,SAAS,QAAQ;IAAU,GAAI,OAAO,MAAM,OAAO,OAAO,kBAAkB,OAAO,aAAa;IAAG,OAAO,EACzI,WAAW,eAAe,UAAU,IAAI,IAC1C;IACO,UAAA,OAAO,KAAK,OAAO,eAAe;KACrC,MAAM,SAAS,eAAe;KAC9B,OAAO,8BAAC,OAAD;MAAK,eAAa,CAAC,UAAU,KAAA;MAAW,cAAY,GAAG,aAAa,EAAE,MAAM;MAAS,wBAAqB;MAAQ,GAAI,OAAO,MAAM,OAAO,KAAK;MAAG,OAAO,CAAC;MAAQ,KAAK,KAAK;MAAa,MAAK;MAAQ,MAAK,SAAQ;OACxN,UAAU,QAAQ,cAAc;MAClC;KAEW,GADF,KACE;IACb,CAAC;GACM,CAAA,GACJ,UAAU,QAAQ,KAAK,qBAAA,YAAA,EAAA,UAAA,CACpB,oBAACA,gBAAD;IAAY,cAAW;IAAiB,UAAU,CAAC,QAAQ,YAAY;IAAG,MAAM;IAAa,MAAM;IAAY,OAAO,EAC1H,kBAAkB,EACpB;IAAG,QAAQ,OAAO;IAAO,SAAS;GAAO,CAAA,GACnC,oBAACA,gBAAD;IAAY,cAAW;IAAa,UAAU;IAAO,MAAM;IAAc,MAAM;IAAY,OAAO,EACtG,gBAAgB,EAClB;IAAG,QAAQ,OAAO;IAAO,SAAS;GAAO,CAAA,CACnC,EAAA,CAAA,CACD;EACJ,CAAA,GAAA,QAAQ,QAAQ,KAAK,oBAAC,OAAD;GAAK,GAAI,OAAO,MAAM,OAAO,IAAI;GAClD,UAAA,OAAO,KAAK,GAAG,aAAa,8BAAC,UAAD;IAAQ,gBAAc,aAAa,WAAW,KAAA;IAAW,cAAY,eAAe,WAAW;IAAK,GAAI,OAAO,MAAM,OAAO,GAAG;IAAG,KAAK,KAAK;IAAW,MAAK;IAAS,eAAe,KAAK,QAAQ;GAAI,CAAA,CAAC;EAChO,CAAA,CACJ;;AACX,CAAC;AACD,SAAS,cAAc"}
1
+ {"version":3,"file":"Carousel.mjs","names":["ActionIcon"],"sources":["../../src/Carousel/Carousel.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport {\n Children,\n isValidElement,\n memo,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { ActionIconImpl as ActionIcon } from '@/ActionIcon/ActionIcon';\nimport { useControlledState } from '@/hooks/useControlledState';\nimport { useEventCallback } from '@/hooks/useEventCallback';\nimport { styleProps } from '@/styles/stylex/props';\n\nimport { styles } from './style';\nimport type { CarouselProps } from './type';\n\nconst DEFAULT_INTERVAL = 5000;\nconst SWIPE_THRESHOLD = 40;\nconst ARROW_SIZE = { blockSize: 28, borderRadius: '50%', size: 16 };\n\nconst Carousel = memo<CarouselProps>(\n ({\n adaptiveHeight = false,\n arrows = false,\n autoplay = false,\n children,\n className,\n defaultIndex = 0,\n dots = true,\n index,\n loop = true,\n onIndexChange,\n onPointerEnter,\n onPointerLeave,\n pauseOnHover = true,\n ref,\n ...rest\n }) => {\n const slides = Children.toArray(children);\n const count = slides.length;\n const keys = slides.map((slide, slideIndex) =>\n isValidElement(slide) && slide.key !== null ? slide.key : slideIndex,\n );\n const [mergedIndex, setMergedIndex] = useControlledState(defaultIndex, {\n onChange: onIndexChange,\n value: index,\n });\n const current = Math.min(Math.max(mergedIndex, 0), Math.max(count - 1, 0));\n\n const [hovered, setHovered] = useState(false);\n const [height, setHeight] = useState<number>();\n const slidesRef = useRef<(HTMLDivElement | null)[]>([]);\n const swipeStartXRef = useRef<number | null>(null);\n\n const goTo = useEventCallback((target: number) => {\n if (count === 0) return;\n const next = loop\n ? ((target % count) + count) % count\n : Math.min(Math.max(target, 0), count - 1);\n if (next !== current) setMergedIndex(next);\n });\n const next = useEventCallback(() => goTo(current + 1));\n const prev = useEventCallback(() => goTo(current - 1));\n\n useImperativeHandle(ref, () => ({ goTo, next, prev }), [goTo, next, prev]);\n\n const interval = autoplay === true ? DEFAULT_INTERVAL : autoplay || 0;\n const paused = pauseOnHover && hovered;\n const atEnd = !loop && current >= count - 1;\n\n useEffect(() => {\n if (!interval || paused || count < 2 || atEnd) return;\n const timer = setTimeout(next, interval);\n return () => clearTimeout(timer);\n }, [interval, paused, count, atEnd, current, next]);\n\n useLayoutEffect(() => {\n const slide = slidesRef.current[current];\n if (!adaptiveHeight || !slide) return;\n setHeight(slide.offsetHeight);\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => setHeight(slide.offsetHeight));\n observer.observe(slide);\n return () => observer.disconnect();\n }, [adaptiveHeight, current, count]);\n\n return (\n <div\n aria-roledescription=\"carousel\"\n className={styleProps(styles.root, className).className}\n role=\"region\"\n onPointerEnter={(event) => {\n onPointerEnter?.(event);\n setHovered(true);\n }}\n onPointerLeave={(event) => {\n onPointerLeave?.(event);\n setHovered(false);\n }}\n {...rest}\n >\n <div\n {...stylex.props(styles.viewport)}\n style={adaptiveHeight && height !== undefined ? { height } : undefined}\n onPointerCancel={() => {\n swipeStartXRef.current = null;\n }}\n onPointerDown={(event) => {\n if (event.pointerType !== 'mouse') swipeStartXRef.current = event.clientX;\n }}\n onPointerUp={(event) => {\n if (swipeStartXRef.current === null) return;\n const delta = event.clientX - swipeStartXRef.current;\n swipeStartXRef.current = null;\n if (Math.abs(delta) < SWIPE_THRESHOLD) return;\n if (delta < 0) next();\n else prev();\n }}\n >\n <div\n aria-live={interval && !paused ? 'off' : 'polite'}\n {...stylex.props(styles.track, adaptiveHeight && styles.trackAdaptive)}\n style={{ transform: `translateX(-${current * 100}%)` }}\n >\n {slides.map((slide, slideIndex) => {\n const active = slideIndex === current;\n return (\n <div\n aria-hidden={!active || undefined}\n aria-label={`${slideIndex + 1} of ${count}`}\n aria-roledescription=\"slide\"\n {...stylex.props(styles.slide)}\n inert={!active}\n key={keys[slideIndex]}\n role=\"group\"\n ref={(node) => {\n slidesRef.current[slideIndex] = node;\n }}\n >\n {slide}\n </div>\n );\n })}\n </div>\n {arrows && count > 1 && (\n <>\n <ActionIcon\n aria-label=\"Previous slide\"\n disabled={!loop && current === 0}\n icon={ChevronLeft}\n size={ARROW_SIZE}\n style={{ insetInlineStart: 8 }}\n xstyle={styles.arrow}\n onClick={prev}\n />\n <ActionIcon\n aria-label=\"Next slide\"\n disabled={atEnd}\n icon={ChevronRight}\n size={ARROW_SIZE}\n style={{ insetInlineEnd: 8 }}\n xstyle={styles.arrow}\n onClick={next}\n />\n </>\n )}\n </div>\n {dots && count > 1 && (\n <div {...stylex.props(styles.dots)}>\n {slides.map((_, dotIndex) => (\n <button\n aria-current={dotIndex === current || undefined}\n aria-label={`Go to slide ${dotIndex + 1}`}\n {...stylex.props(styles.dot)}\n key={keys[dotIndex]}\n type=\"button\"\n onClick={() => goTo(dotIndex)}\n />\n ))}\n </div>\n )}\n </div>\n );\n },\n);\n\nCarousel.displayName = 'Carousel';\n\nexport default Carousel;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CodeDiff.mjs","names":[],"sources":["../../src/CodeDiff/CodeDiff.tsx"],"sourcesContent":["'use client';\n\nimport type { FileDiffOptions } from '@pierre/diffs';\nimport { MultiFileDiff } from '@pierre/diffs/react';\nimport { memo, useMemo } from 'react';\n\nimport { useThemeMode } from '@/styles/theme/scope';\n\nimport { DiffPanel } from './DiffPanel';\nimport { getLobeDiffOptions, registerLobeDiffThemes } from './theme';\nimport type { CodeDiffProps } from './type';\n\nregisterLobeDiffThemes();\n\nconst countContentChanges = (\n oldContent: string,\n newContent: string,\n): { additions: number; deletions: number } => {\n const oldLines = oldContent.split('\\n');\n const newLines = newContent.split('\\n');\n\n const oldSet = new Set(oldLines);\n const newSet = new Set(newLines);\n\n let deletions = 0;\n let additions = 0;\n\n for (const line of oldLines) {\n if (!newSet.has(line)) {\n deletions++;\n }\n }\n\n for (const line of newLines) {\n if (!oldSet.has(line)) {\n additions++;\n }\n }\n\n return { additions, deletions };\n};\n\nexport const CodeDiff = memo<CodeDiffProps>(\n ({\n oldContent,\n newContent,\n language,\n fileName,\n viewMode = 'split',\n showHeader = true,\n defaultExpand = true,\n fullFeatured = true,\n variant = 'filled',\n className,\n classNames,\n styles: customStyles,\n actionsRender,\n diffOptions,\n ...rest\n }) => {\n const { isDarkMode } = useThemeMode();\n\n const displayName = useMemo(() => {\n if (fileName) return fileName;\n if (language) return language;\n return 'diff';\n }, [fileName, language]);\n\n const { additions, deletions } = useMemo(\n () => countContentChanges(oldContent, newContent),\n [oldContent, newContent],\n );\n\n const actions = useMemo(() => {\n if (!actionsRender) return null;\n return actionsRender({\n newContent,\n oldContent,\n originalNode: null,\n });\n }, [actionsRender, oldContent, newContent]);\n\n const oldFile = useMemo(\n () => ({\n contents: oldContent,\n lang: language as any,\n name: fileName || 'file',\n }),\n [oldContent, language, fileName],\n );\n\n const newFile = useMemo(\n () => ({\n contents: newContent,\n lang: language as any,\n name: fileName || 'file',\n }),\n [newContent, language, fileName],\n );\n\n const options = useMemo<FileDiffOptions<string>>(\n () => getLobeDiffOptions({ diffOptions, isDarkMode, viewMode }),\n [isDarkMode, viewMode, diffOptions],\n );\n\n return (\n <DiffPanel\n actions={actions}\n additions={additions}\n body={<MultiFileDiff newFile={newFile} oldFile={oldFile} options={options} />}\n className={className}\n classNames={classNames}\n dataCodeType=\"code-diff\"\n defaultExpand={defaultExpand}\n deletions={deletions}\n displayName={displayName}\n fileName={fileName}\n fullFeatured={fullFeatured}\n showHeader={showHeader}\n styles={customStyles}\n variant={variant}\n {...rest}\n />\n );\n },\n);\n\nCodeDiff.displayName = 'CodeDiff';\n\nexport default CodeDiff;\n"],"mappings":";;;;;;;;AAYA,uBAAuB;AAEvB,MAAM,uBACJ,YACA,eAC6C;CAC7C,MAAM,WAAW,WAAW,MAAM,IAAI;CACtC,MAAM,WAAW,WAAW,MAAM,IAAI;CAEtC,MAAM,SAAS,IAAI,IAAI,QAAQ;CAC/B,MAAM,SAAS,IAAI,IAAI,QAAQ;CAE/B,IAAI,YAAY;CAChB,IAAI,YAAY;CAEhB,KAAK,MAAM,QAAQ,UACjB,IAAI,CAAC,OAAO,IAAI,IAAI,GAClB;CAIJ,KAAK,MAAM,QAAQ,UACjB,IAAI,CAAC,OAAO,IAAI,IAAI,GAClB;CAIJ,OAAO;EAAE;EAAW;CAAU;AAChC;AAEA,MAAa,WAAW,MACrB,EACC,YACA,YACA,UACA,UACA,WAAW,SACX,aAAa,MACb,gBAAgB,MAChB,eAAe,MACf,UAAU,UACV,WACA,YACA,QAAQ,cACR,eACA,aACA,GAAG,WACC;CACJ,MAAM,EAAE,eAAe,aAAa;CAEpC,MAAM,cAAc,cAAc;EAChC,IAAI,UAAU,OAAO;EACrB,IAAI,UAAU,OAAO;EACrB,OAAO;CACT,GAAG,CAAC,UAAU,QAAQ,CAAC;CAEvB,MAAM,EAAE,WAAW,cAAc,cACzB,oBAAoB,YAAY,UAAU,GAChD,CAAC,YAAY,UAAU,CACzB;CAEA,MAAM,UAAU,cAAc;EAC5B,IAAI,CAAC,eAAe,OAAO;EAC3B,OAAO,cAAc;GACnB;GACA;GACA,cAAc;EAChB,CAAC;CACH,GAAG;EAAC;EAAe;EAAY;CAAU,CAAC;CAE1C,MAAM,UAAU,eACP;EACL,UAAU;EACV,MAAM;EACN,MAAM,YAAY;CACpB,IACA;EAAC;EAAY;EAAU;CAAQ,CACjC;CAEA,MAAM,UAAU,eACP;EACL,UAAU;EACV,MAAM;EACN,MAAM,YAAY;CACpB,IACA;EAAC;EAAY;EAAU;CAAQ,CACjC;CAEA,MAAM,UAAU,cACR,mBAAmB;EAAE;EAAa;EAAY;CAAS,CAAC,GAC9D;EAAC;EAAY;EAAU;CAAW,CACpC;CAEA,OACE,oBAAC,WAAD;EACW;EACE;EACX,MAAM,oBAAC,eAAD;GAAwB;GAAkB;GAAkB;EAAU,CAAA;EACjE;EACC;EACZ,cAAa;EACE;EACJ;EACE;EACH;EACI;EACF;EACZ,QAAQ;EACC;EACT,GAAI;CACL,CAAA;AAEL,CACF;AAEA,SAAS,cAAc"}
1
+ {"version":3,"file":"CodeDiff.mjs","names":[],"sources":["../../src/CodeDiff/CodeDiff.tsx"],"sourcesContent":["'use client';\n\nimport type { FileDiffOptions } from '@pierre/diffs';\nimport { MultiFileDiff } from '@pierre/diffs/react';\nimport { memo, useMemo } from 'react';\n\nimport { useThemeMode } from '@/styles/theme/scope';\n\nimport { DiffPanel } from './DiffPanel';\nimport { getLobeDiffOptions, registerLobeDiffThemes } from './theme';\nimport type { CodeDiffProps } from './type';\n\nregisterLobeDiffThemes();\n\nconst countContentChanges = (\n oldContent: string,\n newContent: string,\n): { additions: number; deletions: number } => {\n const oldLines = oldContent.split('\\n');\n const newLines = newContent.split('\\n');\n\n const oldSet = new Set(oldLines);\n const newSet = new Set(newLines);\n\n let deletions = 0;\n let additions = 0;\n\n for (const line of oldLines) {\n if (!newSet.has(line)) {\n deletions++;\n }\n }\n\n for (const line of newLines) {\n if (!oldSet.has(line)) {\n additions++;\n }\n }\n\n return { additions, deletions };\n};\n\nexport const CodeDiff = memo<CodeDiffProps>(\n ({\n oldContent,\n newContent,\n language,\n fileName,\n viewMode = 'split',\n showHeader = true,\n defaultExpand = true,\n fullFeatured = true,\n variant = 'filled',\n className,\n classNames,\n styles: customStyles,\n actionsRender,\n diffOptions,\n ...rest\n }) => {\n const { isDarkMode } = useThemeMode();\n\n const displayName = useMemo(() => {\n if (fileName) return fileName;\n if (language) return language;\n return 'diff';\n }, [fileName, language]);\n\n const { additions, deletions } = useMemo(\n () => countContentChanges(oldContent, newContent),\n [oldContent, newContent],\n );\n\n const actions = useMemo(() => {\n if (!actionsRender) return null;\n return actionsRender({\n newContent,\n oldContent,\n originalNode: null,\n });\n }, [actionsRender, oldContent, newContent]);\n\n const oldFile = useMemo(\n () => ({\n contents: oldContent,\n lang: language as any,\n name: fileName || 'file',\n }),\n [oldContent, language, fileName],\n );\n\n const newFile = useMemo(\n () => ({\n contents: newContent,\n lang: language as any,\n name: fileName || 'file',\n }),\n [newContent, language, fileName],\n );\n\n const options = useMemo<FileDiffOptions<string, undefined>>(\n () => getLobeDiffOptions({ diffOptions, isDarkMode, viewMode }),\n [isDarkMode, viewMode, diffOptions],\n );\n\n return (\n <DiffPanel\n actions={actions}\n additions={additions}\n body={<MultiFileDiff newFile={newFile} oldFile={oldFile} options={options} />}\n className={className}\n classNames={classNames}\n dataCodeType=\"code-diff\"\n defaultExpand={defaultExpand}\n deletions={deletions}\n displayName={displayName}\n fileName={fileName}\n fullFeatured={fullFeatured}\n showHeader={showHeader}\n styles={customStyles}\n variant={variant}\n {...rest}\n />\n );\n },\n);\n\nCodeDiff.displayName = 'CodeDiff';\n\nexport default CodeDiff;\n"],"mappings":";;;;;;;;AAYA,uBAAuB;AAEvB,MAAM,uBACJ,YACA,eAC6C;CAC7C,MAAM,WAAW,WAAW,MAAM,IAAI;CACtC,MAAM,WAAW,WAAW,MAAM,IAAI;CAEtC,MAAM,SAAS,IAAI,IAAI,QAAQ;CAC/B,MAAM,SAAS,IAAI,IAAI,QAAQ;CAE/B,IAAI,YAAY;CAChB,IAAI,YAAY;CAEhB,KAAK,MAAM,QAAQ,UACjB,IAAI,CAAC,OAAO,IAAI,IAAI,GAClB;CAIJ,KAAK,MAAM,QAAQ,UACjB,IAAI,CAAC,OAAO,IAAI,IAAI,GAClB;CAIJ,OAAO;EAAE;EAAW;CAAU;AAChC;AAEA,MAAa,WAAW,MACrB,EACC,YACA,YACA,UACA,UACA,WAAW,SACX,aAAa,MACb,gBAAgB,MAChB,eAAe,MACf,UAAU,UACV,WACA,YACA,QAAQ,cACR,eACA,aACA,GAAG,WACC;CACJ,MAAM,EAAE,eAAe,aAAa;CAEpC,MAAM,cAAc,cAAc;EAChC,IAAI,UAAU,OAAO;EACrB,IAAI,UAAU,OAAO;EACrB,OAAO;CACT,GAAG,CAAC,UAAU,QAAQ,CAAC;CAEvB,MAAM,EAAE,WAAW,cAAc,cACzB,oBAAoB,YAAY,UAAU,GAChD,CAAC,YAAY,UAAU,CACzB;CAEA,MAAM,UAAU,cAAc;EAC5B,IAAI,CAAC,eAAe,OAAO;EAC3B,OAAO,cAAc;GACnB;GACA;GACA,cAAc;EAChB,CAAC;CACH,GAAG;EAAC;EAAe;EAAY;CAAU,CAAC;CAE1C,MAAM,UAAU,eACP;EACL,UAAU;EACV,MAAM;EACN,MAAM,YAAY;CACpB,IACA;EAAC;EAAY;EAAU;CAAQ,CACjC;CAEA,MAAM,UAAU,eACP;EACL,UAAU;EACV,MAAM;EACN,MAAM,YAAY;CACpB,IACA;EAAC;EAAY;EAAU;CAAQ,CACjC;CAEA,MAAM,UAAU,cACR,mBAAmB;EAAE;EAAa;EAAY;CAAS,CAAC,GAC9D;EAAC;EAAY;EAAU;CAAW,CACpC;CAEA,OACE,oBAAC,WAAD;EACW;EACE;EACX,MAAM,oBAAC,eAAD;GAAwB;GAAkB;GAAkB;EAAU,CAAA;EACjE;EACC;EACZ,cAAa;EACE;EACJ;EACE;EACH;EACI;EACF;EACZ,QAAQ;EACC;EACT,GAAI;CACL,CAAA;AAEL,CACF;AAEA,SAAS,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"PatchDiff.mjs","names":["PatchDiff","PierrePatchDiff"],"sources":["../../src/CodeDiff/PatchDiff.tsx"],"sourcesContent":["'use client';\n\nimport type { FileDiffOptions } from '@pierre/diffs';\nimport { PatchDiff as PierrePatchDiff } from '@pierre/diffs/react';\nimport { memo, useMemo } from 'react';\n\nimport { useThemeMode } from '@/styles/theme/scope';\n\nimport { DiffPanel } from './DiffPanel';\nimport { getLobeDiffOptions, registerLobeDiffThemes } from './theme';\nimport type { PatchDiffProps } from './type';\n\nregisterLobeDiffThemes();\n\nconst countPatchChanges = (patch: string): { additions: number; deletions: number } => {\n const lines = patch.split('\\n');\n let additions = 0;\n let deletions = 0;\n\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {\n additions++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n deletions++;\n }\n }\n\n return { additions, deletions };\n};\n\nexport const PatchDiff = memo<PatchDiffProps>(\n ({\n patch,\n language,\n fileName,\n viewMode = 'split',\n showHeader = true,\n defaultExpand = true,\n fullFeatured = true,\n variant = 'filled',\n className,\n classNames,\n styles: customStyles,\n actionsRender,\n diffOptions,\n ...rest\n }) => {\n const { isDarkMode } = useThemeMode();\n\n const displayName = useMemo(() => {\n if (fileName) return fileName;\n // Try to extract filename from patch header\n const match = patch.match(/^(?:-{3}|\\+{3})\\s+(?:a\\/|b\\/)?(.+?)(?:\\t|$)/m);\n if (match?.[1]) return match[1];\n if (language) return language;\n return 'patch';\n }, [fileName, patch, language]);\n\n const { additions, deletions } = useMemo(() => countPatchChanges(patch), [patch]);\n\n const actions = useMemo(() => {\n if (!actionsRender) return null;\n return actionsRender({\n originalNode: null,\n patch,\n });\n }, [actionsRender, patch]);\n\n const options = useMemo<FileDiffOptions<string>>(\n () => getLobeDiffOptions({ diffOptions, isDarkMode, viewMode }),\n [isDarkMode, viewMode, diffOptions],\n );\n\n return (\n <DiffPanel\n actions={actions}\n additions={additions}\n body={<PierrePatchDiff options={options} patch={patch} />}\n className={className}\n classNames={classNames}\n dataCodeType=\"patch-diff\"\n defaultExpand={defaultExpand}\n deletions={deletions}\n displayName={displayName}\n fileName={fileName}\n fullFeatured={fullFeatured}\n showHeader={showHeader}\n styles={customStyles}\n variant={variant}\n {...rest}\n />\n );\n },\n);\n\nPatchDiff.displayName = 'PatchDiff';\n\nexport default PatchDiff;\n"],"mappings":";;;;;;;;AAYA,uBAAuB;AAEvB,MAAM,qBAAqB,UAA4D;CACrF,MAAM,QAAQ,MAAM,MAAM,IAAI;CAC9B,IAAI,YAAY;CAChB,IAAI,YAAY;CAEhB,KAAK,MAAM,QAAQ,OACjB,IAAI,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,WAAW,KAAK,GAChD;MACK,IAAI,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,WAAW,KAAK,GACvD;CAIJ,OAAO;EAAE;EAAW;CAAU;AAChC;AAEA,MAAaA,cAAY,MACtB,EACC,OACA,UACA,UACA,WAAW,SACX,aAAa,MACb,gBAAgB,MAChB,eAAe,MACf,UAAU,UACV,WACA,YACA,QAAQ,cACR,eACA,aACA,GAAG,WACC;CACJ,MAAM,EAAE,eAAe,aAAa;CAEpC,MAAM,cAAc,cAAc;EAChC,IAAI,UAAU,OAAO;EAErB,MAAM,QAAQ,MAAM,MAAM,8CAA8C;EACxE,IAAI,QAAQ,IAAI,OAAO,MAAM;EAC7B,IAAI,UAAU,OAAO;EACrB,OAAO;CACT,GAAG;EAAC;EAAU;EAAO;CAAQ,CAAC;CAE9B,MAAM,EAAE,WAAW,cAAc,cAAc,kBAAkB,KAAK,GAAG,CAAC,KAAK,CAAC;CAEhF,MAAM,UAAU,cAAc;EAC5B,IAAI,CAAC,eAAe,OAAO;EAC3B,OAAO,cAAc;GACnB,cAAc;GACd;EACF,CAAC;CACH,GAAG,CAAC,eAAe,KAAK,CAAC;CAEzB,MAAM,UAAU,cACR,mBAAmB;EAAE;EAAa;EAAY;CAAS,CAAC,GAC9D;EAAC;EAAY;EAAU;CAAW,CACpC;CAEA,OACE,oBAAC,WAAD;EACW;EACE;EACX,MAAM,oBAACC,WAAD;GAA0B;GAAgB;EAAQ,CAAA;EAC7C;EACC;EACZ,cAAa;EACE;EACJ;EACE;EACH;EACI;EACF;EACZ,QAAQ;EACC;EACT,GAAI;CACL,CAAA;AAEL,CACF;AAEA,YAAU,cAAc"}
1
+ {"version":3,"file":"PatchDiff.mjs","names":["PatchDiff","PierrePatchDiff"],"sources":["../../src/CodeDiff/PatchDiff.tsx"],"sourcesContent":["'use client';\n\nimport type { FileDiffOptions } from '@pierre/diffs';\nimport { PatchDiff as PierrePatchDiff } from '@pierre/diffs/react';\nimport { memo, useMemo } from 'react';\n\nimport { useThemeMode } from '@/styles/theme/scope';\n\nimport { DiffPanel } from './DiffPanel';\nimport { getLobeDiffOptions, registerLobeDiffThemes } from './theme';\nimport type { PatchDiffProps } from './type';\n\nregisterLobeDiffThemes();\n\nconst countPatchChanges = (patch: string): { additions: number; deletions: number } => {\n const lines = patch.split('\\n');\n let additions = 0;\n let deletions = 0;\n\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {\n additions++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n deletions++;\n }\n }\n\n return { additions, deletions };\n};\n\nexport const PatchDiff = memo<PatchDiffProps>(\n ({\n patch,\n language,\n fileName,\n viewMode = 'split',\n showHeader = true,\n defaultExpand = true,\n fullFeatured = true,\n variant = 'filled',\n className,\n classNames,\n styles: customStyles,\n actionsRender,\n diffOptions,\n ...rest\n }) => {\n const { isDarkMode } = useThemeMode();\n\n const displayName = useMemo(() => {\n if (fileName) return fileName;\n // Try to extract filename from patch header\n const match = patch.match(/^(?:-{3}|\\+{3})\\s+(?:a\\/|b\\/)?(.+?)(?:\\t|$)/m);\n if (match?.[1]) return match[1];\n if (language) return language;\n return 'patch';\n }, [fileName, patch, language]);\n\n const { additions, deletions } = useMemo(() => countPatchChanges(patch), [patch]);\n\n const actions = useMemo(() => {\n if (!actionsRender) return null;\n return actionsRender({\n originalNode: null,\n patch,\n });\n }, [actionsRender, patch]);\n\n const options = useMemo<FileDiffOptions<string, undefined>>(\n () => getLobeDiffOptions({ diffOptions, isDarkMode, viewMode }),\n [isDarkMode, viewMode, diffOptions],\n );\n\n return (\n <DiffPanel\n actions={actions}\n additions={additions}\n body={<PierrePatchDiff options={options} patch={patch} />}\n className={className}\n classNames={classNames}\n dataCodeType=\"patch-diff\"\n defaultExpand={defaultExpand}\n deletions={deletions}\n displayName={displayName}\n fileName={fileName}\n fullFeatured={fullFeatured}\n showHeader={showHeader}\n styles={customStyles}\n variant={variant}\n {...rest}\n />\n );\n },\n);\n\nPatchDiff.displayName = 'PatchDiff';\n\nexport default PatchDiff;\n"],"mappings":";;;;;;;;AAYA,uBAAuB;AAEvB,MAAM,qBAAqB,UAA4D;CACrF,MAAM,QAAQ,MAAM,MAAM,IAAI;CAC9B,IAAI,YAAY;CAChB,IAAI,YAAY;CAEhB,KAAK,MAAM,QAAQ,OACjB,IAAI,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,WAAW,KAAK,GAChD;MACK,IAAI,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,WAAW,KAAK,GACvD;CAIJ,OAAO;EAAE;EAAW;CAAU;AAChC;AAEA,MAAaA,cAAY,MACtB,EACC,OACA,UACA,UACA,WAAW,SACX,aAAa,MACb,gBAAgB,MAChB,eAAe,MACf,UAAU,UACV,WACA,YACA,QAAQ,cACR,eACA,aACA,GAAG,WACC;CACJ,MAAM,EAAE,eAAe,aAAa;CAEpC,MAAM,cAAc,cAAc;EAChC,IAAI,UAAU,OAAO;EAErB,MAAM,QAAQ,MAAM,MAAM,8CAA8C;EACxE,IAAI,QAAQ,IAAI,OAAO,MAAM;EAC7B,IAAI,UAAU,OAAO;EACrB,OAAO;CACT,GAAG;EAAC;EAAU;EAAO;CAAQ,CAAC;CAE9B,MAAM,EAAE,WAAW,cAAc,cAAc,kBAAkB,KAAK,GAAG,CAAC,KAAK,CAAC;CAEhF,MAAM,UAAU,cAAc;EAC5B,IAAI,CAAC,eAAe,OAAO;EAC3B,OAAO,cAAc;GACnB,cAAc;GACd;EACF,CAAC;CACH,GAAG,CAAC,eAAe,KAAK,CAAC;CAEzB,MAAM,UAAU,cACR,mBAAmB;EAAE;EAAa;EAAY;CAAS,CAAC,GAC9D;EAAC;EAAY;EAAU;CAAW,CACpC;CAEA,OACE,oBAAC,WAAD;EACW;EACE;EACX,MAAM,oBAACC,WAAD;GAA0B;GAAgB;EAAQ,CAAA;EAC7C;EACC;EACZ,cAAa;EACE;EACJ;EACE;EACH;EACI;EACF;EACZ,QAAQ;EACC;EACT,GAAI;CACL,CAAA;AAEL,CACF;AAEA,YAAU,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"theme.mjs","names":["lobeTheme"],"sources":["../../src/CodeDiff/theme.ts"],"sourcesContent":["import type { FileDiffOptions } from '@pierre/diffs';\nimport { registerCustomTheme, resolveTheme } from '@pierre/diffs';\n\nimport lobeTheme from '@/Highlighter/theme/lobe-theme';\nimport { cssVar } from '@/styles/stylex/cssVar.stylex';\n\nimport type { DiffViewMode } from './type';\n\nlet isLobeDiffThemeRegistered = false;\n\nexport const registerLobeDiffThemes = () => {\n if (isLobeDiffThemeRegistered) return;\n\n registerCustomTheme('lobe-theme', () => Promise.resolve(lobeTheme as any));\n void resolveTheme('lobe-theme');\n\n isLobeDiffThemeRegistered = true;\n};\n\nconst customSeparatorCSS = `\n :host {\n --diffs-dark-bg: transparent !important;\n --diffs-light-bg: transparent !important;\n --diffs-gap-fallback: 8px;\n --diffs-added-light: ${cssVar.colorSuccessHover};\n --diffs-added-dark: ${cssVar.colorSuccessBorderHover};\n --diffs-modified-light: ${cssVar.colorInfoHover};\n --diffs-modified-dark: ${cssVar.colorInfoBorderHover};\n --diffs-deleted-light: ${cssVar.colorErrorHover};\n --diffs-deleted-dark: ${cssVar.colorErrorBorderHover};\n }\n\n [data-gutter-buffer] {\n opacity: 0.2 !important;\n }\n\n [data-code] {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n\n [data-gutter] {\n backdrop-filter: blur(16px) !important;\n }\n`;\n\nexport const getLobeDiffOptions = ({\n diffOptions,\n isDarkMode,\n viewMode,\n}: {\n diffOptions?: FileDiffOptions<string>;\n isDarkMode: boolean;\n viewMode: DiffViewMode;\n}): FileDiffOptions<string> => ({\n theme: {\n dark: 'lobe-theme',\n light: 'lobe-theme',\n },\n themeType: isDarkMode ? 'dark' : 'light',\n diffStyle: viewMode,\n disableFileHeader: true,\n unsafeCSS: customSeparatorCSS,\n ...diffOptions,\n});\n"],"mappings":";;;;AAQA,IAAI,4BAA4B;AAEhC,MAAa,+BAA+B;CAC1C,IAAI,2BAA2B;CAE/B,oBAAoB,oBAAoB,QAAQ,QAAQA,kBAAgB,CAAC;CACzE,aAAkB,YAAY;CAE9B,4BAA4B;AAC9B;AAEA,MAAM,qBAAqB;;;;;2BAKA,OAAO,kBAAkB;0BAC1B,OAAO,wBAAwB;8BAC3B,OAAO,eAAe;6BACvB,OAAO,qBAAqB;6BAC5B,OAAO,gBAAgB;4BACxB,OAAO,sBAAsB;;;;;;;;;;;;;;;;AAiBzD,MAAa,sBAAsB,EACjC,aACA,YACA,gBAK8B;CAC9B,OAAO;EACL,MAAM;EACN,OAAO;CACT;CACA,WAAW,aAAa,SAAS;CACjC,WAAW;CACX,mBAAmB;CACnB,WAAW;CACX,GAAG;AACL"}
1
+ {"version":3,"file":"theme.mjs","names":["lobeTheme"],"sources":["../../src/CodeDiff/theme.ts"],"sourcesContent":["import type { FileDiffOptions } from '@pierre/diffs';\nimport { registerCustomTheme, resolveTheme } from '@pierre/diffs';\n\nimport lobeTheme from '@/Highlighter/theme/lobe-theme';\nimport { cssVar } from '@/styles/stylex/cssVar.stylex';\n\nimport type { DiffViewMode } from './type';\n\nlet isLobeDiffThemeRegistered = false;\n\nexport const registerLobeDiffThemes = () => {\n if (isLobeDiffThemeRegistered) return;\n\n registerCustomTheme('lobe-theme', () => Promise.resolve(lobeTheme as any));\n void resolveTheme('lobe-theme');\n\n isLobeDiffThemeRegistered = true;\n};\n\nconst customSeparatorCSS = `\n :host {\n --diffs-dark-bg: transparent !important;\n --diffs-light-bg: transparent !important;\n --diffs-gap-fallback: 8px;\n --diffs-added-light: ${cssVar.colorSuccessHover};\n --diffs-added-dark: ${cssVar.colorSuccessBorderHover};\n --diffs-modified-light: ${cssVar.colorInfoHover};\n --diffs-modified-dark: ${cssVar.colorInfoBorderHover};\n --diffs-deleted-light: ${cssVar.colorErrorHover};\n --diffs-deleted-dark: ${cssVar.colorErrorBorderHover};\n }\n\n [data-gutter-buffer] {\n opacity: 0.2 !important;\n }\n\n [data-code] {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n\n [data-gutter] {\n backdrop-filter: blur(16px) !important;\n }\n`;\n\nexport const getLobeDiffOptions = ({\n diffOptions,\n isDarkMode,\n viewMode,\n}: {\n diffOptions?: FileDiffOptions<string, undefined>;\n isDarkMode: boolean;\n viewMode: DiffViewMode;\n}): FileDiffOptions<string, undefined> => ({\n theme: {\n dark: 'lobe-theme',\n light: 'lobe-theme',\n },\n themeType: isDarkMode ? 'dark' : 'light',\n diffStyle: viewMode,\n disableFileHeader: true,\n unsafeCSS: customSeparatorCSS,\n ...diffOptions,\n});\n"],"mappings":";;;;AAQA,IAAI,4BAA4B;AAEhC,MAAa,+BAA+B;CAC1C,IAAI,2BAA2B;CAE/B,oBAAoB,oBAAoB,QAAQ,QAAQA,kBAAgB,CAAC;CACzE,aAAkB,YAAY;CAE9B,4BAA4B;AAC9B;AAEA,MAAM,qBAAqB;;;;;2BAKA,OAAO,kBAAkB;0BAC1B,OAAO,wBAAwB;8BAC3B,OAAO,eAAe;6BACvB,OAAO,qBAAqB;6BAC5B,OAAO,gBAAgB;4BACxB,OAAO,sBAAsB;;;;;;;;;;;;;;;;AAiBzD,MAAa,sBAAsB,EACjC,aACA,YACA,gBAKyC;CACzC,OAAO;EACL,MAAM;EACN,OAAO;CACT;CACA,WAAW,aAAa,SAAS;CACjC,WAAW;CACX,mBAAmB;CACnB,WAAW;CACX,GAAG;AACL"}
@@ -28,7 +28,7 @@ export interface CodeDiffProps extends Omit<FlexboxProps, 'children'> {
28
28
  /**
29
29
  * Options for the diff component
30
30
  */
31
- diffOptions?: FileDiffOptions<string>;
31
+ diffOptions?: FileDiffOptions<string, undefined>;
32
32
  /**
33
33
  * File name to display
34
34
  */
@@ -96,7 +96,7 @@ export interface PatchDiffProps extends Omit<FlexboxProps, 'children'> {
96
96
  /**
97
97
  * Options for the diff component
98
98
  */
99
- diffOptions?: FileDiffOptions<string>;
99
+ diffOptions?: FileDiffOptions<string, undefined>;
100
100
  /**
101
101
  * File name to display (optional, extracted from patch if not provided)
102
102
  */
@@ -2,12 +2,12 @@
2
2
  import { styleProps } from "../styles/stylex/props.mjs";
3
3
  import { cssVar } from "../styles/stylex/cssVar.stylex.mjs";
4
4
  import FlexBasic_default from "../Flex/FlexBasic.mjs";
5
+ import { useControlledState } from "../hooks/useControlledState.mjs";
5
6
  import { SyntaxHighlighterImpl } from "../Highlighter/SyntaxHighlighter/index.mjs";
6
7
  import { styles, variantStyles } from "./style.mjs";
7
8
  import { memo } from "react";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  import clsx from "clsx";
10
- import useControlledState from "use-merge-value";
11
11
  //#region src/CodeEditor/CodeEditor.tsx
12
12
  const CodeEditor = memo(({ autoFocus, classNames, styles: customStyles, defaultValue = "", onChange, placeholder = "", style, className, onValueChange, value, language = "markdown", variant = "borderless", width, height, flex, ref, ...rest }) => {
13
13
  const [code, setCode] = useControlledState(defaultValue, {
@@ -1 +1 @@
1
- {"version":3,"file":"CodeEditor.mjs","names":["useMergeState","Flexbox"],"sources":["../../src/CodeEditor/CodeEditor.tsx"],"sourcesContent":["'use client';\n\nimport clsx from 'clsx';\nimport { memo } from 'react';\nimport useMergeState from 'use-merge-value';\n\nimport { Flexbox } from '@/Flex';\nimport { SyntaxHighlighterImpl } from '@/Highlighter/SyntaxHighlighter';\nimport { cssVar } from '@/styles/stylex/cssVar.stylex';\nimport { styleProps } from '@/styles/stylex/props';\n\nimport { styles, variantStyles } from './style';\nimport type { CodeEditorProps } from './type';\n\nconst CodeEditor = memo<CodeEditorProps>(\n ({\n autoFocus,\n classNames,\n styles: customStyles,\n defaultValue = '',\n onChange,\n placeholder = '',\n style,\n className,\n onValueChange,\n value,\n language = 'markdown',\n variant = 'borderless',\n width,\n height,\n flex,\n ref,\n ...rest\n }) => {\n const [code, setCode] = useMergeState(defaultValue, {\n defaultValue,\n onChange: onValueChange,\n value,\n });\n\n return (\n <Flexbox\n flex={flex}\n height={height ?? 'fit-content'}\n width={width ?? '100%'}\n {...styleProps(\n [styles.root, variantStyles[variant]],\n clsx(\n 'lobe-code-editor',\n variant === 'borderless' && 'lobe-code-editor-borderless',\n className,\n ),\n style,\n )}\n >\n {value ? (\n <SyntaxHighlighterImpl\n className={clsx('lobe-code-editor-highlight', classNames?.highlight)}\n language={language}\n style={customStyles?.highlight}\n variant={variant}\n xstyle={styles.highlight}\n >\n {value}\n </SyntaxHighlighterImpl>\n ) : (\n <pre\n {...styleProps(\n styles.highlight,\n clsx('lobe-code-editor-highlight', classNames?.highlight),\n {\n color: cssVar.colorTextDescription,\n },\n )}\n >\n {placeholder || ' '}\n </pre>\n )}\n\n <textarea\n autoCapitalize=\"off\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoFocus={autoFocus}\n data-gramm={false}\n ref={ref}\n value={code}\n onChange={(e) => {\n onChange?.(e);\n setCode(e.target.value);\n }}\n {...styleProps(styles.textarea, classNames?.textarea, customStyles?.textarea)}\n {...rest}\n />\n </Flexbox>\n );\n },\n);\n\nCodeEditor.displayName = 'CodeEditor';\n\nexport default CodeEditor;\n"],"mappings":";;;;;;;;;;;AAcA,MAAM,aAAa,MAChB,EACC,WACA,YACA,QAAQ,cACR,eAAe,IACf,UACA,cAAc,IACd,OACA,WACA,eACA,OACA,WAAW,YACX,UAAU,cACV,OACA,QACA,MACA,KACA,GAAG,WACC;CACJ,MAAM,CAAC,MAAM,WAAWA,mBAAc,cAAc;EAClD;EACA,UAAU;EACV;CACF,CAAC;CAED,OACE,qBAACC,mBAAD;EACQ;EACN,QAAQ,UAAU;EAClB,OAAO,SAAS;EAChB,GAAI,WACF,CAAC,OAAO,MAAM,cAAc,QAAQ,GACpC,KACE,oBACA,YAAY,gBAAgB,+BAC5B,SACF,GACA,KACF;EAZF,UAAA,CAcG,QACC,oBAAC,uBAAD;GACE,WAAW,KAAK,8BAA8B,YAAY,SAAS;GACzD;GACV,OAAO,cAAc;GACZ;GACT,QAAQ,OAAO;GAEd,UAAA;EACoB,CAAA,IAEvB,oBAAC,OAAD;GACE,GAAI,WACF,OAAO,WACP,KAAK,8BAA8B,YAAY,SAAS,GACxD,EACE,OAAO,OAAO,qBAChB,CACF;GAEC,UAAA,eAAe;EACb,CAAA,GAGP,oBAAC,YAAD;GACE,gBAAe;GACf,cAAa;GACb,aAAY;GACD;GACX,cAAY;GACP;GACL,OAAO;GACP,WAAW,MAAM;IACf,WAAW,CAAC;IACZ,QAAQ,EAAE,OAAO,KAAK;GACxB;GACA,GAAI,WAAW,OAAO,UAAU,YAAY,UAAU,cAAc,QAAQ;GAC5E,GAAI;EACL,CAAA,CACM;;AAEb,CACF;AAEA,WAAW,cAAc"}
1
+ {"version":3,"file":"CodeEditor.mjs","names":["Flexbox"],"sources":["../../src/CodeEditor/CodeEditor.tsx"],"sourcesContent":["'use client';\n\nimport clsx from 'clsx';\nimport { memo } from 'react';\n\nimport { Flexbox } from '@/Flex';\nimport { SyntaxHighlighterImpl } from '@/Highlighter/SyntaxHighlighter';\nimport { useControlledState } from '@/hooks/useControlledState';\nimport { cssVar } from '@/styles/stylex/cssVar.stylex';\nimport { styleProps } from '@/styles/stylex/props';\n\nimport { styles, variantStyles } from './style';\nimport type { CodeEditorProps } from './type';\n\nconst CodeEditor = memo<CodeEditorProps>(\n ({\n autoFocus,\n classNames,\n styles: customStyles,\n defaultValue = '',\n onChange,\n placeholder = '',\n style,\n className,\n onValueChange,\n value,\n language = 'markdown',\n variant = 'borderless',\n width,\n height,\n flex,\n ref,\n ...rest\n }) => {\n const [code, setCode] = useControlledState(defaultValue, {\n defaultValue,\n onChange: onValueChange,\n value,\n });\n\n return (\n <Flexbox\n flex={flex}\n height={height ?? 'fit-content'}\n width={width ?? '100%'}\n {...styleProps(\n [styles.root, variantStyles[variant]],\n clsx(\n 'lobe-code-editor',\n variant === 'borderless' && 'lobe-code-editor-borderless',\n className,\n ),\n style,\n )}\n >\n {value ? (\n <SyntaxHighlighterImpl\n className={clsx('lobe-code-editor-highlight', classNames?.highlight)}\n language={language}\n style={customStyles?.highlight}\n variant={variant}\n xstyle={styles.highlight}\n >\n {value}\n </SyntaxHighlighterImpl>\n ) : (\n <pre\n {...styleProps(\n styles.highlight,\n clsx('lobe-code-editor-highlight', classNames?.highlight),\n {\n color: cssVar.colorTextDescription,\n },\n )}\n >\n {placeholder || ' '}\n </pre>\n )}\n\n <textarea\n autoCapitalize=\"off\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoFocus={autoFocus}\n data-gramm={false}\n ref={ref}\n value={code}\n onChange={(e) => {\n onChange?.(e);\n setCode(e.target.value);\n }}\n {...styleProps(styles.textarea, classNames?.textarea, customStyles?.textarea)}\n {...rest}\n />\n </Flexbox>\n );\n },\n);\n\nCodeEditor.displayName = 'CodeEditor';\n\nexport default CodeEditor;\n"],"mappings":";;;;;;;;;;;AAcA,MAAM,aAAa,MAChB,EACC,WACA,YACA,QAAQ,cACR,eAAe,IACf,UACA,cAAc,IACd,OACA,WACA,eACA,OACA,WAAW,YACX,UAAU,cACV,OACA,QACA,MACA,KACA,GAAG,WACC;CACJ,MAAM,CAAC,MAAM,WAAW,mBAAmB,cAAc;EACvD;EACA,UAAU;EACV;CACF,CAAC;CAED,OACE,qBAACA,mBAAD;EACQ;EACN,QAAQ,UAAU;EAClB,OAAO,SAAS;EAChB,GAAI,WACF,CAAC,OAAO,MAAM,cAAc,QAAQ,GACpC,KACE,oBACA,YAAY,gBAAgB,+BAC5B,SACF,GACA,KACF;EAZF,UAAA,CAcG,QACC,oBAAC,uBAAD;GACE,WAAW,KAAK,8BAA8B,YAAY,SAAS;GACzD;GACV,OAAO,cAAc;GACZ;GACT,QAAQ,OAAO;GAEd,UAAA;EACoB,CAAA,IAEvB,oBAAC,OAAD;GACE,GAAI,WACF,OAAO,WACP,KAAK,8BAA8B,YAAY,SAAS,GACxD,EACE,OAAO,OAAO,qBAChB,CACF;GAEC,UAAA,eAAe;EACb,CAAA,GAGP,oBAAC,YAAD;GACE,gBAAe;GACf,cAAa;GACb,aAAY;GACD;GACX,cAAY;GACP;GACL,OAAO;GACP,WAAW,MAAM;IACf,WAAW,CAAC;IACZ,QAAQ,EAAE,OAAO,KAAK;GACxB;GACA,GAAI,WAAW,OAAO,UAAU,YAAY,UAAU,cAAc,QAAQ;GAC5E,GAAI;EACL,CAAA,CACM;;AAEb,CACF;AAEA,WAAW,cAAc"}
@@ -3,6 +3,7 @@ import { styleProps } from "../styles/stylex/props.mjs";
3
3
  import { focusRing } from "../styles/stylex/focusRing.mjs";
4
4
  import Icon from "../Icon/Icon.mjs";
5
5
  import { useThemeMode } from "../styles/theme/scope.mjs";
6
+ import { useControlledState } from "../hooks/useControlledState.mjs";
6
7
  import { useTranslation } from "../i18n/useTranslation.mjs";
7
8
  import { inputRootStyles } from "../Input/style.mjs";
8
9
  import Input_default from "../Input/Input.mjs";
@@ -18,7 +19,6 @@ import { createElement, memo, useEffect, useRef, useState } from "react";
18
19
  import { jsx, jsxs } from "react/jsx-runtime";
19
20
  import * as stylex from "@stylexjs/stylex";
20
21
  import { Pipette } from "lucide-react";
21
- import useControlledState from "use-merge-value";
22
22
  //#region src/ColorPicker/ColorPicker.tsx
23
23
  const DEFAULT_COLOR = "#000000";
24
24
  const hasEyeDropper = () => typeof window !== "undefined" && "EyeDropper" in window;
@@ -1 +1 @@
1
- {"version":3,"file":"ColorPicker.mjs","names":["colorPickerMessages","Input","InputNumber"],"sources":["../../src/ColorPicker/ColorPicker.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport { Pipette } from 'lucide-react';\nimport { type CSSProperties, memo, useEffect, useRef, useState } from 'react';\nimport useControlledState from 'use-merge-value';\n\nimport colorPickerMessages from '@/i18n/resources/en/colorPicker';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\nimport { Input, InputNumber } from '@/Input';\nimport { inputRootStyles } from '@/Input/style';\nimport { panelStyles } from '@/internal/panelStyles';\nimport {\n PopoverPopup,\n PopoverPortal,\n PopoverPositioner,\n PopoverRoot,\n PopoverTriggerElement,\n} from '@/Popover';\nimport { Slider } from '@/Slider';\nimport { focusRing } from '@/styles/stylex/focusRing';\nimport { styleProps } from '@/styles/stylex/props';\nimport { useThemeMode } from '@/styles/theme/scope';\n\nimport { formatColor, type Hsva, normalizeHexInput, parseColor } from './color';\nimport SaturationArea from './SaturationArea';\nimport { styles } from './style';\nimport type { ColorPickerProps } from './type';\n\nconst DEFAULT_COLOR = '#000000';\n\nconst hasEyeDropper = () => typeof window !== 'undefined' && 'EyeDropper' in window;\n\nconst ColorPicker = memo<ColorPickerProps>(\n ({\n alpha = false,\n children,\n className,\n defaultValue = DEFAULT_COLOR,\n disabled,\n onChange,\n onChangeComplete,\n presets,\n showText,\n size = 'middle',\n style,\n value,\n }) => {\n const { t } = useTranslation(colorPickerMessages);\n const { isDarkMode } = useThemeMode();\n const [hex, setHex] = useControlledState<string>(defaultValue, {\n defaultValue,\n onChange,\n value,\n });\n const [hsva, setHsva] = useState<Hsva>(() => parseColor(hex));\n const [draft, setDraft] = useState(hex.slice(1).toUpperCase());\n const popupRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n setHsva((current) =>\n formatColor(current, alpha) === hex.toLowerCase() ? current : parseColor(hex, current.h),\n );\n setDraft(hex.slice(1).toUpperCase());\n }, [hex, alpha]);\n\n const update = (next: Hsva) => {\n setHsva(next);\n setHex(formatColor(next, alpha));\n };\n const commit = (next: Hsva) => onChangeComplete?.(formatColor(next, alpha));\n const apply = (next: Hsva) => {\n update(next);\n commit(next);\n };\n\n const commitDraft = () => {\n const normalized = normalizeHexInput(draft);\n if (!normalized) return setDraft(hex.slice(1).toUpperCase());\n apply(parseColor(normalized, hsva.h));\n };\n\n const swatch = (dimension: number) => (\n <span {...stylex.props(styles.swatch)} style={{ height: dimension, width: dimension }}>\n <span {...stylex.props(styles.swatchFill)} style={{ background: hex }} />\n </span>\n );\n\n const trigger =\n children ??\n (showText ? (\n <button\n aria-label={t('colorPicker.trigger')}\n disabled={disabled}\n type=\"button\"\n {...styleProps(\n [\n ...inputRootStyles({ size, variant: isDarkMode ? 'filled' : 'outlined' }),\n styles.textTrigger,\n ],\n className,\n { cursor: 'pointer', ...style },\n )}\n >\n {swatch(18)}\n <span style={{ fontFamily: 'var(--lobe-font-family-code, monospace)' }}>\n {hex.toUpperCase()}\n </span>\n </button>\n ) : (\n <button\n aria-label={t('colorPicker.trigger')}\n disabled={disabled}\n type=\"button\"\n {...styleProps([focusRing.info, styles.swatchButton], className, style)}\n >\n {swatch(24)}\n </button>\n ));\n\n return (\n <PopoverRoot>\n <PopoverTriggerElement>{trigger}</PopoverTriggerElement>\n <PopoverPortal>\n <PopoverPositioner placement=\"bottomLeft\">\n <PopoverPopup\n ref={popupRef}\n xstyle={panelStyles.popup}\n initialFocus={() =>\n popupRef.current?.querySelector<HTMLElement>('[role=\"slider\"]') ?? true\n }\n >\n <div {...stylex.props(styles.panel)}>\n <div {...stylex.props(styles.summary)}>\n {swatch(40)}\n <div>\n <div {...stylex.props(styles.value)}>{hex.toUpperCase()}</div>\n <div {...stylex.props(panelStyles.label)}>\n {alpha ? `HEX · ${Math.round(hsva.a * 100)}%` : 'HEX'}\n </div>\n </div>\n {hasEyeDropper() && (\n <button\n aria-label={t('colorPicker.eyeDropper')}\n {...stylex.props(panelStyles.nav, styles.eyeDropper)}\n type=\"button\"\n onClick={async () => {\n const dropper = new (\n window as unknown as {\n EyeDropper: new () => { open: () => Promise<{ sRGBHex: string }> };\n }\n ).EyeDropper();\n const result = await dropper.open().catch(() => null);\n if (result) apply({ ...parseColor(result.sRGBHex, hsva.h), a: hsva.a });\n }}\n >\n <Icon icon={Pipette} size={14} />\n </button>\n )}\n </div>\n <SaturationArea\n hue={hsva.h}\n label={t('colorPicker.saturation')}\n saturation={hsva.s}\n value={hsva.v}\n onChange={(s, v) => update({ ...hsva, s, v })}\n onChangeComplete={(s, v) => commit({ ...hsva, s, v })}\n />\n <Slider\n aria-label={t('colorPicker.hue')}\n max={360}\n min={0}\n value={hsva.h}\n classNames={{\n indicator: stylex.props(styles.hidden).className,\n thumb: stylex.props(styles.sliderThumb).className,\n track: stylex.props(styles.hueTrack).className,\n }}\n onChange={(h) => update({ ...hsva, h })}\n onChangeComplete={(h) => commit({ ...hsva, h })}\n />\n {alpha && (\n <Slider\n aria-label={t('colorPicker.alpha')}\n max={100}\n min={0}\n value={Math.round(hsva.a * 100)}\n classNames={{\n indicator: stylex.props(styles.hidden).className,\n thumb: stylex.props(styles.sliderThumb).className,\n track: stylex.props(styles.alphaTrack).className,\n }}\n styles={{\n track: {\n '--lobe-color-picker-alpha': formatColor(hsva, false),\n } as CSSProperties,\n }}\n onChange={(a) => update({ ...hsva, a: a / 100 })}\n onChangeComplete={(a) => commit({ ...hsva, a: a / 100 })}\n />\n )}\n <div {...stylex.props(styles.hexRow)}>\n <Input\n aria-label=\"HEX\"\n className={stylex.props(styles.hexField).className}\n prefix={<span {...stylex.props(panelStyles.label)}>HEX</span>}\n value={draft}\n variant=\"filled\"\n onBlur={commitDraft}\n onChange={(event) => setDraft(event.target.value)}\n onPressEnter={commitDraft}\n />\n {alpha && (\n <InputNumber\n aria-label={t('colorPicker.alpha')}\n className={stylex.props(styles.hexField, styles.alphaField).className}\n controls={false}\n max={100}\n min={0}\n suffix=\"%\"\n value={Math.round(hsva.a * 100)}\n variant=\"filled\"\n onChange={(a) => a !== null && apply({ ...hsva, a: a / 100 })}\n />\n )}\n </div>\n {presets && presets.length > 0 && (\n <div\n aria-label={t('colorPicker.presets')}\n {...stylex.props(styles.presets)}\n role=\"group\"\n >\n {presets.map((color) => (\n <button\n aria-label={color}\n aria-pressed={color.toLowerCase() === hex.slice(0, 7).toLowerCase()}\n {...stylex.props(focusRing.info, styles.preset)}\n key={color}\n style={{ background: color }}\n type=\"button\"\n onClick={() =>\n apply({ ...parseColor(color, hsva.h), a: parseColor(color).a })\n }\n />\n ))}\n </div>\n )}\n </div>\n </PopoverPopup>\n </PopoverPositioner>\n </PopoverPortal>\n </PopoverRoot>\n );\n },\n);\n\nColorPicker.displayName = 'ColorPicker';\n\nexport default ColorPicker;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ColorPicker.mjs","names":["colorPickerMessages","Input","InputNumber"],"sources":["../../src/ColorPicker/ColorPicker.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport { Pipette } from 'lucide-react';\nimport { type CSSProperties, memo, useEffect, useRef, useState } from 'react';\n\nimport { useControlledState } from '@/hooks/useControlledState';\nimport colorPickerMessages from '@/i18n/resources/en/colorPicker';\nimport { useTranslation } from '@/i18n/useTranslation';\nimport Icon from '@/Icon';\nimport { Input, InputNumber } from '@/Input';\nimport { inputRootStyles } from '@/Input/style';\nimport { panelStyles } from '@/internal/panelStyles';\nimport {\n PopoverPopup,\n PopoverPortal,\n PopoverPositioner,\n PopoverRoot,\n PopoverTriggerElement,\n} from '@/Popover';\nimport { Slider } from '@/Slider';\nimport { focusRing } from '@/styles/stylex/focusRing';\nimport { styleProps } from '@/styles/stylex/props';\nimport { useThemeMode } from '@/styles/theme/scope';\n\nimport { formatColor, type Hsva, normalizeHexInput, parseColor } from './color';\nimport SaturationArea from './SaturationArea';\nimport { styles } from './style';\nimport type { ColorPickerProps } from './type';\n\nconst DEFAULT_COLOR = '#000000';\n\nconst hasEyeDropper = () => typeof window !== 'undefined' && 'EyeDropper' in window;\n\nconst ColorPicker = memo<ColorPickerProps>(\n ({\n alpha = false,\n children,\n className,\n defaultValue = DEFAULT_COLOR,\n disabled,\n onChange,\n onChangeComplete,\n presets,\n showText,\n size = 'middle',\n style,\n value,\n }) => {\n const { t } = useTranslation(colorPickerMessages);\n const { isDarkMode } = useThemeMode();\n const [hex, setHex] = useControlledState<string>(defaultValue, {\n defaultValue,\n onChange,\n value,\n });\n const [hsva, setHsva] = useState<Hsva>(() => parseColor(hex));\n const [draft, setDraft] = useState(hex.slice(1).toUpperCase());\n const popupRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n setHsva((current) =>\n formatColor(current, alpha) === hex.toLowerCase() ? current : parseColor(hex, current.h),\n );\n setDraft(hex.slice(1).toUpperCase());\n }, [hex, alpha]);\n\n const update = (next: Hsva) => {\n setHsva(next);\n setHex(formatColor(next, alpha));\n };\n const commit = (next: Hsva) => onChangeComplete?.(formatColor(next, alpha));\n const apply = (next: Hsva) => {\n update(next);\n commit(next);\n };\n\n const commitDraft = () => {\n const normalized = normalizeHexInput(draft);\n if (!normalized) return setDraft(hex.slice(1).toUpperCase());\n apply(parseColor(normalized, hsva.h));\n };\n\n const swatch = (dimension: number) => (\n <span {...stylex.props(styles.swatch)} style={{ height: dimension, width: dimension }}>\n <span {...stylex.props(styles.swatchFill)} style={{ background: hex }} />\n </span>\n );\n\n const trigger =\n children ??\n (showText ? (\n <button\n aria-label={t('colorPicker.trigger')}\n disabled={disabled}\n type=\"button\"\n {...styleProps(\n [\n ...inputRootStyles({ size, variant: isDarkMode ? 'filled' : 'outlined' }),\n styles.textTrigger,\n ],\n className,\n { cursor: 'pointer', ...style },\n )}\n >\n {swatch(18)}\n <span style={{ fontFamily: 'var(--lobe-font-family-code, monospace)' }}>\n {hex.toUpperCase()}\n </span>\n </button>\n ) : (\n <button\n aria-label={t('colorPicker.trigger')}\n disabled={disabled}\n type=\"button\"\n {...styleProps([focusRing.info, styles.swatchButton], className, style)}\n >\n {swatch(24)}\n </button>\n ));\n\n return (\n <PopoverRoot>\n <PopoverTriggerElement>{trigger}</PopoverTriggerElement>\n <PopoverPortal>\n <PopoverPositioner placement=\"bottomLeft\">\n <PopoverPopup\n ref={popupRef}\n xstyle={panelStyles.popup}\n initialFocus={() =>\n popupRef.current?.querySelector<HTMLElement>('[role=\"slider\"]') ?? true\n }\n >\n <div {...stylex.props(styles.panel)}>\n <div {...stylex.props(styles.summary)}>\n {swatch(40)}\n <div>\n <div {...stylex.props(styles.value)}>{hex.toUpperCase()}</div>\n <div {...stylex.props(panelStyles.label)}>\n {alpha ? `HEX · ${Math.round(hsva.a * 100)}%` : 'HEX'}\n </div>\n </div>\n {hasEyeDropper() && (\n <button\n aria-label={t('colorPicker.eyeDropper')}\n {...stylex.props(panelStyles.nav, styles.eyeDropper)}\n type=\"button\"\n onClick={async () => {\n const dropper = new (\n window as unknown as {\n EyeDropper: new () => { open: () => Promise<{ sRGBHex: string }> };\n }\n ).EyeDropper();\n const result = await dropper.open().catch(() => null);\n if (result) apply({ ...parseColor(result.sRGBHex, hsva.h), a: hsva.a });\n }}\n >\n <Icon icon={Pipette} size={14} />\n </button>\n )}\n </div>\n <SaturationArea\n hue={hsva.h}\n label={t('colorPicker.saturation')}\n saturation={hsva.s}\n value={hsva.v}\n onChange={(s, v) => update({ ...hsva, s, v })}\n onChangeComplete={(s, v) => commit({ ...hsva, s, v })}\n />\n <Slider\n aria-label={t('colorPicker.hue')}\n max={360}\n min={0}\n value={hsva.h}\n classNames={{\n indicator: stylex.props(styles.hidden).className,\n thumb: stylex.props(styles.sliderThumb).className,\n track: stylex.props(styles.hueTrack).className,\n }}\n onChange={(h) => update({ ...hsva, h })}\n onChangeComplete={(h) => commit({ ...hsva, h })}\n />\n {alpha && (\n <Slider\n aria-label={t('colorPicker.alpha')}\n max={100}\n min={0}\n value={Math.round(hsva.a * 100)}\n classNames={{\n indicator: stylex.props(styles.hidden).className,\n thumb: stylex.props(styles.sliderThumb).className,\n track: stylex.props(styles.alphaTrack).className,\n }}\n styles={{\n track: {\n '--lobe-color-picker-alpha': formatColor(hsva, false),\n } as CSSProperties,\n }}\n onChange={(a) => update({ ...hsva, a: a / 100 })}\n onChangeComplete={(a) => commit({ ...hsva, a: a / 100 })}\n />\n )}\n <div {...stylex.props(styles.hexRow)}>\n <Input\n aria-label=\"HEX\"\n className={stylex.props(styles.hexField).className}\n prefix={<span {...stylex.props(panelStyles.label)}>HEX</span>}\n value={draft}\n variant=\"filled\"\n onBlur={commitDraft}\n onChange={(event) => setDraft(event.target.value)}\n onPressEnter={commitDraft}\n />\n {alpha && (\n <InputNumber\n aria-label={t('colorPicker.alpha')}\n className={stylex.props(styles.hexField, styles.alphaField).className}\n controls={false}\n max={100}\n min={0}\n suffix=\"%\"\n value={Math.round(hsva.a * 100)}\n variant=\"filled\"\n onChange={(a) => a !== null && apply({ ...hsva, a: a / 100 })}\n />\n )}\n </div>\n {presets && presets.length > 0 && (\n <div\n aria-label={t('colorPicker.presets')}\n {...stylex.props(styles.presets)}\n role=\"group\"\n >\n {presets.map((color) => (\n <button\n aria-label={color}\n aria-pressed={color.toLowerCase() === hex.slice(0, 7).toLowerCase()}\n {...stylex.props(focusRing.info, styles.preset)}\n key={color}\n style={{ background: color }}\n type=\"button\"\n onClick={() =>\n apply({ ...parseColor(color, hsva.h), a: parseColor(color).a })\n }\n />\n ))}\n </div>\n )}\n </div>\n </PopoverPopup>\n </PopoverPositioner>\n </PopoverPortal>\n </PopoverRoot>\n );\n },\n);\n\nColorPicker.displayName = 'ColorPicker';\n\nexport default ColorPicker;\n"],"mappings":"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"}
@@ -4,17 +4,17 @@ import Icon from "../Icon/Icon.mjs";
4
4
  import FlexBasic_default from "../Flex/FlexBasic.mjs";
5
5
  import Center from "../Flex/Center.mjs";
6
6
  import { Tooltip } from "../Tooltip/Tooltip.mjs";
7
+ import { useControlledState } from "../hooks/useControlledState.mjs";
7
8
  import { safeReadableColor } from "../utils/safeReadableColor.mjs";
8
- import ColorPicker from "../ColorPicker/ColorPicker.mjs";
9
9
  import { styles } from "./style.mjs";
10
+ import CustomPicker from "./CustomPicker.mjs";
10
11
  import { useMemo } from "react";
11
12
  import { jsx, jsxs } from "react/jsx-runtime";
12
13
  import * as stylex from "@stylexjs/stylex";
13
14
  import { CheckIcon } from "lucide-react";
14
- import useControlledState from "use-merge-value";
15
15
  import chroma from "chroma-js";
16
16
  //#region src/ColorSwatches/ColorSwatches.tsx
17
- const ColorSwatches = ({ enableColorPicker, enableColorSwatches = true, defaultValue, value, style, colors, onChange, size = 24, shape = "circle", texts, ref, ...rest }) => {
17
+ const ColorSwatches = ({ enableColorPicker, enableColorSwatches = true, defaultValue, value, style, colors, onChange, size = 24, shape = "circle", texts, renderPicker, ref, ...rest }) => {
18
18
  const [active, setActive] = useControlledState(defaultValue, {
19
19
  defaultValue,
20
20
  onChange,
@@ -22,6 +22,20 @@ const ColorSwatches = ({ enableColorPicker, enableColorSwatches = true, defaultV
22
22
  });
23
23
  const cssVariables = useMemo(() => ({ "--color-swatches-size": `${size}px` }), [size]);
24
24
  const isCustomActive = useMemo(() => active && active !== cssVar.colorPrimary && !colors.some((c) => c.color === active), [active, colors]);
25
+ const pickerProps = {
26
+ active: !!isCustomActive,
27
+ onChange: setActive,
28
+ presets: colors.map((c) => c.color),
29
+ shape,
30
+ size,
31
+ value: isCustomActive ? active : void 0
32
+ };
33
+ const defaultPicker = enableColorPicker && /* @__PURE__ */ jsx(CustomPicker, {
34
+ ...pickerProps,
35
+ current: active,
36
+ label: texts?.custom || "Custom",
37
+ standalone: !enableColorSwatches
38
+ });
25
39
  return /* @__PURE__ */ jsxs(FlexBasic_default, {
26
40
  horizontal: true,
27
41
  gap: 6,
@@ -62,26 +76,7 @@ const ColorSwatches = ({ enableColorPicker, enableColorSwatches = true, defaultV
62
76
  })
63
77
  })
64
78
  }, c?.key || i);
65
- }), enableColorPicker && /* @__PURE__ */ jsx(Tooltip, {
66
- title: texts?.custom || "Custom",
67
- children: /* @__PURE__ */ jsx("span", {
68
- style: { display: "inline-flex" },
69
- children: /* @__PURE__ */ jsx(ColorPicker, {
70
- presets: enableColorSwatches ? void 0 : colors.map((c) => c.color),
71
- value: isCustomActive ? active : void 0,
72
- onChangeComplete: setActive,
73
- children: /* @__PURE__ */ jsx("button", {
74
- "aria-label": texts?.custom || "Custom",
75
- type: "button",
76
- ...stylex.props(styles.picker, enableColorSwatches && styles.conic, !!isCustomActive && styles.activePicker),
77
- style: {
78
- background: enableColorSwatches ? void 0 : active,
79
- borderRadius: shape === "circle" ? "50%" : cssVar.borderRadius
80
- }
81
- })
82
- })
83
- })
84
- })]
79
+ }), enableColorPicker && (renderPicker ? renderPicker(pickerProps, defaultPicker) : defaultPicker)]
85
80
  });
86
81
  };
87
82
  ColorSwatches.displayName = "ColorSwatches";
@@ -1 +1 @@
1
- {"version":3,"file":"ColorSwatches.mjs","names":["useMergeState","Flexbox"],"sources":["../../src/ColorSwatches/ColorSwatches.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport chroma from 'chroma-js';\nimport { CheckIcon } from 'lucide-react';\nimport { type FC, useMemo } from 'react';\nimport useMergeState from 'use-merge-value';\n\nimport { ColorPicker } from '@/ColorPicker';\nimport { Center, Flexbox } from '@/Flex';\nimport Icon from '@/Icon';\nimport { cssVar } from '@/styles/stylex/cssVar.stylex';\nimport Tooltip from '@/Tooltip';\nimport { safeReadableColor } from '@/utils/safeReadableColor';\n\nimport { styles } from './style';\nimport type { ColorSwatchesProps } from './type';\n\nconst ColorSwatches: FC<ColorSwatchesProps> = ({\n enableColorPicker,\n enableColorSwatches = true,\n defaultValue,\n value,\n style,\n colors,\n onChange,\n size = 24,\n shape = 'circle',\n texts,\n ref,\n ...rest\n}) => {\n const [active, setActive] = useMergeState(defaultValue, {\n defaultValue,\n onChange,\n value,\n });\n\n // Convert size prop to CSS variable\n const cssVariables = useMemo<Record<string, string>>(\n () => ({\n '--color-swatches-size': `${size}px`,\n }),\n [size],\n );\n\n const isCustomActive = useMemo(\n () => active && active !== cssVar.colorPrimary && !colors.some((c) => c.color === active),\n [active, colors],\n );\n\n return (\n <Flexbox\n horizontal\n gap={6}\n ref={ref}\n style={{\n ...cssVariables,\n flexWrap: 'wrap',\n ...style,\n }}\n {...rest}\n >\n {enableColorSwatches &&\n colors.map((c, i) => {\n const color = c.color || cssVar.colorPrimary;\n const isActive = (!active && !c.color) || color === active;\n // Check if color is transparent or CSS variable (which chroma can't parse)\n const isTransparent =\n c.color === 'transparent' ||\n (c.color &&\n !c.color.startsWith('var(') &&\n (() => {\n try {\n return chroma(c.color).alpha() === 0;\n } catch {\n return false;\n }\n })());\n return (\n <Tooltip key={c?.key || i} title={c.title}>\n <Center\n {...stylex.props(\n styles.container,\n !!isTransparent && styles.transparent,\n isActive && styles.activeContainer,\n )}\n style={{\n background: isTransparent ? undefined : color,\n borderRadius: shape === 'circle' ? '50%' : cssVar.borderRadius,\n }}\n onClick={() => setActive(c.color || undefined)}\n >\n {isActive && (\n <Icon\n color={`color-mix(in srgb, ${safeReadableColor(color)} 33%, transparent)`}\n icon={CheckIcon}\n size={{ size: 14, strokeWidth: 4 }}\n style={{\n pointerEvents: 'none',\n }}\n />\n )}\n </Center>\n </Tooltip>\n );\n })}\n {enableColorPicker && (\n <Tooltip title={texts?.custom || 'Custom'}>\n <span style={{ display: 'inline-flex' }}>\n <ColorPicker\n presets={enableColorSwatches ? undefined : colors.map((c) => c.color)}\n value={isCustomActive ? active : undefined}\n onChangeComplete={setActive}\n >\n <button\n aria-label={texts?.custom || 'Custom'}\n type=\"button\"\n {...stylex.props(\n styles.picker,\n enableColorSwatches && styles.conic,\n !!isCustomActive && styles.activePicker,\n )}\n style={{\n background: enableColorSwatches ? undefined : active,\n borderRadius: shape === 'circle' ? '50%' : cssVar.borderRadius,\n }}\n />\n </ColorPicker>\n </span>\n </Tooltip>\n )}\n </Flexbox>\n );\n};\n\nColorSwatches.displayName = 'ColorSwatches';\n\nexport default ColorSwatches;\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,iBAAyC,EAC7C,mBACA,sBAAsB,MACtB,cACA,OACA,OACA,QACA,UACA,OAAO,IACP,QAAQ,UACR,OACA,KACA,GAAG,WACC;CACJ,MAAM,CAAC,QAAQ,aAAaA,mBAAc,cAAc;EACtD;EACA;EACA;CACF,CAAC;CAGD,MAAM,eAAe,eAAuC,EAC1D,yBAAyB,GAAG,KAAK,IACnC,IAAI,CAAC,IAAI,CAAC;CACV,MAAM,iBAAiB,cAAc,UAAU,WAAW,OAAO,gBAAgB,CAAC,OAAO,MAAK,MAAK,EAAE,UAAU,MAAM,GAAG,CAAC,QAAQ,MAAM,CAAC;CACxI,OAAO,qBAACC,mBAAD;EAAS,YAAA;EAAW,KAAK;EAAQ;EAAK,OAAO;GAClD,GAAG;GACH,UAAU;GACV,GAAG;EACL;EAAG,GAAI;EAJA,UAAA,CAKF,uBAAuB,OAAO,KAAK,GAAG,MAAM;GAC7C,MAAM,QAAQ,EAAE,SAAS,OAAO;GAChC,MAAM,WAAW,CAAC,UAAU,CAAC,EAAE,SAAS,UAAU;GAElD,MAAM,gBAAgB,EAAE,UAAU,iBAAiB,EAAE,SAAS,CAAC,EAAE,MAAM,WAAW,MAAM,YAAY;IAClG,IAAI;KACF,OAAO,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,MAAM;IACrC,QAAQ;KACN,OAAO;IACT;GACF,EAAA,CAAG;GACH,OAAO,oBAAC,SAAD;IAA2B,OAAO,EAAE;IACnC,UAAA,oBAAC,QAAD;KAAQ,GAAI,OAAO,MAAM,OAAO,WAAW,CAAC,CAAC,iBAAiB,OAAO,aAAa,YAAY,OAAO,eAAe;KAAG,OAAO;MAClI,YAAY,gBAAgB,KAAA,IAAY;MACxC,cAAc,UAAU,WAAW,QAAQ,OAAO;KACpD;KAAG,eAAe,UAAU,EAAE,SAAS,KAAA,CAAS;KACvC,UAAA,YAAY,oBAAC,MAAD;MAAM,OAAO,sBAAsB,kBAAkB,KAAK,EAAE;MAAqB,MAAM;MAAW,MAAM;OACzH,MAAM;OACN,aAAa;MACf;MAAG,OAAO,EACR,eAAe,OACjB;KAAI,CAAA;IACQ,CAAA;GACD,GAZM,GAAG,OAAO,CAYhB;EACjB,CAAC,GACE,qBAAqB,oBAAC,SAAD;GAAS,OAAO,OAAO,UAAU;GACnD,UAAA,oBAAC,QAAD;IAAM,OAAO,EACf,SAAS,cACX;IACM,UAAA,oBAAC,aAAD;KAAa,SAAS,sBAAsB,KAAA,IAAY,OAAO,KAAI,MAAK,EAAE,KAAK;KAAG,OAAO,iBAAiB,SAAS,KAAA;KAAW,kBAAkB;KAC9I,UAAA,oBAAC,UAAD;MAAQ,cAAY,OAAO,UAAU;MAAU,MAAK;MAAS,GAAI,OAAO,MAAM,OAAO,QAAQ,uBAAuB,OAAO,OAAO,CAAC,CAAC,kBAAkB,OAAO,YAAY;MAAG,OAAO;OACrL,YAAY,sBAAsB,KAAA,IAAY;OAC9C,cAAc,UAAU,WAAW,QAAQ,OAAO;MACpD;KAAI,CAAA;IACW,CAAA;GACT,CAAA;EACC,CAAA,CACJ;;AACb;AACA,cAAc,cAAc"}
1
+ {"version":3,"file":"ColorSwatches.mjs","names":["Flexbox"],"sources":["../../src/ColorSwatches/ColorSwatches.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport chroma from 'chroma-js';\nimport { CheckIcon } from 'lucide-react';\nimport { type FC, useMemo } from 'react';\n\nimport { Center, Flexbox } from '@/Flex';\nimport { useControlledState } from '@/hooks/useControlledState';\nimport Icon from '@/Icon';\nimport { cssVar } from '@/styles/stylex/cssVar.stylex';\nimport Tooltip from '@/Tooltip';\nimport { safeReadableColor } from '@/utils/safeReadableColor';\n\nimport CustomPicker from './CustomPicker';\nimport { styles } from './style';\nimport type { ColorSwatchesPickerRenderProps, ColorSwatchesProps } from './type';\n\nconst ColorSwatches: FC<ColorSwatchesProps> = ({\n enableColorPicker,\n enableColorSwatches = true,\n defaultValue,\n value,\n style,\n colors,\n onChange,\n size = 24,\n shape = 'circle',\n texts,\n renderPicker,\n ref,\n ...rest\n}) => {\n const [active, setActive] = useControlledState(defaultValue, {\n defaultValue,\n onChange,\n value,\n });\n\n // Convert size prop to CSS variable\n const cssVariables = useMemo<Record<string, string>>(\n () => ({\n '--color-swatches-size': `${size}px`,\n }),\n [size],\n );\n\n const isCustomActive = useMemo(\n () => active && active !== cssVar.colorPrimary && !colors.some((c) => c.color === active),\n [active, colors],\n );\n\n const pickerProps: ColorSwatchesPickerRenderProps = {\n active: !!isCustomActive,\n onChange: setActive,\n presets: colors.map((c) => c.color),\n shape,\n size,\n value: isCustomActive ? active : undefined,\n };\n\n const defaultPicker = enableColorPicker && (\n <CustomPicker\n {...pickerProps}\n current={active}\n label={texts?.custom || 'Custom'}\n standalone={!enableColorSwatches}\n />\n );\n\n return (\n <Flexbox\n horizontal\n gap={6}\n ref={ref}\n style={{\n ...cssVariables,\n flexWrap: 'wrap',\n ...style,\n }}\n {...rest}\n >\n {enableColorSwatches &&\n colors.map((c, i) => {\n const color = c.color || cssVar.colorPrimary;\n const isActive = (!active && !c.color) || color === active;\n // Check if color is transparent or CSS variable (which chroma can't parse)\n const isTransparent =\n c.color === 'transparent' ||\n (c.color &&\n !c.color.startsWith('var(') &&\n (() => {\n try {\n return chroma(c.color).alpha() === 0;\n } catch {\n return false;\n }\n })());\n return (\n <Tooltip key={c?.key || i} title={c.title}>\n <Center\n {...stylex.props(\n styles.container,\n !!isTransparent && styles.transparent,\n isActive && styles.activeContainer,\n )}\n style={{\n background: isTransparent ? undefined : color,\n borderRadius: shape === 'circle' ? '50%' : cssVar.borderRadius,\n }}\n onClick={() => setActive(c.color || undefined)}\n >\n {isActive && (\n <Icon\n color={`color-mix(in srgb, ${safeReadableColor(color)} 33%, transparent)`}\n icon={CheckIcon}\n size={{ size: 14, strokeWidth: 4 }}\n style={{\n pointerEvents: 'none',\n }}\n />\n )}\n </Center>\n </Tooltip>\n );\n })}\n {enableColorPicker &&\n (renderPicker ? renderPicker(pickerProps, defaultPicker) : defaultPicker)}\n </Flexbox>\n );\n};\n\nColorSwatches.displayName = 'ColorSwatches';\n\nexport default ColorSwatches;\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,iBAAyC,EAC7C,mBACA,sBAAsB,MACtB,cACA,OACA,OACA,QACA,UACA,OAAO,IACP,QAAQ,UACR,OACA,cACA,KACA,GAAG,WACC;CACJ,MAAM,CAAC,QAAQ,aAAa,mBAAmB,cAAc;EAC3D;EACA;EACA;CACF,CAAC;CAGD,MAAM,eAAe,eAAuC,EAC1D,yBAAyB,GAAG,KAAK,IACnC,IAAI,CAAC,IAAI,CAAC;CACV,MAAM,iBAAiB,cAAc,UAAU,WAAW,OAAO,gBAAgB,CAAC,OAAO,MAAK,MAAK,EAAE,UAAU,MAAM,GAAG,CAAC,QAAQ,MAAM,CAAC;CACxI,MAAM,cAA8C;EAClD,QAAQ,CAAC,CAAC;EACV,UAAU;EACV,SAAS,OAAO,KAAI,MAAK,EAAE,KAAK;EAChC;EACA;EACA,OAAO,iBAAiB,SAAS,KAAA;CACnC;CACA,MAAM,gBAAgB,qBAAqB,oBAAC,cAAD;EAAc,GAAI;EAAa,SAAS;EAAQ,OAAO,OAAO,UAAU;EAAU,YAAY,CAAC;CAAsB,CAAA;CAChK,OAAO,qBAACA,mBAAD;EAAS,YAAA;EAAW,KAAK;EAAQ;EAAK,OAAO;GAClD,GAAG;GACH,UAAU;GACV,GAAG;EACL;EAAG,GAAI;EAJA,UAAA,CAKF,uBAAuB,OAAO,KAAK,GAAG,MAAM;GAC7C,MAAM,QAAQ,EAAE,SAAS,OAAO;GAChC,MAAM,WAAW,CAAC,UAAU,CAAC,EAAE,SAAS,UAAU;GAElD,MAAM,gBAAgB,EAAE,UAAU,iBAAiB,EAAE,SAAS,CAAC,EAAE,MAAM,WAAW,MAAM,YAAY;IAClG,IAAI;KACF,OAAO,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,MAAM;IACrC,QAAQ;KACN,OAAO;IACT;GACF,EAAA,CAAG;GACH,OAAO,oBAAC,SAAD;IAA2B,OAAO,EAAE;IACnC,UAAA,oBAAC,QAAD;KAAQ,GAAI,OAAO,MAAM,OAAO,WAAW,CAAC,CAAC,iBAAiB,OAAO,aAAa,YAAY,OAAO,eAAe;KAAG,OAAO;MAClI,YAAY,gBAAgB,KAAA,IAAY;MACxC,cAAc,UAAU,WAAW,QAAQ,OAAO;KACpD;KAAG,eAAe,UAAU,EAAE,SAAS,KAAA,CAAS;KACvC,UAAA,YAAY,oBAAC,MAAD;MAAM,OAAO,sBAAsB,kBAAkB,KAAK,EAAE;MAAqB,MAAM;MAAW,MAAM;OACzH,MAAM;OACN,aAAa;MACf;MAAG,OAAO,EACR,eAAe,OACjB;KAAI,CAAA;IACQ,CAAA;GACD,GAZM,GAAG,OAAO,CAYhB;EACjB,CAAC,GACE,sBAAsB,eAAe,aAAa,aAAa,aAAa,IAAI,cAC1E;;AACb;AACA,cAAc,cAAc"}
@@ -0,0 +1,101 @@
1
+ "use client";
2
+ import { cssVar } from "../styles/stylex/cssVar.stylex.mjs";
3
+ import Icon from "../Icon/Icon.mjs";
4
+ import { Tooltip } from "../Tooltip/Tooltip.mjs";
5
+ import { safeReadableColor } from "../utils/safeReadableColor.mjs";
6
+ import ColorPicker from "../ColorPicker/ColorPicker.mjs";
7
+ import { chipMarker } from "./marker.stylex.mjs";
8
+ import { styles } from "./style.mjs";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import * as stylex from "@stylexjs/stylex";
11
+ import { CheckIcon, PencilIcon, PlusIcon } from "lucide-react";
12
+ //#region src/ColorSwatches/CustomPicker.tsx
13
+ const CustomPicker = ({ active, current, label, onChange, presets, shape, standalone, value }) => {
14
+ const borderRadius = shape === "circle" ? "50%" : cssVar.borderRadius;
15
+ if (standalone) return /* @__PURE__ */ jsx(Tooltip, {
16
+ title: label,
17
+ children: /* @__PURE__ */ jsx("span", {
18
+ style: { display: "inline-flex" },
19
+ children: /* @__PURE__ */ jsx(ColorPicker, {
20
+ presets,
21
+ value,
22
+ onChangeComplete: onChange,
23
+ children: /* @__PURE__ */ jsx("button", {
24
+ "aria-label": label,
25
+ type: "button",
26
+ ...stylex.props(styles.picker, active && styles.activePicker),
27
+ style: {
28
+ background: current,
29
+ borderRadius
30
+ }
31
+ })
32
+ })
33
+ })
34
+ });
35
+ const iconColor = value ? `color-mix(in srgb, ${safeReadableColor(value)} 33%, transparent)` : void 0;
36
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
37
+ /* @__PURE__ */ jsx("span", {
38
+ "aria-hidden": true,
39
+ ...stylex.props(styles.divider)
40
+ }),
41
+ active && value && /* @__PURE__ */ jsx(ColorPicker, {
42
+ value,
43
+ onChangeComplete: onChange,
44
+ children: /* @__PURE__ */ jsxs("button", {
45
+ "aria-label": value,
46
+ "aria-pressed": "true",
47
+ type: "button",
48
+ ...stylex.props(styles.picker, styles.chip, styles.activePicker, chipMarker),
49
+ style: {
50
+ background: value,
51
+ borderRadius
52
+ },
53
+ children: [/* @__PURE__ */ jsx(Icon, {
54
+ className: stylex.props(styles.chipIcon, styles.chipCheck).className,
55
+ color: iconColor,
56
+ icon: CheckIcon,
57
+ size: {
58
+ size: 14,
59
+ strokeWidth: 4
60
+ }
61
+ }), /* @__PURE__ */ jsx(Icon, {
62
+ className: stylex.props(styles.chipIcon, styles.chipEdit).className,
63
+ color: iconColor,
64
+ icon: PencilIcon,
65
+ size: {
66
+ size: 12,
67
+ strokeWidth: 3
68
+ }
69
+ })]
70
+ })
71
+ }),
72
+ /* @__PURE__ */ jsx(Tooltip, {
73
+ title: label,
74
+ children: /* @__PURE__ */ jsx("span", {
75
+ style: { display: "inline-flex" },
76
+ children: /* @__PURE__ */ jsx(ColorPicker, {
77
+ value,
78
+ onChangeComplete: onChange,
79
+ children: /* @__PURE__ */ jsx("button", {
80
+ "aria-label": label,
81
+ type: "button",
82
+ ...stylex.props(styles.picker, styles.conic, styles.add),
83
+ style: { borderRadius },
84
+ children: /* @__PURE__ */ jsx(Icon, {
85
+ icon: PlusIcon,
86
+ size: {
87
+ size: 12,
88
+ strokeWidth: 3
89
+ }
90
+ })
91
+ })
92
+ })
93
+ })
94
+ })
95
+ ] });
96
+ };
97
+ CustomPicker.displayName = "ColorSwatchesCustomPicker";
98
+ //#endregion
99
+ export { CustomPicker as default };
100
+
101
+ //# sourceMappingURL=CustomPicker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomPicker.mjs","names":[],"sources":["../../src/ColorSwatches/CustomPicker.tsx"],"sourcesContent":["'use client';\n\nimport * as stylex from '@stylexjs/stylex';\nimport { CheckIcon, PencilIcon, PlusIcon } from 'lucide-react';\nimport { type FC } from 'react';\n\nimport { ColorPicker } from '@/ColorPicker';\nimport Icon from '@/Icon';\nimport { cssVar } from '@/styles/stylex/cssVar.stylex';\nimport Tooltip from '@/Tooltip';\nimport { safeReadableColor } from '@/utils/safeReadableColor';\n\nimport { chipMarker } from './marker.stylex';\nimport { styles } from './style';\nimport type { ColorSwatchesPickerRenderProps } from './type';\n\ninterface CustomPickerProps extends ColorSwatchesPickerRenderProps {\n current?: string;\n label: string;\n standalone: boolean;\n}\n\nconst CustomPicker: FC<CustomPickerProps> = ({\n active,\n current,\n label,\n onChange,\n presets,\n shape,\n standalone,\n value,\n}) => {\n const borderRadius = shape === 'circle' ? '50%' : cssVar.borderRadius;\n\n if (standalone)\n return (\n <Tooltip title={label}>\n <span style={{ display: 'inline-flex' }}>\n <ColorPicker presets={presets} value={value} onChangeComplete={onChange}>\n <button\n aria-label={label}\n type=\"button\"\n {...stylex.props(styles.picker, active && styles.activePicker)}\n style={{ background: current, borderRadius }}\n />\n </ColorPicker>\n </span>\n </Tooltip>\n );\n\n const iconColor = value\n ? `color-mix(in srgb, ${safeReadableColor(value)} 33%, transparent)`\n : undefined;\n\n return (\n <>\n <span aria-hidden {...stylex.props(styles.divider)} />\n {active && value && (\n <ColorPicker value={value} onChangeComplete={onChange}>\n <button\n aria-label={value}\n aria-pressed=\"true\"\n type=\"button\"\n {...stylex.props(styles.picker, styles.chip, styles.activePicker, chipMarker)}\n style={{ background: value, borderRadius }}\n >\n <Icon\n className={stylex.props(styles.chipIcon, styles.chipCheck).className}\n color={iconColor}\n icon={CheckIcon}\n size={{ size: 14, strokeWidth: 4 }}\n />\n <Icon\n className={stylex.props(styles.chipIcon, styles.chipEdit).className}\n color={iconColor}\n icon={PencilIcon}\n size={{ size: 12, strokeWidth: 3 }}\n />\n </button>\n </ColorPicker>\n )}\n <Tooltip title={label}>\n <span style={{ display: 'inline-flex' }}>\n <ColorPicker value={value} onChangeComplete={onChange}>\n <button\n aria-label={label}\n type=\"button\"\n {...stylex.props(styles.picker, styles.conic, styles.add)}\n style={{ borderRadius }}\n >\n <Icon icon={PlusIcon} size={{ size: 12, strokeWidth: 3 }} />\n </button>\n </ColorPicker>\n </span>\n </Tooltip>\n </>\n );\n};\n\nCustomPicker.displayName = 'ColorSwatchesCustomPicker';\n\nexport default CustomPicker;\n"],"mappings":";;;;;;;;;;;;AAkBA,MAAM,gBAAuC,EAC3C,QACA,SACA,OACA,UACA,SACA,OACA,YACA,YACI;CACJ,MAAM,eAAe,UAAU,WAAW,QAAQ,OAAO;CACzD,IAAI,YAAY,OAAO,oBAAC,SAAD;EAAS,OAAO;EACjC,UAAA,oBAAC,QAAD;GAAM,OAAO,EACf,SAAS,cACX;GACM,UAAA,oBAAC,aAAD;IAAsB;IAAgB;IAAO,kBAAkB;IAC7D,UAAA,oBAAC,UAAD;KAAQ,cAAY;KAAO,MAAK;KAAS,GAAI,OAAO,MAAM,OAAO,QAAQ,UAAU,OAAO,YAAY;KAAG,OAAO;MAClH,YAAY;MACZ;KACF;IAAI,CAAA;GACW,CAAA;EACT,CAAA;CACC,CAAA;CACb,MAAM,YAAY,QAAQ,sBAAsB,kBAAkB,KAAK,EAAE,sBAAsB,KAAA;CAC/F,OAAO,qBAAA,UAAA,EAAA,UAAA;EACH,oBAAC,QAAD;GAAM,eAAA;GAAY,GAAI,OAAO,MAAM,OAAO,OAAO;EAAI,CAAA;EACpD,UAAU,SAAS,oBAAC,aAAD;GAAoB;GAAO,kBAAkB;GAC7D,UAAA,qBAAC,UAAD;IAAQ,cAAY;IAAO,gBAAa;IAAO,MAAK;IAAS,GAAI,OAAO,MAAM,OAAO,QAAQ,OAAO,MAAM,OAAO,cAAc,UAAU;IAAG,OAAO;KACrJ,YAAY;KACZ;IACF;IAHI,UAAA,CAIE,oBAAC,MAAD;KAAM,WAAW,OAAO,MAAM,OAAO,UAAU,OAAO,SAAS,CAAC,CAAC;KAAW,OAAO;KAAW,MAAM;KAAW,MAAM;MACvH,MAAM;MACN,aAAa;KACf;IAAI,CAAA,GACA,oBAAC,MAAD;KAAM,WAAW,OAAO,MAAM,OAAO,UAAU,OAAO,QAAQ,CAAC,CAAC;KAAW,OAAO;KAAW,MAAM;KAAY,MAAM;MACvH,MAAM;MACN,aAAa;KACf;IAAI,CAAA,CACM;;EACG,CAAA;EACf,oBAAC,SAAD;GAAS,OAAO;GACd,UAAA,oBAAC,QAAD;IAAM,OAAO,EACb,SAAS,cACX;IACI,UAAA,oBAAC,aAAD;KAAoB;KAAO,kBAAkB;KAC3C,UAAA,oBAAC,UAAD;MAAQ,cAAY;MAAO,MAAK;MAAS,GAAI,OAAO,MAAM,OAAO,QAAQ,OAAO,OAAO,OAAO,GAAG;MAAG,OAAO,EAC3G,aACF;MACI,UAAA,oBAAC,MAAD;OAAM,MAAM;OAAU,MAAM;QAC5B,MAAM;QACN,aAAa;OACf;MAAI,CAAA;KACI,CAAA;IACG,CAAA;GACT,CAAA;EACC,CAAA;CACT,EAAA,CAAA;AACN;AACA,aAAa,cAAc"}
@@ -1,3 +1,3 @@
1
- import { ColorSwatchesProps } from "./type.mjs";
1
+ import { ColorSwatchesPickerRenderProps, ColorSwatchesProps } from "./type.mjs";
2
2
  import ColorSwatches from "./ColorSwatches.mjs";
3
- export { ColorSwatchesProps, ColorSwatches as default };
3
+ export { ColorSwatchesPickerRenderProps, ColorSwatchesProps, ColorSwatches as default };
@@ -0,0 +1,9 @@
1
+ //#region src/ColorSwatches/marker.stylex.ts
2
+ const chipMarker = {
3
+ lb1pgf9nm: "lb1pgf9nm",
4
+ $$css: true
5
+ };
6
+ //#endregion
7
+ export { chipMarker };
8
+
9
+ //# sourceMappingURL=marker.stylex.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker.stylex.mjs","names":[],"sources":["../../src/ColorSwatches/marker.stylex.ts"],"sourcesContent":["import * as stylex from '@stylexjs/stylex';\n\nexport const chipMarker = stylex.defineMarker();\n"],"mappings":";AACA,MAAa,aAAa;CACxB,WAAW;CACX,OAAO;AACT"}