@muten/shadcn 0.0.7 → 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.
- package/AGENTS.md +47 -0
- package/README.md +47 -0
- package/kit.css +2763 -0
- package/motion.css +31 -1
- package/nova.css +1387 -0
- package/package.json +6 -2
- package/registry/accordion.muten +11 -10
- package/registry/agenda.js +35 -0
- package/registry/agenda.muten +10 -0
- package/registry/alert-dialog.muten +9 -12
- package/registry/alert.muten +8 -8
- package/registry/app-shell.js +9 -0
- package/registry/app-shell.muten +12 -0
- package/registry/attachment.muten +13 -9
- package/registry/avatar.muten +24 -5
- package/registry/badge.muten +23 -8
- package/registry/band.muten +16 -0
- package/registry/bar-chart.muten +7 -0
- package/registry/bell.muten +3 -0
- package/registry/bento.muten +6 -9
- package/registry/booking.js +21 -0
- package/registry/booking.muten +13 -0
- package/registry/breadcrumb.muten +9 -7
- package/registry/button-group.muten +13 -4
- package/registry/button.muten +21 -8
- package/registry/calendar.js +28 -93
- package/registry/calendar.muten +9 -8
- package/registry/canvas-viewport.js +12 -5
- package/registry/canvas-viewport.muten +9 -9
- package/registry/card-field.muten +4 -0
- package/registry/card.muten +12 -8
- package/registry/carousel.js +5 -36
- package/registry/carousel.muten +12 -5
- package/registry/chatbot.muten +9 -0
- package/registry/checklist.muten +6 -0
- package/registry/choice-list.muten +16 -0
- package/registry/code.js +14 -12
- package/registry/code.muten +6 -7
- package/registry/collapsible.muten +14 -10
- package/registry/color-picker.js +460 -41
- package/registry/color-picker.muten +7 -6
- package/registry/combobox.js +5 -0
- package/registry/combobox.muten +6 -23
- package/registry/command-palette.muten +8 -12
- package/registry/command.js +32 -0
- package/registry/command.muten +32 -11
- package/registry/context-menu.muten +9 -8
- package/registry/count-up.muten +5 -10
- package/registry/date-field.js +5 -0
- package/registry/date-field.muten +7 -0
- package/registry/device-frame.muten +8 -0
- package/registry/dialog.muten +6 -12
- package/registry/dirty-bar.js +19 -0
- package/registry/dirty-bar.muten +13 -0
- package/registry/drawer.muten +6 -11
- package/registry/dropdown-menu.muten +37 -13
- package/registry/empty.muten +11 -7
- package/registry/feature-grid.muten +10 -12
- package/registry/feature-rows.muten +12 -8
- package/registry/field-behavior.js +33 -0
- package/registry/field-behavior.muten +9 -0
- package/registry/field.muten +26 -7
- package/registry/file-input.js +36 -21
- package/registry/file-input.muten +8 -7
- package/registry/fixed-card.muten +25 -0
- package/registry/folder-picker.js +13 -15
- package/registry/folder-picker.muten +5 -8
- package/registry/gradient-blinds.muten +6 -13
- package/registry/hover-card.muten +7 -9
- package/registry/image-upload.js +5 -0
- package/registry/image-upload.muten +8 -0
- package/registry/indicator.muten +5 -0
- package/registry/input-group.muten +27 -4
- package/registry/input-otp.js +8 -35
- package/registry/input-otp.muten +6 -6
- package/registry/input.muten +8 -7
- package/registry/inspector.muten +13 -15
- package/registry/island.js +7 -0
- package/registry/island.muten +5 -0
- package/registry/item.muten +20 -7
- package/registry/kbd.muten +3 -3
- package/registry/kit/board.js +300 -0
- package/registry/kit/collections.js +148 -0
- package/registry/kit/core.js +989 -0
- package/registry/kit/dates.js +106 -0
- package/registry/kit/menus.js +90 -0
- package/registry/kit/overlays.js +114 -0
- package/registry/kit/paint.js +211 -0
- package/registry/kit/qrcode.js +2291 -0
- package/registry/kit/structure.js +393 -0
- package/registry/kit/table.js +198 -0
- package/registry/kit/values.js +179 -0
- package/registry/kit-layer.js +2 -0
- package/registry/kit-layer.muten +5 -0
- package/registry/kit-skeleton.js +24 -0
- package/registry/kit-skeleton.muten +16 -0
- package/registry/kit-widget.js +79 -0
- package/registry/kit-widget.muten +4 -0
- package/registry/link-btn.muten +9 -7
- package/registry/live-stack.js +29 -0
- package/registry/live-stack.muten +7 -0
- package/registry/logo-cloud.muten +6 -11
- package/registry/member-list.muten +6 -0
- package/registry/menubar.muten +10 -14
- package/registry/message-scroller.js +12 -0
- package/registry/message-scroller.muten +8 -4
- package/registry/message.muten +27 -10
- package/registry/messaging.muten +11 -0
- package/registry/modal-behavior.js +56 -0
- package/registry/modal-behavior.muten +4 -0
- package/registry/modal.muten +29 -0
- package/registry/money-field.js +5 -0
- package/registry/money-field.muten +7 -0
- package/registry/nav-button.muten +14 -0
- package/registry/navigation-menu.muten +16 -14
- package/registry/navpill.muten +15 -9
- package/registry/new-appointment.js +8 -0
- package/registry/new-appointment.muten +10 -0
- package/registry/number-field.js +34 -24
- package/registry/number-field.muten +8 -6
- package/registry/order-board.js +6 -0
- package/registry/order-board.muten +21 -0
- package/registry/overlay-behavior.js +13 -0
- package/registry/overlay-behavior.muten +4 -0
- package/registry/pagination-nav.js +6 -0
- package/registry/pagination-nav.muten +8 -0
- package/registry/pagination.muten +12 -9
- package/registry/password-field.muten +3 -0
- package/registry/permission-matrix.muten +6 -0
- package/registry/phone-field.js +5 -0
- package/registry/phone-field.muten +7 -0
- package/registry/phone-shell.js +7 -0
- package/registry/phone-shell.muten +9 -0
- package/registry/pill.muten +6 -5
- package/registry/plans.muten +4 -0
- package/registry/popover.muten +16 -9
- package/registry/pricing.muten +21 -21
- package/registry/progress.muten +5 -5
- package/registry/queue.muten +3 -0
- package/registry/radio-group.muten +16 -8
- package/registry/range-slider.js +9 -24
- package/registry/range-slider.muten +4 -5
- package/registry/resizable.js +34 -27
- package/registry/resizable.muten +16 -5
- package/registry/roving-behavior.js +16 -0
- package/registry/roving-behavior.muten +3 -0
- package/registry/row-menu.js +5 -0
- package/registry/row-menu.muten +5 -0
- package/registry/save-button.muten +11 -0
- package/registry/scale-slider.js +7 -0
- package/registry/scale-slider.muten +9 -0
- package/registry/scroll-area.muten +8 -4
- package/registry/segmented-control.muten +8 -8
- package/registry/separator.muten +3 -3
- package/registry/share-button.js +7 -0
- package/registry/share-button.muten +10 -0
- package/registry/sheet.muten +6 -10
- package/registry/sidebar.muten +23 -15
- package/registry/skeleton.muten +6 -4
- package/registry/slider.js +73 -27
- package/registry/slider.muten +6 -6
- package/registry/sortable-behavior.js +43 -0
- package/registry/sortable-behavior.muten +2 -0
- package/registry/sortable-list.js +10 -26
- package/registry/sortable-list.muten +6 -7
- package/registry/sortable.muten +15 -0
- package/registry/spark.js +14 -0
- package/registry/spark.muten +3 -0
- package/registry/spinner.muten +4 -3
- package/registry/split-button.muten +12 -10
- package/registry/stamp-card.muten +7 -0
- package/registry/stat-band.muten +6 -9
- package/registry/stat.muten +23 -0
- package/registry/status-bar.muten +7 -6
- package/registry/stepper.muten +17 -14
- package/registry/store-qr.js +5 -0
- package/registry/store-qr.muten +5 -0
- package/registry/swatch.muten +8 -8
- package/registry/switch.muten +14 -6
- package/registry/table-view.muten +10 -0
- package/registry/tabs-behavior.js +27 -0
- package/registry/tabs-behavior.muten +3 -0
- package/registry/tabs.muten +19 -10
- package/registry/tag-input.js +4 -27
- package/registry/tag-input.muten +6 -6
- package/registry/text.muten +7 -0
- package/registry/time-field.js +5 -0
- package/registry/time-field.muten +6 -0
- package/registry/timeline.muten +14 -14
- package/registry/toaster.js +34 -22
- package/registry/toaster.muten +10 -8
- package/registry/toggle-group.muten +11 -6
- package/registry/toggle.muten +8 -5
- package/registry/toolbar.muten +11 -6
- package/registry/tooltip.muten +6 -9
- package/registry/tree-view.js +27 -7
- package/registry/tree-view.muten +8 -13
- package/registry/vector-field.muten +9 -8
- package/registry/virtual-list.js +5 -0
- package/registry/virtual-list.muten +6 -0
- package/registry/weekly-hours.muten +4 -0
- package/registry/wordline.muten +6 -0
- package/registry/zoom-control.muten +9 -9
- package/registry.json +872 -406
- package/registry/context-menu.js +0 -34
package/registry/calendar.muten
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
# Calendar -
|
|
2
|
-
#
|
|
3
|
-
# selected
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
# Calendar - the month grid: a day or a range, one or two months. The page owns nothing until the person picks:
|
|
2
|
+
# onSelect gets "yyyy-mm-dd" (single) or "from/to" (range).
|
|
3
|
+
# Calendar(selected: "today", min: "today", caption: "on", onSelect: pickDay)
|
|
4
|
+
# Calendar(selected: "-6/0", mode: "range", months: 2, presets: "reports", caption: "on", onSelect: pickRange)
|
|
5
|
+
# selected/min take dates or days from today ("today", "-6/0"). presets "reports" adds Hoy · Últimos 7 días · Este
|
|
6
|
+
# mes · Mes pasado beside a range; caption "on" writes what was chosen under it.
|
|
7
|
+
# shadcn-for-muten · Custom (kit core) · host JS is calendar.js.
|
|
8
|
+
part Calendar(selected: text = "", mode: text = "single", months: number = 1, min: text = "", presets: text = "", caption: text = "", onSelect: action) {
|
|
9
|
+
Custom Calendar inputs(selected: $selected, mode: $mode, months: $months, min: $min, presets: $presets, caption: $caption) on(select: $onSelect) class("cx-cal-host")
|
|
9
10
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// CanvasHost (muten Custom). A <canvas> with pan (drag) + zoom (wheel). handlers: { view(zoomPercent) }.
|
|
2
|
-
// Draws a checkerboard + a sample
|
|
2
|
+
// Draws a checkerboard + a sample square as a placeholder in the skin's colours - replace draw() with your scene.
|
|
3
|
+
// inputs: zoom (percent; the page can set it, e.g. from a ZoomControl). Double-click puts the view back at 100 %.
|
|
3
4
|
export function mount(el, inputs, handlers) {
|
|
4
5
|
const canvas = document.createElement('canvas');
|
|
5
6
|
el.appendChild(canvas);
|
|
6
7
|
const ctx = canvas.getContext('2d');
|
|
7
8
|
let scale = 1, ox = 0, oy = 0;
|
|
8
9
|
const dpr = () => window.devicePixelRatio || 1;
|
|
10
|
+
const token = (name, fallback) => getComputedStyle(el).getPropertyValue(name).trim() || fallback;
|
|
9
11
|
|
|
10
12
|
const draw = () => {
|
|
11
13
|
const w = canvas.width / dpr(), h = canvas.height / dpr();
|
|
@@ -16,11 +18,11 @@ export function mount(el, inputs, handlers) {
|
|
|
16
18
|
const sx = Math.floor((-ox / scale) / cell) - 1, sy = Math.floor((-oy / scale) / cell) - 1;
|
|
17
19
|
const cols = Math.ceil(w / cell / scale) + 3, rows = Math.ceil(h / cell / scale) + 3;
|
|
18
20
|
for (let i = sx; i < sx + cols; i++) for (let j = sy; j < sy + rows; j++) {
|
|
19
|
-
ctx.fillStyle = (i + j) % 2 ? '
|
|
21
|
+
ctx.fillStyle = (i + j) % 2 ? token('--muted', '#f4f4f5') : token('--background', '#fff');
|
|
20
22
|
ctx.fillRect(i * cell, j * cell, cell, cell);
|
|
21
23
|
}
|
|
22
|
-
ctx.fillStyle = '#
|
|
23
|
-
ctx.strokeStyle = '
|
|
24
|
+
ctx.fillStyle = token('--selected', '#6B46F2'); ctx.fillRect(-32, -32, 64, 64);
|
|
25
|
+
ctx.strokeStyle = token('--foreground', '#111'); ctx.lineWidth = 1 / scale; ctx.strokeRect(-32, -32, 64, 64);
|
|
24
26
|
ctx.restore();
|
|
25
27
|
};
|
|
26
28
|
const resize = () => { const r = el.getBoundingClientRect(); canvas.width = r.width * dpr(); canvas.height = r.height * dpr(); ctx.setTransform(dpr(), 0, 0, dpr(), 0, 0); draw(); };
|
|
@@ -40,5 +42,10 @@ export function mount(el, inputs, handlers) {
|
|
|
40
42
|
|
|
41
43
|
requestAnimationFrame(() => { const r = el.getBoundingClientRect(); ox = r.width / 2; oy = r.height / 2; resize(); });
|
|
42
44
|
window.addEventListener('resize', resize);
|
|
43
|
-
|
|
45
|
+
// the page sets the zoom (a ZoomControl): zoom around the centre of the view
|
|
46
|
+
const zoomTo = (pct) => { const ns = Math.min(8, Math.max(0.2, pct / 100)); if (Math.abs(ns - scale) < 1e-3) return; const r = el.getBoundingClientRect(), cx = r.width / 2, cy = r.height / 2, k = ns / scale; ox = cx - (cx - ox) * k; oy = cy - (cy - oy) * k; scale = ns; draw(); };
|
|
47
|
+
canvas.addEventListener('dblclick', () => { zoomTo(100); handlers.view?.(100); });
|
|
48
|
+
new MutationObserver(draw).observe(document.documentElement, { attributes: true, subtree: true, attributeFilter: ['data-theme', 'data-skin'] });
|
|
49
|
+
if (inputs.zoom) requestAnimationFrame(() => zoomTo(Number(inputs.zoom)));
|
|
50
|
+
return (next) => { if (next.zoom) zoomTo(Number(next.zoom)); };
|
|
44
51
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# CanvasViewport - a
|
|
2
|
-
# The
|
|
3
|
-
#
|
|
4
|
-
# CanvasViewport(onView:
|
|
5
|
-
# shadcn-for-muten · Custom (
|
|
6
|
-
part CanvasViewport(onView: action) {
|
|
7
|
-
Stack class("canvas-viewport") {
|
|
8
|
-
Custom CanvasHost on(view: $onView) class("canvas-host")
|
|
9
|
-
Stack class("canvas-
|
|
1
|
+
# CanvasViewport - a canvas you move by dragging and zoom with the wheel (around the pointer), with muten content
|
|
2
|
+
# floating over it (a Toolbar, a ZoomControl). The page can set the zoom and hears it change; a double click goes
|
|
3
|
+
# back to 100 %. The placeholder scene is in canvas-viewport.js: replace its draw() with yours.
|
|
4
|
+
# CanvasViewport(zoom: zoom, onView: setZoom) { Toolbar { … } }
|
|
5
|
+
# shadcn-for-muten · part + Custom (CanvasHost) · kit.css (.cx-canvas) · host JS canvas-viewport.js.
|
|
6
|
+
part CanvasViewport(zoom: number = 100, height: text = "360px", onView: action) {
|
|
7
|
+
Stack class("cx-canvas") data(slot: "canvas-viewport") style(h: "{$height}") {
|
|
8
|
+
Custom CanvasHost inputs(zoom: $zoom) on(view: $onView) class("cx-canvas-host")
|
|
9
|
+
Stack class("cx-canvas-over") { slot }
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# CardField - card number with its brand, expiry, code; validates (Luhn) and says what was saved.
|
|
2
|
+
# CardField(onSave: saved)
|
|
3
|
+
# shadcn-for-muten · part over KitWidget (kit core).
|
|
4
|
+
part CardField(onSave: action) { Custom KitWidget inputs(name: "cardField") on(action: $onSave) class("cx-cardform") }
|
package/registry/card.muten
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
# Card
|
|
2
|
-
#
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
part
|
|
6
|
-
part
|
|
7
|
-
part
|
|
8
|
-
part
|
|
1
|
+
# Card - a surface that only CONVEYS: header (title, description, an action at the corner), content, footer.
|
|
2
|
+
# Decisions go in a modal, not on the card.
|
|
3
|
+
# Card(size: "sm") { CardHeader { CardTitle(label: "Hoy") CardDescription(label: "3 citas") CardAction { Btn(variant: "ghost", size: "icon-sm", onClick: more) { Icon "lucide:ellipsis" } } } CardContent { … } }
|
|
4
|
+
# size: default | sm (compact: items edge to edge)
|
|
5
|
+
# shadcn-for-muten · part · no deps · Nova (.cn-card) + kit.css (size sm).
|
|
6
|
+
part Card(size: text = "default") { Section class("cn-card group/card") data(slot: "card", size: $size) { slot } }
|
|
7
|
+
part CardHeader() { Stack class("cn-card-header group/card-header") data(slot: "card-header") { slot } }
|
|
8
|
+
part CardTitle(label: text) { Title "{$label}" h3 class("cn-card-title") data(slot: "card-title") }
|
|
9
|
+
part CardDescription(label: text) { Text "{$label}" class("cn-card-description") data(slot: "card-description") }
|
|
10
|
+
part CardAction() { Stack class("cn-card-action") data(slot: "card-action") { slot } }
|
|
11
|
+
part CardContent() { Stack class("cn-card-content") data(slot: "card-content") { slot } }
|
|
12
|
+
part CardFooter() { Stack class("cn-card-footer") data(slot: "card-footer") { slot } }
|
package/registry/carousel.js
CHANGED
|
@@ -1,37 +1,6 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
viewport.appendChild(track); el.appendChild(viewport);
|
|
7
|
-
const SVG = (p) => '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' + p + '</svg>';
|
|
8
|
-
const prev = document.createElement('button'); prev.type = 'button'; prev.className = 'carousel-prev'; prev.innerHTML = SVG('<path d="m15 18-6-6 6-6"/>'); // lucide chevron-left
|
|
9
|
-
const next = document.createElement('button'); next.type = 'button'; next.className = 'carousel-next'; next.innerHTML = SVG('<path d="m9 18 6-6-6-6"/>'); // lucide chevron-right
|
|
10
|
-
el.appendChild(prev); el.appendChild(next);
|
|
11
|
-
|
|
12
|
-
let idx = 0;
|
|
13
|
-
let items = [];
|
|
14
|
-
// Move by exact viewport widths (px). A `%` translate is relative to the multi-slide track, not the viewport.
|
|
15
|
-
const paint = () => {
|
|
16
|
-
const w = viewport.clientWidth || el.clientWidth || 0;
|
|
17
|
-
for (const s of track.children) s.style.width = w + 'px';
|
|
18
|
-
track.style.transform = 'translateX(' + (-idx * w) + 'px)';
|
|
19
|
-
};
|
|
20
|
-
const build = (list) => {
|
|
21
|
-
items = Array.isArray(list) ? list : [];
|
|
22
|
-
track.innerHTML = '';
|
|
23
|
-
for (const it of items) {
|
|
24
|
-
const s = document.createElement('div'); s.className = 'carousel-slide';
|
|
25
|
-
s.textContent = (it && typeof it === 'object') ? (it.label ?? it.title ?? '') : String(it);
|
|
26
|
-
track.appendChild(s);
|
|
27
|
-
}
|
|
28
|
-
if (idx > items.length - 1) idx = Math.max(0, items.length - 1);
|
|
29
|
-
paint();
|
|
30
|
-
};
|
|
31
|
-
window.addEventListener('resize', paint);
|
|
32
|
-
prev.addEventListener('click', () => { if (items.length) { idx = (idx - 1 + items.length) % items.length; paint(); } });
|
|
33
|
-
next.addEventListener('click', () => { if (items.length) { idx = (idx + 1) % items.length; paint(); } });
|
|
34
|
-
|
|
35
|
-
build(inputs.items);
|
|
36
|
-
return (n) => build(n.items);
|
|
1
|
+
// CarouselBehavior (muten Custom) - the kit's carousel behaviour over the slides muten rendered (kit/collections.js).
|
|
2
|
+
export function mount(el, inputs) {
|
|
3
|
+
const root = el.closest('.cx-car');
|
|
4
|
+
Promise.all([import('@muten/shadcn/registry/kit/core.js'), import('@muten/shadcn/registry/kit/collections.js')]).then(([core, c]) => c.carouselBehavior(root, inputs, core));
|
|
5
|
+
return () => {};
|
|
37
6
|
}
|
package/registry/carousel.muten
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
# Carousel -
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
# Carousel - one component, options instead of copies. The slides are your muten content (CarouselSlide).
|
|
2
|
+
# perView "4" or "2,4" (phone, wider) · center "on" (the active one centred, neighbours peeking) · loop "on" ·
|
|
3
|
+
# autoplay ms (pauses on hover, focus, touch, hidden tab; off with reduced motion; its own pause button) ·
|
|
4
|
+
# indicator dots | progress | count | thumbs · arrows bar | overlay
|
|
5
|
+
# Carousel(label: "Productos", perView: "2,4") { each products as p { CarouselSlide { … } } }
|
|
6
|
+
# shadcn-for-muten · part + Custom (CarouselBehavior, kit collections) · kit.css (.cx-car).
|
|
7
|
+
part Carousel(label: text, perView: text = "1", center: text = "", loop: text = "", autoplay: number = 0, indicator: text = "dots", arrows: text = "bar") {
|
|
8
|
+
Section class("cx-car") aria(label: $label, roledescription: "carrusel") {
|
|
9
|
+
Stack class("cx-car-view") { Stack class("cx-car-track") { slot } }
|
|
10
|
+
Custom Carousel inputs(perView: $perView, center: $center, loop: $loop, autoplay: $autoplay, indicator: $indicator, arrows: $arrows) class("cx-car-behavior")
|
|
11
|
+
}
|
|
6
12
|
}
|
|
13
|
+
part CarouselSlide() { Stack class("cx-car-slide") { slot } }
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Chatbot - the assistant: greets, offers suggestions, «thinks», writes the answer live (with Stop), can carry an
|
|
2
|
+
# action button inside the answer (onAction gets its label), rated with 👍 / 👎. answers: {match (regex), text, action,
|
|
3
|
+
# primary}; the one without match is the fallback.
|
|
4
|
+
# Chatbot(title: "Rober", greeting: "Hola, soy Rober…", suggestions: @ideas, answers: @answers, onAction: act)
|
|
5
|
+
# demo "on": it taps its own suggestions in turn and answers them live, for a landing; the first touch stops it.
|
|
6
|
+
# shadcn-for-muten · part over KitWidget (kit core).
|
|
7
|
+
part Chatbot(title: text, greeting: text, suggestions: list, answers: list, demo: text = "", onAction: action) {
|
|
8
|
+
Custom KitWidget inputs(name: "chatbot", title: $title, greeting: $greeting, suggestions: $suggestions, answers: $answers, demo: $demo) on(action: $onAction) class("cx-bot")
|
|
9
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Checklist - first steps with progress: done steps checked, the next ones with their action (onAction gets its label).
|
|
2
|
+
# Checklist(title: "Tu tienda en 5 pasos", steps: @steps, onAction: act) steps: {title, desc, done, action}
|
|
3
|
+
# shadcn-for-muten · part over KitWidget (kit core).
|
|
4
|
+
part Checklist(title: text, steps: list, onAction: action) {
|
|
5
|
+
Custom KitWidget inputs(name: "checklist", title: $title, steps: $steps) on(action: $onAction) class("cx-onboard")
|
|
6
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# ChoiceList - Items you choose one of: a real radio group (arrows move and pick). The page owns the current value.
|
|
2
|
+
# ChoiceList(label: "Servicio") {
|
|
3
|
+
# ChoiceItem(value: "cut", current: service, onPick: pick, title: "Corte clásico", description: "30 min", price: "$25.000")
|
|
4
|
+
# }
|
|
5
|
+
# shadcn-for-muten · part + Custom (RovingBehavior) · kit.css (.cx-radiogroup, .cx-radio).
|
|
6
|
+
part ChoiceList(label: text) { Stack class("cx-radiogroup") aria(role: "radiogroup", label: $label) { slot RovingBehavior() } }
|
|
7
|
+
part ChoiceItem(value: text, current: text, onPick: action, title: text, description: text = "", price: text = "") {
|
|
8
|
+
Button -> $onPick($value) class("cn-item cn-item-variant-outline cn-item-size-sm group/item cx-item cx-choice") data(slot: "item") aria(role: "radio", checked: $value == $current) {
|
|
9
|
+
Span "" class("cx-radio")
|
|
10
|
+
Stack class("cn-item-content") data(slot: "item-content") {
|
|
11
|
+
Span "{$title}" class("cn-item-title") data(slot: "item-title")
|
|
12
|
+
Text "{$description}" class("cn-item-description") data(slot: "item-description")
|
|
13
|
+
}
|
|
14
|
+
Span "{$price}" class("cx-price")
|
|
15
|
+
}
|
|
16
|
+
}
|
package/registry/code.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
// Code
|
|
2
|
-
//
|
|
1
|
+
// Code (muten Custom) - a code block: a bar with the language (or a title) and Copiar, then the code highlighted with
|
|
2
|
+
// the muten grammar (any other lang shows plain). inputs: code, lang, title. The highlighter is the shared
|
|
3
|
+
// highlight.js, loaded lazily so the token rules live in one place.
|
|
3
4
|
export function mount(el, inputs) {
|
|
4
|
-
const code = String(inputs.code
|
|
5
|
-
|
|
6
|
-
el.
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.then((
|
|
13
|
-
|
|
5
|
+
const code = String(inputs.code ?? ''), lang = String(inputs.lang || 'muten');
|
|
6
|
+
el.innerHTML = '<div class="cx-code-bar"><span></span><button type="button" class="cn-button cn-button-variant-outline cn-button-size-xs">Copiar</button></div><pre class="cx-code-pre"><code></code></pre>';
|
|
7
|
+
el.querySelector('.cx-code-bar span').textContent = inputs.title || lang;
|
|
8
|
+
const box = el.querySelector('code'), copy = el.querySelector('button');
|
|
9
|
+
box.textContent = code;
|
|
10
|
+
if (lang === 'muten') import('@muten/shadcn/registry/highlight.js').then((m) => { box.innerHTML = m.highlight(code, lang); }).catch(() => {});
|
|
11
|
+
copy.onclick = () => {
|
|
12
|
+
const done = (t) => { copy.textContent = t; setTimeout(() => { copy.textContent = 'Copiar'; }, 1400); };
|
|
13
|
+
try { navigator.clipboard.writeText(code).then(() => done('Copiado'), () => { getSelection().selectAllChildren(box); done('Selecciónalo'); }); } catch { getSelection().selectAllChildren(box); done('Selecciónalo'); }
|
|
14
|
+
};
|
|
15
|
+
return (next) => { const c = String(next.code ?? ''); if (c === box.textContent) return; box.textContent = c; if (lang === 'muten') import('@muten/shadcn/registry/highlight.js').then((m) => { box.innerHTML = m.highlight(c, lang); }); };
|
|
14
16
|
}
|
package/registry/code.muten
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
# Code - a
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
1
|
+
# Code - a code block with a bar (the language or a title) and Copiar; muten code comes highlighted with the same
|
|
2
|
+
# grammar as the editor. muten strings cannot hold quotes or braces, so pass the code from a state (or a store),
|
|
3
|
+
# not inline. For other languages pass lang: it shows plain.
|
|
4
|
+
# state { snippet = "…" : text } Code(code: snippet, title: "src/app.muten")
|
|
5
|
+
# shadcn-for-muten · Custom · kit.css (.cx-code) · host JS code.js (shares highlight.js).
|
|
6
|
+
part Code(code: text, lang: text = "muten", title: text = "") { Custom Code inputs(code: $code, lang: $lang, title: $title) class("cx-code") }
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
# Collapsible -
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
# Collapsible - one block that opens and closes: a trigger line and the content under it, folding to its exact
|
|
2
|
+
# height (200 ms) while the chevron turns. The page owns the bool. For several stacked questions use Accordion.
|
|
3
|
+
# state { more = false : bool } action toggleMore() mutates more { more.toggle() }
|
|
4
|
+
# Collapsible(label: "Más opciones", open: more, onToggle: toggleMore) { … }
|
|
5
|
+
# Collapsible(label: "3 pedidos entregados", hint: "Ver", open: done, onToggle: toggleDone) { … }
|
|
6
|
+
# shadcn-for-muten · part · no deps · kit.css (.cx-coll, the same fold as Accordion).
|
|
7
|
+
part Collapsible(label: text, open: bool, onToggle: action, hint: text = "") {
|
|
8
|
+
Stack class("cx-coll") data(slot: "collapsible", open: $open) {
|
|
9
|
+
Button -> $onToggle class("cx-coll-trigger") data(slot: "collapsible-trigger") aria(expanded: $open) {
|
|
10
|
+
Span "{$label}" class("cx-coll-label")
|
|
11
|
+
Span "{$hint}" class("cx-coll-hint")
|
|
12
|
+
Icon "lucide:chevron-down" class("cx-acc-chev")
|
|
9
13
|
}
|
|
10
|
-
Stack class("
|
|
11
|
-
Stack class("
|
|
14
|
+
Stack class("cn-accordion-content cx-acc-fold") data(slot: "collapsible-content", open: $open) aria(role: "region") {
|
|
15
|
+
Stack class("cn-accordion-content-inner cx-coll-inner") { slot }
|
|
12
16
|
}
|
|
13
17
|
}
|
|
14
18
|
}
|