@muten/shadcn 0.1.1 → 0.1.3

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 (48) hide show
  1. package/AGENTS.md +69 -1
  2. package/README.md +7 -0
  3. package/kit.css +2406 -24
  4. package/motion.css +15 -0
  5. package/package.json +3 -2
  6. package/registry/accordion.muten +10 -0
  7. package/registry/agenda.js +72 -24
  8. package/registry/agenda.muten +30 -2
  9. package/registry/band.muten +1 -1
  10. package/registry/bio-play.muten +16 -0
  11. package/registry/booking-play.muten +43 -0
  12. package/registry/button.muten +3 -2
  13. package/registry/chat-play.muten +77 -0
  14. package/registry/day-plan.muten +40 -0
  15. package/registry/device-frame.muten +25 -7
  16. package/registry/gradient-blinds.js +88 -89
  17. package/registry/gradient-blinds.muten +11 -4
  18. package/registry/heatmap.muten +30 -0
  19. package/registry/inbox-play.muten +56 -0
  20. package/registry/input-group.muten +3 -1
  21. package/registry/kit/collections.js +10 -2
  22. package/registry/kit/core.js +519 -99
  23. package/registry/kit/structure.js +3 -3
  24. package/registry/kit-widget.js +1 -1
  25. package/registry/legal-doc.muten +27 -0
  26. package/registry/modal-behavior.js +11 -0
  27. package/registry/modal.muten +1 -1
  28. package/registry/order-play.muten +33 -0
  29. package/registry/permission-matrix.muten +31 -5
  30. package/registry/phone-bar.muten +18 -0
  31. package/registry/phone-shell.muten +1 -1
  32. package/registry/product-play.muten +20 -0
  33. package/registry/progress.muten +5 -2
  34. package/registry/rank-item.muten +32 -0
  35. package/registry/screen-tour.js +59 -0
  36. package/registry/screen-tour.muten +10 -0
  37. package/registry/share-bar.muten +22 -0
  38. package/registry/sidebar.muten +9 -0
  39. package/registry/site-footer.muten +37 -0
  40. package/registry/stacked-bars.js +75 -0
  41. package/registry/stacked-bars.muten +13 -0
  42. package/registry/stamp-card.muten +5 -2
  43. package/registry/stat-band.muten +5 -1
  44. package/registry/stat.muten +19 -7
  45. package/registry/veil.muten +18 -0
  46. package/registry/zoom-control.muten +3 -3
  47. package/registry.json +116 -0
  48. package/scripts/reuse-audit.mjs +37 -0
package/AGENTS.md CHANGED
@@ -1,5 +1,71 @@
1
1
  # @muten/shadcn - component catalog (for an AI assembling a muten app)
2
2
 
