@namroodinc/liquid-editorial 0.0.0-stage → 0.1.1

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 (375) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -2
  3. package/dist/chunks/EntryEditor-BF808OZR.js +181 -0
  4. package/dist/chunks/EntryEditor-BF808OZR.js.map +1 -0
  5. package/dist/chunks/EntryEditor-cjDk4vdH.cjs +2 -0
  6. package/dist/chunks/EntryEditor-cjDk4vdH.cjs.map +1 -0
  7. package/dist/chunks/Icon-CGY1FNXT.js +77 -0
  8. package/dist/chunks/Icon-CGY1FNXT.js.map +1 -0
  9. package/dist/chunks/Icon-CWsA1W83.cjs +2 -0
  10. package/dist/chunks/Icon-CWsA1W83.cjs.map +1 -0
  11. package/dist/chunks/RichTextEditor-DRt-kibg.js +248 -0
  12. package/dist/chunks/RichTextEditor-DRt-kibg.js.map +1 -0
  13. package/dist/chunks/RichTextEditor-tFkISOvq.cjs +2 -0
  14. package/dist/chunks/RichTextEditor-tFkISOvq.cjs.map +1 -0
  15. package/dist/components/AssetGrid/index.cjs +2 -0
  16. package/dist/components/AssetGrid/index.cjs.map +1 -0
  17. package/dist/components/AssetGrid/index.d.cts +54 -0
  18. package/dist/components/AssetGrid/index.d.cts.map +1 -0
  19. package/dist/components/AssetGrid/index.d.ts +54 -0
  20. package/dist/components/AssetGrid/index.d.ts.map +1 -0
  21. package/dist/components/AssetGrid/index.js +137 -0
  22. package/dist/components/AssetGrid/index.js.map +1 -0
  23. package/dist/components/AssetGrid/style.css +196 -0
  24. package/dist/components/Avatar/index.cjs +2 -0
  25. package/dist/components/Avatar/index.cjs.map +1 -0
  26. package/dist/components/Avatar/index.d.cts +24 -0
  27. package/dist/components/Avatar/index.d.cts.map +1 -0
  28. package/dist/components/Avatar/index.d.ts +24 -0
  29. package/dist/components/Avatar/index.d.ts.map +1 -0
  30. package/dist/components/Avatar/index.js +43 -0
  31. package/dist/components/Avatar/index.js.map +1 -0
  32. package/dist/components/Avatar/style.css +70 -0
  33. package/dist/components/Badge/index.cjs +2 -0
  34. package/dist/components/Badge/index.cjs.map +1 -0
  35. package/dist/components/Badge/index.d.cts +25 -0
  36. package/dist/components/Badge/index.d.cts.map +1 -0
  37. package/dist/components/Badge/index.d.ts +25 -0
  38. package/dist/components/Badge/index.d.ts.map +1 -0
  39. package/dist/components/Badge/index.js +28 -0
  40. package/dist/components/Badge/index.js.map +1 -0
  41. package/dist/components/Badge/style.css +103 -0
  42. package/dist/components/Board/index.cjs +2 -0
  43. package/dist/components/Board/index.cjs.map +1 -0
  44. package/dist/components/Board/index.d.cts +62 -0
  45. package/dist/components/Board/index.d.cts.map +1 -0
  46. package/dist/components/Board/index.d.ts +62 -0
  47. package/dist/components/Board/index.d.ts.map +1 -0
  48. package/dist/components/Board/index.js +227 -0
  49. package/dist/components/Board/index.js.map +1 -0
  50. package/dist/components/Board/style.css +145 -0
  51. package/dist/components/Button/index.cjs +2 -0
  52. package/dist/components/Button/index.cjs.map +1 -0
  53. package/dist/components/Button/index.d.cts +22 -0
  54. package/dist/components/Button/index.d.cts.map +1 -0
  55. package/dist/components/Button/index.d.ts +22 -0
  56. package/dist/components/Button/index.d.ts.map +1 -0
  57. package/dist/components/Button/index.js +37 -0
  58. package/dist/components/Button/index.js.map +1 -0
  59. package/dist/components/Button/style.css +139 -0
  60. package/dist/components/ButtonGroup/index.cjs +2 -0
  61. package/dist/components/ButtonGroup/index.cjs.map +1 -0
  62. package/dist/components/ButtonGroup/index.d.cts +17 -0
  63. package/dist/components/ButtonGroup/index.d.cts.map +1 -0
  64. package/dist/components/ButtonGroup/index.d.ts +17 -0
  65. package/dist/components/ButtonGroup/index.d.ts.map +1 -0
  66. package/dist/components/ButtonGroup/index.js +18 -0
  67. package/dist/components/ButtonGroup/index.js.map +1 -0
  68. package/dist/components/ButtonGroup/style.css +66 -0
  69. package/dist/components/Choice/index.cjs +2 -0
  70. package/dist/components/Choice/index.cjs.map +1 -0
  71. package/dist/components/Choice/index.d.cts +25 -0
  72. package/dist/components/Choice/index.d.cts.map +1 -0
  73. package/dist/components/Choice/index.d.ts +25 -0
  74. package/dist/components/Choice/index.d.ts.map +1 -0
  75. package/dist/components/Choice/index.js +58 -0
  76. package/dist/components/Choice/index.js.map +1 -0
  77. package/dist/components/Choice/style.css +96 -0
  78. package/dist/components/Container/index.cjs +2 -0
  79. package/dist/components/Container/index.cjs.map +1 -0
  80. package/dist/components/Container/index.d.cts +19 -0
  81. package/dist/components/Container/index.d.cts.map +1 -0
  82. package/dist/components/Container/index.d.ts +19 -0
  83. package/dist/components/Container/index.d.ts.map +1 -0
  84. package/dist/components/Container/index.js +20 -0
  85. package/dist/components/Container/index.js.map +1 -0
  86. package/dist/components/Container/style.css +41 -0
  87. package/dist/components/DatePicker/index.cjs +2 -0
  88. package/dist/components/DatePicker/index.cjs.map +1 -0
  89. package/dist/components/DatePicker/index.d.cts +57 -0
  90. package/dist/components/DatePicker/index.d.cts.map +1 -0
  91. package/dist/components/DatePicker/index.d.ts +57 -0
  92. package/dist/components/DatePicker/index.d.ts.map +1 -0
  93. package/dist/components/DatePicker/index.js +248 -0
  94. package/dist/components/DatePicker/index.js.map +1 -0
  95. package/dist/components/DatePicker/style.css +149 -0
  96. package/dist/components/Drawer/index.cjs +2 -0
  97. package/dist/components/Drawer/index.cjs.map +1 -0
  98. package/dist/components/Drawer/index.d.cts +23 -0
  99. package/dist/components/Drawer/index.d.cts.map +1 -0
  100. package/dist/components/Drawer/index.d.ts +23 -0
  101. package/dist/components/Drawer/index.d.ts.map +1 -0
  102. package/dist/components/Drawer/index.js +85 -0
  103. package/dist/components/Drawer/index.js.map +1 -0
  104. package/dist/components/Drawer/style.css +147 -0
  105. package/dist/components/EntryEditor/index.cjs +1 -0
  106. package/dist/components/EntryEditor/index.d.cts +21 -0
  107. package/dist/components/EntryEditor/index.d.cts.map +1 -0
  108. package/dist/components/EntryEditor/index.d.ts +21 -0
  109. package/dist/components/EntryEditor/index.d.ts.map +1 -0
  110. package/dist/components/EntryEditor/index.js +6 -0
  111. package/dist/components/EntryEditor/model.d.cts +33 -0
  112. package/dist/components/EntryEditor/model.d.cts.map +1 -0
  113. package/dist/components/EntryEditor/model.d.ts +33 -0
  114. package/dist/components/EntryEditor/model.d.ts.map +1 -0
  115. package/dist/components/EntryEditor/style.css +8 -0
  116. package/dist/components/EntryPicker/index.cjs +2 -0
  117. package/dist/components/EntryPicker/index.cjs.map +1 -0
  118. package/dist/components/EntryPicker/index.d.cts +36 -0
  119. package/dist/components/EntryPicker/index.d.cts.map +1 -0
  120. package/dist/components/EntryPicker/index.d.ts +36 -0
  121. package/dist/components/EntryPicker/index.d.ts.map +1 -0
  122. package/dist/components/EntryPicker/index.js +181 -0
  123. package/dist/components/EntryPicker/index.js.map +1 -0
  124. package/dist/components/EntryPicker/style.css +162 -0
  125. package/dist/components/Field/index.cjs +2 -0
  126. package/dist/components/Field/index.cjs.map +1 -0
  127. package/dist/components/Field/index.d.cts +22 -0
  128. package/dist/components/Field/index.d.cts.map +1 -0
  129. package/dist/components/Field/index.d.ts +22 -0
  130. package/dist/components/Field/index.d.ts.map +1 -0
  131. package/dist/components/Field/index.js +47 -0
  132. package/dist/components/Field/index.js.map +1 -0
  133. package/dist/components/Field/style.css +112 -0
  134. package/dist/components/FieldAffix/index.cjs +2 -0
  135. package/dist/components/FieldAffix/index.cjs.map +1 -0
  136. package/dist/components/FieldAffix/index.d.cts +19 -0
  137. package/dist/components/FieldAffix/index.d.cts.map +1 -0
  138. package/dist/components/FieldAffix/index.d.ts +19 -0
  139. package/dist/components/FieldAffix/index.d.ts.map +1 -0
  140. package/dist/components/FieldAffix/index.js +45 -0
  141. package/dist/components/FieldAffix/index.js.map +1 -0
  142. package/dist/components/FieldAffix/style.css +54 -0
  143. package/dist/components/Grid/index.cjs +2 -0
  144. package/dist/components/Grid/index.cjs.map +1 -0
  145. package/dist/components/Grid/index.d.cts +44 -0
  146. package/dist/components/Grid/index.d.cts.map +1 -0
  147. package/dist/components/Grid/index.d.ts +44 -0
  148. package/dist/components/Grid/index.d.ts.map +1 -0
  149. package/dist/components/Grid/index.js +49 -0
  150. package/dist/components/Grid/index.js.map +1 -0
  151. package/dist/components/Grid/style.css +226 -0
  152. package/dist/components/Icon/icons.d.cts +64 -0
  153. package/dist/components/Icon/icons.d.cts.map +1 -0
  154. package/dist/components/Icon/icons.d.ts +64 -0
  155. package/dist/components/Icon/icons.d.ts.map +1 -0
  156. package/dist/components/Icon/index.cjs +1 -0
  157. package/dist/components/Icon/index.d.cts +15 -0
  158. package/dist/components/Icon/index.d.cts.map +1 -0
  159. package/dist/components/Icon/index.d.ts +15 -0
  160. package/dist/components/Icon/index.d.ts.map +1 -0
  161. package/dist/components/Icon/index.js +1 -0
  162. package/dist/components/Icon/style.css +10 -0
  163. package/dist/components/ImageCropper/index.cjs +2 -0
  164. package/dist/components/ImageCropper/index.cjs.map +1 -0
  165. package/dist/components/ImageCropper/index.d.cts +66 -0
  166. package/dist/components/ImageCropper/index.d.cts.map +1 -0
  167. package/dist/components/ImageCropper/index.d.ts +66 -0
  168. package/dist/components/ImageCropper/index.d.ts.map +1 -0
  169. package/dist/components/ImageCropper/index.js +263 -0
  170. package/dist/components/ImageCropper/index.js.map +1 -0
  171. package/dist/components/ImageCropper/style.css +160 -0
  172. package/dist/components/Menu/index.cjs +2 -0
  173. package/dist/components/Menu/index.cjs.map +1 -0
  174. package/dist/components/Menu/index.d.cts +35 -0
  175. package/dist/components/Menu/index.d.cts.map +1 -0
  176. package/dist/components/Menu/index.d.ts +35 -0
  177. package/dist/components/Menu/index.d.ts.map +1 -0
  178. package/dist/components/Menu/index.js +110 -0
  179. package/dist/components/Menu/index.js.map +1 -0
  180. package/dist/components/Menu/style.css +87 -0
  181. package/dist/components/Modal/index.cjs +2 -0
  182. package/dist/components/Modal/index.cjs.map +1 -0
  183. package/dist/components/Modal/index.d.cts +19 -0
  184. package/dist/components/Modal/index.d.cts.map +1 -0
  185. package/dist/components/Modal/index.d.ts +19 -0
  186. package/dist/components/Modal/index.d.ts.map +1 -0
  187. package/dist/components/Modal/index.js +84 -0
  188. package/dist/components/Modal/index.js.map +1 -0
  189. package/dist/components/Modal/style.css +106 -0
  190. package/dist/components/NumberField/index.cjs +2 -0
  191. package/dist/components/NumberField/index.cjs.map +1 -0
  192. package/dist/components/NumberField/index.d.cts +50 -0
  193. package/dist/components/NumberField/index.d.cts.map +1 -0
  194. package/dist/components/NumberField/index.d.ts +50 -0
  195. package/dist/components/NumberField/index.d.ts.map +1 -0
  196. package/dist/components/NumberField/index.js +124 -0
  197. package/dist/components/NumberField/index.js.map +1 -0
  198. package/dist/components/NumberField/style.css +85 -0
  199. package/dist/components/Popover/index.cjs +2 -0
  200. package/dist/components/Popover/index.cjs.map +1 -0
  201. package/dist/components/Popover/index.d.cts +28 -0
  202. package/dist/components/Popover/index.d.cts.map +1 -0
  203. package/dist/components/Popover/index.d.ts +28 -0
  204. package/dist/components/Popover/index.d.ts.map +1 -0
  205. package/dist/components/Popover/index.js +52 -0
  206. package/dist/components/Popover/index.js.map +1 -0
  207. package/dist/components/Popover/style.css +23 -0
  208. package/dist/components/RichTextEditor/document.d.cts +10 -0
  209. package/dist/components/RichTextEditor/document.d.cts.map +1 -0
  210. package/dist/components/RichTextEditor/document.d.ts +10 -0
  211. package/dist/components/RichTextEditor/document.d.ts.map +1 -0
  212. package/dist/components/RichTextEditor/index.cjs +1 -0
  213. package/dist/components/RichTextEditor/index.d.cts +38 -0
  214. package/dist/components/RichTextEditor/index.d.cts.map +1 -0
  215. package/dist/components/RichTextEditor/index.d.ts +38 -0
  216. package/dist/components/RichTextEditor/index.d.ts.map +1 -0
  217. package/dist/components/RichTextEditor/index.js +1 -0
  218. package/dist/components/RichTextEditor/style.css +136 -0
  219. package/dist/components/SearchField/index.cjs +2 -0
  220. package/dist/components/SearchField/index.cjs.map +1 -0
  221. package/dist/components/SearchField/index.d.cts +11 -0
  222. package/dist/components/SearchField/index.d.cts.map +1 -0
  223. package/dist/components/SearchField/index.d.ts +11 -0
  224. package/dist/components/SearchField/index.d.ts.map +1 -0
  225. package/dist/components/SearchField/index.js +49 -0
  226. package/dist/components/SearchField/index.js.map +1 -0
  227. package/dist/components/SearchField/style.css +27 -0
  228. package/dist/components/Select/index.cjs +2 -0
  229. package/dist/components/Select/index.cjs.map +1 -0
  230. package/dist/components/Select/index.d.cts +26 -0
  231. package/dist/components/Select/index.d.cts.map +1 -0
  232. package/dist/components/Select/index.d.ts +26 -0
  233. package/dist/components/Select/index.d.ts.map +1 -0
  234. package/dist/components/Select/index.js +129 -0
  235. package/dist/components/Select/index.js.map +1 -0
  236. package/dist/components/Select/style.css +88 -0
  237. package/dist/components/SelectionCard/index.cjs +2 -0
  238. package/dist/components/SelectionCard/index.cjs.map +1 -0
  239. package/dist/components/SelectionCard/index.d.cts +32 -0
  240. package/dist/components/SelectionCard/index.d.cts.map +1 -0
  241. package/dist/components/SelectionCard/index.d.ts +32 -0
  242. package/dist/components/SelectionCard/index.d.ts.map +1 -0
  243. package/dist/components/SelectionCard/index.js +71 -0
  244. package/dist/components/SelectionCard/index.js.map +1 -0
  245. package/dist/components/SelectionCard/style.css +133 -0
  246. package/dist/components/SideNav/index.cjs +2 -0
  247. package/dist/components/SideNav/index.cjs.map +1 -0
  248. package/dist/components/SideNav/index.d.cts +58 -0
  249. package/dist/components/SideNav/index.d.cts.map +1 -0
  250. package/dist/components/SideNav/index.d.ts +58 -0
  251. package/dist/components/SideNav/index.d.ts.map +1 -0
  252. package/dist/components/SideNav/index.js +113 -0
  253. package/dist/components/SideNav/index.js.map +1 -0
  254. package/dist/components/SideNav/style.css +184 -0
  255. package/dist/components/Skeleton/index.cjs +2 -0
  256. package/dist/components/Skeleton/index.cjs.map +1 -0
  257. package/dist/components/Skeleton/index.d.cts +21 -0
  258. package/dist/components/Skeleton/index.d.cts.map +1 -0
  259. package/dist/components/Skeleton/index.d.ts +21 -0
  260. package/dist/components/Skeleton/index.d.ts.map +1 -0
  261. package/dist/components/Skeleton/index.js +31 -0
  262. package/dist/components/Skeleton/index.js.map +1 -0
  263. package/dist/components/Skeleton/style.css +55 -0
  264. package/dist/components/Slider/index.cjs +2 -0
  265. package/dist/components/Slider/index.cjs.map +1 -0
  266. package/dist/components/Slider/index.d.cts +40 -0
  267. package/dist/components/Slider/index.d.cts.map +1 -0
  268. package/dist/components/Slider/index.d.ts +40 -0
  269. package/dist/components/Slider/index.d.ts.map +1 -0
  270. package/dist/components/Slider/index.js +117 -0
  271. package/dist/components/Slider/index.js.map +1 -0
  272. package/dist/components/Slider/style.css +156 -0
  273. package/dist/components/SortableList/index.cjs +2 -0
  274. package/dist/components/SortableList/index.cjs.map +1 -0
  275. package/dist/components/SortableList/index.d.cts +27 -0
  276. package/dist/components/SortableList/index.d.cts.map +1 -0
  277. package/dist/components/SortableList/index.d.ts +27 -0
  278. package/dist/components/SortableList/index.d.ts.map +1 -0
  279. package/dist/components/SortableList/index.js +85 -0
  280. package/dist/components/SortableList/index.js.map +1 -0
  281. package/dist/components/SortableList/style.css +71 -0
  282. package/dist/components/Stepper/index.cjs +2 -0
  283. package/dist/components/Stepper/index.cjs.map +1 -0
  284. package/dist/components/Stepper/index.d.cts +32 -0
  285. package/dist/components/Stepper/index.d.cts.map +1 -0
  286. package/dist/components/Stepper/index.d.ts +32 -0
  287. package/dist/components/Stepper/index.d.ts.map +1 -0
  288. package/dist/components/Stepper/index.js +69 -0
  289. package/dist/components/Stepper/index.js.map +1 -0
  290. package/dist/components/Stepper/style.css +154 -0
  291. package/dist/components/SubNav/index.cjs +2 -0
  292. package/dist/components/SubNav/index.cjs.map +1 -0
  293. package/dist/components/SubNav/index.d.cts +31 -0
  294. package/dist/components/SubNav/index.d.cts.map +1 -0
  295. package/dist/components/SubNav/index.d.ts +31 -0
  296. package/dist/components/SubNav/index.d.ts.map +1 -0
  297. package/dist/components/SubNav/index.js +62 -0
  298. package/dist/components/SubNav/index.js.map +1 -0
  299. package/dist/components/SubNav/style.css +86 -0
  300. package/dist/components/Switch/index.cjs +2 -0
  301. package/dist/components/Switch/index.cjs.map +1 -0
  302. package/dist/components/Switch/index.d.cts +12 -0
  303. package/dist/components/Switch/index.d.cts.map +1 -0
  304. package/dist/components/Switch/index.d.ts +12 -0
  305. package/dist/components/Switch/index.d.ts.map +1 -0
  306. package/dist/components/Switch/index.js +37 -0
  307. package/dist/components/Switch/index.js.map +1 -0
  308. package/dist/components/Switch/style.css +65 -0
  309. package/dist/components/Table/index.cjs +2 -0
  310. package/dist/components/Table/index.cjs.map +1 -0
  311. package/dist/components/Table/index.d.cts +54 -0
  312. package/dist/components/Table/index.d.cts.map +1 -0
  313. package/dist/components/Table/index.d.ts +54 -0
  314. package/dist/components/Table/index.d.ts.map +1 -0
  315. package/dist/components/Table/index.js +102 -0
  316. package/dist/components/Table/index.js.map +1 -0
  317. package/dist/components/Table/style.css +122 -0
  318. package/dist/components/TagsInput/index.cjs +2 -0
  319. package/dist/components/TagsInput/index.cjs.map +1 -0
  320. package/dist/components/TagsInput/index.d.cts +22 -0
  321. package/dist/components/TagsInput/index.d.cts.map +1 -0
  322. package/dist/components/TagsInput/index.d.ts +22 -0
  323. package/dist/components/TagsInput/index.d.ts.map +1 -0
  324. package/dist/components/TagsInput/index.js +60 -0
  325. package/dist/components/TagsInput/index.js.map +1 -0
  326. package/dist/components/TagsInput/style.css +83 -0
  327. package/dist/components/TextField/index.cjs +2 -0
  328. package/dist/components/TextField/index.cjs.map +1 -0
  329. package/dist/components/TextField/index.d.cts +11 -0
  330. package/dist/components/TextField/index.d.cts.map +1 -0
  331. package/dist/components/TextField/index.d.ts +11 -0
  332. package/dist/components/TextField/index.d.ts.map +1 -0
  333. package/dist/components/TextField/index.js +29 -0
  334. package/dist/components/TextField/index.js.map +1 -0
  335. package/dist/components/TextField/style.css +1 -0
  336. package/dist/components/Time/index.cjs +2 -0
  337. package/dist/components/Time/index.cjs.map +1 -0
  338. package/dist/components/Time/index.d.cts +35 -0
  339. package/dist/components/Time/index.d.cts.map +1 -0
  340. package/dist/components/Time/index.d.ts +35 -0
  341. package/dist/components/Time/index.d.ts.map +1 -0
  342. package/dist/components/Time/index.js +98 -0
  343. package/dist/components/Time/index.js.map +1 -0
  344. package/dist/components/Time/style.css +30 -0
  345. package/dist/components/Toast/index.cjs +2 -0
  346. package/dist/components/Toast/index.cjs.map +1 -0
  347. package/dist/components/Toast/index.d.cts +30 -0
  348. package/dist/components/Toast/index.d.cts.map +1 -0
  349. package/dist/components/Toast/index.d.ts +30 -0
  350. package/dist/components/Toast/index.d.ts.map +1 -0
  351. package/dist/components/Toast/index.js +96 -0
  352. package/dist/components/Toast/index.js.map +1 -0
  353. package/dist/components/Toast/style.css +80 -0
  354. package/dist/components/TopNav/index.cjs +2 -0
  355. package/dist/components/TopNav/index.cjs.map +1 -0
  356. package/dist/components/TopNav/index.d.cts +28 -0
  357. package/dist/components/TopNav/index.d.cts.map +1 -0
  358. package/dist/components/TopNav/index.d.ts +28 -0
  359. package/dist/components/TopNav/index.d.ts.map +1 -0
  360. package/dist/components/TopNav/index.js +45 -0
  361. package/dist/components/TopNav/index.js.map +1 -0
  362. package/dist/components/TopNav/style.css +80 -0
  363. package/dist/index.cjs +1 -0
  364. package/dist/index.d.cts +79 -0
  365. package/dist/index.d.cts.map +1 -0
  366. package/dist/index.d.ts +79 -0
  367. package/dist/index.d.ts.map +1 -0
  368. package/dist/index.js +39 -0
  369. package/dist/reset.css +15 -0
  370. package/dist/reset.css.d.ts +2 -0
  371. package/dist/styles.css +40 -0
  372. package/dist/styles.css.d.ts +2 -0
  373. package/dist/tokens.css +457 -0
  374. package/dist/tokens.css.d.ts +2 -0
  375. package/package.json +156 -4
