@omerdlw/base-framework 1.0.6 → 2.0.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 (234) hide show
  1. package/dist/atoms/index.js +1 -103
  2. package/dist/atoms/index.js.map +1 -1
  3. package/dist/chunk-3BUP64Q6.js +105 -0
  4. package/dist/chunk-3BUP64Q6.js.map +1 -0
  5. package/dist/chunk-4GMQKD6F.js +353 -0
  6. package/dist/chunk-4GMQKD6F.js.map +1 -0
  7. package/dist/chunk-6SG7V77J.js +577 -0
  8. package/dist/chunk-6SG7V77J.js.map +1 -0
  9. package/dist/chunk-6ZJVLUBE.js +26 -0
  10. package/dist/chunk-6ZJVLUBE.js.map +1 -0
  11. package/dist/chunk-7HQMXTNP.js +419 -0
  12. package/dist/chunk-7HQMXTNP.js.map +1 -0
  13. package/dist/chunk-7TAVYJ3A.js +371 -0
  14. package/dist/chunk-7TAVYJ3A.js.map +1 -0
  15. package/dist/chunk-A5RE3F6O.js +9905 -0
  16. package/dist/chunk-A5RE3F6O.js.map +1 -0
  17. package/dist/chunk-AQ4BNXA2.js +349 -0
  18. package/dist/chunk-AQ4BNXA2.js.map +1 -0
  19. package/dist/chunk-CGHZSSFR.js +2166 -0
  20. package/dist/chunk-CGHZSSFR.js.map +1 -0
  21. package/dist/chunk-DGCQWQLZ.js +61 -0
  22. package/dist/chunk-DGCQWQLZ.js.map +1 -0
  23. package/dist/chunk-FIMPHODX.js +67 -0
  24. package/dist/chunk-FIMPHODX.js.map +1 -0
  25. package/dist/chunk-GF7TUX5I.js +1889 -0
  26. package/dist/chunk-GF7TUX5I.js.map +1 -0
  27. package/dist/chunk-JELG4JLT.js +454 -0
  28. package/dist/chunk-JELG4JLT.js.map +1 -0
  29. package/dist/chunk-K676GL7Z.js +51 -0
  30. package/dist/chunk-K676GL7Z.js.map +1 -0
  31. package/dist/chunk-QI3ALLIB.js +38 -0
  32. package/dist/chunk-QI3ALLIB.js.map +1 -0
  33. package/dist/chunk-QXR55VVS.js +1139 -0
  34. package/dist/chunk-QXR55VVS.js.map +1 -0
  35. package/dist/chunk-R2YGFJDJ.js +408 -0
  36. package/dist/chunk-R2YGFJDJ.js.map +1 -0
  37. package/dist/chunk-RFZQWLC5.js +27 -0
  38. package/dist/chunk-RFZQWLC5.js.map +1 -0
  39. package/dist/chunk-SKBITB5X.js +888 -0
  40. package/dist/chunk-SKBITB5X.js.map +1 -0
  41. package/dist/chunk-SYAVGTOX.js +521 -0
  42. package/dist/chunk-SYAVGTOX.js.map +1 -0
  43. package/dist/chunk-TV3WEF5G.js +784 -0
  44. package/dist/chunk-TV3WEF5G.js.map +1 -0
  45. package/dist/chunk-XASQT4CQ.js +280 -0
  46. package/dist/chunk-XASQT4CQ.js.map +1 -0
  47. package/dist/error/index.js +5 -682
  48. package/dist/error/index.js.map +1 -1
  49. package/dist/error/reporter.d.ts.map +1 -1
  50. package/dist/error/theme.d.ts +1 -1
  51. package/dist/error/theme.d.ts.map +1 -1
  52. package/dist/events.js +1 -7
  53. package/dist/events.js.map +1 -1
  54. package/dist/hooks/index.js +1 -358
  55. package/dist/hooks/index.js.map +1 -1
  56. package/dist/hooks/use-global-event.d.ts +1 -1
  57. package/dist/index.js +18 -20029
  58. package/dist/index.js.map +1 -1
  59. package/dist/kernel/index.js +2 -2035
  60. package/dist/kernel/index.js.map +1 -1
  61. package/dist/kernel/types.d.ts +1 -1
  62. package/dist/modules/ambient/analyze.d.ts +46 -0
  63. package/dist/modules/ambient/analyze.d.ts.map +1 -0
  64. package/dist/modules/ambient/constants.d.ts +1 -5
  65. package/dist/modules/ambient/constants.d.ts.map +1 -1
  66. package/dist/modules/ambient/context.d.ts.map +1 -1
  67. package/dist/modules/ambient/dom.d.ts +11 -12
  68. package/dist/modules/ambient/dom.d.ts.map +1 -1
  69. package/dist/modules/ambient/extractor.d.ts +10 -10
  70. package/dist/modules/ambient/extractor.d.ts.map +1 -1
  71. package/dist/modules/ambient/hooks.d.ts +1 -1
  72. package/dist/modules/ambient/hooks.d.ts.map +1 -1
  73. package/dist/modules/ambient/index.d.ts +6 -4
  74. package/dist/modules/ambient/index.d.ts.map +1 -1
  75. package/dist/modules/ambient/index.js +7 -762
  76. package/dist/modules/ambient/index.js.map +1 -1
  77. package/dist/modules/ambient/module.d.ts +1 -1
  78. package/dist/modules/ambient/module.d.ts.map +1 -1
  79. package/dist/modules/ambient/oklab.d.ts +36 -0
  80. package/dist/modules/ambient/oklab.d.ts.map +1 -0
  81. package/dist/modules/ambient/pipeline.d.ts +28 -0
  82. package/dist/modules/ambient/pipeline.d.ts.map +1 -0
  83. package/dist/modules/ambient/quantize.d.ts +22 -0
  84. package/dist/modules/ambient/quantize.d.ts.map +1 -0
  85. package/dist/modules/ambient/server/address.d.ts +8 -0
  86. package/dist/modules/ambient/server/address.d.ts.map +1 -0
  87. package/dist/modules/ambient/server/index.d.ts +53 -0
  88. package/dist/modules/ambient/server/index.d.ts.map +1 -0
  89. package/dist/modules/ambient/server/index.js +221 -0
  90. package/dist/modules/ambient/server/index.js.map +1 -0
  91. package/dist/modules/ambient/settings.d.ts +19 -0
  92. package/dist/modules/ambient/settings.d.ts.map +1 -0
  93. package/dist/modules/ambient/types.d.ts +105 -9
  94. package/dist/modules/ambient/types.d.ts.map +1 -1
  95. package/dist/modules/ambient/worker/index.d.ts +15 -0
  96. package/dist/modules/ambient/worker/index.d.ts.map +1 -0
  97. package/dist/modules/ambient/worker/index.js +114 -0
  98. package/dist/modules/ambient/worker/index.js.map +1 -0
  99. package/dist/modules/background/constants.d.ts +2 -2
  100. package/dist/modules/background/constants.d.ts.map +1 -1
  101. package/dist/modules/background/hooks.d.ts +1 -1
  102. package/dist/modules/background/index.js +6 -3078
  103. package/dist/modules/background/index.js.map +1 -1
  104. package/dist/modules/background/motion.d.ts +9 -7
  105. package/dist/modules/background/motion.d.ts.map +1 -1
  106. package/dist/modules/background/overlay.d.ts +3 -8
  107. package/dist/modules/background/overlay.d.ts.map +1 -1
  108. package/dist/modules/background/types.d.ts +16 -2
  109. package/dist/modules/background/types.d.ts.map +1 -1
  110. package/dist/modules/context-menu/constants.d.ts +2 -2
  111. package/dist/modules/context-menu/constants.d.ts.map +1 -1
  112. package/dist/modules/context-menu/hooks.d.ts +1 -1
  113. package/dist/modules/context-menu/index.js +10 -1896
  114. package/dist/modules/context-menu/index.js.map +1 -1
  115. package/dist/modules/context-menu/motion.d.ts +1 -8
  116. package/dist/modules/context-menu/motion.d.ts.map +1 -1
  117. package/dist/modules/context-menu/overlay.d.ts.map +1 -1
  118. package/dist/modules/context-menu/types.d.ts +16 -2
  119. package/dist/modules/context-menu/types.d.ts.map +1 -1
  120. package/dist/modules/controls/constants.d.ts +1 -1
  121. package/dist/modules/controls/constants.d.ts.map +1 -1
  122. package/dist/modules/controls/entries.d.ts +1 -1
  123. package/dist/modules/controls/hooks.d.ts +1 -1
  124. package/dist/modules/controls/index.js +4 -1110
  125. package/dist/modules/controls/index.js.map +1 -1
  126. package/dist/modules/controls/overlay.d.ts +1 -1
  127. package/dist/modules/controls/types.d.ts +2 -2
  128. package/dist/modules/dock/cards.d.ts +711 -24
  129. package/dist/modules/dock/cards.d.ts.map +1 -1
  130. package/dist/modules/dock/constants.d.ts +2 -2
  131. package/dist/modules/dock/constants.d.ts.map +1 -1
  132. package/dist/modules/dock/helpers.d.ts +2 -2
  133. package/dist/modules/dock/hooks.d.ts +2 -2
  134. package/dist/modules/dock/index.d.ts +1 -1
  135. package/dist/modules/dock/index.d.ts.map +1 -1
  136. package/dist/modules/dock/index.js +9 -12132
  137. package/dist/modules/dock/index.js.map +1 -1
  138. package/dist/modules/dock/layout.d.ts.map +1 -1
  139. package/dist/modules/dock/module.d.ts +1 -1
  140. package/dist/modules/dock/motion.d.ts +44 -912
  141. package/dist/modules/dock/motion.d.ts.map +1 -1
  142. package/dist/modules/dock/overlay.d.ts +1 -1
  143. package/dist/modules/dock/overlay.d.ts.map +1 -1
  144. package/dist/modules/dock/runtime/dock.d.ts +1 -23
  145. package/dist/modules/dock/runtime/dock.d.ts.map +1 -1
  146. package/dist/modules/dock/styles.d.ts +4 -4
  147. package/dist/modules/dock/surface/hooks.d.ts +5 -20
  148. package/dist/modules/dock/surface/hooks.d.ts.map +1 -1
  149. package/dist/modules/dock/surface/machine.d.ts +4 -3
  150. package/dist/modules/dock/surface/machine.d.ts.map +1 -1
  151. package/dist/modules/dock/surface/stack.d.ts.map +1 -1
  152. package/dist/modules/dock/surface/view-model.d.ts.map +1 -1
  153. package/dist/modules/dock/types.d.ts +162 -3
  154. package/dist/modules/dock/types.d.ts.map +1 -1
  155. package/dist/modules/index.js +16 -17883
  156. package/dist/modules/index.js.map +1 -1
  157. package/dist/modules/loading/constants.d.ts +1 -1
  158. package/dist/modules/loading/constants.d.ts.map +1 -1
  159. package/dist/modules/loading/context.d.ts +1 -1
  160. package/dist/modules/loading/hooks.d.ts +1 -1
  161. package/dist/modules/loading/index.js +5 -1153
  162. package/dist/modules/loading/index.js.map +1 -1
  163. package/dist/modules/loading/types.d.ts +2 -2
  164. package/dist/modules/media/context.d.ts +1 -1
  165. package/dist/modules/media/index.js +3 -570
  166. package/dist/modules/media/index.js.map +1 -1
  167. package/dist/modules/media/types.d.ts +2 -2
  168. package/dist/modules/modal/constants.d.ts +2 -2
  169. package/dist/modules/modal/constants.d.ts.map +1 -1
  170. package/dist/modules/modal/context.d.ts +1 -1
  171. package/dist/modules/modal/hooks.d.ts +3 -3
  172. package/dist/modules/modal/index.js +8 -2355
  173. package/dist/modules/modal/index.js.map +1 -1
  174. package/dist/modules/modal/motion.d.ts +3 -8
  175. package/dist/modules/modal/motion.d.ts.map +1 -1
  176. package/dist/modules/modal/overlay.d.ts.map +1 -1
  177. package/dist/modules/modal/types.d.ts +21 -0
  178. package/dist/modules/modal/types.d.ts.map +1 -1
  179. package/dist/modules/notification/constants.d.ts +2 -2
  180. package/dist/modules/notification/constants.d.ts.map +1 -1
  181. package/dist/modules/notification/context.d.ts +1 -1
  182. package/dist/modules/notification/hooks.d.ts +1 -1
  183. package/dist/modules/notification/index.js +4 -828
  184. package/dist/modules/notification/index.js.map +1 -1
  185. package/dist/modules/notification/motion.d.ts +1 -7
  186. package/dist/modules/notification/motion.d.ts.map +1 -1
  187. package/dist/modules/notification/overlay.d.ts.map +1 -1
  188. package/dist/modules/notification/types.d.ts +9 -1
  189. package/dist/modules/notification/types.d.ts.map +1 -1
  190. package/dist/overlay-TZ6L52A5.js +9 -0
  191. package/dist/overlay-TZ6L52A5.js.map +1 -0
  192. package/dist/provider.d.ts +1 -1
  193. package/dist/provider.d.ts.map +1 -1
  194. package/dist/provider.js +6 -1968
  195. package/dist/provider.js.map +1 -1
  196. package/dist/result.js +2 -63
  197. package/dist/result.js.map +1 -1
  198. package/dist/theme.d.ts +45 -8
  199. package/dist/theme.d.ts.map +1 -1
  200. package/dist/theme.js +3 -41
  201. package/dist/theme.js.map +1 -1
  202. package/dist/tokens/index.d.ts +1 -0
  203. package/dist/tokens/index.d.ts.map +1 -1
  204. package/dist/tokens/index.js +126 -155
  205. package/dist/tokens/index.js.map +1 -1
  206. package/dist/tokens/motion-config.d.ts +44 -0
  207. package/dist/tokens/motion-config.d.ts.map +1 -0
  208. package/dist/tokens/motion.d.ts +23 -174
  209. package/dist/tokens/motion.d.ts.map +1 -1
  210. package/dist/utils/index.js +4 -82
  211. package/dist/utils/index.js.map +1 -1
  212. package/dist/utils/report.d.ts.map +1 -1
  213. package/docs/README.md +1 -0
  214. package/docs/architecture-and-rules.md +4 -3
  215. package/docs/core-engine.md +7 -10
  216. package/docs/getting-started.md +4 -2
  217. package/docs/modules/ambient.md +194 -80
  218. package/docs/modules/background.md +3 -3
  219. package/docs/modules/context-menu.md +2 -2
  220. package/docs/modules/dock.md +9 -6
  221. package/docs/modules/modal.md +2 -2
  222. package/docs/modules/notification.md +2 -2
  223. package/docs/theming.md +81 -9
  224. package/package.json +22 -5
  225. package/templates/AGENTS.md +1 -1
  226. package/templates/motion/background.ts +17 -0
  227. package/templates/motion/context-menu.ts +63 -0
  228. package/templates/motion/dock.ts +327 -0
  229. package/templates/motion/modal.ts +79 -0
  230. package/templates/motion/notification.ts +27 -0
  231. package/templates/motion/tokens.ts +47 -0
  232. package/templates/tsconfig.json +7 -0
  233. package/dist/modules/ambient/color.d.ts +0 -21
  234. package/dist/modules/ambient/color.d.ts.map +0 -1