3
+ ## Read this first: reuse before you build
4
+
5
+ This library is the app's component set, built as atoms that compose into molecules and organisms. The most common
6
+ mistake when building with muten is to draw from scratch something the library already has: a phone mockup, a button
7
+ with its own border, a picker glued inside an input, a skeleton, a legal page. Each copy looks a little different, has
8
+ its own bugs, and is one more thing to fix. So before you write any UI piece, walk this loop:
9
+
10
+ 1. **Look it up.** List the parts: `ls node_modules/@muten/shadcn/registry/`. Each `<name>.muten` opens with a header
11
+ comment: what it is, its props, an example. Read the header of every candidate (the catalog below names them; the
12
+ header is the API). Search by meaning: `grep -il "phone\|chat\|calendar" node_modules/@muten/shadcn/registry/*.muten`.
13
+ 2. **Compose, don't redraw.** If a part covers 80% of it, use the part and add the rest around it (layout, data, copy).
14
+ Build bigger pieces out of smaller ones: a form is `Field` + `Input` + `Btn`, a store tile is `DeviceFrame` +
15
+ two spans. Never copy a part's look into your own classes.
16
+ 3. **Your CSS only places and sizes.** Write classes for layout (grid, gaps, where a thing sits) and sizes, set through
17
+ the variable a part exposes (`--dw` for DeviceFrame, `width`/`height` props). Do not restyle what a part draws: its
18
+ border, radius, shadow, bezel, padding or colours. If that look is wrong, it is wrong everywhere: fix it in the library.
19
+ 4. **Missing for real? Add it to the library, not to the app.** A new part goes in `registry/` with its header comment,
20
+ its CSS in `kit.css`, an entry in `registry.json` and a page in the library's bench (`plugins/playground/docs/` in
21
+ its repo). If you cannot change the library, say so instead of building a private copy. Then every app
22
+ gets it, and the next person finds it in step 1.
23
+ 5. **Check.** `node node_modules/@muten/shadcn/scripts/reuse-audit.mjs src` lists the markup in your app that redraws a
24
+ library piece (a Button wearing `cn-button` classes, a hand-made avatar, a phone frame of its own, a skeleton by
25
+ hand). Every finding is a question: answer it before adding more. Then `muten check`.
26
+
27
+ ### If you need… use…
28
+
29
+ | You need | Use | Not |
30
+ |---|---|---|
31
+ | a button / icon button / link that looks like one | `Btn(variant, size, label, onClick, disabled)`, `LinkBtn(to, variant)` | `Button … class("cn-button …")` |
32
+ | buttons joined in a row, an action with a menu | `ButtonGroup`, `SplitButton` | two buttons with their own borders |
33
+ | a text field, with an icon, a currency or a country | `Input`, `InputGroup` + `GroupInput`, `MoneyField`, `PhoneField` | a select drawn inside an input |
34
+ | a label, help text and error around a control | `Field(label, description, error)` | spans with margins |
35
+ | a person's face or initials, a name with a subtitle | `Avatar`, `AvatarImage`, `Who` | a circle div with a letter |
36
+ | **a phone or browser mockup** (screenshot, live screen, store preview) | **`DeviceFrame`** (`island`, `width`, `href`, `label`, `shot`, `kind: "browser"`, `url`) | any frame of your own: it is the one phone, the iPhone 18 Pro to scale |
37
+ | a chat preview in WhatsApp, Instagram or Telegram style | `ChatPlay` (+ `ChatPlayMsg`, `ChatPlayDay`, …) | a hand-made chat screen |
38
+ | a conversation column | `MessageScroller` + `Message` + `Marker` | a scrolling div of bubbles |
39
+ | a dialog, a drawer, a side sheet | `Modal(mode: "auto" \| "drawer" \| …)` | a fixed div with a backdrop |
40
+ | a short notice, an alert, a band | `Island`, `Alert`, `Band` | a toast of your own |
41
+ | a loading state | `Loading(busy, kind) { … }`, `Skeletons(kind)`, `Skeleton` | grey boxes by hand |
42
+ | an empty state | `Empty(title, description)` | a centred paragraph |
43
+ | tabs, a segmented switch | `Tabs`, `SegmentedControl` | buttons with an active class |
44
+ | the app's left menu, the phone's bottom bar | `AppSidebar` + `SidebarLink`, `PhoneBar` | a nav of your own |
45
+ | a menu, a searchable picker | `DropdownMenu`, `Combobox` | a native `<select>` |
46
+ | dates and times, an agenda | `Calendar`, `DateField`, `TimeField`, `AgendaLive` | an input with a library |
47
+ | a KPI, a price, a status | `StatCard`, `Price`, `Badge` / `StatusBadge` | a styled number |
48
+ | a chart: bars, line, area, pie, donut, scatter | muten's `Chart` primitive (styled by the library) | an SVG or a chart library |
49
+ | bars over time with stacked series, a pickable bar, an axis in money | `StackedBars(rows, series, selected, unit, empty, busy, onPick)` | bars of divs |
50
+ | how a whole splits (citas vs pedidos, new vs returning) | `ShareBar(parts)` | two flex boxes |
51
+ | how much happens where two things cross (day × hour) | `Heatmap(rows, cols, cells)` | a grid of coloured cells |
52
+ | a bar per row (channels, a ranking) | `Progress(value, tone)` | a width in % |
53
+ | a legal or long document | `DocHead`, `DocToc` + `DocTocLink`, `DocSection` | a wall of paragraphs |
54
+ | a hero background, a product tour | `GradientBlinds(colors, from)`, `ScreenTour` | your own canvas or gradient |
55
+ | text with the library's type scale | `Txt(value, variant: "title" \| "heading" \| "muted" \| "caption")` | font sizes in your CSS |
56
+
57
+ ### Things that went wrong before (don't repeat them)
58
+
59
+ - A second (and third) phone drawn by hand in the app, each with its own bezel and buttons. There is one phone:
60
+ `DeviceFrame`. Size it with `width` or `--dw`; give it `island: "on"` or a `shot`; never redraw it.
61
+ - A percent `padding` used for a bezel or a border: a percent padding is a share of the PARENT's width, so the border
62
+ grows with the page. Shares of the element itself come from its children's margin or from `cqw`.
63
+ - A picker given its own border and radius inside an input: it reads as a button stuck in a field. `InputGroup` makes
64
+ it a segment of the same field.
65
+ - Bubbles squashed and hours drawn over the text in a fixed-height column: flex shrank them. The library's parts already
66
+ hold their size; a hand-made list did not.
67
+ - A gradient with hard stripes and a sudden cut: `GradientBlinds` melts into the page and can come `from` any side.
68
+
3
69
  ## Setup (once): `plugins { shadcn {} }` in muten.config + `@import "@muten/shadcn/globals.css";` in src/styles.css. Then everything below is usable directly; `muten add <name>` only ejects a source.