@@ -0,0 +1,44 @@
1
+ import { type HTMLAttributes } from "react";
2
+ /** Gap steps map onto the spacing scale — never a raw pixel value. */
3
+ export type GapSize = "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
4
+ /** Column counts the system offers. `auto` fills by minimum column width. */
5
+ export type GridColumns = 1 | 2 | 3 | 4 | 6 | 12 | "auto";
6
+ export type GridAlign = "start" | "center" | "end" | "stretch";
7
+ export interface GridProps extends HTMLAttributes<HTMLDivElement> {
8
+ /** Columns at the widest. Narrow containers step down automatically. */
9
+ columns?: GridColumns;
10
+ /** Space between every child, in both axes. */
11
+ gap?: GapSize;
12
+ /** Override the row gap when rows should breathe differently. */
13
+ rowGap?: GapSize;
14
+ /** Smallest a column may get before the grid drops one, for `columns="auto"`. */
15
+ minColumnWidth?: string;
16
+ align?: GridAlign;
17
+ /** Render as a different element — `ul`, `section`, and so on. */
18
+ as?: "div" | "ul" | "ol" | "section";
19
+ }
20
+ /**
21
+ * A spacing wrapper. Put things inside it and they take their rhythm from the
22
+ * wrapper's `gap` — no margins on the children, ever. Columns step down on
23
+ * their own inside a narrow container, so a Grid is safe anywhere.
24
+ */
25
+ export declare const Grid: import("react").ForwardRefExoticComponent<GridProps & import("react").RefAttributes<HTMLDivElement>>;
26
+ export interface GridItemProps extends HTMLAttributes<HTMLDivElement> {
27
+ /** How many columns this child takes. `full` spans the whole row. */
28
+ span?: 1 | 2 | 3 | 4 | 6 | 12 | "full";
29
+ as?: "div" | "li" | "article" | "section";
30
+ }
31
+ /** Only needed when one child should be wider than the rest. */
32
+ export declare const GridItem: import("react").ForwardRefExoticComponent<GridItemProps & import("react").RefAttributes<HTMLDivElement>>;
33
+ export type StackDirection = "vertical" | "horizontal";
34
+ export interface StackProps extends HTMLAttributes<HTMLDivElement> {
35
+ direction?: StackDirection;
36
+ gap?: GapSize;
37
+ align?: "start" | "center" | "end" | "stretch" | "baseline";
38
+ justify?: "start" | "center" | "end" | "between";
39
+ wrap?: boolean;
40
+ as?: "div" | "ul" | "ol" | "section" | "header" | "footer";
41
+ }
42
+ /** The one-axis version of Grid: same gap scale, no columns. */
43
+ export declare const Stack: import("react").ForwardRefExoticComponent<StackProps & import("react").RefAttributes<HTMLDivElement>>;
44
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Grid/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoD,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAC9F,OAAO,aAAa,CAAC;AAErB,sEAAsE;AACtE,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;AAExE,6EAA6E;AAC7E,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;AAE1D,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAE/D,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,cAAc,CAAC;IAC/D,wEAAwE;IACxE,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,+CAA+C;IAC/C,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,kEAAkE;IAClE,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;CACtC;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI,sGAgCf,CAAC;AAEH,MAAM,WAAW,aAAc,SAAQ,cAAc,CAAC,cAAc,CAAC;IACnE,qEAAqE;IACrE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;IACvC,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,CAAC;CAC3C;AAED,gEAAgE;AAChE,eAAO,MAAM,QAAQ,0GAcnB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;AAEvD,MAAM,WAAW,UAAW,SAAQ,cAAc,CAAC,cAAc,CAAC;IAChE,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,UAAU,CAAC;IAC5D,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IACjD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;CAC5D;AAED,gEAAgE;AAChE,eAAO,MAAM,KAAK,uGA+BhB,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { forwardRef as e } from "react";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ //#region src/components/Grid/index.tsx
4
+ var n = e(function({ columns: e = "auto", gap: n = "md", rowGap: r, minColumnWidth: i = "var(--asset-tile-min-width)", align: a = "stretch", as: o = "div", className: s, style: c, ...l }, u) {
5
+ return /* @__PURE__ */ t(o, {
6
+ ref: u,
7
+ className: [
8
+ "ds-grid",
9
+ `ds-grid--cols-${e}`,
10
+ `ds-grid--gap-${n}`,
11
+ r ? `ds-grid--row-gap-${r}` : null,
12
+ `ds-grid--align-${a}`,
13
+ s
14
+ ].filter(Boolean).join(" "),
15
+ style: {
16
+ "--grid-min-column": i,
17
+ ...c
18
+ },
19
+ ...l
20
+ });
21
+ }), r = e(function({ span: e = 1, as: n = "div", className: r, ...i }, a) {
22
+ return /* @__PURE__ */ t(n, {
23
+ ref: a,
24
+ className: [
25
+ "ds-grid__item",
26
+ `ds-grid__item--span-${e}`,
27
+ r
28
+ ].filter(Boolean).join(" "),
29
+ ...i
30
+ });
31
+ }), i = e(function({ direction: e = "vertical", gap: n = "md", align: r = "stretch", justify: i = "start", wrap: a = !1, as: o = "div", className: s, ...c }, l) {
32
+ return /* @__PURE__ */ t(o, {
33
+ ref: l,
34
+ className: [
35
+ "ds-stack",
36
+ `ds-stack--${e}`,
37
+ `ds-grid--gap-${n}`,
38
+ `ds-stack--align-${r}`,
39
+ `ds-stack--justify-${i}`,
40
+ a ? "ds-stack--wrap" : null,
41
+ s
42
+ ].filter(Boolean).join(" "),
43
+ ...c
44
+ });
45
+ });
46
+ //#endregion
47
+ export { n as Grid, r as GridItem, i as Stack };
48
+
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["TagEl","Grid","forwardRef","asTag","rest","columns","gap","rowGap","align","className","minColumnWidth","style","GridItem","span","Stack","direction","justify","wrap"],"sources":["../../../src/components/Grid/index.tsx"],"sourcesContent":["import { forwardRef, type CSSProperties, type ElementType, type HTMLAttributes } from \"react\";\nimport \"./style.css\";\n\n/** Gap steps map onto the spacing scale — never a raw pixel value. */\nexport type GapSize = \"none\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\";\n\n/** Column counts the system offers. `auto` fills by minimum column width. */\nexport type GridColumns = 1 | 2 | 3 | 4 | 6 | 12 | \"auto\";\n\nexport type GridAlign = \"start\" | \"center\" | \"end\" | \"stretch\";\n\nexport interface GridProps extends HTMLAttributes<HTMLDivElement> {\n /** Columns at the widest. Narrow containers step down automatically. */\n columns?: GridColumns;\n /** Space between every child, in both axes. */\n gap?: GapSize;\n /** Override the row gap when rows should breathe differently. */\n rowGap?: GapSize;\n /** Smallest a column may get before the grid drops one, for `columns=\"auto\"`. */\n minColumnWidth?: string;\n align?: GridAlign;\n /** Render as a different element — `ul`, `section`, and so on. */\n as?: \"div\" | \"ul\" | \"ol\" | \"section\";\n}\n\n/**\n * A spacing wrapper. Put things inside it and they take their rhythm from the\n * wrapper's `gap` — no margins on the children, ever. Columns step down on\n * their own inside a narrow container, so a Grid is safe anywhere.\n */\nexport const Grid = forwardRef<HTMLDivElement, GridProps>(function Grid(\n {\n columns = \"auto\",\n gap = \"md\",\n rowGap,\n minColumnWidth = \"var(--asset-tile-min-width)\",\n align = \"stretch\",\n as: asTag = \"div\",\n className,\n style,\n ...rest\n },\n ref,\n) {\n const TagEl = asTag as ElementType;\n return (\n <TagEl\n ref={ref as never}\n className={[\n \"ds-grid\",\n `ds-grid--cols-${columns}`,\n `ds-grid--gap-${gap}`,\n rowGap ? `ds-grid--row-gap-${rowGap}` : null,\n `ds-grid--align-${align}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={{ \"--grid-min-column\": minColumnWidth, ...style } as CSSProperties}\n {...rest}\n />\n );\n});\n\nexport interface GridItemProps extends HTMLAttributes<HTMLDivElement> {\n /** How many columns this child takes. `full` spans the whole row. */\n span?: 1 | 2 | 3 | 4 | 6 | 12 | \"full\";\n as?: \"div\" | \"li\" | \"article\" | \"section\";\n}\n\n/** Only needed when one child should be wider than the rest. */\nexport const GridItem = forwardRef<HTMLDivElement, GridItemProps>(function GridItem(\n { span = 1, as: asTag = \"div\", className, ...rest },\n ref,\n) {\n const TagEl = asTag as ElementType;\n return (\n <TagEl\n ref={ref as never}\n className={[\"ds-grid__item\", `ds-grid__item--span-${span}`, className]\n .filter(Boolean)\n .join(\" \")}\n {...rest}\n />\n );\n});\n\nexport type StackDirection = \"vertical\" | \"horizontal\";\n\nexport interface StackProps extends HTMLAttributes<HTMLDivElement> {\n direction?: StackDirection;\n gap?: GapSize;\n align?: \"start\" | \"center\" | \"end\" | \"stretch\" | \"baseline\";\n justify?: \"start\" | \"center\" | \"end\" | \"between\";\n wrap?: boolean;\n as?: \"div\" | \"ul\" | \"ol\" | \"section\" | \"header\" | \"footer\";\n}\n\n/** The one-axis version of Grid: same gap scale, no columns. */\nexport const Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(\n {\n direction = \"vertical\",\n gap = \"md\",\n align = \"stretch\",\n justify = \"start\",\n wrap = false,\n as: asTag = \"div\",\n className,\n ...rest\n },\n ref,\n) {\n const TagEl = asTag as ElementType;\n return (\n <TagEl\n ref={ref as never}\n className={[\n \"ds-stack\",\n `ds-stack--${direction}`,\n `ds-grid--gap-${gap}`,\n `ds-stack--align-${align}`,\n `ds-stack--justify-${justify}`,\n wrap ? \"ds-stack--wrap\" : null,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n {...rest}\n />\n );\n});\n"],"mappings":";;;AA8BA,IAAaC,IAAOC,EAAsC,SACxD,EACE,aAAU,QACV,SAAM,MACN,WACA,oBAAiB,+BACjB,WAAQ,WACR,IAAIC,IAAQ,OACZ,cACA,UACA,GAAGC,KAEL,GACA;CAEA,OACE,kBAACJ,GAAD;EACO;EACL,WAAW;GACT;GACA,iBAAiBK;GACjB,gBAAgBC;GAChBC,IAAS,oBAAoBA,MAAW;GACxC,kBAAkBC;GAClBC;EACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;EACX,OAAO;GAAE,qBAAqBC;GAAgB,GAAGC;EAAM;EACvD,GAAIP;CACL,CAAA;AAEL,CAAC,GASYQ,IAAWV,EAA0C,SAChE,EAAE,UAAO,GAAG,IAAIC,IAAQ,OAAO,cAAW,GAAGC,KAC7C,GACA;CAEA,OACE,kBAACJ,GAAD;EACO;EACL,WAAW;GAAC;GAAiB,uBAAuBa;GAAQJ;EAAS,CAAC,CACnE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;EACX,GAAIL;CACL,CAAA;AAEL,CAAC,GAcYU,IAAQZ,EAAuC,SAC1D,EACE,eAAY,YACZ,SAAM,MACN,WAAQ,WACR,aAAU,SACV,UAAO,IACP,IAAIC,IAAQ,OACZ,cACA,GAAGC,KAEL,GACA;CAEA,OACE,kBAACJ,GAAD;EACO;EACL,WAAW;GACT;GACA,aAAae;GACb,gBAAgBT;GAChB,mBAAmBE;GACnB,qBAAqBQ;GACrBC,IAAO,mBAAmB;GAC1BR;EACF,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;EACX,GAAIL;CACL,CAAA;AAEL,CAAC"}
@@ -0,0 +1,226 @@
1
+ @layer components {
2
+ /* One gap scale, shared by Grid and Stack. Children never carry margins —
3
+ * the wrapper owns all the space between things. */
4
+ .ds-grid--gap-none {
5
+ --grid-gap: 0;
6
+ }
7
+
8
+ .ds-grid--gap-xs {
9
+ --grid-gap: var(--space-1);
10
+ }
11
+
12
+ .ds-grid--gap-sm {
13
+ --grid-gap: var(--space-2);
14
+ }
15
+
16
+ .ds-grid--gap-md {
17
+ --grid-gap: var(--space-4);
18
+ }
19
+
20
+ .ds-grid--gap-lg {
21
+ --grid-gap: var(--space-6);
22
+ }
23
+
24
+ .ds-grid--gap-xl {
25
+ --grid-gap: var(--space-8);
26
+ }
27
+
28
+ .ds-grid--gap-2xl {
29
+ --grid-gap: var(--space-12);
30
+ }
31
+
32
+ .ds-grid--row-gap-none {
33
+ --grid-row-gap: 0;
34
+ }
35
+
36
+ .ds-grid--row-gap-xs {
37
+ --grid-row-gap: var(--space-1);
38
+ }
39
+
40
+ .ds-grid--row-gap-sm {
41
+ --grid-row-gap: var(--space-2);
42
+ }
43
+
44
+ .ds-grid--row-gap-md {
45
+ --grid-row-gap: var(--space-4);
46
+ }
47
+
48
+ .ds-grid--row-gap-lg {
49
+ --grid-row-gap: var(--space-6);
50
+ }
51
+
52
+ .ds-grid--row-gap-xl {
53
+ --grid-row-gap: var(--space-8);
54
+ }
55
+
56
+ .ds-grid--row-gap-2xl {
57
+ --grid-row-gap: var(--space-12);
58
+ }
59
+
60
+ .ds-grid {
61
+ display: grid;
62
+ gap: var(--grid-row-gap, var(--grid-gap)) var(--grid-gap);
63
+ margin: 0;
64
+ padding: 0;
65
+ list-style: none;
66
+ container-type: inline-size;
67
+ }
68
+
69
+ .ds-grid--cols-auto {
70
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--grid-min-column)), 1fr));
71
+ }
72
+
73
+ .ds-grid--cols-1 {
74
+ grid-template-columns: repeat(1, minmax(0, 1fr));
75
+ }
76
+
77
+ .ds-grid--cols-2 {
78
+ grid-template-columns: repeat(2, minmax(0, 1fr));
79
+ }
80
+
81
+ .ds-grid--cols-3 {
82
+ grid-template-columns: repeat(3, minmax(0, 1fr));
83
+ }
84
+
85
+ .ds-grid--cols-4 {
86
+ grid-template-columns: repeat(4, minmax(0, 1fr));
87
+ }
88
+
89
+ .ds-grid--cols-6 {
90
+ grid-template-columns: repeat(6, minmax(0, 1fr));
91
+ }
92
+
93
+ .ds-grid--cols-12 {
94
+ grid-template-columns: repeat(12, minmax(0, 1fr));
95
+ }
96
+
97
+ .ds-grid--align-start {
98
+ align-items: start;
99
+ }
100
+
101
+ .ds-grid--align-center {
102
+ align-items: center;
103
+ }
104
+
105
+ .ds-grid--align-end {
106
+ align-items: end;
107
+ }
108
+
109
+ .ds-grid--align-stretch {
110
+ align-items: stretch;
111
+ }
112
+
113
+ .ds-grid__item--span-1 {
114
+ grid-column: span 1;
115
+ }
116
+
117
+ .ds-grid__item--span-2 {
118
+ grid-column: span 2;
119
+ }
120
+
121
+ .ds-grid__item--span-3 {
122
+ grid-column: span 3;
123
+ }
124
+
125
+ .ds-grid__item--span-4 {
126
+ grid-column: span 4;
127
+ }
128
+
129
+ .ds-grid__item--span-6 {
130
+ grid-column: span 6;
131
+ }
132
+
133
+ .ds-grid__item--span-12 {
134
+ grid-column: span 12;
135
+ }
136
+
137
+ .ds-grid__item--span-full {
138
+ grid-column: 1 / -1;
139
+ }
140
+
141
+ /* A grid steps down inside a narrow container, not a narrow window, so it
142
+ * behaves the same in a page, a drawer and a modal. */
143
+ @container (max-width: 60rem) {
144
+ .ds-grid--cols-12 {
145
+ grid-template-columns: repeat(6, minmax(0, 1fr));
146
+ }
147
+
148
+ .ds-grid--cols-6 {
149
+ grid-template-columns: repeat(3, minmax(0, 1fr));
150
+ }
151
+
152
+ .ds-grid--cols-4 {
153
+ grid-template-columns: repeat(2, minmax(0, 1fr));
154
+ }
155
+ }
156
+
157
+ @container (max-width: 40rem) {
158
+ .ds-grid--cols-12,
159
+ .ds-grid--cols-6,
160
+ .ds-grid--cols-4,
161
+ .ds-grid--cols-3,
162
+ .ds-grid--cols-2 {
163
+ grid-template-columns: repeat(1, minmax(0, 1fr));
164
+ }
165
+
166
+ .ds-grid__item {
167
+ grid-column: 1 / -1;
168
+ }
169
+ }
170
+
171
+ .ds-stack {
172
+ display: flex;
173
+ gap: var(--grid-gap);
174
+ margin: 0;
175
+ padding: 0;
176
+ list-style: none;
177
+ }
178
+
179
+ .ds-stack--vertical {
180
+ flex-direction: column;
181
+ }
182
+
183
+ .ds-stack--horizontal {
184
+ flex-direction: row;
185
+ }
186
+
187
+ .ds-stack--wrap {
188
+ flex-wrap: wrap;
189
+ }
190
+
191
+ .ds-stack--align-start {
192
+ align-items: flex-start;
193
+ }
194
+
195
+ .ds-stack--align-center {
196
+ align-items: center;
197
+ }
198
+
199
+ .ds-stack--align-end {
200
+ align-items: flex-end;
201
+ }
202
+
203
+ .ds-stack--align-stretch {
204
+ align-items: stretch;
205
+ }
206
+
207
+ .ds-stack--align-baseline {
208
+ align-items: baseline;
209
+ }
210
+
211
+ .ds-stack--justify-start {
212
+ justify-content: flex-start;
213
+ }
214
+
215
+ .ds-stack--justify-center {
216
+ justify-content: center;
217
+ }
218
+
219
+ .ds-stack--justify-end {
220
+ justify-content: flex-end;
221
+ }
222
+
223
+ .ds-stack--justify-between {
224
+ justify-content: space-between;
225
+ }
226
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * The finite icon set. Adding a glyph means adding a line here — a visible
3
+ * decision rather than an import someone typed at a call site.
4
+ */
5
+ export declare const icons: {
6
+ readonly "alert-triangle": import("lucide-react").LucideIcon;
7
+ readonly archive: import("lucide-react").LucideIcon;
8
+ readonly bold: import("lucide-react").LucideIcon;
9
+ readonly code: import("lucide-react").LucideIcon;
10
+ readonly "heading-2": import("lucide-react").LucideIcon;
11
+ readonly "heading-3": import("lucide-react").LucideIcon;
12
+ readonly italic: import("lucide-react").LucideIcon;
13
+ readonly "link-off": import("lucide-react").LucideIcon;
14
+ readonly list: import("lucide-react").LucideIcon;
15
+ readonly "list-ordered": import("lucide-react").LucideIcon;
16
+ readonly quote: import("lucide-react").LucideIcon;
17
+ readonly redo: import("lucide-react").LucideIcon;
18
+ readonly strikethrough: import("lucide-react").LucideIcon;
19
+ readonly undo: import("lucide-react").LucideIcon;
20
+ readonly "arrow-left": import("lucide-react").LucideIcon;
21
+ readonly "arrow-right": import("lucide-react").LucideIcon;
22
+ readonly calendar: import("lucide-react").LucideIcon;
23
+ readonly check: import("lucide-react").LucideIcon;
24
+ readonly "chevron-down": import("lucide-react").LucideIcon;
25
+ readonly "chevron-left": import("lucide-react").LucideIcon;
26
+ readonly "chevron-up": import("lucide-react").LucideIcon;
27
+ readonly minus: import("lucide-react").LucideIcon;
28
+ readonly "chevron-right": import("lucide-react").LucideIcon;
29
+ readonly clock: import("lucide-react").LucideIcon;
30
+ readonly copy: import("lucide-react").LucideIcon;
31
+ readonly download: import("lucide-react").LucideIcon;
32
+ readonly eye: import("lucide-react").LucideIcon;
33
+ readonly filter: import("lucide-react").LucideIcon;
34
+ readonly bell: import("lucide-react").LucideIcon;
35
+ readonly "chevrons-left": import("lucide-react").LucideIcon;
36
+ readonly "chevrons-right": import("lucide-react").LucideIcon;
37
+ readonly "file-text": import("lucide-react").LucideIcon;
38
+ readonly folder: import("lucide-react").LucideIcon;
39
+ readonly globe: import("lucide-react").LucideIcon;
40
+ readonly home: import("lucide-react").LucideIcon;
41
+ readonly "layout-grid": import("lucide-react").LucideIcon;
42
+ readonly menu: import("lucide-react").LucideIcon;
43
+ readonly users: import("lucide-react").LucideIcon;
44
+ readonly "grip-horizontal": import("lucide-react").LucideIcon;
45
+ readonly "grip-vertical": import("lucide-react").LucideIcon;
46
+ readonly image: import("lucide-react").LucideIcon;
47
+ readonly info: import("lucide-react").LucideIcon;
48
+ readonly link: import("lucide-react").LucideIcon;
49
+ readonly spinner: import("lucide-react").LucideIcon;
50
+ readonly "more-horizontal": import("lucide-react").LucideIcon;
51
+ readonly pencil: import("lucide-react").LucideIcon;
52
+ readonly plus: import("lucide-react").LucideIcon;
53
+ readonly "rotate-ccw": import("lucide-react").LucideIcon;
54
+ readonly "rotate-cw": import("lucide-react").LucideIcon;
55
+ readonly search: import("lucide-react").LucideIcon;
56
+ readonly settings: import("lucide-react").LucideIcon;
57
+ readonly trash: import("lucide-react").LucideIcon;
58
+ readonly upload: import("lucide-react").LucideIcon;
59
+ readonly user: import("lucide-react").LucideIcon;
60
+ readonly x: import("lucide-react").LucideIcon;
61
+ };
62
+ export type IconName = keyof typeof icons;
63
+ export declare const iconNames: IconName[];
64
+ //# sourceMappingURL=icons.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.d.cts","sourceRoot":"","sources":["../../../src/components/Icon/icons.ts"],"names":[],"mappings":"AA0DA;;;GAGG;AACH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDR,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,KAAK,CAAC;AAE1C,eAAO,MAAM,SAAS,EAAyB,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * The finite icon set. Adding a glyph means adding a line here — a visible
3
+ * decision rather than an import someone typed at a call site.
4
+ */
5
+ export declare const icons: {
6
+ readonly "alert-triangle": import("lucide-react").LucideIcon;
7
+ readonly archive: import("lucide-react").LucideIcon;
8
+ readonly bold: import("lucide-react").LucideIcon;
9
+ readonly code: import("lucide-react").LucideIcon;
10
+ readonly "heading-2": import("lucide-react").LucideIcon;
11
+ readonly "heading-3": import("lucide-react").LucideIcon;
12
+ readonly italic: import("lucide-react").LucideIcon;
13
+ readonly "link-off": import("lucide-react").LucideIcon;
14
+ readonly list: import("lucide-react").LucideIcon;
15
+ readonly "list-ordered": import("lucide-react").LucideIcon;
16
+ readonly quote: import("lucide-react").LucideIcon;
17
+ readonly redo: import("lucide-react").LucideIcon;
18
+ readonly strikethrough: import("lucide-react").LucideIcon;
19
+ readonly undo: import("lucide-react").LucideIcon;
20
+ readonly "arrow-left": import("lucide-react").LucideIcon;
21
+ readonly "arrow-right": import("lucide-react").LucideIcon;
22
+ readonly calendar: import("lucide-react").LucideIcon;
23
+ readonly check: import("lucide-react").LucideIcon;
24
+ readonly "chevron-down": import("lucide-react").LucideIcon;
25
+ readonly "chevron-left": import("lucide-react").LucideIcon;
26
+ readonly "chevron-up": import("lucide-react").LucideIcon;
27
+ readonly minus: import("lucide-react").LucideIcon;
28
+ readonly "chevron-right": import("lucide-react").LucideIcon;
29
+ readonly clock: import("lucide-react").LucideIcon;
30
+ readonly copy: import("lucide-react").LucideIcon;
31
+ readonly download: import("lucide-react").LucideIcon;
32
+ readonly eye: import("lucide-react").LucideIcon;
33
+ readonly filter: import("lucide-react").LucideIcon;
34
+ readonly bell: import("lucide-react").LucideIcon;
35
+ readonly "chevrons-left": import("lucide-react").LucideIcon;
36
+ readonly "chevrons-right": import("lucide-react").LucideIcon;
37
+ readonly "file-text": import("lucide-react").LucideIcon;
38
+ readonly folder: import("lucide-react").LucideIcon;
39
+ readonly globe: import("lucide-react").LucideIcon;
40
+ readonly home: import("lucide-react").LucideIcon;
41
+ readonly "layout-grid": import("lucide-react").LucideIcon;
42
+ readonly menu: import("lucide-react").LucideIcon;
43
+ readonly users: import("lucide-react").LucideIcon;
44
+ readonly "grip-horizontal": import("lucide-react").LucideIcon;
45
+ readonly "grip-vertical": import("lucide-react").LucideIcon;
46
+ readonly image: import("lucide-react").LucideIcon;
47
+ readonly info: import("lucide-react").LucideIcon;
48
+ readonly link: import("lucide-react").LucideIcon;
49
+ readonly spinner: import("lucide-react").LucideIcon;
50
+ readonly "more-horizontal": import("lucide-react").LucideIcon;
51
+ readonly pencil: import("lucide-react").LucideIcon;
52
+ readonly plus: import("lucide-react").LucideIcon;
53
+ readonly "rotate-ccw": import("lucide-react").LucideIcon;
54
+ readonly "rotate-cw": import("lucide-react").LucideIcon;
55
+ readonly search: import("lucide-react").LucideIcon;
56
+ readonly settings: import("lucide-react").LucideIcon;
57
+ readonly trash: import("lucide-react").LucideIcon;
58
+ readonly upload: import("lucide-react").LucideIcon;
59
+ readonly user: import("lucide-react").LucideIcon;
60
+ readonly x: import("lucide-react").LucideIcon;
61
+ };
62
+ export type IconName = keyof typeof icons;
63
+ export declare const iconNames: IconName[];
64
+ //# sourceMappingURL=icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/Icon/icons.ts"],"names":[],"mappings":"AA0DA;;;GAGG;AACH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDR,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,KAAK,CAAC;AAE1C,eAAO,MAAM,SAAS,EAAyB,QAAQ,EAAE,CAAC"}
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/Icon-CWsA1W83.cjs");exports.Icon=e.t;
@@ -0,0 +1,15 @@
1
+ import { type SVGProps } from "react";
2
+ import { type IconName } from "./icons.cjs";
3
+ export type IconSize = 16 | 20 | 24;
4
+ export interface IconProps extends Omit<SVGProps<SVGSVGElement>, "ref"> {
5
+ /** Glyph name from the curated set in `icons.ts`. */
6
+ name: IconName;
7
+ /** 16 inside controls, 20 standalone, 24 for empty states. No other sizes. */
8
+ size?: IconSize;
9
+ }
10
+ /**
11
+ * A glyph that clarifies an action or a status. Inherits `currentColor`, so it
12
+ * takes its colour from the control it sits in — it never carries its own.
13
+ */
14
+ export declare const Icon: import("react").ForwardRefExoticComponent<IconProps & import("react").RefAttributes<SVGSVGElement>>;
15
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/components/Icon/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,EAAS,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,aAAa,CAAC;AAErB,MAAM,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAEpC,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC;IACrE,qDAAqD;IACrD,IAAI,EAAE,QAAQ,CAAC;IACf,8EAA8E;IAC9E,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,qGAiBf,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { type SVGProps } from "react";
2
+ import { type IconName } from "./icons.js";
3
+ export type IconSize = 16 | 20 | 24;
4
+ export interface IconProps extends Omit<SVGProps<SVGSVGElement>, "ref"> {
5
+ /** Glyph name from the curated set in `icons.ts`. */
6
+ name: IconName;
7
+ /** 16 inside controls, 20 standalone, 24 for empty states. No other sizes. */
8
+ size?: IconSize;
9
+ }
10
+ /**
11
+ * A glyph that clarifies an action or a status. Inherits `currentColor`, so it
12
+ * takes its colour from the control it sits in — it never carries its own.
13
+ */
14
+ export declare const Icon: import("react").ForwardRefExoticComponent<IconProps & import("react").RefAttributes<SVGSVGElement>>;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Icon/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,EAAS,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,aAAa,CAAC;AAErB,MAAM,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAEpC,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC;IACrE,qDAAqD;IACrD,IAAI,EAAE,QAAQ,CAAC;IACf,8EAA8E;IAC9E,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,qGAiBf,CAAC"}
@@ -0,0 +1 @@
1
+ export { t as Icon } from "../../chunks/Icon-CGY1FNXT.js";
@@ -0,0 +1,10 @@
1
+ @layer components {
2
+ .ds-icon {
3
+ flex: none;
4
+ fill: none;
5
+ stroke: currentColor;
6
+ stroke-width: var(--icon-stroke);
7
+ stroke-linecap: round;
8
+ stroke-linejoin: round;
9
+ }
10
+ }
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../Button/index.cjs"),t=require("../ButtonGroup/index.cjs");let n=require("react"),r=require("react/jsx-runtime");var i=[{label:`1:1`,value:1},{label:`4:5`,value:4/5},{label:`4:3`,value:4/3},{label:`16:9`,value:16/9}],a=1,o={offsetX:0,offsetY:0,zoom:1,rotation:0},s=(0,n.forwardRef)(function({src:i,alt:s=``,aspect:c=1,ratios:l,onAspectChange:u,maxZoom:d=3,rotatable:f=!0,onChange:p,className:m,...h},g){let _=(0,n.useRef)(null),[v,y]=(0,n.useState)({width:0,height:0}),[b,x]=(0,n.useState)({width:0,height:0}),[S,C]=(0,n.useState)(o),[w,T]=(0,n.useState)(c),E=(0,n.useRef)(null),D=(0,n.useRef)(null);(0,n.useEffect)(()=>{T(c),C(e=>({...o,rotation:e.rotation}))},[c]);let O=e=>{T(e),C(e=>({...o,rotation:e.rotation})),u?.(e)},k=e=>C(t=>({...o,rotation:(t.rotation+e+360)%360})),A=(0,n.useCallback)(e=>{e.naturalWidth&&(x({width:e.naturalWidth,height:e.naturalHeight}),C(o))},[]);(0,n.useEffect)(()=>{let e=D.current;e?.complete&&A(e)},[A,i]);let j=S.rotation%180!=0,M={width:j?b.height:b.width,height:j?b.width:b.height},N=M.width&&v.width?Math.max(v.width/M.width,v.height/M.height):0,P=N*S.zoom,F=P?Math.max(0,(M.width*P-v.width)/2):0,I=P?Math.max(0,(M.height*P-v.height)/2):0;(0,n.useLayoutEffect)(()=>{let e=_.current;if(!e)return;let t=()=>y({width:e.clientWidth,height:e.clientHeight});t();let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[]);let L=(0,n.useCallback)(e=>{let t=N*e.zoom,n=t?Math.max(0,(M.width*t-v.width)/2):0,r=t?Math.max(0,(M.height*t-v.height)/2):0;return{rotation:e.rotation,zoom:Math.min(d,Math.max(a,e.zoom)),offsetX:Math.min(n,Math.max(-n,e.offsetX)),offsetY:Math.min(r,Math.max(-r,e.offsetY))}},[N,d,M.height,M.width,v.height,v.width]);(0,n.useEffect)(()=>{if(!P||!v.width)return;let e=v.width/P,t=v.height/P;p?.({x:Math.round(M.width/2-S.offsetX/P-e/2),y:Math.round(M.height/2-S.offsetY/P-t/2),width:Math.round(e),height:Math.round(t)},S)},[P,v.width,v.height,M.width,M.height,S]);let R=e=>{e.button===0&&(E.current={pointerId:e.pointerId,x:e.clientX,y:e.clientY},e.currentTarget.setPointerCapture(e.pointerId))},z=e=>{let t=E.current;if(!t||t.pointerId!==e.pointerId)return;let n=e.clientX-t.x,r=e.clientY-t.y;E.current={...t,x:e.clientX,y:e.clientY},C(e=>L({...e,offsetX:e.offsetX+n,offsetY:e.offsetY+r}))},B=e=>{E.current?.pointerId===e.pointerId&&(E.current=null,e.currentTarget.releasePointerCapture?.(e.pointerId))},V=(e,t)=>C(n=>L({...n,offsetX:n.offsetX+e,offsetY:n.offsetY+t}));return(0,r.jsxs)(`div`,{ref:g,className:[`ds-cropper`,m].filter(Boolean).join(` `),...h,children:[l&&l.length>1&&(0,r.jsx)(t.ButtonGroup,{"aria-label":`Crop ratio`,className:`ds-cropper__ratios`,children:l.map(t=>(0,r.jsx)(e.Button,{size:`sm`,variant:t.value===w?`active`:`neutral`,"aria-pressed":t.value===w,onClick:()=>O(t.value),children:t.label},t.label))}),(0,r.jsxs)(`div`,{role:`application`,"aria-label":`Crop area — drag to reposition, arrow keys to nudge`,tabIndex:0,className:`ds-cropper__stage`,style:{"--cropper-aspect":String(w)},onPointerDown:R,onPointerMove:z,onPointerUp:B,onPointerCancel:B,onKeyDown:e=>{let t=e.shiftKey?24:8,n={ArrowLeft:[-t,0],ArrowRight:[t,0],ArrowUp:[0,-t],ArrowDown:[0,t]}[e.key];n&&(e.preventDefault(),V(n[0],n[1]))},children:[(0,r.jsx)(`img`,{ref:D,src:i,alt:s,draggable:!1,className:`ds-cropper__image`,onLoad:e=>A(e.currentTarget),style:{inlineSize:b.width*P||void 0,blockSize:b.height*P||void 0,transform:`translate(calc(-50% + ${S.offsetX}px), calc(-50% + ${S.offsetY}px)) rotate(${S.rotation}deg)`}}),(0,r.jsx)(`div`,{className:`ds-cropper__frame`,ref:_,"aria-hidden":`true`,children:(0,r.jsx)(`div`,{className:`ds-cropper__guides`})})]}),(0,r.jsxs)(`div`,{className:`ds-cropper__controls`,children:[(0,r.jsxs)(`label`,{className:`ds-cropper__zoom`,children:[(0,r.jsx)(`span`,{className:`ds-cropper__zoom-label`,children:`Zoom`}),(0,r.jsx)(`input`,{type:`range`,min:a,max:d,step:.01,value:S.zoom,className:`ds-cropper__slider`,onChange:e=>C(t=>L({...t,zoom:Number(e.target.value)}))}),(0,r.jsxs)(`span`,{className:`ds-cropper__value`,children:[S.zoom.toFixed(2),`×`]})]}),(0,r.jsxs)(t.ButtonGroup,{"aria-label":`Crop actions`,children:[f&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.Button,{size:`sm`,iconStart:`rotate-ccw`,"aria-label":`Rotate left`,onClick:()=>k(-90)}),(0,r.jsx)(e.Button,{size:`sm`,iconStart:`rotate-cw`,"aria-label":`Rotate right`,onClick:()=>k(90)})]}),(0,r.jsx)(e.Button,{size:`sm`,onClick:()=>C(o),children:`Reset`})]})]}),(0,r.jsxs)(`p`,{className:`ds-cropper__hint`,children:[`Drag the picture to reposition it. Nothing is written until you save —`,` `,F===0&&I===0?`at this zoom the whole picture is in frame.`:`the veiled edges are what gets trimmed.`]})]})});async function c(e,t,{outputWidth:n,rotation:r=0,type:i=`image/png`,quality:a=.92}={}){let o=new Image;o.crossOrigin=`anonymous`,o.src=e,await o.decode();let s=r%180!=0,c=document.createElement(`canvas`);c.width=s?o.naturalHeight:o.naturalWidth,c.height=s?o.naturalWidth:o.naturalHeight;let l=c.getContext(`2d`);if(!l)throw Error(`Canvas 2D context unavailable`);l.translate(c.width/2,c.height/2),l.rotate(r*Math.PI/180),l.drawImage(o,-o.naturalWidth/2,-o.naturalHeight/2);let u=n??t.width,d=Math.round(t.height/t.width*u),f=document.createElement(`canvas`);f.width=u,f.height=d;let p=f.getContext(`2d`);if(!p)throw Error(`Canvas 2D context unavailable`);return p.drawImage(c,t.x,t.y,t.width,t.height,0,0,u,d),new Promise((e,t)=>{f.toBlob(n=>n?e(n):t(Error(`Could not encode the crop`)),i,a)})}exports.ImageCropper=s,exports.cropRatios=i,exports.cropToBlob=c;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["forwardRef","useRef","useState","useCallback","ButtonGroup","Button","_Fragment","require_components_Button_index","require_components_ButtonGroup_index","react","react_jsx_runtime","cropRatios","MIN_ZOOM","REST","ImageCropper","rest","frameRef","frame","setFrame","natural","setNatural","state","setState","ratio","setRatio","aspect","dragRef","imageRef","prev","chooseRatio","next","onAspectChange","turn","by","adopt","img","src","quarter","view","baseScale","scale","maxOffsetX","maxOffsetY","node","measure","observer","clamp","nextScale","limitX","limitY","maxZoom","width","height","onChange","onPointerDown","event","onPointerMove","drag","dx","dy","endDrag","nudge","className","ratios","option","step","move","rotatable","cropToBlob","image","rotation","turned","turnedContext","outputWidth","crop","canvas","context","blob","resolve","reject","type","quality"],"sources":["../../../src/components/ImageCropper/index.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type PointerEvent as ReactPointerEvent,\n} from \"react\";\nimport { Button } from \"../Button\";\nimport { ButtonGroup } from \"../ButtonGroup\";\nimport \"./style.css\";\n\nexport interface CropRect {\n /** Left edge of the crop, in the (rotated) image's own pixels. */\n x: number;\n /** Top edge of the crop, in the (rotated) image's own pixels. */\n y: number;\n width: number;\n height: number;\n}\n\nexport interface CropState {\n /** Pan, in stage pixels, from the centre. */\n offsetX: number;\n offsetY: number;\n /** 1 is \"cover the crop window exactly\". */\n zoom: number;\n /** Quarter turns applied to the picture, clockwise: 0, 90, 180 or 270. */\n rotation: number;\n}\n\n/** One offered output shape. `value` is width / height. */\nexport interface CropRatio {\n label: string;\n value: number;\n}\n\n/** The house set: square, portrait, landscape, wide. */\nexport const cropRatios: CropRatio[] = [\n { label: \"1:1\", value: 1 },\n { label: \"4:5\", value: 4 / 5 },\n { label: \"4:3\", value: 4 / 3 },\n { label: \"16:9\", value: 16 / 9 },\n];\n\nexport interface ImageCropperProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n src: string;\n /** Describes the picture for people who cannot see the stage. */\n alt?: string;\n /** Output shape, width / height. 1 for an avatar, 16 / 9 for a hero. */\n aspect?: number;\n /**\n * Offer the reader a choice of output shapes. Omit it — or pass one ratio —\n * when the shape is fixed by the slot the picture is going into.\n */\n ratios?: CropRatio[];\n /** Fires when the reader picks a different shape. */\n onAspectChange?: (aspect: number) => void;\n /** Highest allowed zoom. Past 3 the result is mush on most uploads. */\n maxZoom?: number;\n /** Offer the quarter-turn controls. */\n rotatable?: boolean;\n /** Fires on every pan, zoom, turn and reset, with the crop in image pixels. */\n onChange?: (crop: CropRect, state: CropState) => void;\n}\n\nconst MIN_ZOOM = 1;\nconst REST: CropState = { offsetX: 0, offsetY: 0, zoom: 1, rotation: 0 };\n\n/**\n * Pan-and-zoom cropping over a fixed frame. The frame never moves — the\n * picture does — and the parts that fall outside it stay visible under a\n * veil, so the reader can see what they are trimming away.\n * Drag with a pointer, or focus the stage and use the arrow keys.\n */\nexport const ImageCropper = forwardRef<HTMLDivElement, ImageCropperProps>(\n function ImageCropper(\n {\n src,\n alt = \"\",\n aspect = 1,\n ratios,\n onAspectChange,\n maxZoom = 3,\n rotatable = true,\n onChange,\n className,\n ...rest\n },\n ref,\n ) {\n const frameRef = useRef<HTMLDivElement | null>(null);\n const [frame, setFrame] = useState({ width: 0, height: 0 });\n const [natural, setNatural] = useState({ width: 0, height: 0 });\n const [state, setState] = useState<CropState>(REST);\n const [ratio, setRatio] = useState(aspect);\n const dragRef = useRef<{ pointerId: number; x: number; y: number } | null>(null);\n const imageRef = useRef<HTMLImageElement | null>(null);\n\n // The prop stays the source of truth when the caller drives the shape.\n useEffect(() => {\n setRatio(aspect);\n setState((prev) => ({ ...REST, rotation: prev.rotation }));\n }, [aspect]);\n\n const chooseRatio = (next: number) => {\n setRatio(next);\n setState((prev) => ({ ...REST, rotation: prev.rotation }));\n onAspectChange?.(next);\n };\n\n const turn = (by: number) =>\n setState((prev) => ({ ...REST, rotation: (prev.rotation + by + 360) % 360 }));\n\n /** Take the picture's own pixels and start from a centred, unzoomed view. */\n const adopt = useCallback((img: HTMLImageElement) => {\n if (!img.naturalWidth) return;\n setNatural({ width: img.naturalWidth, height: img.naturalHeight });\n setState(REST);\n }, []);\n\n // A cached or server-rendered image can already be decoded before React\n // attaches onLoad, and then that event never fires.\n useEffect(() => {\n const img = imageRef.current;\n if (img?.complete) adopt(img);\n }, [adopt, src]);\n\n // After a quarter turn the picture presents its other side to the frame.\n const quarter = state.rotation % 180 !== 0;\n const view = {\n width: quarter ? natural.height : natural.width,\n height: quarter ? natural.width : natural.height,\n };\n\n // The scale at which the image exactly covers the frame; zoom multiplies it.\n const baseScale =\n view.width && frame.width\n ? Math.max(frame.width / view.width, frame.height / view.height)\n : 0;\n const scale = baseScale * state.zoom;\n const maxOffsetX = scale ? Math.max(0, (view.width * scale - frame.width) / 2) : 0;\n const maxOffsetY = scale ? Math.max(0, (view.height * scale - frame.height) / 2) : 0;\n\n useLayoutEffect(() => {\n const node = frameRef.current;\n if (!node) return;\n const measure = () =>\n setFrame({ width: node.clientWidth, height: node.clientHeight });\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const clamp = useCallback(\n (next: CropState): CropState => {\n const nextScale = baseScale * next.zoom;\n const limitX = nextScale\n ? Math.max(0, (view.width * nextScale - frame.width) / 2)\n : 0;\n const limitY = nextScale\n ? Math.max(0, (view.height * nextScale - frame.height) / 2)\n : 0;\n return {\n rotation: next.rotation,\n zoom: Math.min(maxZoom, Math.max(MIN_ZOOM, next.zoom)),\n offsetX: Math.min(limitX, Math.max(-limitX, next.offsetX)),\n offsetY: Math.min(limitY, Math.max(-limitY, next.offsetY)),\n };\n },\n [baseScale, maxZoom, view.height, view.width, frame.height, frame.width],\n );\n\n useEffect(() => {\n if (!scale || !frame.width) return;\n const width = frame.width / scale;\n const height = frame.height / scale;\n onChange?.(\n {\n x: Math.round(view.width / 2 - state.offsetX / scale - width / 2),\n y: Math.round(view.height / 2 - state.offsetY / scale - height / 2),\n width: Math.round(width),\n height: Math.round(height),\n },\n state,\n );\n // onChange is intentionally not a dependency: callers pass inline handlers.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [scale, frame.width, frame.height, view.width, view.height, state]);\n\n const onPointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) return;\n dragRef.current = { pointerId: event.pointerId, x: event.clientX, y: event.clientY };\n event.currentTarget.setPointerCapture(event.pointerId);\n };\n\n const onPointerMove = (event: ReactPointerEvent<HTMLDivElement>) => {\n const drag = dragRef.current;\n if (!drag || drag.pointerId !== event.pointerId) return;\n const dx = event.clientX - drag.x;\n const dy = event.clientY - drag.y;\n dragRef.current = { ...drag, x: event.clientX, y: event.clientY };\n setState((prev) => clamp({ ...prev, offsetX: prev.offsetX + dx, offsetY: prev.offsetY + dy }));\n };\n\n const endDrag = (event: ReactPointerEvent<HTMLDivElement>) => {\n if (dragRef.current?.pointerId !== event.pointerId) return;\n dragRef.current = null;\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n };\n\n const nudge = (dx: number, dy: number) =>\n setState((prev) => clamp({ ...prev, offsetX: prev.offsetX + dx, offsetY: prev.offsetY + dy }));\n\n return (\n <div ref={ref} className={[\"ds-cropper\", className].filter(Boolean).join(\" \")} {...rest}>\n {ratios && ratios.length > 1 && (\n <ButtonGroup aria-label=\"Crop ratio\" className=\"ds-cropper__ratios\">\n {ratios.map((option) => (\n <Button\n key={option.label}\n size=\"sm\"\n variant={option.value === ratio ? \"active\" : \"neutral\"}\n aria-pressed={option.value === ratio}\n onClick={() => chooseRatio(option.value)}\n >\n {option.label}\n </Button>\n ))}\n </ButtonGroup>\n )}\n <div\n role=\"application\"\n aria-label=\"Crop area — drag to reposition, arrow keys to nudge\"\n tabIndex={0}\n className=\"ds-cropper__stage\"\n style={{ \"--cropper-aspect\": String(ratio) } as CSSProperties}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onKeyDown={(event) => {\n const step = event.shiftKey ? 24 : 8;\n const moves: Record<string, [number, number]> = {\n ArrowLeft: [-step, 0],\n ArrowRight: [step, 0],\n ArrowUp: [0, -step],\n ArrowDown: [0, step],\n };\n const move = moves[event.key];\n if (!move) return;\n event.preventDefault();\n nudge(move[0], move[1]);\n }}\n >\n <img\n ref={imageRef}\n src={src}\n alt={alt}\n draggable={false}\n className=\"ds-cropper__image\"\n onLoad={(event) => adopt(event.currentTarget)}\n style={{\n inlineSize: natural.width * scale || undefined,\n blockSize: natural.height * scale || undefined,\n transform: `translate(calc(-50% + ${state.offsetX}px), calc(-50% + ${state.offsetY}px)) rotate(${state.rotation}deg)`,\n }}\n />\n {/* The window: everything outside it is veiled, not hidden. */}\n <div className=\"ds-cropper__frame\" ref={frameRef} aria-hidden=\"true\">\n <div className=\"ds-cropper__guides\" />\n </div>\n </div>\n\n <div className=\"ds-cropper__controls\">\n <label className=\"ds-cropper__zoom\">\n <span className=\"ds-cropper__zoom-label\">Zoom</span>\n <input\n type=\"range\"\n min={MIN_ZOOM}\n max={maxZoom}\n step={0.01}\n value={state.zoom}\n className=\"ds-cropper__slider\"\n onChange={(event) =>\n setState((prev) => clamp({ ...prev, zoom: Number(event.target.value) }))\n }\n />\n <span className=\"ds-cropper__value\">{state.zoom.toFixed(2)}×</span>\n </label>\n <ButtonGroup aria-label=\"Crop actions\">\n {rotatable && (\n <>\n <Button\n size=\"sm\"\n iconStart=\"rotate-ccw\"\n aria-label=\"Rotate left\"\n onClick={() => turn(-90)}\n />\n <Button\n size=\"sm\"\n iconStart=\"rotate-cw\"\n aria-label=\"Rotate right\"\n onClick={() => turn(90)}\n />\n </>\n )}\n <Button size=\"sm\" onClick={() => setState(REST)}>\n Reset\n </Button>\n </ButtonGroup>\n </div>\n\n <p className=\"ds-cropper__hint\">\n Drag the picture to reposition it. Nothing is written until you save —{\" \"}\n {maxOffsetX === 0 && maxOffsetY === 0\n ? \"at this zoom the whole picture is in frame.\"\n : \"the veiled edges are what gets trimmed.\"}\n </p>\n </div>\n );\n },\n);\n\nexport interface CropToBlobOptions {\n /** Width of the output in pixels; the height follows the crop's aspect. */\n outputWidth?: number;\n /** Quarter turns applied before cropping — pass `state.rotation`. */\n rotation?: number;\n type?: \"image/png\" | \"image/jpeg\" | \"image/webp\";\n quality?: number;\n}\n\n/**\n * Renders a `CropRect` to an image blob in the browser. Same-origin or\n * CORS-enabled sources only — a tainted canvas cannot be exported.\n */\nexport async function cropToBlob(\n src: string,\n crop: CropRect,\n { outputWidth, rotation = 0, type = \"image/png\", quality = 0.92 }: CropToBlobOptions = {},\n): Promise<Blob> {\n const image = new Image();\n image.crossOrigin = \"anonymous\";\n image.src = src;\n await image.decode();\n\n // The crop is expressed against the turned picture, so turn it first.\n const quarter = rotation % 180 !== 0;\n const turned = document.createElement(\"canvas\");\n turned.width = quarter ? image.naturalHeight : image.naturalWidth;\n turned.height = quarter ? image.naturalWidth : image.naturalHeight;\n const turnedContext = turned.getContext(\"2d\");\n if (!turnedContext) throw new Error(\"Canvas 2D context unavailable\");\n turnedContext.translate(turned.width / 2, turned.height / 2);\n turnedContext.rotate((rotation * Math.PI) / 180);\n turnedContext.drawImage(image, -image.naturalWidth / 2, -image.naturalHeight / 2);\n\n const width = outputWidth ?? crop.width;\n const height = Math.round((crop.height / crop.width) * width);\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext(\"2d\");\n if (!context) throw new Error(\"Canvas 2D context unavailable\");\n context.drawImage(turned, crop.x, crop.y, crop.width, crop.height, 0, 0, width, height);\n\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => (blob ? resolve(blob) : reject(new Error(\"Could not encode the crop\"))),\n type,\n quality,\n );\n });\n}\n"],"mappings":"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"}