@@ -1,106 +1,4 @@
1
1
  "use client";
2
- import { Icon as Icon$1 } from '@iconify-icon/react';
3
- import { jsx, jsxs } from 'react/jsx-runtime';
4
- import * as TooltipPrimitive from '@radix-ui/react-tooltip';
5
-
6
- function Icon({
7
- className = "center",
8
- color,
9
- icon,
10
- onClick,
11
- size = 20,
12
- style,
13
- ...props
14
- }) {
15
- return /* @__PURE__ */ jsx(
16
- Icon$1,
17
- {
18
- className,
19
- height: size,
20
- icon,
21
- onClick,
22
- style: { color, ...style },
23
- width: size,
24
- ...props
25
- }
26
- );
27
- }
28
- Icon.displayName = "Icon";
29
- function Spinner({ className = "", size = 15 }) {
30
- return /* @__PURE__ */ jsx(
31
- "div",
32
- {
33
- className,
34
- "aria-label": "Loading",
35
- role: "status",
36
- children: /* @__PURE__ */ jsx(Icon, { icon: "mingcute:loading-3-fill", size })
37
- }
38
- );
39
- }
40
- Spinner.displayName = "Spinner";
41
- function Tooltip({
42
- children,
43
- className,
44
- collisionPadding = 8,
45
- defaultOpen,
46
- delayMs,
47
- onOpenChange,
48
- open,
49
- position = "top",
50
- sideOffset = 6,
51
- text,
52
- ...props
53
- }) {
54
- return /* @__PURE__ */ jsxs(
55
- TooltipPrimitive.Root,
56
- {
57
- defaultOpen,
58
- delayDuration: delayMs,
59
- onOpenChange,
60
- open,
61
- children: [
62
- /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { asChild: true, children }),
63
- /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
64
- TooltipPrimitive.Content,
65
- {
66
- side: position,
67
- align: "center",
68
- sideOffset,
69
- collisionPadding,
70
- className,
71
- ...props,
72
- children: text
73
- }
74
- ) })
75
- ]
76
- }
77
- );
78
- }
79
- Tooltip.displayName = "Tooltip";
80
- function Button({
81
- ref,
82
- children,
83
- className,
84
- disabled = false,
85
- loading = false,
86
- type = "button",
87
- ...props
88
- }) {
89
- return /* @__PURE__ */ jsx(
90
- "button",
91
- {
92
- ref,
93
- type,
94
- disabled: disabled || loading,
95
- "aria-busy": loading ? true : void 0,
96
- className,
97
- ...props,
98
- children
99
- }
100
- );
101
- }
102
- Button.displayName = "Button";
103
-
104
- export { Button, Icon, Spinner, Tooltip };
2
+ export { Button, Icon, Spinner, Tooltip } from '../chunk-3BUP64Q6.js';
105
3
  //# sourceMappingURL=index.js.map