4
70
 
5
71
  > **Native primitives always win — for a checkbox / select / number / range / date / chart, use the native muten
@@ -160,4 +226,6 @@ Rules the kit keeps: the page owns the state and gets JSON back through actions;
160
226
 
161
227
  ### Gotcha: a part can not be named after a core primitive — the **primitive wins** and any same-named plugin part is unreachable on import. The primitives include `Button/Link/Form/Image/SearchField/DataTable/Icon/Text/Title/Span` (→ this plugin uses `Btn`/`Input`/`LinkBtn`) AND `Select/Checkbox/Number/Range/Date/Chart` (→ use those primitives directly, see the note at the top). If you write a part call and the oracle says `missing-prop: X is missing the required "bind"`, X is a primitive shadowing the part — switch to the primitive's API.
162
228
 
163
- ### Gotcha: a **part takes NO trailing modifiers** — `Part(...) class(...)`, `Part(...) disabled when x`, `Part(...) on(...)` and `Part(...) aria(...)` are all syntax errors (a part call ends at its `)`/`{}`). When you need `class`/`disabled when`/`on`/`aria` on a control, use the **native primitive** (`Button "Save" -> save disabled when not valid class("btn btn-default")`), not the `Btn(...)` part.
229
+ ### Gotcha: at the CALL SITE a part takes only `class(...)`, which is added to the part's root (for placing and sizing:
230
+ `DeviceFrame(island: "on") class("my-phone-slot")`). `disabled when`, `on(...)` and `aria(...)` there are syntax
231
+ errors: pass them as the part's props when it has them (`Btn(disabled: busy)`), or use the native primitive.
package/README.md CHANGED
@@ -8,6 +8,13 @@ is 100% shadcn (zinc dark theme, the same tokens, the same animations).
8
8
  This is a **muten plugin**: a registry of components you either **import** (use as-is) or **eject** (`muten add`,
9
9
  copy the source and own it, the shadcn way). It is not a runtime - the components compile away with your app.
10
10
 
11
+ ## Before you build anything
12
+
13
+ Use what the library has before drawing your own: one phone (`DeviceFrame`), one button (`Btn`), one field family,
14
+ one modal. The reuse loop, the "if you need X, use Y" table and the mistakes not to repeat are in
15
+ [AGENTS.md](AGENTS.md#read-this-first-reuse-before-you-build). To check an app:
16
+ `node node_modules/@muten/shadcn/scripts/reuse-audit.mjs src`.
17
+
11
18
  ## Requirements
12
19
 
13
20
  A muten app using **Tailwind CSS v4** (scaffold with `npm create muten@latest` and pick Tailwind, or add it). The