@muten/shadcn 0.1.0 → 0.1.2
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 +64 -1
- package/README.md +7 -0
- package/kit.css +2289 -25
- package/motion.css +16 -1
- package/package.json +3 -2
- package/registry/accordion.muten +10 -0
- package/registry/agenda.js +72 -24
- package/registry/agenda.muten +30 -2
- package/registry/band.muten +1 -1
- package/registry/bio-play.muten +16 -0
- package/registry/booking-play.muten +43 -0
- package/registry/button.muten +3 -2
- package/registry/chat-play.muten +77 -0
- package/registry/day-plan.muten +40 -0
- package/registry/device-frame.muten +25 -7
- package/registry/drawer.muten +1 -1
- package/registry/gradient-blinds.js +88 -89
- package/registry/gradient-blinds.muten +11 -4
- package/registry/inbox-play.muten +56 -0
- package/registry/input-group.muten +3 -1
- package/registry/kit/board.js +1 -1
- package/registry/kit/collections.js +10 -2
- package/registry/kit/core.js +519 -99
- package/registry/kit/structure.js +7 -5
- package/registry/kit-widget.js +1 -1
- package/registry/legal-doc.muten +27 -0
- package/registry/modal-behavior.js +11 -0
- package/registry/modal.muten +2 -2
- package/registry/order-play.muten +33 -0
- package/registry/permission-matrix.muten +31 -5
- package/registry/phone-bar.muten +18 -0
- package/registry/phone-shell.muten +1 -1
- package/registry/product-play.muten +20 -0
- package/registry/screen-tour.js +59 -0
- package/registry/screen-tour.muten +10 -0
- package/registry/sidebar.muten +9 -0
- package/registry/site-footer.muten +37 -0
- package/registry/stamp-card.muten +5 -2
- package/registry/zoom-control.muten +3 -3
- package/registry.json +78 -0
- package/scripts/reuse-audit.mjs +37 -0
package/AGENTS.md
CHANGED
|
@@ -1,5 +1,66 @@
|
|
|
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 legal or long document | `DocHead`, `DocToc` + `DocTocLink`, `DocSection` | a wall of paragraphs |
|
|
49
|
+
| a hero background, a product tour | `GradientBlinds(colors, from)`, `ScreenTour` | your own canvas or gradient |
|
|
50
|
+
| text with the library's type scale | `Txt(value, variant: "title" \| "heading" \| "muted" \| "caption")` | font sizes in your CSS |
|
|
51
|
+
|
|
52
|
+
### Things that went wrong before (don't repeat them)
|
|
53
|
+
|
|
54
|
+
- A second (and third) phone drawn by hand in the app, each with its own bezel and buttons. There is one phone:
|
|
55
|
+
`DeviceFrame`. Size it with `width` or `--dw`; give it `island: "on"` or a `shot`; never redraw it.
|
|
56
|
+
- A percent `padding` used for a bezel or a border: a percent padding is a share of the PARENT's width, so the border
|
|
57
|
+
grows with the page. Shares of the element itself come from its children's margin or from `cqw`.
|
|
58
|
+
- A picker given its own border and radius inside an input: it reads as a button stuck in a field. `InputGroup` makes
|
|
59
|
+
it a segment of the same field.
|
|
60
|
+
- Bubbles squashed and hours drawn over the text in a fixed-height column: flex shrank them. The library's parts already
|
|
61
|
+
hold their size; a hand-made list did not.
|
|
62
|
+
- A gradient with hard stripes and a sudden cut: `GradientBlinds` melts into the page and can come `from` any side.
|
|
63
|
+
|
|
3
64
|
## 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
65
|
|
|
5
66
|
> **Native primitives always win — for a checkbox / select / number / range / date / chart, use the native muten
|
|
@@ -160,4 +221,6 @@ Rules the kit keeps: the page owns the state and gets JSON back through actions;
|
|
|
160
221
|
|
|
161
222
|
### 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
223
|
|
|
163
|
-
### Gotcha: a
|
|
224
|
+
### Gotcha: at the CALL SITE a part takes only `class(...)`, which is added to the part's root (for placing and sizing:
|
|
225
|
+
`DeviceFrame(island: "on") class("my-phone-slot")`). `disabled when`, `on(...)` and `aria(...)` there are syntax
|
|
226
|
+
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
|