@hanzo/ui 8.27.10 → 8.27.11

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 (303) hide show
  1. package/dist/backends/gui/comparison.cjs +17 -21
  2. package/dist/backends/gui/comparison.d.ts +4 -5
  3. package/dist/backends/gui/comparison.d.ts.map +1 -1
  4. package/dist/backends/gui/comparison.js +18 -22
  5. package/dist/backends/gui/comparison.js.map +1 -1
  6. package/dist/backends/gui/crypto-screener.cjs +21 -31
  7. package/dist/backends/gui/crypto-screener.d.ts +20 -24
  8. package/dist/backends/gui/crypto-screener.d.ts.map +1 -1
  9. package/dist/backends/gui/crypto-screener.js +21 -31
  10. package/dist/backends/gui/crypto-screener.js.map +1 -1
  11. package/dist/backends/gui/cursor.cjs +15 -18
  12. package/dist/backends/gui/cursor.d.ts +4 -3
  13. package/dist/backends/gui/cursor.d.ts.map +1 -1
  14. package/dist/backends/gui/cursor.js +15 -18
  15. package/dist/backends/gui/cursor.js.map +1 -1
  16. package/dist/backends/gui/data-table.cjs +144 -184
  17. package/dist/backends/gui/data-table.d.ts +64 -44
  18. package/dist/backends/gui/data-table.d.ts.map +1 -1
  19. package/dist/backends/gui/data-table.js +146 -152
  20. package/dist/backends/gui/data-table.js.map +1 -1
  21. package/dist/backends/gui/dock.cjs +1 -1
  22. package/dist/backends/gui/dock.d.ts.map +1 -1
  23. package/dist/backends/gui/dock.js +1 -1
  24. package/dist/backends/gui/dock.js.map +1 -1
  25. package/dist/backends/gui/editor.cjs +35 -31
  26. package/dist/backends/gui/editor.d.ts +11 -11
  27. package/dist/backends/gui/editor.d.ts.map +1 -1
  28. package/dist/backends/gui/editor.js +35 -31
  29. package/dist/backends/gui/editor.js.map +1 -1
  30. package/dist/backends/gui/field.cjs +132 -0
  31. package/dist/backends/gui/field.d.ts +74 -0
  32. package/dist/backends/gui/field.d.ts.map +1 -0
  33. package/dist/backends/gui/field.js +121 -0
  34. package/dist/backends/gui/field.js.map +1 -0
  35. package/dist/backends/gui/gantt.cjs +17 -19
  36. package/dist/backends/gui/gantt.d.ts +4 -5
  37. package/dist/backends/gui/gantt.d.ts.map +1 -1
  38. package/dist/backends/gui/gantt.js +18 -21
  39. package/dist/backends/gui/gantt.js.map +1 -1
  40. package/dist/backends/gui/glimpse.cjs +88 -0
  41. package/dist/backends/gui/glimpse.d.ts +57 -0
  42. package/dist/backends/gui/glimpse.d.ts.map +1 -0
  43. package/dist/backends/gui/glimpse.js +81 -0
  44. package/dist/backends/gui/glimpse.js.map +1 -0
  45. package/dist/backends/gui/grid-pattern.cjs +119 -0
  46. package/dist/backends/gui/grid-pattern.d.ts +96 -0
  47. package/dist/backends/gui/grid-pattern.d.ts.map +1 -0
  48. package/dist/backends/gui/grid-pattern.js +84 -0
  49. package/dist/backends/gui/grid-pattern.js.map +1 -0
  50. package/dist/backends/gui/image-crop.cjs +35 -0
  51. package/dist/backends/gui/image-crop.d.ts +20 -0
  52. package/dist/backends/gui/image-crop.d.ts.map +1 -0
  53. package/dist/backends/gui/image-crop.js +33 -0
  54. package/dist/backends/gui/image-crop.js.map +1 -0
  55. package/dist/backends/gui/image-zoom.cjs +58 -0
  56. package/dist/backends/gui/image-zoom.d.ts +16 -0
  57. package/dist/backends/gui/image-zoom.d.ts.map +1 -0
  58. package/dist/backends/gui/image-zoom.js +56 -0
  59. package/dist/backends/gui/image-zoom.js.map +1 -0
  60. package/dist/backends/gui/index.cjs +159 -1
  61. package/dist/backends/gui/index.d.ts +49 -0
  62. package/dist/backends/gui/index.d.ts.map +1 -1
  63. package/dist/backends/gui/index.js +49 -0
  64. package/dist/backends/gui/index.js.map +1 -1
  65. package/dist/backends/gui/interactive-grid-pattern.cjs +61 -0
  66. package/dist/backends/gui/interactive-grid-pattern.d.ts +28 -0
  67. package/dist/backends/gui/interactive-grid-pattern.d.ts.map +1 -0
  68. package/dist/backends/gui/interactive-grid-pattern.js +26 -0
  69. package/dist/backends/gui/interactive-grid-pattern.js.map +1 -0
  70. package/dist/backends/gui/iphone-15-pro.cjs +83 -0
  71. package/dist/backends/gui/iphone-15-pro.d.ts +16 -0
  72. package/dist/backends/gui/iphone-15-pro.d.ts.map +1 -0
  73. package/dist/backends/gui/iphone-15-pro.js +81 -0
  74. package/dist/backends/gui/iphone-15-pro.js.map +1 -0
  75. package/dist/backends/gui/item.cjs +154 -0
  76. package/dist/backends/gui/item.d.ts +72 -0
  77. package/dist/backends/gui/item.d.ts.map +1 -0
  78. package/dist/backends/gui/item.js +143 -0
  79. package/dist/backends/gui/item.js.map +1 -0
  80. package/dist/backends/gui/kanban.cjs +247 -0
  81. package/dist/backends/gui/kanban.d.ts +37 -0
  82. package/dist/backends/gui/kanban.d.ts.map +1 -0
  83. package/dist/backends/gui/kanban.js +212 -0
  84. package/dist/backends/gui/kanban.js.map +1 -0
  85. package/dist/backends/gui/kbd.cjs +45 -0
  86. package/dist/backends/gui/kbd.d.ts +8 -0
  87. package/dist/backends/gui/kbd.d.ts.map +1 -0
  88. package/dist/backends/gui/kbd.js +42 -0
  89. package/dist/backends/gui/kbd.js.map +1 -0
  90. package/dist/backends/gui/limelight-nav.cjs +201 -0
  91. package/dist/backends/gui/limelight-nav.d.ts +20 -0
  92. package/dist/backends/gui/limelight-nav.d.ts.map +1 -0
  93. package/dist/backends/gui/limelight-nav.js +166 -0
  94. package/dist/backends/gui/limelight-nav.js.map +1 -0
  95. package/dist/backends/gui/list.cjs +26 -0
  96. package/dist/backends/gui/list.d.ts +15 -0
  97. package/dist/backends/gui/list.d.ts.map +1 -0
  98. package/dist/backends/gui/list.js +23 -0
  99. package/dist/backends/gui/list.js.map +1 -0
  100. package/dist/backends/gui/macos-dock.cjs +84 -0
  101. package/dist/backends/gui/macos-dock.d.ts +30 -0
  102. package/dist/backends/gui/macos-dock.d.ts.map +1 -0
  103. package/dist/backends/gui/macos-dock.js +82 -0
  104. package/dist/backends/gui/macos-dock.js.map +1 -0
  105. package/dist/backends/gui/magnetic.cjs +40 -0
  106. package/dist/backends/gui/magnetic.d.ts +12 -0
  107. package/dist/backends/gui/magnetic.d.ts.map +1 -0
  108. package/dist/backends/gui/magnetic.js +38 -0
  109. package/dist/backends/gui/magnetic.js.map +1 -0
  110. package/dist/backends/gui/marquee.cjs +110 -0
  111. package/dist/backends/gui/marquee.d.ts +44 -0
  112. package/dist/backends/gui/marquee.d.ts.map +1 -0
  113. package/dist/backends/gui/marquee.js +75 -0
  114. package/dist/backends/gui/marquee.js.map +1 -0
  115. package/dist/backends/gui/menu-dock.cjs +64 -0
  116. package/dist/backends/gui/menu-dock.d.ts +21 -0
  117. package/dist/backends/gui/menu-dock.d.ts.map +1 -0
  118. package/dist/backends/gui/menu-dock.js +62 -0
  119. package/dist/backends/gui/menu-dock.js.map +1 -0
  120. package/dist/backends/gui/menubar.cjs +227 -0
  121. package/dist/backends/gui/menubar.d.ts +106 -0
  122. package/dist/backends/gui/menubar.d.ts.map +1 -0
  123. package/dist/backends/gui/menubar.js +177 -0
  124. package/dist/backends/gui/menubar.js.map +1 -0
  125. package/dist/backends/gui/message-dock.cjs +111 -0
  126. package/dist/backends/gui/message-dock.d.ts +22 -0
  127. package/dist/backends/gui/message-dock.d.ts.map +1 -0
  128. package/dist/backends/gui/message-dock.js +110 -0
  129. package/dist/backends/gui/message-dock.js.map +1 -0
  130. package/dist/backends/gui/mini-calendar.cjs +25 -0
  131. package/dist/backends/gui/mini-calendar.d.ts +22 -0
  132. package/dist/backends/gui/mini-calendar.d.ts.map +1 -0
  133. package/dist/backends/gui/mini-calendar.js +24 -0
  134. package/dist/backends/gui/mini-calendar.js.map +1 -0
  135. package/dist/backends/gui/minimal-tiptap.cjs +56 -0
  136. package/dist/backends/gui/minimal-tiptap.d.ts +20 -0
  137. package/dist/backends/gui/minimal-tiptap.d.ts.map +1 -0
  138. package/dist/backends/gui/minimal-tiptap.js +21 -0
  139. package/dist/backends/gui/minimal-tiptap.js.map +1 -0
  140. package/dist/backends/gui/motion-highlight.cjs +83 -0
  141. package/dist/backends/gui/motion-highlight.d.ts +27 -0
  142. package/dist/backends/gui/motion-highlight.d.ts.map +1 -0
  143. package/dist/backends/gui/motion-highlight.js +48 -0
  144. package/dist/backends/gui/motion-highlight.js.map +1 -0
  145. package/dist/backends/gui/navigation-bar.cjs +47 -0
  146. package/dist/backends/gui/navigation-bar.d.ts +48 -0
  147. package/dist/backends/gui/navigation-bar.d.ts.map +1 -0
  148. package/dist/backends/gui/navigation-bar.js +45 -0
  149. package/dist/backends/gui/navigation-bar.js.map +1 -0
  150. package/dist/backends/gui/news-timeline.cjs +47 -0
  151. package/dist/backends/gui/news-timeline.d.ts +39 -0
  152. package/dist/backends/gui/news-timeline.d.ts.map +1 -0
  153. package/dist/backends/gui/news-timeline.js +45 -0
  154. package/dist/backends/gui/news-timeline.js.map +1 -0
  155. package/dist/backends/gui/order-entry.cjs +53 -0
  156. package/dist/backends/gui/order-entry.d.ts +21 -0
  157. package/dist/backends/gui/order-entry.d.ts.map +1 -0
  158. package/dist/backends/gui/order-entry.js +52 -0
  159. package/dist/backends/gui/order-entry.js.map +1 -0
  160. package/dist/backends/gui/orders-history.cjs +102 -0
  161. package/dist/backends/gui/orders-history.d.ts +24 -0
  162. package/dist/backends/gui/orders-history.d.ts.map +1 -0
  163. package/dist/backends/gui/orders-history.js +67 -0
  164. package/dist/backends/gui/orders-history.js.map +1 -0
  165. package/dist/backends/gui/pagination.cjs +51 -0
  166. package/dist/backends/gui/pagination.d.ts +52 -0
  167. package/dist/backends/gui/pagination.d.ts.map +1 -0
  168. package/dist/backends/gui/pagination.js +42 -0
  169. package/dist/backends/gui/pagination.js.map +1 -0
  170. package/dist/backends/gui/particles-background.cjs +135 -0
  171. package/dist/backends/gui/particles-background.d.ts +24 -0
  172. package/dist/backends/gui/particles-background.d.ts.map +1 -0
  173. package/dist/backends/gui/particles-background.js +133 -0
  174. package/dist/backends/gui/particles-background.js.map +1 -0
  175. package/dist/backends/gui/particles.cjs +145 -0
  176. package/dist/backends/gui/particles.d.ts +25 -0
  177. package/dist/backends/gui/particles.d.ts.map +1 -0
  178. package/dist/backends/gui/particles.js +143 -0
  179. package/dist/backends/gui/particles.js.map +1 -0
  180. package/dist/backends/gui/pill.cjs +82 -0
  181. package/dist/backends/gui/pill.d.ts +12 -0
  182. package/dist/backends/gui/pill.d.ts.map +1 -0
  183. package/dist/backends/gui/pill.js +78 -0
  184. package/dist/backends/gui/pill.js.map +1 -0
  185. package/dist/backends/gui/pin-list.cjs +82 -0
  186. package/dist/backends/gui/pin-list.d.ts +42 -0
  187. package/dist/backends/gui/pin-list.d.ts.map +1 -0
  188. package/dist/backends/gui/pin-list.js +80 -0
  189. package/dist/backends/gui/pin-list.js.map +1 -0
  190. package/dist/backends/gui/pixel-image.cjs +63 -0
  191. package/dist/backends/gui/pixel-image.d.ts +21 -0
  192. package/dist/backends/gui/pixel-image.d.ts.map +1 -0
  193. package/dist/backends/gui/pixel-image.js +61 -0
  194. package/dist/backends/gui/pixel-image.js.map +1 -0
  195. package/dist/backends/gui/positions-list.cjs +60 -0
  196. package/dist/backends/gui/positions-list.d.ts +14 -0
  197. package/dist/backends/gui/positions-list.d.ts.map +1 -0
  198. package/dist/backends/gui/positions-list.js +58 -0
  199. package/dist/backends/gui/positions-list.js.map +1 -0
  200. package/dist/backends/gui/qr-code.cjs +438 -0
  201. package/dist/backends/gui/qr-code.d.ts +42 -0
  202. package/dist/backends/gui/qr-code.d.ts.map +1 -0
  203. package/dist/backends/gui/qr-code.js +402 -0
  204. package/dist/backends/gui/qr-code.js.map +1 -0
  205. package/dist/backends/gui/relative-time.cjs +167 -0
  206. package/dist/backends/gui/relative-time.d.ts +10 -0
  207. package/dist/backends/gui/relative-time.d.ts.map +1 -0
  208. package/dist/backends/gui/relative-time.js +132 -0
  209. package/dist/backends/gui/relative-time.js.map +1 -0
  210. package/dist/backends/gui/safari.cjs +65 -0
  211. package/dist/backends/gui/safari.d.ts +23 -0
  212. package/dist/backends/gui/safari.d.ts.map +1 -0
  213. package/dist/backends/gui/safari.js +63 -0
  214. package/dist/backends/gui/safari.js.map +1 -0
  215. package/dist/backends/gui/snippet.cjs +144 -0
  216. package/dist/backends/gui/snippet.d.ts +38 -0
  217. package/dist/backends/gui/snippet.d.ts.map +1 -0
  218. package/dist/backends/gui/snippet.js +141 -0
  219. package/dist/backends/gui/snippet.js.map +1 -0
  220. package/dist/backends/gui/stars-scrolling-wheel.cjs +106 -0
  221. package/dist/backends/gui/stars-scrolling-wheel.d.ts +24 -0
  222. package/dist/backends/gui/stars-scrolling-wheel.d.ts.map +1 -0
  223. package/dist/backends/gui/stars-scrolling-wheel.js +104 -0
  224. package/dist/backends/gui/stars-scrolling-wheel.js.map +1 -0
  225. package/dist/backends/gui/status.cjs +79 -0
  226. package/dist/backends/gui/status.d.ts +15 -0
  227. package/dist/backends/gui/status.d.ts.map +1 -0
  228. package/dist/backends/gui/status.js +77 -0
  229. package/dist/backends/gui/status.js.map +1 -0
  230. package/dist/backends/gui/stock-market.cjs +21 -0
  231. package/dist/backends/gui/stock-market.d.ts +17 -0
  232. package/dist/backends/gui/stock-market.d.ts.map +1 -0
  233. package/dist/backends/gui/stock-market.js +19 -0
  234. package/dist/backends/gui/stock-market.js.map +1 -0
  235. package/dist/backends/gui/stock-screener.cjs +55 -0
  236. package/dist/backends/gui/stock-screener.d.ts +41 -0
  237. package/dist/backends/gui/stock-screener.d.ts.map +1 -0
  238. package/dist/backends/gui/stock-screener.js +53 -0
  239. package/dist/backends/gui/stock-screener.js.map +1 -0
  240. package/dist/backends/gui/symbol-info.cjs +46 -0
  241. package/dist/backends/gui/symbol-info.d.ts +36 -0
  242. package/dist/backends/gui/symbol-info.d.ts.map +1 -0
  243. package/dist/backends/gui/symbol-info.js +44 -0
  244. package/dist/backends/gui/symbol-info.js.map +1 -0
  245. package/dist/backends/gui/table.cjs +104 -0
  246. package/dist/backends/gui/table.d.ts +57 -0
  247. package/dist/backends/gui/table.d.ts.map +1 -0
  248. package/dist/backends/gui/table.js +95 -0
  249. package/dist/backends/gui/table.js.map +1 -0
  250. package/dist/backends/gui/tags.cjs +22 -0
  251. package/dist/backends/gui/tags.d.ts +22 -0
  252. package/dist/backends/gui/tags.d.ts.map +1 -0
  253. package/dist/backends/gui/tags.js +20 -0
  254. package/dist/backends/gui/tags.js.map +1 -0
  255. package/dist/backends/gui/technical-analysis.cjs +58 -0
  256. package/dist/backends/gui/technical-analysis.d.ts +41 -0
  257. package/dist/backends/gui/technical-analysis.d.ts.map +1 -0
  258. package/dist/backends/gui/technical-analysis.js +56 -0
  259. package/dist/backends/gui/technical-analysis.js.map +1 -0
  260. package/dist/backends/gui/terminal.cjs +266 -0
  261. package/dist/backends/gui/terminal.d.ts +38 -0
  262. package/dist/backends/gui/terminal.d.ts.map +1 -0
  263. package/dist/backends/gui/terminal.js +231 -0
  264. package/dist/backends/gui/terminal.js.map +1 -0
  265. package/dist/backends/gui/ticker.cjs +79 -0
  266. package/dist/backends/gui/ticker.d.ts +19 -0
  267. package/dist/backends/gui/ticker.d.ts.map +1 -0
  268. package/dist/backends/gui/ticker.js +44 -0
  269. package/dist/backends/gui/ticker.js.map +1 -0
  270. package/dist/backends/gui/timeline.cjs +154 -0
  271. package/dist/backends/gui/timeline.d.ts +42 -0
  272. package/dist/backends/gui/timeline.d.ts.map +1 -0
  273. package/dist/backends/gui/timeline.js +118 -0
  274. package/dist/backends/gui/timeline.js.map +1 -0
  275. package/dist/backends/gui/toggle.cjs +96 -0
  276. package/dist/backends/gui/toggle.d.ts +29 -0
  277. package/dist/backends/gui/toggle.d.ts.map +1 -0
  278. package/dist/backends/gui/toggle.js +95 -0
  279. package/dist/backends/gui/toggle.js.map +1 -0
  280. package/dist/backends/gui/video-player.cjs +383 -0
  281. package/dist/backends/gui/video-player.d.ts +54 -0
  282. package/dist/backends/gui/video-player.d.ts.map +1 -0
  283. package/dist/backends/gui/video-player.js +348 -0
  284. package/dist/backends/gui/video-player.js.map +1 -0
  285. package/dist/chat/Composer.cjs +10 -10
  286. package/dist/chat/Composer.d.ts +16 -17
  287. package/dist/chat/Composer.d.ts.map +1 -1
  288. package/dist/chat/Composer.js +11 -11
  289. package/dist/chat/Composer.js.map +1 -1
  290. package/dist/gallery.cjs +180 -1
  291. package/dist/gallery.d.ts.map +1 -1
  292. package/dist/gallery.html +391 -3
  293. package/dist/gallery.js +181 -2
  294. package/dist/gallery.js.map +1 -1
  295. package/dist/index.cjs +110 -1
  296. package/dist/index.d.ts +1 -1
  297. package/dist/index.d.ts.map +1 -1
  298. package/dist/index.js +1 -1
  299. package/dist/index.js.map +1 -1
  300. package/dist/index.node.cjs +110 -1
  301. package/dist/index.node.js +1 -1
  302. package/dist/styles.css +356 -0
  303. package/package.json +1 -1
