@muten/shadcn 0.0.5 → 0.1.0

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 (213) hide show
  1. package/AGENTS.md +61 -6
  2. package/README.md +57 -4
  3. package/globals.css +30 -2
  4. package/kit.css +2763 -0
  5. package/motion.css +79 -0
  6. package/nova.css +1387 -0
  7. package/package.json +10 -2
  8. package/registry/accordion.muten +11 -10
  9. package/registry/agenda.js +35 -0
  10. package/registry/agenda.muten +10 -0
  11. package/registry/alert-dialog.muten +9 -12
  12. package/registry/alert.muten +8 -8
  13. package/registry/app-shell.js +9 -0
  14. package/registry/app-shell.muten +12 -0
  15. package/registry/attachment.muten +13 -9
  16. package/registry/avatar.muten +24 -5
  17. package/registry/badge.muten +23 -8
  18. package/registry/band.muten +16 -0
  19. package/registry/bar-chart.muten +7 -0
  20. package/registry/bell.muten +3 -0
  21. package/registry/bento.muten +6 -9
  22. package/registry/booking.js +21 -0
  23. package/registry/booking.muten +13 -0
  24. package/registry/breadcrumb.muten +9 -7
  25. package/registry/button-group.muten +13 -4
  26. package/registry/button.muten +21 -8
  27. package/registry/calendar.js +28 -93
  28. package/registry/calendar.muten +9 -8
  29. package/registry/canvas-viewport.js +12 -5
  30. package/registry/canvas-viewport.muten +9 -9
  31. package/registry/card-field.muten +4 -0
  32. package/registry/card.muten +12 -8
  33. package/registry/carousel.js +5 -36
  34. package/registry/carousel.muten +12 -5
  35. package/registry/chatbot.muten +9 -0
  36. package/registry/checklist.muten +6 -0
  37. package/registry/choice-list.muten +16 -0
  38. package/registry/code.js +14 -12
  39. package/registry/code.muten +6 -7
  40. package/registry/collapsible.muten +14 -10
  41. package/registry/color-picker.js +460 -41
  42. package/registry/color-picker.muten +7 -6
  43. package/registry/combobox.js +5 -0
  44. package/registry/combobox.muten +6 -23
  45. package/registry/command-palette.muten +8 -12
  46. package/registry/command.js +32 -0
  47. package/registry/command.muten +32 -11
  48. package/registry/context-menu.muten +9 -8
  49. package/registry/count-up.muten +5 -10
  50. package/registry/date-field.js +5 -0
  51. package/registry/date-field.muten +7 -0
  52. package/registry/device-frame.muten +8 -0
  53. package/registry/dialog.muten +6 -12
  54. package/registry/dirty-bar.js +19 -0
  55. package/registry/dirty-bar.muten +13 -0
  56. package/registry/drawer.muten +6 -11
  57. package/registry/dropdown-menu.muten +37 -13
  58. package/registry/empty.muten +11 -7
  59. package/registry/feature-grid.muten +10 -12
  60. package/registry/feature-rows.muten +12 -8
  61. package/registry/field-behavior.js +33 -0
  62. package/registry/field-behavior.muten +9 -0
  63. package/registry/field.muten +26 -7
  64. package/registry/file-input.js +36 -21
  65. package/registry/file-input.muten +8 -7
  66. package/registry/fixed-card.muten +25 -0
  67. package/registry/folder-picker.js +13 -15
  68. package/registry/folder-picker.muten +5 -8
  69. package/registry/gradient-blinds.muten +6 -13
  70. package/registry/hover-card.muten +7 -9
  71. package/registry/image-upload.js +5 -0
  72. package/registry/image-upload.muten +8 -0
  73. package/registry/indicator.muten +5 -0
  74. package/registry/input-group.muten +27 -4
  75. package/registry/input-otp.js +8 -35
  76. package/registry/input-otp.muten +6 -6
  77. package/registry/input.muten +8 -7
  78. package/registry/inspector.muten +13 -15
  79. package/registry/island.js +7 -0
  80. package/registry/island.muten +5 -0
  81. package/registry/item.muten +20 -7
  82. package/registry/kbd.muten +3 -3
  83. package/registry/kit/board.js +300 -0
  84. package/registry/kit/collections.js +148 -0
  85. package/registry/kit/core.js +989 -0
  86. package/registry/kit/dates.js +106 -0
  87. package/registry/kit/menus.js +90 -0
  88. package/registry/kit/overlays.js +114 -0
  89. package/registry/kit/paint.js +211 -0
  90. package/registry/kit/qrcode.js +2291 -0
  91. package/registry/kit/structure.js +393 -0
  92. package/registry/kit/table.js +198 -0
  93. package/registry/kit/values.js +179 -0
  94. package/registry/kit-layer.js +2 -0
  95. package/registry/kit-layer.muten +5 -0
  96. package/registry/kit-skeleton.js +24 -0
  97. package/registry/kit-skeleton.muten +16 -0
  98. package/registry/kit-widget.js +79 -0
  99. package/registry/kit-widget.muten +4 -0
  100. package/registry/link-btn.muten +9 -7
  101. package/registry/live-stack.js +29 -0
  102. package/registry/live-stack.muten +7 -0
  103. package/registry/logo-cloud.muten +6 -11
  104. package/registry/member-list.muten +6 -0
  105. package/registry/menubar.muten +10 -14
  106. package/registry/message-scroller.js +12 -0
  107. package/registry/message-scroller.muten +8 -4
  108. package/registry/message.muten +27 -10
  109. package/registry/messaging.muten +11 -0
  110. package/registry/modal-behavior.js +56 -0
  111. package/registry/modal-behavior.muten +4 -0
  112. package/registry/modal.muten +29 -0
  113. package/registry/money-field.js +5 -0
  114. package/registry/money-field.muten +7 -0
  115. package/registry/nav-button.muten +14 -0
  116. package/registry/navigation-menu.muten +16 -14
  117. package/registry/navpill.muten +15 -9
  118. package/registry/new-appointment.js +8 -0
  119. package/registry/new-appointment.muten +10 -0
  120. package/registry/number-field.js +34 -24
  121. package/registry/number-field.muten +8 -6
  122. package/registry/order-board.js +6 -0
  123. package/registry/order-board.muten +21 -0
  124. package/registry/overlay-behavior.js +13 -0
  125. package/registry/overlay-behavior.muten +4 -0
  126. package/registry/pagination-nav.js +6 -0
  127. package/registry/pagination-nav.muten +8 -0
  128. package/registry/pagination.muten +12 -9
  129. package/registry/password-field.muten +3 -0
  130. package/registry/permission-matrix.muten +6 -0
  131. package/registry/phone-field.js +5 -0
  132. package/registry/phone-field.muten +7 -0
  133. package/registry/phone-shell.js +7 -0
  134. package/registry/phone-shell.muten +9 -0
  135. package/registry/pill.muten +6 -5
  136. package/registry/plans.muten +4 -0
  137. package/registry/popover.muten +16 -9
  138. package/registry/pricing.muten +21 -21
  139. package/registry/progress.muten +5 -5
  140. package/registry/queue.muten +3 -0
  141. package/registry/radio-group.muten +16 -8
  142. package/registry/range-slider.js +9 -24
  143. package/registry/range-slider.muten +4 -5
  144. package/registry/resizable.js +34 -27
  145. package/registry/resizable.muten +16 -5
  146. package/registry/roving-behavior.js +16 -0
  147. package/registry/roving-behavior.muten +3 -0
  148. package/registry/row-menu.js +5 -0
  149. package/registry/row-menu.muten +5 -0
  150. package/registry/save-button.muten +11 -0
  151. package/registry/scale-slider.js +7 -0
  152. package/registry/scale-slider.muten +9 -0
  153. package/registry/scroll-area.muten +8 -4
  154. package/registry/segmented-control.muten +8 -8
  155. package/registry/separator.muten +3 -3
  156. package/registry/share-button.js +7 -0
  157. package/registry/share-button.muten +10 -0
  158. package/registry/sheet.muten +6 -10
  159. package/registry/sidebar.muten +23 -15
  160. package/registry/skeleton.muten +6 -4
  161. package/registry/slider.js +73 -27
  162. package/registry/slider.muten +6 -6
  163. package/registry/sortable-behavior.js +43 -0
  164. package/registry/sortable-behavior.muten +2 -0
  165. package/registry/sortable-list.js +10 -26
  166. package/registry/sortable-list.muten +6 -7
  167. package/registry/sortable.muten +15 -0
  168. package/registry/spark.js +14 -0
  169. package/registry/spark.muten +3 -0
  170. package/registry/spinner.muten +4 -3
  171. package/registry/split-button.muten +12 -10
  172. package/registry/stamp-card.muten +7 -0
  173. package/registry/stat-band.muten +6 -9
  174. package/registry/stat.muten +23 -0
  175. package/registry/status-bar.muten +7 -6
  176. package/registry/stepper.muten +17 -14
  177. package/registry/store-qr.js +5 -0
  178. package/registry/store-qr.muten +5 -0
  179. package/registry/swatch.muten +8 -8
  180. package/registry/switch.muten +14 -6
  181. package/registry/table-view.muten +10 -0
  182. package/registry/tabs-behavior.js +27 -0
  183. package/registry/tabs-behavior.muten +3 -0
  184. package/registry/tabs.muten +19 -10
  185. package/registry/tag-input.js +4 -27
  186. package/registry/tag-input.muten +6 -6
  187. package/registry/text.muten +7 -0
  188. package/registry/time-field.js +5 -0
  189. package/registry/time-field.muten +6 -0
  190. package/registry/timeline.muten +14 -14
  191. package/registry/toaster.js +34 -22
  192. package/registry/toaster.muten +10 -8
  193. package/registry/toggle-group.muten +11 -6
  194. package/registry/toggle.muten +8 -5
  195. package/registry/toolbar.muten +11 -6
  196. package/registry/tooltip.muten +6 -9
  197. package/registry/tree-view.js +27 -7
  198. package/registry/tree-view.muten +8 -13
  199. package/registry/vector-field.muten +9 -8
  200. package/registry/virtual-list.js +5 -0
  201. package/registry/virtual-list.muten +6 -0
  202. package/registry/weekly-hours.muten +4 -0
  203. package/registry/wordline.muten +6 -0
  204. package/registry/zoom-control.muten +9 -9
  205. package/registry.json +868 -424
  206. package/themes/bloom.css +53 -0
  207. package/themes/editorial.css +65 -0
  208. package/themes/noir.css +54 -0
  209. package/registry/chart.js +0 -34
  210. package/registry/chart.muten +0 -7
  211. package/registry/checkbox.muten +0 -8
  212. package/registry/context-menu.js +0 -34
  213. package/registry/select.muten +0 -21