106
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/atoms/icon.tsx","../../src/atoms/spinner.tsx","../../src/atoms/tooltip.tsx","../../src/atoms/button.tsx"],"names":["IconifyIcon","jsx"],"mappings":";;;;AAeO,SAAS,IAAA,CAAK;AAAA,EACnB,SAAA,GAAY,QAAA;AAAA,EACZ,KAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA,GAAO,EAAA;AAAA,EACP,KAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAc;AACZ,EAAA,uBACE,GAAA;AAAA,IAACA,MAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,MAAA,EAAQ,IAAA;AAAA,MACR,IAAA;AAAA,MACA,OAAA;AAAA,MACA,KAAA,EAAO,EAAE,KAAA,EAAO,GAAG,KAAA,EAAM;AAAA,MACzB,KAAA,EAAO,IAAA;AAAA,MACN,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,IAAA,CAAK,WAAA,GAAc,MAAA;AC5BZ,SAAS,QAAQ,EAAE,SAAA,GAAY,EAAA,EAAI,IAAA,GAAO,IAAG,EAAiB;AACnE,EAAA,uBACEC,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,YAAA,EAAW,SAAA;AAAA,MACX,IAAA,EAAK,QAAA;AAAA,MAEL,QAAA,kBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAK,2BAA0B,IAAA,EAAY;AAAA;AAAA,GACnD;AAEJ;AAEA,OAAA,CAAQ,WAAA,GAAc,SAAA;ACHf,SAAS,OAAA,CAAQ;AAAA,EACtB,QAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA,GAAmB,CAAA;AAAA,EACnB,WAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,UAAA,GAAa,CAAA;AAAA,EACb,IAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiB;AACf,EAAA,uBACE,IAAA;AAAA,IAAkB,gBAAA,CAAA,IAAA;AAAA,IAAjB;AAAA,MACC,WAAA;AAAA,MACA,aAAA,EAAe,OAAA;AAAA,MACf,YAAA;AAAA,MACA,IAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAkB,gBAAA,CAAA,OAAA,EAAjB,EAAyB,OAAA,EAAO,MAC9B,QAAA,EACH,CAAA;AAAA,wBAEAA,GAAAA,CAAkB,gBAAA,CAAA,MAAA,EAAjB,EACC,QAAA,kBAAAA,GAAAA;AAAA,UAAkB,gBAAA,CAAA,OAAA;AAAA,UAAjB;AAAA,YACC,IAAA,EAAM,QAAA;AAAA,YACN,KAAA,EAAM,QAAA;AAAA,YACN,UAAA;AAAA,YACA,gBAAA;AAAA,YACA,SAAA;AAAA,YACC,GAAG,KAAA;AAAA,YAEH,QAAA,EAAA;AAAA;AAAA,SACH,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,OAAA,CAAQ,WAAA,GAAc,SAAA;AChDf,SAAS,MAAA,CAAO;AAAA,EACrB,GAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,OAAA,GAAU,KAAA;AAAA,EACV,IAAA,GAAO,QAAA;AAAA,EACP,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,uBACEA,GAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAU,QAAA,IAAY,OAAA;AAAA,MACtB,WAAA,EAAW,UAAU,IAAA,GAAO,MAAA;AAAA,MAC5B,SAAA;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"index.js","sourcesContent":["\"use client\";\n\nimport { Icon as IconifyIcon } from \"@iconify-icon/react\";\nimport type { ComponentProps, CSSProperties } from \"react\";\n\nexport interface IconProps\n extends Omit<ComponentProps<typeof IconifyIcon>, \"icon\" | \"size\"> {\n icon: string | ComponentProps<typeof IconifyIcon>[\"icon\"];\n size?: number | string;\n color?: string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nexport function Icon({\n className = \"center\",\n color,\n icon,\n onClick,\n size = 20,\n style,\n ...props\n}: IconProps) {\n return (\n <IconifyIcon\n className={className}\n height={size}\n icon={icon}\n onClick={onClick}\n style={{ color, ...style }}\n width={size}\n {...props}\n />\n );\n}\n\nIcon.displayName = \"Icon\";\n","\"use client\";\n\nimport { Icon } from \"./icon\";\n\nexport interface SpinnerProps {\n className?: string;\n size?: number;\n}\n\nexport function Spinner({ className = \"\", size = 15 }: SpinnerProps) {\n return (\n <div\n className={className}\n aria-label=\"Loading\"\n role=\"status\"\n >\n <Icon icon=\"mingcute:loading-3-fill\" size={size} />\n </div>\n );\n}\n\nSpinner.displayName = \"Spinner\";\n","\"use client\";\n\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport type { ReactNode } from \"react\";\n\nexport interface TooltipProps {\n children: ReactNode;\n text: ReactNode;\n className?: string;\n open?: boolean;\n defaultOpen?: boolean;\n delayMs?: number;\n position?: \"top\" | \"bottom\" | \"left\" | \"right\";\n sideOffset?: number;\n collisionPadding?: number;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport function Tooltip({\n children,\n className,\n collisionPadding = 8,\n defaultOpen,\n delayMs,\n onOpenChange,\n open,\n position = \"top\",\n sideOffset = 6,\n text,\n ...props\n}: TooltipProps) {\n return (\n <TooltipPrimitive.Root\n defaultOpen={defaultOpen}\n delayDuration={delayMs}\n onOpenChange={onOpenChange}\n open={open}\n >\n <TooltipPrimitive.Trigger asChild>\n {children}\n </TooltipPrimitive.Trigger>\n\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n side={position}\n align=\"center\"\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n className={className}\n {...props}\n >\n {text}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n </TooltipPrimitive.Root>\n );\n}\n\nTooltip.displayName = \"Tooltip\";\n","\"use client\";\n\nimport type { ButtonHTMLAttributes, ReactNode, Ref } from \"react\";\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n ref?: Ref<HTMLButtonElement>;\n children?: ReactNode;\n loading?: boolean;\n}\n\nexport function Button({\n ref,\n children,\n className,\n disabled = false,\n loading = false,\n type = \"button\",\n ...props\n}: ButtonProps) {\n return (\n <button\n ref={ref}\n type={type}\n disabled={disabled || loading}\n aria-busy={loading ? true : undefined}\n className={className}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nButton.displayName = \"Button\";\n"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,105 @@
1
+ import { Icon as Icon$1 } from '@iconify-icon/react';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
4
+
5
+ function Icon({
6
+ className = "center",
7
+ color,
8
+ icon,
9
+ onClick,
10
+ size = 20,
11
+ style,
12
+ ...props
13
+ }) {
14
+ return /* @__PURE__ */ jsx(
15
+ Icon$1,
16
+ {
17
+ className,
18
+ height: size,
19
+ icon,
20
+ onClick,
21
+ style: { color, ...style },
22
+ width: size,
23
+ ...props
24
+ }
25
+ );
26
+ }
27
+ Icon.displayName = "Icon";
28
+ function Spinner({ className = "", size = 15 }) {
29
+ return /* @__PURE__ */ jsx(
30
+ "div",
31
+ {
32
+ className,
33
+ "aria-label": "Loading",
34
+ role: "status",
35
+ children: /* @__PURE__ */ jsx(Icon, { icon: "mingcute:loading-3-fill", size })
36
+ }
37
+ );
38
+ }
39
+ Spinner.displayName = "Spinner";
40
+ function Tooltip({
41
+ children,
42
+ className,
43
+ collisionPadding = 8,
44
+ defaultOpen,
45
+ delayMs,
46
+ onOpenChange,
47
+ open,
48
+ position = "top",
49
+ sideOffset = 6,
50
+ text,
51
+ ...props
52
+ }) {
53
+ return /* @__PURE__ */ jsxs(
54
+ TooltipPrimitive.Root,
55
+ {
56
+ defaultOpen,
57
+ delayDuration: delayMs,
58
+ onOpenChange,
59
+ open,
60
+ children: [
61
+ /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { asChild: true, children }),
62
+ /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
63
+ TooltipPrimitive.Content,
64
+ {
65
+ side: position,
66
+ align: "center",
67
+ sideOffset,
68
+ collisionPadding,
69
+ className,
70
+ ...props,
71
+ children: text
72
+ }
73
+ ) })
74
+ ]
75
+ }
76
+ );
77
+ }
78
+ Tooltip.displayName = "Tooltip";
79
+ function Button({
80
+ ref,
81
+ children,
82
+ className,
83
+ disabled = false,
84
+ loading = false,
85
+ type = "button",
86
+ ...props
87
+ }) {
88
+ return /* @__PURE__ */ jsx(
89
+ "button",
90
+ {
91
+ ref,
92
+ type,
93
+ disabled: disabled || loading,
94
+ "aria-busy": loading ? true : void 0,
95
+ className,
96
+ ...props,
97
+ children
98
+ }
99
+ );
100
+ }
101
+ Button.displayName = "Button";
102
+
103
+ export { Button, Icon, Spinner, Tooltip };
104
+ //# sourceMappingURL=chunk-3BUP64Q6.js.map
105
+ //# sourceMappingURL=chunk-3BUP64Q6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/atoms/icon.tsx","../src/atoms/spinner.tsx","../src/atoms/tooltip.tsx","../src/atoms/button.tsx"],"names":["IconifyIcon","jsx"],"mappings":";;;;AAeO,SAAS,IAAA,CAAK;AAAA,EACnB,SAAA,GAAY,QAAA;AAAA,EACZ,KAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA,GAAO,EAAA;AAAA,EACP,KAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAc;AACZ,EAAA,uBACE,GAAA;AAAA,IAACA,MAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,MAAA,EAAQ,IAAA;AAAA,MACR,IAAA;AAAA,MACA,OAAA;AAAA,MACA,KAAA,EAAO,EAAE,KAAA,EAAO,GAAG,KAAA,EAAM;AAAA,MACzB,KAAA,EAAO,IAAA;AAAA,MACN,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,IAAA,CAAK,WAAA,GAAc,MAAA;AC5BZ,SAAS,QAAQ,EAAE,SAAA,GAAY,EAAA,EAAI,IAAA,GAAO,IAAG,EAAiB;AACnE,EAAA,uBACEC,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,YAAA,EAAW,SAAA;AAAA,MACX,IAAA,EAAK,QAAA;AAAA,MAEL,QAAA,kBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAK,2BAA0B,IAAA,EAAY;AAAA;AAAA,GACnD;AAEJ;AAEA,OAAA,CAAQ,WAAA,GAAc,SAAA;ACHf,SAAS,OAAA,CAAQ;AAAA,EACtB,QAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA,GAAmB,CAAA;AAAA,EACnB,WAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,UAAA,GAAa,CAAA;AAAA,EACb,IAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiB;AACf,EAAA,uBACE,IAAA;AAAA,IAAkB,gBAAA,CAAA,IAAA;AAAA,IAAjB;AAAA,MACC,WAAA;AAAA,MACA,aAAA,EAAe,OAAA;AAAA,MACf,YAAA;AAAA,MACA,IAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAkB,gBAAA,CAAA,OAAA,EAAjB,EAAyB,OAAA,EAAO,MAC9B,QAAA,EACH,CAAA;AAAA,wBAEAA,GAAAA,CAAkB,gBAAA,CAAA,MAAA,EAAjB,EACC,QAAA,kBAAAA,GAAAA;AAAA,UAAkB,gBAAA,CAAA,OAAA;AAAA,UAAjB;AAAA,YACC,IAAA,EAAM,QAAA;AAAA,YACN,KAAA,EAAM,QAAA;AAAA,YACN,UAAA;AAAA,YACA,gBAAA;AAAA,YACA,SAAA;AAAA,YACC,GAAG,KAAA;AAAA,YAEH,QAAA,EAAA;AAAA;AAAA,SACH,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,OAAA,CAAQ,WAAA,GAAc,SAAA;AChDf,SAAS,MAAA,CAAO;AAAA,EACrB,GAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,OAAA,GAAU,KAAA;AAAA,EACV,IAAA,GAAO,QAAA;AAAA,EACP,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,uBACEA,GAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,IAAA;AAAA,MACA,UAAU,QAAA,IAAY,OAAA;AAAA,MACtB,WAAA,EAAW,UAAU,IAAA,GAAO,MAAA;AAAA,MAC5B,SAAA;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-3BUP64Q6.js","sourcesContent":["\"use client\";\n\nimport { Icon as IconifyIcon } from \"@iconify-icon/react\";\nimport type { ComponentProps, CSSProperties } from \"react\";\n\nexport interface IconProps\n extends Omit<ComponentProps<typeof IconifyIcon>, \"icon\" | \"size\"> {\n icon: string | ComponentProps<typeof IconifyIcon>[\"icon\"];\n size?: number | string;\n color?: string;\n className?: string;\n style?: CSSProperties;\n onClick?: () => void;\n}\n\nexport function Icon({\n className = \"center\",\n color,\n icon,\n onClick,\n size = 20,\n style,\n ...props\n}: IconProps) {\n return (\n <IconifyIcon\n className={className}\n height={size}\n icon={icon}\n onClick={onClick}\n style={{ color, ...style }}\n width={size}\n {...props}\n />\n );\n}\n\nIcon.displayName = \"Icon\";\n","\"use client\";\n\nimport { Icon } from \"./icon\";\n\nexport interface SpinnerProps {\n className?: string;\n size?: number;\n}\n\nexport function Spinner({ className = \"\", size = 15 }: SpinnerProps) {\n return (\n <div\n className={className}\n aria-label=\"Loading\"\n role=\"status\"\n >\n <Icon icon=\"mingcute:loading-3-fill\" size={size} />\n </div>\n );\n}\n\nSpinner.displayName = \"Spinner\";\n","\"use client\";\n\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport type { ReactNode } from \"react\";\n\nexport interface TooltipProps {\n children: ReactNode;\n text: ReactNode;\n className?: string;\n open?: boolean;\n defaultOpen?: boolean;\n delayMs?: number;\n position?: \"top\" | \"bottom\" | \"left\" | \"right\";\n sideOffset?: number;\n collisionPadding?: number;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport function Tooltip({\n children,\n className,\n collisionPadding = 8,\n defaultOpen,\n delayMs,\n onOpenChange,\n open,\n position = \"top\",\n sideOffset = 6,\n text,\n ...props\n}: TooltipProps) {\n return (\n <TooltipPrimitive.Root\n defaultOpen={defaultOpen}\n delayDuration={delayMs}\n onOpenChange={onOpenChange}\n open={open}\n >\n <TooltipPrimitive.Trigger asChild>\n {children}\n </TooltipPrimitive.Trigger>\n\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n side={position}\n align=\"center\"\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n className={className}\n {...props}\n >\n {text}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n </TooltipPrimitive.Root>\n );\n}\n\nTooltip.displayName = \"Tooltip\";\n","\"use client\";\n\nimport type { ButtonHTMLAttributes, ReactNode, Ref } from \"react\";\n\nexport interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n ref?: Ref<HTMLButtonElement>;\n children?: ReactNode;\n loading?: boolean;\n}\n\nexport function Button({\n ref,\n children,\n className,\n disabled = false,\n loading = false,\n type = \"button\",\n ...props\n}: ButtonProps) {\n return (\n <button\n ref={ref}\n type={type}\n disabled={disabled || loading}\n aria-busy={loading ? true : undefined}\n className={className}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nButton.displayName = \"Button\";\n"]}
@@ -0,0 +1,353 @@
1
+ import { defineThemeSpec, useTheme } from './chunk-7TAVYJ3A.js';
2
+ import { defineModule, useRegistryEntries, useModuleRegistration } from './chunk-GF7TUX5I.js';
3
+ import { isPlainObject, trimToNull, toFiniteNumber, clamp } from './chunk-TV3WEF5G.js';
4
+ import { useMemo, isValidElement, useSyncExternalStore, Fragment as Fragment$1, useState, useEffect, createElement } from 'react';
5
+ import { usePathname } from 'next/navigation';
6
+ import { createPortal } from 'react-dom';
7
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
8
+
9
+ // src/modules/controls/constants.ts
10
+ var CONTROLS_EDGE_INSET = 4;
11
+ var CONTROLS_DOCK_GAP = 8;
12
+ var CONTROLS_DOCK_ELEMENT_ID = "dock-card-stack";
13
+ var CONTROL_SIDE_NAMES = Object.freeze(["left", "right"]);
14
+ var controlsTheme = defineThemeSpec("controls");
15
+ function isControlSide(value) {
16
+ return CONTROL_SIDE_NAMES.includes(value);
17
+ }
18
+ function hasContent(content) {
19
+ return content !== void 0 && content !== null && content !== false;
20
+ }
21
+ function isRenderable(value) {
22
+ if (value === null || value === void 0 || ["boolean", "number", "string"].includes(typeof value) || isValidElement(value)) {
23
+ return true;
24
+ }
25
+ return Array.isArray(value) && value.every(isRenderable);
26
+ }
27
+ function validateControlEntry(entry) {
28
+ if (!isPlainObject(entry)) {
29
+ return { issues: ["control must be a plain object"], valid: false };
30
+ }
31
+ const issues = [];
32
+ if (!trimToNull(entry.id)) {
33
+ issues.push("control id must be a non-empty string");
34
+ }
35
+ if (!isControlSide(entry.side)) {
36
+ issues.push("control side must be left or right");
37
+ }
38
+ if (!hasContent(entry.content) || !isRenderable(entry.content)) {
39
+ issues.push("control content must be renderable");
40
+ }
41
+ if (!Number.isFinite(Number(entry.order))) {
42
+ issues.push("control order must be a finite number");
43
+ }
44
+ return { issues, valid: issues.length === 0 };
45
+ }
46
+ function resolveSlot(slot, props) {
47
+ if (slot == null || slot === false) return null;
48
+ if (isValidElement(slot)) return slot;
49
+ if (typeof slot === "function") return createElement(slot, props);
50
+ return slot;
51
+ }
52
+ function normalizePageControls(controls) {
53
+ if (!controls) return null;
54
+ if (Array.isArray(controls)) return controls;
55
+ if ("side" in controls) return [controls];
56
+ const { id = "controls", order = 0, path, registry } = controls;
57
+ return CONTROL_SIDE_NAMES.flatMap((side) => {
58
+ const content = controls[side];
59
+ if (!hasContent(content)) return [];
60
+ return [
61
+ {
62
+ ...registry ? { registry } : {},
63
+ content,
64
+ id: `${id}-${side}`,
65
+ order,
66
+ ...path ? { path } : {},
67
+ side
68
+ }
69
+ ];
70
+ });
71
+ }
72
+ function resolveControlsPairs(entries, pathname) {
73
+ const rows = /* @__PURE__ */ new Map();
74
+ for (const entry of Array.isArray(entries) ? entries : Object.values(entries || {})) {
75
+ if (entry?.path !== pathname || !isControlSide(entry.side) || !hasContent(entry.content)) {
76
+ continue;
77
+ }
78
+ const order = toFiniteNumber(entry.order);
79
+ const row = rows.get(order) ?? {};
80
+ rows.set(order, row);
81
+ const current = row[entry.side];
82
+ if (!current || String(entry.id).localeCompare(String(current.id)) < 0) {
83
+ row[entry.side] = { content: entry.content, id: entry.id };
84
+ }
85
+ }
86
+ const pairs = [...rows].sort(([a], [b]) => a - b).map(([, row]) => row).filter(
87
+ (row) => Boolean(row.left && row.right)
88
+ );
89
+ return {
90
+ left: pairs.map((row) => row.left),
91
+ right: pairs.map((row) => row.right)
92
+ };
93
+ }
94
+
95
+ // src/modules/controls/layout.ts
96
+ function getControlsLayout(dockRect, viewport) {
97
+ const { height, width } = viewport;
98
+ if (!dockRect || width <= 0 || height <= 0) return null;
99
+ const inset = CONTROLS_EDGE_INSET;
100
+ const gap = CONTROLS_DOCK_GAP;
101
+ const dockLeft = clamp(dockRect.left, 0, width);
102
+ const dockRight = clamp(dockRect.right, dockLeft, width);
103
+ const dockBottom = clamp(dockRect.bottom, 0, height);
104
+ return {
105
+ bottom: Math.max(0, height - dockBottom),
106
+ height: Math.max(0, dockRect.height) / 2,
107
+ left: {
108
+ maxWidth: Math.max(0, dockLeft - inset * 2 - gap),
109
+ right: Math.max(inset, width - dockLeft + gap)
110
+ },
111
+ right: {
112
+ left: Math.min(width - inset, dockRight + gap),
113
+ maxWidth: Math.max(0, width - dockRight - inset * 2 - gap)
114
+ }
115
+ };
116
+ }
117
+ function areLayoutsEqual(a, b) {
118
+ if (a === b) return true;
119
+ if (!a || !b) return false;
120
+ return a.bottom === b.bottom && a.height === b.height && a.isHidden === b.isHidden && a.left.maxWidth === b.left.maxWidth && a.left.right === b.left.right && a.right.left === b.right.left && a.right.maxWidth === b.right.maxWidth;
121
+ }
122
+ function getDockStackElement() {
123
+ return document.getElementById(CONTROLS_DOCK_ELEMENT_ID);
124
+ }
125
+ function getDockElement() {
126
+ return document.querySelector('[data-controls-anchor="true"]') ?? getDockStackElement();
127
+ }
128
+ function measureLayout() {
129
+ const dockElement = getDockElement();
130
+ if (!dockElement) return null;
131
+ const layout = getControlsLayout(dockElement.getBoundingClientRect(), {
132
+ height: window.innerHeight,
133
+ width: window.innerWidth
134
+ });
135
+ return layout && {
136
+ ...layout,
137
+ isHidden: getDockStackElement()?.dataset.controlsHidden === "true"
138
+ };
139
+ }
140
+ function useControlsLayout() {
141
+ const [layout, setLayout] = useState(null);
142
+ useEffect(() => {
143
+ let observed;
144
+ let resizeObserver;
145
+ const update = () => {
146
+ const next = measureLayout();
147
+ setLayout((prev) => areLayoutsEqual(prev, next) ? prev : next);
148
+ };
149
+ const observe = () => {
150
+ const dockElement = getDockElement();
151
+ if (dockElement !== observed) {
152
+ observed = dockElement;
153
+ resizeObserver?.disconnect();
154
+ mutationObserver.disconnect();
155
+ if (dockElement) {
156
+ if (typeof ResizeObserver !== "undefined") {
157
+ resizeObserver = new ResizeObserver(update);
158
+ resizeObserver.observe(dockElement);
159
+ }
160
+ mutationObserver.observe(dockElement, {
161
+ attributes: true,
162
+ attributeFilter: ["data-controls-anchor", "data-controls-hidden"]
163
+ });
164
+ if (dockElement.parentElement) {
165
+ mutationObserver.observe(dockElement.parentElement, {
166
+ childList: true
167
+ });
168
+ }
169
+ } else {
170
+ mutationObserver.observe(document.body, {
171
+ childList: true,
172
+ subtree: true
173
+ });
174
+ }
175
+ }
176
+ update();
177
+ };
178
+ const mutationObserver = new MutationObserver(observe);
179
+ observe();
180
+ window.addEventListener("resize", update);
181
+ return () => {
182
+ mutationObserver.disconnect();
183
+ resizeObserver?.disconnect();
184
+ window.removeEventListener("resize", update);
185
+ };
186
+ }, []);
187
+ return layout;
188
+ }
189
+ function useControlsRegistration(config, options) {
190
+ useModuleRegistration("controls", config, options);
191
+ }
192
+ function useControls(config, options) {
193
+ const pathname = usePathname();
194
+ const definitionPath = config && "path" in config ? config.path : void 0;
195
+ const path = options?.path || definitionPath || pathname;
196
+ const entries = useMemo(() => {
197
+ if (!config) return null;
198
+ if (Array.isArray(config) || "side" in config) return config;
199
+ const { defaultProps = {}, left, right, ...page } = config;
200
+ const resolved = normalizePageControls({
201
+ ...page,
202
+ left: resolveSlot(left, defaultProps),
203
+ path,
204
+ right: resolveSlot(right, defaultProps)
205
+ });
206
+ return resolved?.length ? resolved : null;
207
+ }, [config, path]);
208
+ useControlsRegistration(entries, options);
209
+ return useControlsLayout();
210
+ }
211
+ var emptySubscribe = () => () => {
212
+ };
213
+ function useControlsModel() {
214
+ const portalTarget = useSyncExternalStore(
215
+ emptySubscribe,
216
+ () => typeof document !== "undefined" ? document.body : null,
217
+ () => null
218
+ );
219
+ const layout = useControlsLayout();
220
+ const pathname = usePathname();
221
+ const entries = useRegistryEntries("controls");
222
+ const { left, right } = useMemo(
223
+ () => resolveControlsPairs(entries, pathname),
224
+ [entries, pathname]
225
+ );
226
+ const theme = useTheme(controlsTheme);
227
+ return { portalTarget, layout, left, right, theme };
228
+ }
229
+ function ControlsSide({
230
+ controls,
231
+ geometry,
232
+ side,
233
+ theme
234
+ }) {
235
+ if (controls.length === 0 || !geometry.height || !geometry.maxWidth) {
236
+ return null;
237
+ }
238
+ const positionStyle = side === "left" ? {
239
+ bottom: geometry.bottom,
240
+ maxWidth: geometry.maxWidth,
241
+ right: geometry.right
242
+ } : {
243
+ bottom: geometry.bottom,
244
+ left: geometry.left,
245
+ maxWidth: geometry.maxWidth
246
+ };
247
+ return /* @__PURE__ */ jsx(
248
+ "aside",
249
+ {
250
+ "aria-label": `${side === "left" ? "Left" : "Right"} page controls`,
251
+ className: theme.slots.rail,
252
+ style: { ...theme.styles.rail, ...positionStyle },
253
+ children: /* @__PURE__ */ jsx(
254
+ "div",
255
+ {
256
+ "data-side": side,
257
+ className: theme.slots.stack,
258
+ style: {
259
+ ...theme.styles.stack,
260
+ "--controls-height": `${geometry.height}px`
261
+ },
262
+ children: controls.map(({ content, id }, index) => /* @__PURE__ */ jsx(Fragment$1, { children: content }, id || index))
263
+ }
264
+ )
265
+ }
266
+ );
267
+ }
268
+ function Controls() {
269
+ const { portalTarget, layout, left, right, theme } = useControlsModel();
270
+ if (!portalTarget || !layout || layout.isHidden || left.length === 0) {
271
+ return null;
272
+ }
273
+ return createPortal(
274
+ /* @__PURE__ */ jsxs(Fragment, { children: [
275
+ /* @__PURE__ */ jsx(
276
+ ControlsSide,
277
+ {
278
+ controls: left,
279
+ geometry: {
280
+ ...layout.left,
281
+ bottom: layout.bottom,
282
+ height: layout.height
283
+ },
284
+ side: "left",
285
+ theme
286
+ }
287
+ ),
288
+ /* @__PURE__ */ jsx(
289
+ ControlsSide,
290
+ {
291
+ controls: right,
292
+ geometry: {
293
+ ...layout.right,
294
+ bottom: layout.bottom,
295
+ height: layout.height
296
+ },
297
+ side: "right",
298
+ theme
299
+ }
300
+ )
301
+ ] }),
302
+ portalTarget
303
+ );
304
+ }
305
+ function selectPageControls(config) {
306
+ return normalizePageControls(config.controls);
307
+ }
308
+ function useControlsPage(_slice, page) {
309
+ return useMemo(
310
+ () => ({
311
+ set: (controls) => page.set({ controls })
312
+ }),
313
+ [page]
314
+ );
315
+ }
316
+ function defineControls(definition = {}) {
317
+ const { id = "controls", order = 0 } = definition;
318
+ return Object.freeze({
319
+ config: definition,
320
+ id,
321
+ order,
322
+ use: function useDefinedControls(props = {}, options = {}) {
323
+ return useControls(
324
+ {
325
+ ...definition,
326
+ defaultProps: { ...definition.defaultProps, ...props }
327
+ },
328
+ options
329
+ );
330
+ }
331
+ });
332
+ }
333
+ var controlsModule = defineModule({
334
+ id: "controls",
335
+ Overlay: Controls,
336
+ registry: {
337
+ keyPolicy: "named",
338
+ lifecycle: "immediate",
339
+ validate: validateControlEntry
340
+ },
341
+ page: {
342
+ select: selectPageControls,
343
+ entries: (entry, { pathname }) => {
344
+ const path = pathname || "/";
345
+ return [{ key: `${path}::${entry.id}`, value: { ...entry, path } }];
346
+ },
347
+ use: useControlsPage
348
+ }
349
+ });
350
+
351
+ export { CONTROLS_DOCK_ELEMENT_ID, CONTROLS_DOCK_GAP, CONTROLS_EDGE_INSET, CONTROL_SIDE_NAMES, Controls, ControlsSide, areLayoutsEqual, controlsModule, controlsTheme, defineControls, getControlsLayout, getDockElement, getDockStackElement, hasContent, isControlSide, measureLayout, normalizePageControls, resolveControlsPairs, resolveSlot, useControls, useControlsLayout, useControlsRegistration, validateControlEntry };
352
+ //# sourceMappingURL=chunk-4GMQKD6F.js.map
353
+ //# sourceMappingURL=chunk-4GMQKD6F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/modules/controls/constants.ts","../src/modules/controls/entries.ts","../src/modules/controls/layout.ts","../src/modules/controls/hooks.ts","../src/modules/controls/overlay.tsx","../src/modules/controls/module.tsx"],"names":["usePathname","useMemo","Fragment"],"mappings":"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","file":"chunk-4GMQKD6F.js","sourcesContent":["import { defineThemeSpec } from \"@/theme\";\nimport { type ControlsThemeSlot } from \"./types\";\n\nexport const CONTROLS_EDGE_INSET = 4;\nexport const CONTROLS_DOCK_GAP = 8;\nexport const CONTROLS_DOCK_ELEMENT_ID = \"dock-card-stack\";\nexport const CONTROL_SIDE_NAMES = Object.freeze([\"left\", \"right\"] as const);\n\nexport const controlsTheme = defineThemeSpec<ControlsThemeSlot>(\"controls\");\n","import { createElement, isValidElement, type ReactNode } from \"react\";\nimport { type ValidationResult } from \"@/kernel\";\nimport { isPlainObject, toFiniteNumber, trimToNull } from \"@/utils\";\nimport { CONTROL_SIDE_NAMES } from \"./constants\";\nimport {\n type ControlEntry,\n type ControlSide,\n type ControlSlot,\n type ControlsPageConfig,\n type ControlsPairItem,\n type PageControlEntry,\n type ResolvedControlsPairs,\n} from \"./types\";\n\nexport function isControlSide(value: unknown): value is ControlSide {\n return CONTROL_SIDE_NAMES.includes(value as ControlSide);\n}\n\nexport function hasContent(content: unknown): boolean {\n return content !== undefined && content !== null && content !== false;\n}\n\nfunction isRenderable(value: unknown): boolean {\n if (\n value === null ||\n value === undefined ||\n [\"boolean\", \"number\", \"string\"].includes(typeof value) ||\n isValidElement(value)\n ) {\n return true;\n }\n return Array.isArray(value) && value.every(isRenderable);\n}\n\nexport function validateControlEntry(entry: unknown): ValidationResult {\n if (!isPlainObject(entry)) {\n return { issues: [\"control must be a plain object\"], valid: false };\n }\n const issues: string[] = [];\n if (!trimToNull(entry.id)) {\n issues.push(\"control id must be a non-empty string\");\n }\n if (!isControlSide(entry.side)) {\n issues.push(\"control side must be left or right\");\n }\n if (!hasContent(entry.content) || !isRenderable(entry.content)) {\n issues.push(\"control content must be renderable\");\n }\n if (!Number.isFinite(Number(entry.order))) {\n issues.push(\"control order must be a finite number\");\n }\n return { issues, valid: issues.length === 0 };\n}\n\nexport function resolveSlot(\n slot: ControlSlot | undefined,\n props: Record<string, unknown>,\n): ReactNode {\n if (slot == null || slot === false) return null;\n if (isValidElement(slot)) return slot;\n if (typeof slot === \"function\") return createElement(slot, props);\n return slot;\n}\n\nexport function normalizePageControls(\n controls: ControlsPageConfig | null | undefined,\n): PageControlEntry[] | null {\n if (!controls) return null;\n if (Array.isArray(controls)) return controls;\n if (\"side\" in controls) return [controls];\n\n const { id = \"controls\", order = 0, path, registry } = controls;\n return CONTROL_SIDE_NAMES.flatMap((side) => {\n const content = controls[side];\n if (!hasContent(content)) return [];\n return [\n {\n ...(registry ? { registry } : {}),\n content,\n id: `${id}-${side}`,\n order,\n ...(path ? { path } : {}),\n side,\n },\n ];\n });\n}\n\nexport function resolveControlsPairs(\n entries: Record<string, ControlEntry> | ControlEntry[] | null | undefined,\n pathname: string,\n): ResolvedControlsPairs {\n const rows = new Map<\n number,\n { left?: ControlsPairItem; right?: ControlsPairItem }\n >();\n\n for (const entry of Array.isArray(entries)\n ? entries\n : Object.values(entries || {})) {\n if (\n entry?.path !== pathname ||\n !isControlSide(entry.side) ||\n !hasContent(entry.content)\n ) {\n continue;\n }\n const order = toFiniteNumber(entry.order);\n const row = rows.get(order) ?? {};\n rows.set(order, row);\n const current = row[entry.side];\n if (!current || String(entry.id).localeCompare(String(current.id)) < 0) {\n row[entry.side] = { content: entry.content, id: entry.id };\n }\n }\n\n const pairs = [...rows]\n .sort(([a], [b]) => a - b)\n .map(([, row]) => row)\n .filter((row): row is Required<typeof row> =>\n Boolean(row.left && row.right),\n );\n\n return {\n left: pairs.map((row) => row.left),\n right: pairs.map((row) => row.right),\n };\n}\n","import { clamp } from \"@/utils\";\nimport {\n CONTROLS_DOCK_ELEMENT_ID,\n CONTROLS_DOCK_GAP,\n CONTROLS_EDGE_INSET,\n} from \"./constants\";\nimport { type ControlsLayout, type ViewportDimensions } from \"./types\";\n\nexport function getControlsLayout(\n dockRect: Pick<DOMRect, \"bottom\" | \"height\" | \"left\" | \"right\"> | null,\n viewport: ViewportDimensions,\n): ControlsLayout | null {\n const { height, width } = viewport;\n if (!dockRect || width <= 0 || height <= 0) return null;\n\n const inset = CONTROLS_EDGE_INSET;\n const gap = CONTROLS_DOCK_GAP;\n const dockLeft = clamp(dockRect.left, 0, width);\n const dockRight = clamp(dockRect.right, dockLeft, width);\n const dockBottom = clamp(dockRect.bottom, 0, height);\n\n return {\n bottom: Math.max(0, height - dockBottom),\n height: Math.max(0, dockRect.height) / 2,\n left: {\n maxWidth: Math.max(0, dockLeft - inset * 2 - gap),\n right: Math.max(inset, width - dockLeft + gap),\n },\n right: {\n left: Math.min(width - inset, dockRight + gap),\n maxWidth: Math.max(0, width - dockRight - inset * 2 - gap),\n },\n };\n}\n\nexport function areLayoutsEqual(\n a: ControlsLayout | null,\n b: ControlsLayout | null,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n return (\n a.bottom === b.bottom &&\n a.height === b.height &&\n a.isHidden === b.isHidden &&\n a.left.maxWidth === b.left.maxWidth &&\n a.left.right === b.left.right &&\n a.right.left === b.right.left &&\n a.right.maxWidth === b.right.maxWidth\n );\n}\n\nexport function getDockStackElement(): HTMLElement | null {\n return document.getElementById(CONTROLS_DOCK_ELEMENT_ID);\n}\n\nexport function getDockElement(): Element | null {\n return (\n document.querySelector('[data-controls-anchor=\"true\"]') ??\n getDockStackElement()\n );\n}\n\nexport function measureLayout(): ControlsLayout | null {\n const dockElement = getDockElement();\n if (!dockElement) return null;\n const layout = getControlsLayout(dockElement.getBoundingClientRect(), {\n height: window.innerHeight,\n width: window.innerWidth,\n });\n return (\n layout && {\n ...layout,\n isHidden: getDockStackElement()?.dataset.controlsHidden === \"true\",\n }\n );\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { usePathname } from \"next/navigation\";\nimport { useModuleRegistration, type RegistryMetadata } from \"@/kernel\";\nimport {\n type ControlEntry,\n type ControlsLayout,\n type ControlsPageConfig,\n type ControlsUseOptions,\n type DefineControlsOptions,\n} from \"./types\";\nimport { normalizePageControls, resolveSlot } from \"./entries\";\nimport {\n areLayoutsEqual,\n getDockElement,\n measureLayout,\n} from \"./layout\";\n\nexport function useControlsLayout(): ControlsLayout | null {\n const [layout, setLayout] = useState<ControlsLayout | null>(null);\n\n useEffect(() => {\n let observed: Element | null | undefined;\n let resizeObserver: ResizeObserver | undefined;\n\n const update = () => {\n const next = measureLayout();\n setLayout((prev) => (areLayoutsEqual(prev, next) ? prev : next));\n };\n\n const observe = () => {\n const dockElement = getDockElement();\n if (dockElement !== observed) {\n observed = dockElement;\n resizeObserver?.disconnect();\n mutationObserver.disconnect();\n if (dockElement) {\n if (typeof ResizeObserver !== \"undefined\") {\n resizeObserver = new ResizeObserver(update);\n resizeObserver.observe(dockElement);\n }\n mutationObserver.observe(dockElement, {\n attributes: true,\n attributeFilter: [\"data-controls-anchor\", \"data-controls-hidden\"],\n });\n if (dockElement.parentElement) {\n mutationObserver.observe(dockElement.parentElement, {\n childList: true,\n });\n }\n } else {\n mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n }\n }\n update();\n };\n\n const mutationObserver = new MutationObserver(observe);\n\n observe();\n window.addEventListener(\"resize\", update);\n return () => {\n mutationObserver.disconnect();\n resizeObserver?.disconnect();\n window.removeEventListener(\"resize\", update);\n };\n }, []);\n\n return layout;\n}\n\nexport function useControlsRegistration(\n config: ControlsPageConfig | null | undefined,\n options?: RegistryMetadata & { enabled?: boolean },\n): void {\n useModuleRegistration(\"controls\", config, options);\n}\n\nexport function useControls(\n config?: DefineControlsOptions | ControlEntry | ControlEntry[] | null,\n options?: ControlsUseOptions,\n): ControlsLayout | null {\n const pathname = usePathname();\n const definitionPath = config && \"path\" in config ? config.path : undefined;\n const path = options?.path || definitionPath || pathname;\n\n const entries = useMemo(() => {\n if (!config) return null;\n if (Array.isArray(config) || \"side\" in config) return config;\n const { defaultProps = {}, left, right, ...page } = config;\n const resolved = normalizePageControls({\n ...page,\n left: resolveSlot(left, defaultProps),\n path,\n right: resolveSlot(right, defaultProps),\n });\n return resolved?.length ? resolved : null;\n }, [config, path]);\n\n useControlsRegistration(entries, options);\n return useControlsLayout();\n}\n","\"use client\";\n\nimport {\n Fragment,\n useMemo,\n useSyncExternalStore,\n type CSSProperties,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { usePathname } from \"next/navigation\";\nimport { useRegistryEntries } from \"@/kernel\";\nimport { useModuleTheme } from \"@/theme\";\nimport { controlsTheme } from \"./constants\";\nimport { resolveControlsPairs } from \"./entries\";\nimport { useControlsLayout } from \"./hooks\";\nimport { type ControlEntry, type ControlsSideProps } from \"./types\";\n\nconst emptySubscribe = () => () => {};\n\nexport function useControlsModel() {\n const portalTarget = useSyncExternalStore(\n emptySubscribe,\n () => (typeof document !== \"undefined\" ? document.body : null),\n () => null,\n );\n const layout = useControlsLayout();\n const pathname = usePathname();\n const entries = useRegistryEntries<\"controls\", ControlEntry>(\"controls\");\n const { left, right } = useMemo(\n () => resolveControlsPairs(entries, pathname),\n [entries, pathname],\n );\n\n const theme = useModuleTheme(controlsTheme);\n\n return { portalTarget, layout, left, right, theme };\n}\n\nexport function ControlsSide({\n controls,\n geometry,\n side,\n theme,\n}: ControlsSideProps) {\n if (controls.length === 0 || !geometry.height || !geometry.maxWidth) {\n return null;\n }\n const positionStyle: CSSProperties =\n side === \"left\"\n ? {\n bottom: geometry.bottom,\n maxWidth: geometry.maxWidth,\n right: geometry.right,\n }\n : {\n bottom: geometry.bottom,\n left: geometry.left,\n maxWidth: geometry.maxWidth,\n };\n return (\n <aside\n aria-label={`${side === \"left\" ? \"Left\" : \"Right\"} page controls`}\n className={theme.slots.rail}\n style={{ ...theme.styles.rail, ...positionStyle }}\n >\n <div\n data-side={side}\n className={theme.slots.stack}\n style={\n {\n ...theme.styles.stack,\n \"--controls-height\": `${geometry.height}px`,\n } as CSSProperties\n }\n >\n {controls.map(({ content, id }, index) => (\n <Fragment key={id || index}>{content}</Fragment>\n ))}\n </div>\n </aside>\n );\n}\n\nexport function Controls() {\n const { portalTarget, layout, left, right, theme } = useControlsModel();\n if (!portalTarget || !layout || layout.isHidden || left.length === 0) {\n return null;\n }\n return createPortal(\n <>\n <ControlsSide\n controls={left}\n geometry={{\n ...layout.left,\n bottom: layout.bottom,\n height: layout.height,\n }}\n side=\"left\"\n theme={theme}\n />\n <ControlsSide\n controls={right}\n geometry={{\n ...layout.right,\n bottom: layout.bottom,\n height: layout.height,\n }}\n side=\"right\"\n theme={theme}\n />\n </>,\n portalTarget,\n );\n}\n","\"use client\";\n\nimport { useMemo } from \"react\";\nimport {\n defineModule,\n type PageConfig,\n type PageModuleApi,\n} from \"@/kernel\";\nimport { useControls } from \"./hooks\";\nimport { normalizePageControls, validateControlEntry } from \"./entries\";\nimport { Controls } from \"./overlay\";\nimport {\n type ControlsPageApi,\n type DefinedControls,\n type DefineControlsOptions,\n type ControlsPageConfig,\n type PageControlEntry,\n} from \"./types\";\n\nfunction selectPageControls(config: PageConfig) {\n return normalizePageControls(config.controls);\n}\n\nfunction useControlsPage(\n _slice: PageControlEntry[] | null,\n page: PageModuleApi,\n): ControlsPageApi {\n return useMemo(\n () => ({\n set: (controls: ControlsPageConfig | null) => page.set({ controls }),\n }),\n [page],\n );\n}\n\nexport function defineControls(\n definition: DefineControlsOptions = {},\n): DefinedControls {\n const { id = \"controls\", order = 0 } = definition;\n\n return Object.freeze({\n config: definition,\n id,\n order,\n use: function useDefinedControls(props = {}, options = {}) {\n return useControls(\n {\n ...definition,\n defaultProps: { ...definition.defaultProps, ...props },\n },\n options,\n );\n },\n });\n}\n\nexport const controlsModule = defineModule({\n id: \"controls\",\n Overlay: Controls,\n registry: {\n keyPolicy: \"named\",\n lifecycle: \"immediate\",\n validate: validateControlEntry,\n },\n page: {\n select: selectPageControls,\n entries: (entry: PageControlEntry, { pathname }) => {\n const path = pathname || \"/\";\n return [{ key: `${path}::${entry.id}`, value: { ...entry, path } }];\n },\n use: useControlsPage,\n },\n});\n\ndeclare module \"@omerdlw/base-framework/kernel\" {\n interface CoreModules {\n controls: typeof controlsModule;\n }\n interface PageConfig {\n controls?: ControlsPageConfig | null;\n }\n}\n"]}