@@ -0,0 +1,82 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.pillVariants = void 0;
5
+ exports.Pill = Pill;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ /**
8
+ * Pill — a small rounded label for a status, a tag or a filter, with an
9
+ * optional remove control. `variant`, `onRemove`, `pillVariants`, and the
10
+ * `data-slot`/`data-variant` markers, rendering through @hanzo/gui so the
11
+ * same component runs on web, native and Tauri.
12
+ *
13
+ * Surface and label are two styled parts sharing one `variant` through a
14
+ * styled context, the same split Badge uses — the frame owns background and
15
+ * text color, the label owns type. The remove control reuses this backend's
16
+ * own Button (ghost, icon-sized, shrunk to fit the pill) rather than a raw
17
+ * element, so it already carries the real `<button type="button">` host and
18
+ * the 44px touch floor.
19
+ */
20
+ const gui_1 = require("@hanzo/gui");
21
+ const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
22
+ const sx_1 = require("../../sx.cjs");
23
+ const button_1 = require("./button.cjs");
24
+ const ink_1 = require("./ink.cjs");
25
+ const gesture_1 = require("./gesture.cjs");
26
+ const slot_1 = require("./slot.cjs");
27
+ /** A pill is a 28px capsule; the slop makes its remove control meet the 44px floor. */
28
+ const MIN_TOUCH = 44;
29
+ const HEIGHT = 28;
30
+ const REMOVE = 16;
31
+ const PillContext = /* @__PURE__ */ (0, gui_1.createStyledContext)({ variant: 'default' });
32
+ const PillFrame = (0, gui_1.styled)(gui_1.XStack, {
33
+ name: 'Pill',
34
+ context: PillContext,
35
+ display: 'inline-flex',
36
+ self: 'flex-start',
37
+ items: 'center',
38
+ justify: 'center',
39
+ shrink: 0,
40
+ gap: '$1.5',
41
+ minH: HEIGHT,
42
+ px: '$3',
43
+ py: '$1',
44
+ rounded: 999,
45
+ borderWidth: 1,
46
+ borderColor: 'transparent',
47
+ overflow: 'hidden',
48
+ variants: {
49
+ variant: {
50
+ default: { bg: '$accentBackground' },
51
+ secondary: { bg: '$edge' },
52
+ outline: { bg: '$background', borderColor: '$borderColor' },
53
+ success: { bg: '$green4' },
54
+ warning: { bg: '$yellow4' },
55
+ error: { bg: '$red4' },
56
+ },
57
+ },
58
+ defaultVariants: { variant: 'default' },
59
+ });
60
+ const PillText = (0, gui_1.styled)(gui_1.SizableText, {
61
+ name: 'PillText',
62
+ context: PillContext,
63
+ size: '$2',
64
+ fontWeight: '500',
65
+ variants: {
66
+ variant: {
67
+ default: { color: '$accentColor' },
68
+ secondary: { color: '$ink' },
69
+ outline: { color: '$ink' },
70
+ success: { color: '$green11' },
71
+ warning: { color: '$yellow11' },
72
+ error: { color: '$red11' },
73
+ },
74
+ },
75
+ });
76
+ /** A pill's classes, for hosts that hook it from CSS. Styling lives in the tokens. */
77
+ const pillVariants = ({ variant } = {}) => `pill pill-${variant ?? 'default'}`;
78
+ exports.pillVariants = pillVariants;
79
+ function Pill({ className, variant = 'default', onRemove, children, ...props }) {
80
+ const resolved = variant ?? 'default';
81
+ return ((0, jsx_runtime_1.jsxs)(PillFrame, { ...(0, slot_1.slot)('pill'), "data-variant": resolved, variant: resolved, ...(0, sx_1.sx)([(0, exports.pillVariants)({ variant: resolved }), className].filter(Boolean).join(' ')), ...props, children: [(0, ink_1.ink)(children, PillText), onRemove ? ((0, jsx_runtime_1.jsx)(button_1.Button, { ...(0, slot_1.slot)('pill-remove'), variant: "ghost", size: "icon", minH: REMOVE, minW: REMOVE, rounded: 999, ...(0, gesture_1.touch)(REMOVE, MIN_TOUCH), "aria-label": "Remove", onPress: onRemove, children: (0, jsx_runtime_1.jsx)(lucide_icons_2_1.X, { size: 12 }) })) : null] }));
82
+ }
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ export type PillVariant = 'default' | 'secondary' | 'outline' | 'success' | 'warning' | 'error';
3
+ /** A pill's classes, for hosts that hook it from CSS. Styling lives in the tokens. */
4
+ export declare const pillVariants: ({ variant }?: {
5
+ variant?: PillVariant | null;
6
+ }) => string;
7
+ export type PillProps = React.ComponentProps<'span'> & {
8
+ variant?: PillVariant | null;
9
+ onRemove?: () => void;
10
+ };
11
+ export declare function Pill({ className, variant, onRemove, children, ...props }: PillProps): React.JSX.Element;
12
+ //# sourceMappingURL=pill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pill.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/pill.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AA0D/F,sFAAsF;AACtF,eAAO,MAAM,YAAY,iBAAiB;IAAE,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,WACrC,CAAA;AAErC,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG;IACrD,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA;AAED,wBAAgB,IAAI,CAAC,EAAE,SAAS,EAAE,OAAmB,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,SAAS,qBA4B/F"}
@@ -0,0 +1,78 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * Pill — a small rounded label for a status, a tag or a filter, with an
5
+ * optional remove control. `variant`, `onRemove`, `pillVariants`, and the
6
+ * `data-slot`/`data-variant` markers, rendering through @hanzo/gui so the
7
+ * same component runs on web, native and Tauri.
8
+ *
9
+ * Surface and label are two styled parts sharing one `variant` through a
10
+ * styled context, the same split Badge uses — the frame owns background and
11
+ * text color, the label owns type. The remove control reuses this backend's
12
+ * own Button (ghost, icon-sized, shrunk to fit the pill) rather than a raw
13
+ * element, so it already carries the real `<button type="button">` host and
14
+ * the 44px touch floor.
15
+ */
16
+ import { SizableText, XStack, createStyledContext, styled } from '@hanzo/gui';
17
+ import { X } from '@hanzogui/lucide-icons-2';
18
+ import { sx } from '../../sx.js';
19
+ import { Button } from './button.js';
20
+ import { ink } from './ink.js';
21
+ import { touch } from './gesture.js';
22
+ import { slot } from './slot.js';
23
+ /** A pill is a 28px capsule; the slop makes its remove control meet the 44px floor. */
24
+ const MIN_TOUCH = 44;
25
+ const HEIGHT = 28;
26
+ const REMOVE = 16;
27
+ const PillContext = /* @__PURE__ */ createStyledContext({ variant: 'default' });
28
+ const PillFrame = styled(XStack, {
29
+ name: 'Pill',
30
+ context: PillContext,
31
+ display: 'inline-flex',
32
+ self: 'flex-start',
33
+ items: 'center',
34
+ justify: 'center',
35
+ shrink: 0,
36
+ gap: '$1.5',
37
+ minH: HEIGHT,
38
+ px: '$3',
39
+ py: '$1',
40
+ rounded: 999,
41
+ borderWidth: 1,
42
+ borderColor: 'transparent',
43
+ overflow: 'hidden',
44
+ variants: {
45
+ variant: {
46
+ default: { bg: '$accentBackground' },
47
+ secondary: { bg: '$edge' },
48
+ outline: { bg: '$background', borderColor: '$borderColor' },
49
+ success: { bg: '$green4' },
50
+ warning: { bg: '$yellow4' },
51
+ error: { bg: '$red4' },
52
+ },
53
+ },
54
+ defaultVariants: { variant: 'default' },
55
+ });
56
+ const PillText = styled(SizableText, {
57
+ name: 'PillText',
58
+ context: PillContext,
59
+ size: '$2',
60
+ fontWeight: '500',
61
+ variants: {
62
+ variant: {
63
+ default: { color: '$accentColor' },
64
+ secondary: { color: '$ink' },
65
+ outline: { color: '$ink' },
66
+ success: { color: '$green11' },
67
+ warning: { color: '$yellow11' },
68
+ error: { color: '$red11' },
69
+ },
70
+ },
71
+ });
72
+ /** A pill's classes, for hosts that hook it from CSS. Styling lives in the tokens. */
73
+ export const pillVariants = ({ variant } = {}) => `pill pill-${variant ?? 'default'}`;
74
+ export function Pill({ className, variant = 'default', onRemove, children, ...props }) {
75
+ const resolved = variant ?? 'default';
76
+ return (_jsxs(PillFrame, { ...slot('pill'), "data-variant": resolved, variant: resolved, ...sx([pillVariants({ variant: resolved }), className].filter(Boolean).join(' ')), ...props, children: [ink(children, PillText), onRemove ? (_jsx(Button, { ...slot('pill-remove'), variant: "ghost", size: "icon", minH: REMOVE, minW: REMOVE, rounded: 999, ...touch(REMOVE, MIN_TOUCH), "aria-label": "Remove", onPress: onRemove, children: _jsx(X, { size: 12 }) })) : null] }));
77
+ }
78
+ //# sourceMappingURL=pill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pill.js","sourceRoot":"","sources":["../../../src/backends/gui/pill.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PinList = PinList;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ /**
7
+ * PinList — a list of rows a viewer can pin to the top: a favourites list, a
8
+ * recent-files rail, a set of saved queries. Pinning is order, not deletion —
9
+ * a pinned row moves to its own group above the rest and an unpinned one keeps
10
+ * its original position among its peers.
11
+ *
12
+ * Controlled the same shape as `ToggleGroup`: `value`/`defaultValue` is the set
13
+ * of pinned ids, `onValueChange` fires the next set, and `useControllableState`
14
+ * is the one place that reconciles "does the caller drive this" so an
15
+ * uncontrolled `PinList` and a controlled one share every other line.
16
+ *
17
+ * `max` caps how many rows may be pinned at once — reaching it disables the pin
18
+ * toggle on every UNPINNED row while leaving every PINNED row free to unpin,
19
+ * because the cap is on how many are held, never on which one a viewer chooses
20
+ * to release.
21
+ */
22
+ const gui_1 = require("@hanzo/gui");
23
+ const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
24
+ const ink_1 = require("./ink.cjs");
25
+ const slot_1 = require("./slot.cjs");
26
+ const gesture_1 = require("./gesture.cjs");
27
+ const ICON = 14;
28
+ const BUTTON = 28;
29
+ const RowFrame = (0, gui_1.styled)(gui_1.XStack, {
30
+ name: 'PinListRow',
31
+ items: 'center',
32
+ gap: '$3',
33
+ px: '$3',
34
+ py: '$2.5',
35
+ rounded: '$3',
36
+ borderWidth: 1,
37
+ borderColor: 'transparent',
38
+ hoverStyle: { bg: '$hover' },
39
+ variants: {
40
+ pinned: {
41
+ true: { bg: '$edge' },
42
+ false: {},
43
+ },
44
+ },
45
+ defaultVariants: { pinned: false },
46
+ });
47
+ const PinButton = (0, gui_1.styled)(gui_1.XStack, {
48
+ name: 'PinListPin',
49
+ items: 'center',
50
+ justify: 'center',
51
+ width: BUTTON,
52
+ height: BUTTON,
53
+ rounded: '$2',
54
+ cursor: 'pointer',
55
+ hoverStyle: { bg: '$background' },
56
+ });
57
+ /** A list of rows a viewer can pin to the top. */
58
+ function PinList({ items, value, defaultValue, onValueChange, pinnedFirst = true, max, ...props }) {
59
+ const [pinned, setPinned] = (0, gui_1.useControllableState)({
60
+ prop: value,
61
+ defaultProp: defaultValue ?? [],
62
+ onChange: onValueChange,
63
+ });
64
+ const current = pinned ?? [];
65
+ const atMax = max != null && current.length >= max;
66
+ const toggle = (id) => {
67
+ const next = current.includes(id)
68
+ ? current.filter((existing) => existing !== id)
69
+ : [...current, id];
70
+ setPinned(next);
71
+ };
72
+ const ordered = pinnedFirst
73
+ ? [...items.filter((item) => current.includes(item.id)), ...items.filter((item) => !current.includes(item.id))]
74
+ : items;
75
+ return ((0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('pin-list'), gap: "$1", render: "ul", ...props, children: ordered.map((item) => {
76
+ const isPinned = current.includes(item.id);
77
+ const pinDisabled = Boolean(item.disabled) || (!isPinned && atMax);
78
+ return ((0, jsx_runtime_1.jsxs)(RowFrame, { ...(0, slot_1.slot)('pin-list-row'), "data-pinned": isPinned, pinned: isPinned, render: "li", children: [item.icon, (0, jsx_runtime_1.jsxs)(gui_1.YStack, { flex: 1, gap: "$0.5", children: [(0, ink_1.ink)(item.label, gui_1.SizableText, { fontSize: '$3', fontWeight: '500', color: '$color' }), item.description
79
+ ? (0, ink_1.ink)(item.description, gui_1.SizableText, { fontSize: '$2', color: '$quiet' })
80
+ : null] }), (0, jsx_runtime_1.jsx)(PinButton, { ...(0, slot_1.slot)('pin-list-toggle'), ...(0, slot_1.tip)(isPinned ? `Unpin ${item.label}` : `Pin ${item.label}`), ...(0, gesture_1.touch)(BUTTON, 44), render: "button", ...{ type: 'button', disabled: pinDisabled }, "aria-pressed": isPinned, "aria-label": isPinned ? `Unpin ${item.label}` : `Pin ${item.label}`, opacity: pinDisabled ? 0.4 : 1, cursor: pinDisabled ? 'not-allowed' : 'pointer', onClick: () => !pinDisabled && toggle(item.id), children: isPinned ? (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Pin, { size: ICON, fill: "currentColor" }) : (0, jsx_runtime_1.jsx)(lucide_icons_2_1.PinOff, { size: ICON }) })] }, item.id));
81
+ }) }));
82
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * PinList — a list of rows a viewer can pin to the top: a favourites list, a
3
+ * recent-files rail, a set of saved queries. Pinning is order, not deletion —
4
+ * a pinned row moves to its own group above the rest and an unpinned one keeps
5
+ * its original position among its peers.
6
+ *
7
+ * Controlled the same shape as `ToggleGroup`: `value`/`defaultValue` is the set
8
+ * of pinned ids, `onValueChange` fires the next set, and `useControllableState`
9
+ * is the one place that reconciles "does the caller drive this" so an
10
+ * uncontrolled `PinList` and a controlled one share every other line.
11
+ *
12
+ * `max` caps how many rows may be pinned at once — reaching it disables the pin
13
+ * toggle on every UNPINNED row while leaving every PINNED row free to unpin,
14
+ * because the cap is on how many are held, never on which one a viewer chooses
15
+ * to release.
16
+ */
17
+ import { YStack } from '@hanzo/gui';
18
+ import type { ComponentProps, ReactNode } from 'react';
19
+ export interface PinListItem {
20
+ id: string;
21
+ label: string;
22
+ description?: string;
23
+ icon?: ReactNode;
24
+ disabled?: boolean;
25
+ }
26
+ export type PinListProps = Omit<ComponentProps<typeof YStack>, 'children' | 'onChange' | 'items'> & {
27
+ /** Rows to list, in their unpinned (base) order. */
28
+ items: PinListItem[];
29
+ /** The pinned ids — controlled. */
30
+ value?: string[];
31
+ /** The pinned ids — uncontrolled initial state. */
32
+ defaultValue?: string[];
33
+ /** Fires with the next set of pinned ids whenever a row is pinned or unpinned. */
34
+ onValueChange?: (value: string[]) => void;
35
+ /** Group pinned rows above the rest. Defaults to `true`; `false` pins in place. */
36
+ pinnedFirst?: boolean;
37
+ /** How many rows may be pinned at once. Unset means no limit. */
38
+ max?: number;
39
+ };
40
+ /** A list of rows a viewer can pin to the top. */
41
+ export declare function PinList({ items, value, defaultValue, onValueChange, pinnedFirst, max, ...props }: PinListProps): import("react").JSX.Element;
42
+ //# sourceMappingURL=pin-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pin-list.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/pin-list.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAuB,MAAM,EAAgC,MAAM,YAAY,CAAA;AAEtF,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAQtD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAkCD,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC,GAAG;IAClG,oDAAoD;IACpD,KAAK,EAAE,WAAW,EAAE,CAAA;IACpB,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,kFAAkF;IAClF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACzC,mFAAmF;IACnF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED,kDAAkD;AAClD,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,KAAK,EACL,YAAY,EACZ,aAAa,EACb,WAAkB,EAClB,GAAG,EACH,GAAG,KAAK,EACT,EAAE,YAAY,+BAsDd"}
@@ -0,0 +1,80 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * PinList — a list of rows a viewer can pin to the top: a favourites list, a
5
+ * recent-files rail, a set of saved queries. Pinning is order, not deletion —
6
+ * a pinned row moves to its own group above the rest and an unpinned one keeps
7
+ * its original position among its peers.
8
+ *
9
+ * Controlled the same shape as `ToggleGroup`: `value`/`defaultValue` is the set
10
+ * of pinned ids, `onValueChange` fires the next set, and `useControllableState`
11
+ * is the one place that reconciles "does the caller drive this" so an
12
+ * uncontrolled `PinList` and a controlled one share every other line.
13
+ *
14
+ * `max` caps how many rows may be pinned at once — reaching it disables the pin
15
+ * toggle on every UNPINNED row while leaving every PINNED row free to unpin,
16
+ * because the cap is on how many are held, never on which one a viewer chooses
17
+ * to release.
18
+ */
19
+ import { SizableText, XStack, YStack, styled, useControllableState } from '@hanzo/gui';
20
+ import { Pin, PinOff } from '@hanzogui/lucide-icons-2';
21
+ import { ink } from './ink.js';
22
+ import { slot, tip } from './slot.js';
23
+ import { touch } from './gesture.js';
24
+ const ICON = 14;
25
+ const BUTTON = 28;
26
+ const RowFrame = styled(XStack, {
27
+ name: 'PinListRow',
28
+ items: 'center',
29
+ gap: '$3',
30
+ px: '$3',
31
+ py: '$2.5',
32
+ rounded: '$3',
33
+ borderWidth: 1,
34
+ borderColor: 'transparent',
35
+ hoverStyle: { bg: '$hover' },
36
+ variants: {
37
+ pinned: {
38
+ true: { bg: '$edge' },
39
+ false: {},
40
+ },
41
+ },
42
+ defaultVariants: { pinned: false },
43
+ });
44
+ const PinButton = styled(XStack, {
45
+ name: 'PinListPin',
46
+ items: 'center',
47
+ justify: 'center',
48
+ width: BUTTON,
49
+ height: BUTTON,
50
+ rounded: '$2',
51
+ cursor: 'pointer',
52
+ hoverStyle: { bg: '$background' },
53
+ });
54
+ /** A list of rows a viewer can pin to the top. */
55
+ export function PinList({ items, value, defaultValue, onValueChange, pinnedFirst = true, max, ...props }) {
56
+ const [pinned, setPinned] = useControllableState({
57
+ prop: value,
58
+ defaultProp: defaultValue ?? [],
59
+ onChange: onValueChange,
60
+ });
61
+ const current = pinned ?? [];
62
+ const atMax = max != null && current.length >= max;
63
+ const toggle = (id) => {
64
+ const next = current.includes(id)
65
+ ? current.filter((existing) => existing !== id)
66
+ : [...current, id];
67
+ setPinned(next);
68
+ };
69
+ const ordered = pinnedFirst
70
+ ? [...items.filter((item) => current.includes(item.id)), ...items.filter((item) => !current.includes(item.id))]
71
+ : items;
72
+ return (_jsx(YStack, { ...slot('pin-list'), gap: "$1", render: "ul", ...props, children: ordered.map((item) => {
73
+ const isPinned = current.includes(item.id);
74
+ const pinDisabled = Boolean(item.disabled) || (!isPinned && atMax);
75
+ return (_jsxs(RowFrame, { ...slot('pin-list-row'), "data-pinned": isPinned, pinned: isPinned, render: "li", children: [item.icon, _jsxs(YStack, { flex: 1, gap: "$0.5", children: [ink(item.label, SizableText, { fontSize: '$3', fontWeight: '500', color: '$color' }), item.description
76
+ ? ink(item.description, SizableText, { fontSize: '$2', color: '$quiet' })
77
+ : null] }), _jsx(PinButton, { ...slot('pin-list-toggle'), ...tip(isPinned ? `Unpin ${item.label}` : `Pin ${item.label}`), ...touch(BUTTON, 44), render: "button", ...{ type: 'button', disabled: pinDisabled }, "aria-pressed": isPinned, "aria-label": isPinned ? `Unpin ${item.label}` : `Pin ${item.label}`, opacity: pinDisabled ? 0.4 : 1, cursor: pinDisabled ? 'not-allowed' : 'pointer', onClick: () => !pinDisabled && toggle(item.id), children: isPinned ? _jsx(Pin, { size: ICON, fill: "currentColor" }) : _jsx(PinOff, { size: ICON }) })] }, item.id));
78
+ }) }));
79
+ }
80
+ //# sourceMappingURL=pin-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pin-list.js","sourceRoot":"","sources":["../../../src/backends/gui/pin-list.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PixelImage = PixelImage;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ /**
7
+ * PixelImage — a source image redrawn as flat pixelation blocks.
8
+ *
9
+ * Sampling one colour per block and filling that block flat is 2D Canvas work
10
+ * — draw the image once, read its pixels back, paint blocks over them — and no
11
+ * gui primitive performs it, so a raw `<canvas>` is mounted inside a gui frame
12
+ * (`YStack`) and everything around it (the frame, the slot marker, the layout
13
+ * props) is ordinary gui. Web-only: `isWeb` gates the canvas draw, and native
14
+ * or a server render gets the empty frame with nothing to choke on.
15
+ */
16
+ const gui_1 = require("@hanzo/gui");
17
+ const react_1 = require("react");
18
+ const slot_1 = require("./slot.cjs");
19
+ function PixelImage({ src, pixelSize = 10, alt, ...props }) {
20
+ const canvasRef = (0, react_1.useRef)(null);
21
+ const [loaded, setLoaded] = (0, react_1.useState)(false);
22
+ (0, react_1.useEffect)(() => {
23
+ if (!gui_1.isWeb)
24
+ return undefined;
25
+ const canvas = canvasRef.current;
26
+ if (!canvas)
27
+ return undefined;
28
+ const ctx = canvas.getContext('2d');
29
+ if (!ctx)
30
+ return undefined;
31
+ let cancelled = false;
32
+ setLoaded(false);
33
+ const img = new Image();
34
+ img.crossOrigin = 'anonymous';
35
+ img.onload = () => {
36
+ if (cancelled)
37
+ return;
38
+ canvas.width = img.width;
39
+ canvas.height = img.height;
40
+ ctx.imageSmoothingEnabled = false;
41
+ ctx.drawImage(img, 0, 0);
42
+ const { data } = ctx.getImageData(0, 0, canvas.width, canvas.height);
43
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
44
+ for (let y = 0; y < canvas.height; y += pixelSize) {
45
+ for (let x = 0; x < canvas.width; x += pixelSize) {
46
+ const i = (y * canvas.width + x) * 4;
47
+ const r = data[i];
48
+ const g = data[i + 1];
49
+ const b = data[i + 2];
50
+ const a = data[i + 3] / 255;
51
+ ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
52
+ ctx.fillRect(x, y, pixelSize, pixelSize);
53
+ }
54
+ }
55
+ setLoaded(true);
56
+ };
57
+ img.src = src;
58
+ return () => {
59
+ cancelled = true;
60
+ };
61
+ }, [src, pixelSize]);
62
+ return ((0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('pixel-image'), maxW: "100%", "data-loaded": loaded, ...props, children: gui_1.isWeb && ((0, jsx_runtime_1.jsx)("canvas", { ref: canvasRef, ...(0, slot_1.slot)('pixel-image-canvas'), "data-pixel-size": pixelSize, "aria-label": alt, role: alt ? 'img' : undefined, style: { display: 'block', maxWidth: '100%' } })) }));
63
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * PixelImage — a source image redrawn as flat pixelation blocks.
3
+ *
4
+ * Sampling one colour per block and filling that block flat is 2D Canvas work
5
+ * — draw the image once, read its pixels back, paint blocks over them — and no
6
+ * gui primitive performs it, so a raw `<canvas>` is mounted inside a gui frame
7
+ * (`YStack`) and everything around it (the frame, the slot marker, the layout
8
+ * props) is ordinary gui. Web-only: `isWeb` gates the canvas draw, and native
9
+ * or a server render gets the empty frame with nothing to choke on.
10
+ */
11
+ import { type YStackProps } from '@hanzo/gui';
12
+ export interface PixelImageProps extends Omit<YStackProps, 'children'> {
13
+ /** The image to pixelate. */
14
+ src: string;
15
+ /** Edge length, in source pixels, of one pixelation block. */
16
+ pixelSize?: number;
17
+ /** Accessible label for the pictured image. */
18
+ alt?: string;
19
+ }
20
+ export declare function PixelImage({ src, pixelSize, alt, ...props }: PixelImageProps): import("react").JSX.Element;
21
+ //# sourceMappingURL=pixel-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixel-image.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/pixel-image.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAI5D,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC;IACpE,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,wBAAgB,UAAU,CAAC,EAAE,GAAG,EAAE,SAAc,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,+BA6DjF"}
@@ -0,0 +1,61 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * PixelImage — a source image redrawn as flat pixelation blocks.
5
+ *
6
+ * Sampling one colour per block and filling that block flat is 2D Canvas work
7
+ * — draw the image once, read its pixels back, paint blocks over them — and no
8
+ * gui primitive performs it, so a raw `<canvas>` is mounted inside a gui frame
9
+ * (`YStack`) and everything around it (the frame, the slot marker, the layout
10
+ * props) is ordinary gui. Web-only: `isWeb` gates the canvas draw, and native
11
+ * or a server render gets the empty frame with nothing to choke on.
12
+ */
13
+ import { YStack, isWeb } from '@hanzo/gui';
14
+ import { useEffect, useRef, useState } from 'react';
15
+ import { slot } from './slot.js';
16
+ export function PixelImage({ src, pixelSize = 10, alt, ...props }) {
17
+ const canvasRef = useRef(null);
18
+ const [loaded, setLoaded] = useState(false);
19
+ useEffect(() => {
20
+ if (!isWeb)
21
+ return undefined;
22
+ const canvas = canvasRef.current;
23
+ if (!canvas)
24
+ return undefined;
25
+ const ctx = canvas.getContext('2d');
26
+ if (!ctx)
27
+ return undefined;
28
+ let cancelled = false;
29
+ setLoaded(false);
30
+ const img = new Image();
31
+ img.crossOrigin = 'anonymous';
32
+ img.onload = () => {
33
+ if (cancelled)
34
+ return;
35
+ canvas.width = img.width;
36
+ canvas.height = img.height;
37
+ ctx.imageSmoothingEnabled = false;
38
+ ctx.drawImage(img, 0, 0);
39
+ const { data } = ctx.getImageData(0, 0, canvas.width, canvas.height);
40
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
41
+ for (let y = 0; y < canvas.height; y += pixelSize) {
42
+ for (let x = 0; x < canvas.width; x += pixelSize) {
43
+ const i = (y * canvas.width + x) * 4;
44
+ const r = data[i];
45
+ const g = data[i + 1];
46
+ const b = data[i + 2];
47
+ const a = data[i + 3] / 255;
48
+ ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`;
49
+ ctx.fillRect(x, y, pixelSize, pixelSize);
50
+ }
51
+ }
52
+ setLoaded(true);
53
+ };
54
+ img.src = src;
55
+ return () => {
56
+ cancelled = true;
57
+ };
58
+ }, [src, pixelSize]);
59
+ return (_jsx(YStack, { ...slot('pixel-image'), maxW: "100%", "data-loaded": loaded, ...props, children: isWeb && (_jsx("canvas", { ref: canvasRef, ...slot('pixel-image-canvas'), "data-pixel-size": pixelSize, "aria-label": alt, role: alt ? 'img' : undefined, style: { display: 'block', maxWidth: '100%' } })) }));
60
+ }
61
+ //# sourceMappingURL=pixel-image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixel-image.js","sourceRoot":"","sources":["../../../src/backends/gui/pixel-image.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PositionsList = PositionsList;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ /**
7
+ * PositionsList — a list of open trading positions, each row showing its
8
+ * ticker, share count, average and current price, total value and P&L, with
9
+ * the P&L sign colouring the row's trend icon. Clicking a row is optional; it
10
+ * only becomes a button when `onPositionClick` is given.
11
+ *
12
+ * The two price stats and the two value stats sit in `@hanzo/ui`'s own `Grid`
13
+ * — a real CSS grid, so both pairs of columns stay even regardless of how wide
14
+ * any one value is.
15
+ */
16
+ const gui_1 = require("@hanzo/gui");
17
+ const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
18
+ const grid_1 = require("../../grid.cjs");
19
+ const ink_1 = require("./ink.cjs");
20
+ const slot_1 = require("./slot.cjs");
21
+ /** The ticker half of an exchange-qualified symbol, e.g. `NASDAQ:AAPL` -> `AAPL`. */
22
+ const ticker = (symbol) => symbol.split(':')[1] || symbol;
23
+ const RowFrame = (0, gui_1.styled)(gui_1.YStack, {
24
+ name: 'PositionsListRow',
25
+ bg: '$hover',
26
+ rounded: '$4',
27
+ p: '$3',
28
+ gap: '$2',
29
+ variants: {
30
+ clickable: { true: { cursor: 'pointer', hoverStyle: { bg: '$edge' } } },
31
+ },
32
+ });
33
+ function PositionRow({ position, onPositionClick, }) {
34
+ const pl = (position.currentPrice - position.avgPrice) * position.shares;
35
+ const plPercent = ((position.currentPrice - position.avgPrice) / position.avgPrice) * 100;
36
+ const totalValue = position.currentPrice * position.shares;
37
+ const gain = pl >= 0;
38
+ return ((0, jsx_runtime_1.jsxs)(RowFrame, { ...(0, slot_1.slot)('positions-list-row'), "data-trend": gain ? 'up' : 'down', clickable: !!onPositionClick, onPress: onPositionClick ? () => onPositionClick(position) : undefined, children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { justify: "space-between", items: "center", children: [(0, ink_1.ink)(ticker(position.symbol), gui_1.SizableText, { fontWeight: '600' }), (0, jsx_runtime_1.jsxs)(gui_1.XStack, { items: "center", gap: "$1", children: [gain ? (0, jsx_runtime_1.jsx)(lucide_icons_2_1.TrendingUp, { size: 14, color: "$green9" }) : (0, jsx_runtime_1.jsx)(lucide_icons_2_1.TrendingDown, { size: 14, color: "$red9" }), (0, ink_1.ink)(`${gain ? '+' : ''}${plPercent.toFixed(2)}%`, gui_1.SizableText, {
39
+ size: '$1',
40
+ fontWeight: '600',
41
+ color: gain ? '$green9' : '$red9',
42
+ })] })] }), (0, jsx_runtime_1.jsxs)(grid_1.Grid, { columns: 2, gap: "$2", children: [(0, jsx_runtime_1.jsx)(grid_1.Cell, { children: (0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$1", children: [(0, ink_1.ink)('Shares', gui_1.SizableText, { size: '$1', color: '$quiet' }), (0, ink_1.ink)(String(position.shares), gui_1.SizableText, { size: '$1', fontWeight: '500' })] }) }), (0, jsx_runtime_1.jsx)(grid_1.Cell, { children: (0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$1", children: [(0, ink_1.ink)('Avg Price', gui_1.SizableText, { size: '$1', color: '$quiet' }), (0, ink_1.ink)(`$${position.avgPrice.toFixed(2)}`, gui_1.SizableText, {
43
+ size: '$1',
44
+ fontWeight: '500',
45
+ })] }) })] }), (0, jsx_runtime_1.jsxs)(grid_1.Grid, { columns: 2, gap: "$2", children: [(0, jsx_runtime_1.jsx)(grid_1.Cell, { children: (0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$1", children: [(0, ink_1.ink)('Current Price', gui_1.SizableText, { size: '$1', color: '$quiet' }), (0, ink_1.ink)(`$${position.currentPrice.toFixed(2)}`, gui_1.SizableText, {
46
+ size: '$1',
47
+ fontWeight: '500',
48
+ })] }) }), (0, jsx_runtime_1.jsx)(grid_1.Cell, { children: (0, jsx_runtime_1.jsxs)(gui_1.YStack, { gap: "$1", children: [(0, ink_1.ink)('Total Value', gui_1.SizableText, { size: '$1', color: '$quiet' }), (0, ink_1.ink)(`$${totalValue.toFixed(2)}`, gui_1.SizableText, { size: '$1', fontWeight: '500' })] }) })] }), (0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('positions-list-pnl'), justify: "space-between", items: "center", children: [(0, ink_1.ink)('P&L', gui_1.SizableText, { size: '$1', color: '$quiet' }), (0, ink_1.ink)(`${gain ? '+' : ''}$${pl.toFixed(2)}`, gui_1.SizableText, {
49
+ size: '$1',
50
+ fontWeight: '600',
51
+ color: gain ? '$green9' : '$red9',
52
+ })] })] }));
53
+ }
54
+ function PositionsList({ positions = [], onPositionClick }) {
55
+ if (positions.length === 0) {
56
+ return ((0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('positions-list-empty'), items: "center", py: "$8", children: (0, ink_1.ink)('No open positions', gui_1.SizableText, { size: '$2', color: '$quiet' }) }));
57
+ }
58
+ return ((0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('positions-list'), gap: "$2", p: "$4", children: positions.map((position) => ((0, jsx_runtime_1.jsx)(PositionRow, { position: position, onPositionClick: onPositionClick }, position.symbol))) }));
59
+ }
60
+ exports.default = PositionsList;
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+ export interface Position {
3
+ symbol: string;
4
+ shares: number;
5
+ avgPrice: number;
6
+ currentPrice: number;
7
+ }
8
+ export interface PositionsListProps {
9
+ positions: Position[];
10
+ onPositionClick?: (position: Position) => void;
11
+ }
12
+ export declare function PositionsList({ positions, onPositionClick }: Partial<PositionsListProps>): React.JSX.Element;
13
+ export default PositionsList;
14
+ //# sourceMappingURL=positions-list.d.ts.map