@@ -0,0 +1,53 @@
1
+ /* @muten/shadcn/themes/bloom.css — "Bloom": soft, friendly, rounded. A rounded display (Quicksand) + Inter, gentle
2
+ pastel tints (lavender paper, violet accent), large radius, airy soft shadows. Import AFTER globals.css.
3
+ @import "@muten/shadcn/globals.css"; @import "@muten/shadcn/themes/bloom.css"; */
4
+
5
+ @import url("https://fonts.googleapis.com/css2?family=Quicksand:wght@500;600;700&family=Inter:wght@400;500;600&display=swap");
6
+ @theme {
7
+ --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
8
+ --font-serif: "Quicksand", ui-rounded, ui-sans-serif, system-ui, sans-serif; /* `font-serif` on headings → rounded display */
9
+ }
10
+
11
+ :root {
12
+ --radius: 1rem; /* pillowy */
13
+ --background: oklch(0.99 0.008 310);
14
+ --foreground: oklch(0.30 0.04 300);
15
+ --card: oklch(1 0.004 310);
16
+ --card-foreground: oklch(0.30 0.04 300);
17
+ --popover: oklch(1 0.004 310);
18
+ --popover-foreground: oklch(0.30 0.04 300);
19
+ --primary: oklch(0.62 0.19 300); /* soft violet */
20
+ --primary-foreground: oklch(0.99 0.008 310);
21
+ --secondary: oklch(0.95 0.03 310);
22
+ --secondary-foreground: oklch(0.40 0.06 300);
23
+ --muted: oklch(0.955 0.022 315);
24
+ --muted-foreground: oklch(0.55 0.05 300);
25
+ --accent: oklch(0.93 0.04 340); /* rose tint */
26
+ --accent-foreground: oklch(0.40 0.08 340);
27
+ --destructive: oklch(0.60 0.20 20);
28
+ --border: oklch(0.91 0.025 315);
29
+ --input: oklch(0.91 0.025 315);
30
+ --ring: oklch(0.62 0.19 300);
31
+ }
32
+ /* bridge both selectors: muten sets `data-theme="dark"`, shadcn keys off the `.dark` class (globals.css does the same). */
33
+ .dark, [data-theme="dark"] {
34
+ --background: oklch(0.21 0.03 300);
35
+ --foreground: oklch(0.95 0.02 315);
36
+ --card: oklch(0.25 0.035 300);
37
+ --card-foreground: oklch(0.95 0.02 315);
38
+ --popover: oklch(0.25 0.035 300);
39
+ --popover-foreground: oklch(0.95 0.02 315);
40
+ --primary: oklch(0.72 0.17 300);
41
+ --primary-foreground: oklch(0.20 0.03 300);
42
+ --secondary: oklch(0.30 0.035 300);
43
+ --secondary-foreground: oklch(0.95 0.02 315);
44
+ --muted: oklch(0.30 0.035 300);
45
+ --muted-foreground: oklch(0.75 0.03 310);
46
+ --accent: oklch(0.34 0.05 340);
47
+ --accent-foreground: oklch(0.95 0.02 315);
48
+ --destructive: oklch(0.68 0.18 20);
49
+ --border: oklch(0.33 0.035 300);
50
+ --input: oklch(0.35 0.035 300);
51
+ --ring: oklch(0.72 0.17 300);
52
+ }
53
+ @theme { --shadow-soft: 0 2px 8px oklch(0.5 0.1 300 / 0.06), 0 16px 40px -16px oklch(0.5 0.15 300 / 0.20); }
@@ -0,0 +1,65 @@
1
+ /* @muten/shadcn/themes/editorial.css — "Editorial": a warm, quiet, luxury look. A display serif (Fraunces) + a
2
+ clean sans (Inter), sand/stone neutrals with a terracotta accent, generous radius, soft warm shadows.
3
+ Import AFTER globals.css: @import "@muten/shadcn/globals.css"; @import "@muten/shadcn/themes/editorial.css";
4
+ Works in light (default) and dark. `font-serif` now renders Fraunces, so headings feel editorial for free. */
5
+
6
+ @import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=Inter:wght@400;500;600&display=swap");
7
+
8
+ /* Tailwind picks these up: `font-sans` → Inter, `font-serif` → Fraunces (use it on headings). */
9
+ @theme {
10
+ --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
11
+ --font-serif: "Fraunces", ui-serif, Georgia, "Times New Roman", serif;
12
+ }
13
+
14
+ /* LIGHT — warm sand paper, deep-ink text, terracotta as the single accent (primary = buttons + `text-primary`). */
15
+ :root {
16
+ --radius: 0.625rem;
17
+ --background: oklch(0.985 0.007 83);
18
+ --foreground: oklch(0.24 0.017 55);
19
+ --card: oklch(0.997 0.004 83);
20
+ --card-foreground: oklch(0.24 0.017 55);
21
+ --popover: oklch(0.997 0.004 83);
22
+ --popover-foreground: oklch(0.24 0.017 55);
23
+ --primary: oklch(0.62 0.115 46); /* terracotta */
24
+ --primary-foreground: oklch(0.99 0.006 83);
25
+ --secondary: oklch(0.955 0.011 80);
26
+ --secondary-foreground: oklch(0.30 0.02 50);
27
+ --muted: oklch(0.955 0.011 80);
28
+ --muted-foreground: oklch(0.52 0.018 60);
29
+ --accent: oklch(0.94 0.016 74); /* subtle warm hover bg (stays neutral, per shadcn) */
30
+ --accent-foreground: oklch(0.30 0.02 50);
31
+ --destructive: oklch(0.577 0.245 27.325);
32
+ --border: oklch(0.905 0.012 76);
33
+ --input: oklch(0.905 0.012 76);
34
+ --ring: oklch(0.62 0.115 46);
35
+ }
36
+
37
+ /* DARK — warm near-black, cream text, terracotta glows. */
38
+ /* bridge both selectors: muten sets `data-theme="dark"`, shadcn keys off the `.dark` class (globals.css does the same). */
39
+ .dark, [data-theme="dark"] {
40
+ --background: oklch(0.195 0.012 58);
41
+ --foreground: oklch(0.955 0.008 83);
42
+ --card: oklch(0.235 0.014 58);
43
+ --card-foreground: oklch(0.955 0.008 83);
44
+ --popover: oklch(0.235 0.014 58);
45
+ --popover-foreground: oklch(0.955 0.008 83);
46
+ --primary: oklch(0.70 0.128 47); /* terracotta, brighter for dark */
47
+ --primary-foreground: oklch(0.20 0.012 58);
48
+ --secondary: oklch(0.28 0.014 58);
49
+ --secondary-foreground: oklch(0.955 0.008 83);
50
+ --muted: oklch(0.28 0.014 58);
51
+ --muted-foreground: oklch(0.72 0.013 72);
52
+ --accent: oklch(0.30 0.015 58);
53
+ --accent-foreground: oklch(0.955 0.008 83);
54
+ --destructive: oklch(0.65 0.19 25);
55
+ --border: oklch(0.31 0.014 58);
56
+ --input: oklch(0.33 0.014 58);
57
+ --ring: oklch(0.70 0.128 47);
58
+ }
59
+
60
+ /* Editorial polish that the token vars alone can't express. */
61
+ body { font-feature-settings: "liga" 1, "calt" 1; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
62
+ /* Fraunces headings: a touch of optical weight + tight tracking reads as "designed", not default-serif. */
63
+ h1, h2, h3, .font-serif { letter-spacing: -0.01em; }
64
+ /* soft, warm-tinted elevation (shadcn ships flat) — reach for it on cards/hero via `shadow-soft`. */
65
+ @theme { --shadow-soft: 0 1px 2px oklch(0.4 0.03 60 / 0.04), 0 8px 24px -12px oklch(0.4 0.05 60 / 0.14); }
@@ -0,0 +1,54 @@
1
+ /* @muten/shadcn/themes/noir.css — "Noir": crisp, high-contrast, mono-minimal. A grotesk display (Space Grotesk) +
2
+ Inter, near-monochrome cool neutrals, sharp corners, one stark ink accent. Import AFTER globals.css.
3
+ @import "@muten/shadcn/globals.css"; @import "@muten/shadcn/themes/noir.css"; */
4
+
5
+ @import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600&display=swap");
6
+ @theme {
7
+ --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
8
+ --font-serif: "Space Grotesk", ui-sans-serif, system-ui, sans-serif; /* `font-serif` on headings → grotesk display */
9
+ }
10
+
11
+ :root {
12
+ --radius: 0.25rem; /* sharp */
13
+ --background: oklch(0.995 0 0);
14
+ --foreground: oklch(0.16 0.004 260);
15
+ --card: oklch(1 0 0);
16
+ --card-foreground: oklch(0.16 0.004 260);
17
+ --popover: oklch(1 0 0);
18
+ --popover-foreground: oklch(0.16 0.004 260);
19
+ --primary: oklch(0.16 0.004 260); /* ink */
20
+ --primary-foreground: oklch(0.99 0 0);
21
+ --secondary: oklch(0.965 0.002 260);
22
+ --secondary-foreground: oklch(0.16 0.004 260);
23
+ --muted: oklch(0.965 0.002 260);
24
+ --muted-foreground: oklch(0.48 0.006 260);
25
+ --accent: oklch(0.95 0.003 260);
26
+ --accent-foreground: oklch(0.16 0.004 260);
27
+ --destructive: oklch(0.577 0.245 27.325);
28
+ --border: oklch(0.90 0.004 260);
29
+ --input: oklch(0.90 0.004 260);
30
+ --ring: oklch(0.16 0.004 260);
31
+ }
32
+ /* bridge both selectors: muten sets `data-theme="dark"`, shadcn keys off the `.dark` class (globals.css does the same). */
33
+ .dark, [data-theme="dark"] {
34
+ --background: oklch(0.145 0.004 260);
35
+ --foreground: oklch(0.98 0 0);
36
+ --card: oklch(0.185 0.005 260);
37
+ --card-foreground: oklch(0.98 0 0);
38
+ --popover: oklch(0.185 0.005 260);
39
+ --popover-foreground: oklch(0.98 0 0);
40
+ --primary: oklch(0.98 0 0); /* stark white on black */
41
+ --primary-foreground: oklch(0.16 0.004 260);
42
+ --secondary: oklch(0.24 0.006 260);
43
+ --secondary-foreground: oklch(0.98 0 0);
44
+ --muted: oklch(0.24 0.006 260);
45
+ --muted-foreground: oklch(0.68 0.006 260);
46
+ --accent: oklch(0.26 0.006 260);
47
+ --accent-foreground: oklch(0.98 0 0);
48
+ --destructive: oklch(0.65 0.19 25);
49
+ --border: oklch(0.27 0.006 260);
50
+ --input: oklch(0.30 0.006 260);
51
+ --ring: oklch(0.98 0 0);
52
+ }
53
+ .font-serif, h1, h2, h3 { letter-spacing: -0.02em; }
54
+ @theme { --shadow-soft: 0 1px 2px oklch(0 0 0 / 0.05), 0 12px 28px -14px oklch(0 0 0 / 0.18); }
package/registry/chart.js DELETED
@@ -1,34 +0,0 @@
1
- // Chart host component (muten Custom). inputs: { data } (a list of { label, value }). Renders an SVG bar chart.
2
- // Edit this file for line/area/pie variants; this default is a clean bar chart driven by the page's data.
3
- export function mount(el, inputs, handlers) {
4
- const NS = 'http://www.w3.org/2000/svg';
5
- const render = (data) => {
6
- el.innerHTML = '';
7
- const items = Array.isArray(data) ? data : [];
8
- const W = 480, H = 200, pad = 24, gap = 10;
9
- const max = Math.max(1, ...items.map((d) => Number(d.value) || 0));
10
- const bw = items.length ? (W - pad * 2 - gap * (items.length - 1)) / items.length : 0;
11
- const svg = document.createElementNS(NS, 'svg');
12
- svg.setAttribute('viewBox', '0 0 ' + W + ' ' + H);
13
- svg.setAttribute('class', 'chart-svg');
14
- items.forEach((d, i) => {
15
- const v = Number(d.value) || 0;
16
- const bh = (v / max) * (H - pad * 2);
17
- const x = pad + i * (bw + gap);
18
- const y = H - pad - bh;
19
- const rect = document.createElementNS(NS, 'rect');
20
- rect.setAttribute('x', x); rect.setAttribute('y', y);
21
- rect.setAttribute('width', bw); rect.setAttribute('height', bh);
22
- rect.setAttribute('rx', 4); rect.setAttribute('class', 'chart-bar');
23
- svg.appendChild(rect);
24
- const t = document.createElementNS(NS, 'text');
25
- t.setAttribute('x', x + bw / 2); t.setAttribute('y', H - pad + 14);
26
- t.setAttribute('text-anchor', 'middle'); t.setAttribute('class', 'chart-label');
27
- t.textContent = d.label == null ? '' : String(d.label);
28
- svg.appendChild(t);
29
- });
30
- el.appendChild(svg);
31
- };
32
- render(inputs.data);
33
- return (n) => render(n.data);
34
- }
@@ -1,7 +0,0 @@
1
- # Chart - an SVG bar chart over a list of { label, value }. The PAGE owns the data:
2
- # entity Metric { label text value number } state { data = query data : list<Metric> } mock { data: [ … ] }
3
- # Chart(data: data)
4
- # shadcn-for-muten · Custom · host JS is src/components/Chart.js (edit it for line/area/pie variants).
5
- part Chart(data: list) {
6
- Custom Chart inputs(data: $data) class("chart")
7
- }
@@ -1,8 +0,0 @@
1
- # Checkbox - the PAGE owns the bool + the action that flips it (container/presentational):
2
- # state { agree = false : bool } action toggle mutates agree { agree.toggle() } Checkbox(checked: agree, onToggle: toggle)
3
- # shadcn-for-muten · part · no deps · the check always renders and scales/fades in via .checkbox-icon-on.
4
- part Checkbox(checked: bool, onToggle: action) {
5
- Button -> $onToggle aria(checked: $checked) class("checkbox", "checkbox-checked" when $checked) {
6
- Icon "lucide:check" class("checkbox-icon", "checkbox-icon-on" when $checked)
7
- }
8
- }
@@ -1,34 +0,0 @@
1
- // Context Menu host component (muten Custom). inputs: { label, items }. handlers: { select(label) }.
2
- // Right-clicking the area opens a menu of items at the cursor; choosing one emits its label.
3
- export function mount(el, inputs, handlers) {
4
- const area = document.createElement('div'); area.className = 'context-area';
5
- area.textContent = inputs.label == null ? 'Right-click here' : String(inputs.label);
6
- el.appendChild(area);
7
- const menu = document.createElement('div'); menu.className = 'context-menu';
8
- el.appendChild(menu);
9
-
10
- let open = false;
11
- const hide = () => { menu.classList.remove('context-menu-open'); open = false; };
12
- const build = (items) => {
13
- menu.innerHTML = '';
14
- (Array.isArray(items) ? items : []).forEach((it) => {
15
- const label = (it && typeof it === 'object') ? (it.label == null ? '' : String(it.label)) : String(it);
16
- const b = document.createElement('button'); b.type = 'button'; b.className = 'context-item'; b.textContent = label;
17
- b.addEventListener('click', () => { hide(); if (handlers.select) handlers.select(label); });
18
- menu.appendChild(b);
19
- });
20
- };
21
-
22
- area.addEventListener('contextmenu', (e) => {
23
- e.preventDefault();
24
- const r = el.getBoundingClientRect();
25
- menu.style.left = (e.clientX - r.left) + 'px';
26
- menu.style.top = (e.clientY - r.top) + 'px';
27
- menu.classList.add('context-menu-open');
28
- open = true;
29
- });
30
- document.addEventListener('click', () => { if (open) hide(); });
31
-
32
- build(inputs.items);
33
- return (n) => { area.textContent = n.label == null ? 'Right-click here' : String(n.label); build(n.items); };
34
- }
@@ -1,21 +0,0 @@
1
- # Select - a dropdown that shows the chosen value. The PAGE owns the value (text) + the open bool + actions:
2
- # state { fruit = "Apple" : text open = false : bool } action setFruit(v: text) mutates fruit { fruit.set(v) … }
3
- # Select(value: fruit, open: open, onToggle: t) { SelectItem(value: "Apple", current: fruit, label: "Apple", onSelect: setFruit) … }
4
- # Each SelectItem's action should set the value AND close. The backdrop catches outside clicks.
5
- # shadcn-for-muten · part · no deps · styles via the semantic .select* classes in globals.css.
6
- part Select(value: text, open: bool, onToggle: action) {
7
- Stack class("select-wrap") {
8
- Button -> $onToggle aria(expanded: $open) class("select-trigger") {
9
- Span "{$value}"
10
- Icon "lucide:chevrons-up-down" class("size-4 opacity-50")
11
- }
12
- when $open { Button -> $onToggle class("select-backdrop") }
13
- Stack class("select-content", "select-content-open" when $open) { slot }
14
- }
15
- }
16
- part SelectItem(value: text, current: text, label: text, onSelect: action) {
17
- Button -> $onSelect($value) class("select-item") {
18
- Span "{$label}"
19
- when $value == $current { Icon "lucide:check" class("size-4") }
20
- }
21
- }