@engineio/ui 0.4.1 → 0.4.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 +138 -0
- package/README.md +29 -0
- package/package.json +12 -6
package/AGENTS.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# @engineio/ui — agent reference
|
|
2
|
+
|
|
3
|
+
The Engine design system. This file ships inside the package, so it arrives in
|
|
4
|
+
`node_modules/@engineio/ui/AGENTS.md` and versions with the code — point at it
|
|
5
|
+
rather than copying its contents into a repo, or the copy goes stale.
|
|
6
|
+
|
|
7
|
+
Authoritative source: `docs/brand/ENGINE-DESIGN-SYSTEM.md` and
|
|
8
|
+
`ENGINE-BRAND.md` in the `engineio/engine` repo. Where this file and those
|
|
9
|
+
disagree, **they win and this is a bug**.
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
```css
|
|
14
|
+
@import "tailwindcss";
|
|
15
|
+
@import "@engineio/ui/styles";
|
|
16
|
+
@source "../../../node_modules/@engineio/ui/dist";
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**The `@source` line is not optional and its absence is silent.** Tailwind 4
|
|
20
|
+
does not scan `node_modules`, so without it the utility classes the components
|
|
21
|
+
are written against are never generated. The tokens still land and any class
|
|
22
|
+
that also appears in local source still works, so you get a half-styled app
|
|
23
|
+
that reads like a component bug. Path is relative to the CSS file declaring it.
|
|
24
|
+
|
|
25
|
+
## Importing
|
|
26
|
+
|
|
27
|
+
```svelte
|
|
28
|
+
import { Button, Card, CardHeader } from "@engineio/ui"
|
|
29
|
+
import { Button } from "@engineio/ui/components/ui/button/index.js"
|
|
30
|
+
import * as Card from "@engineio/ui/components/ui/card/index.js"
|
|
31
|
+
import { EngineWordmark } from "@engineio/ui/components/brand/index.js"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Root barrel exports flat prefixed names (`CardHeader`). Subpath modules export
|
|
35
|
+
`Root`/`Header`/`Content`, so `import * as Card` works. Both `/index.js` and the
|
|
36
|
+
bare subpath resolve.
|
|
37
|
+
|
|
38
|
+
## Components
|
|
39
|
+
|
|
40
|
+
Alert, Badge, Button, Card, Checkbox, Dialog, Input, Label, Popover, Progress,
|
|
41
|
+
RadioGroup, Select, Separator, Skeleton, Switch, Table, Tabs, Textarea, Tooltip.
|
|
42
|
+
Marks: `EngineWordmark`, `EngineIcon`.
|
|
43
|
+
|
|
44
|
+
Not shipped, on purpose: `sonner`, `form`, `data-table`, `drawer`, `resizable`,
|
|
45
|
+
`carousel`, `chart`. Copy from the engine repo if needed.
|
|
46
|
+
|
|
47
|
+
| Component | Variants |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| Button | `default` `inverse` `outline` `ghost` `secondary` `link` `icon` `destructive` `success`; sizes `sm` `default` `lg` `icon` `icon-sm` `icon-lg` |
|
|
50
|
+
| Badge | `default` `secondary` `outline` `partner` `success` `warning` `danger` `destructive` |
|
|
51
|
+
| Alert | `default` `success` `warning` `danger` `destructive`; optional `onDismiss` |
|
|
52
|
+
| Marks | `variant="primary"` (white) or `"secondary"` (Off Black) |
|
|
53
|
+
|
|
54
|
+
There is **one** chip. Badge absorbed Tag — a soft tinted chip, not a solid
|
|
55
|
+
pill. There is no `Tag` export and no `solid` badge variant: an opaque fill can
|
|
56
|
+
only be correct on one surface, and badge fills are translucent so they read on
|
|
57
|
+
the page, on a card and on a table tile alike.
|
|
58
|
+
|
|
59
|
+
## Tokens
|
|
60
|
+
|
|
61
|
+
Use these names; never a literal.
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
colour --color-background #0E0E0E --color-foreground #FFFFFF
|
|
65
|
+
--color-primary #FF006A --color-primary-press #D60059
|
|
66
|
+
--color-primary-300 #FF5C9B (ink on a magenta tint)
|
|
67
|
+
--color-primary-tint-12 / -24
|
|
68
|
+
--color-card #161616 --color-popover #1C1C1C
|
|
69
|
+
--color-grey-950 … --color-grey-050 (the only greys)
|
|
70
|
+
--color-partner-yellow #FFDD00 (reserved, not in use)
|
|
71
|
+
status --color-success #00C46A --color-warning #FFB020 --color-danger #FF3B30
|
|
72
|
+
each with -foreground (always Off Black) and -tint-12
|
|
73
|
+
--color-destructive aliases danger
|
|
74
|
+
radii --radius-tag 6 --radius-field 10 --radius-card-inner 10
|
|
75
|
+
--radius-media 14 --radius-card 18 --radius-frame 26
|
|
76
|
+
--radius-control 999
|
|
77
|
+
motion --ease-brand --ease-brand-out --ease-brand-accelerate
|
|
78
|
+
140ms controls · 220ms surfaces · 360–640ms reveals
|
|
79
|
+
type --font-brand (Proxima Nova) --font-mono (JetBrains Mono, see gaps)
|
|
80
|
+
depth --shadow-panel --shadow-modal (product chrome and modals only)
|
|
81
|
+
utility `field` — the shared input skin, incl. the focus ring
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Rules
|
|
85
|
+
|
|
86
|
+
- **Three brand colours**: Off Black, Pure White, Magenta. One accent per
|
|
87
|
+
surface, never two.
|
|
88
|
+
- **Status colour is functional.** `success`/`warning`/`danger` report state.
|
|
89
|
+
Never use them as a categorical palette — `success` for "slots" because green
|
|
90
|
+
looked right spends the only signal they carry.
|
|
91
|
+
- **No off-palette colour.** Not Tailwind's stock ramps, not a hex literal. CI
|
|
92
|
+
fails on both.
|
|
93
|
+
- **Retired and unavailable**: Originals Orange `#FF6200`, Sportsbook Blue
|
|
94
|
+
`#00CCFF`. No accents, no charts, no status.
|
|
95
|
+
- **Ink on any status or accent fill is Off Black.** White fails AA on all three.
|
|
96
|
+
- **Magenta text**: never below 15px bold. Use `--color-primary-300` on a tint.
|
|
97
|
+
- No gradients. No light theme. No `dark:` variants — the dark palette is the
|
|
98
|
+
only palette. No drop shadows on brand surfaces. No coloured borders, and no
|
|
99
|
+
coloured left-edge accent to signal category or ownership.
|
|
100
|
+
- Radii by role, and the outer frame is always larger than the inner panel.
|
|
101
|
+
- Borders are 1px hairline or 1.5px container rule. Nothing else.
|
|
102
|
+
- **No emoji, anywhere.** Only `×` for close and `✱` for footnotes.
|
|
103
|
+
- Voice: declarative, British/AU spelling, headlines end in a full stop.
|
|
104
|
+
- Icons: Lucide, 2px stroke, `currentColor`.
|
|
105
|
+
|
|
106
|
+
## Extending
|
|
107
|
+
|
|
108
|
+
Do not fork a component to add a variant, and do not upstream a product-only
|
|
109
|
+
variant. Every variant map is exported:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { buttonVariants } from "@engineio/ui"
|
|
113
|
+
import { tv } from "tailwind-variants"
|
|
114
|
+
|
|
115
|
+
export const appButtonVariants = tv({
|
|
116
|
+
extend: buttonVariants,
|
|
117
|
+
variants: { variant: { drawer: "w-full justify-start rounded-none …" } },
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Brand rules stay in the package; product variants stay in the product. Every
|
|
122
|
+
primitive also passes `class` through `cn`, so `<Button class="w-full" />` works
|
|
123
|
+
without `!important`.
|
|
124
|
+
|
|
125
|
+
## Known gaps
|
|
126
|
+
|
|
127
|
+
State these rather than working around them silently.
|
|
128
|
+
|
|
129
|
+
1. **No categorical palette.** A per-topic hue set is an unmade brand decision.
|
|
130
|
+
2. **Two deviations from the brand document**, both deliberate: Badge is one
|
|
131
|
+
component where §6 specifies two, and Alert signals state with a coloured
|
|
132
|
+
left-edge bar which §11 prohibits for *category or ownership* — state is a
|
|
133
|
+
narrower reading, not an exemption.
|
|
134
|
+
3. **JetBrains Mono is not loaded.** `--font-mono` falls back to the platform
|
|
135
|
+
monospace, so every mono surface is off-brand until the binary ships.
|
|
136
|
+
4. **Proxima Nova is commercially licensed** and ships inside this package.
|
|
137
|
+
5. **Engine Integration's accent is unsettled** — build Integration in magenta;
|
|
138
|
+
`--color-partner-yellow` exists but is not in use.
|
package/README.md
CHANGED
|
@@ -121,6 +121,35 @@ engine repo into your product if you need them. `sonner` was excluded because
|
|
|
121
121
|
toasts need success and error colours that did not exist; now that they do, it
|
|
122
122
|
is a candidate for the next release.
|
|
123
123
|
|
|
124
|
+
## Using it with AI agents
|
|
125
|
+
|
|
126
|
+
The package ships `AGENTS.md`, so it lands at
|
|
127
|
+
`node_modules/@engineio/ui/AGENTS.md` and **versions with the code**. Point at
|
|
128
|
+
that path from a consuming repo rather than copying the rules in — a copy in
|
|
129
|
+
someone's `CLAUDE.md` silently goes stale on the next version bump, and stale
|
|
130
|
+
brand rules are worse than none.
|
|
131
|
+
|
|
132
|
+
In a consumer's `AGENTS.md` or `CLAUDE.md`:
|
|
133
|
+
|
|
134
|
+
```md
|
|
135
|
+
UI is built on `@engineio/ui`. Read `node_modules/@engineio/ui/AGENTS.md`
|
|
136
|
+
before writing or reviewing any UI.
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
For Claude Code specifically, copy the skill instead — it loads only when
|
|
140
|
+
relevant, so the reference costs nothing until a UI task actually needs it:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
mkdir -p .claude/skills
|
|
144
|
+
cp -R node_modules/@engineio/ui/../../../ui/.claude/skills/engine-design-system \
|
|
145
|
+
.claude/skills/ # or from a checkout of engineio/ui
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Skills have to live in `.claude/skills/`, `~/.claude/skills/` or a plugin —
|
|
149
|
+
Claude Code does not load them from `node_modules` — which is why the substance
|
|
150
|
+
lives in `AGENTS.md` and the skill is a thin pointer to it. That way the copied
|
|
151
|
+
file has nothing in it that can rot.
|
|
152
|
+
|
|
124
153
|
## Development
|
|
125
154
|
|
|
126
155
|
```bash
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@engineio/ui",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "The Engine design system — tokens, fonts and Svelte primitives.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"dist",
|
|
19
|
+
"AGENTS.md",
|
|
19
20
|
"!dist/**/*.test.*",
|
|
20
21
|
"!dist/**/*.spec.*"
|
|
21
22
|
],
|
|
@@ -25,7 +26,8 @@
|
|
|
25
26
|
"exports": {
|
|
26
27
|
".": {
|
|
27
28
|
"types": "./dist/index.d.ts",
|
|
28
|
-
"svelte": "./dist/index.js"
|
|
29
|
+
"svelte": "./dist/index.js",
|
|
30
|
+
"default": "./dist/index.js"
|
|
29
31
|
},
|
|
30
32
|
"./styles": "./dist/styles/index.css",
|
|
31
33
|
"./styles/tokens": "./dist/styles/tokens.css",
|
|
@@ -38,19 +40,23 @@
|
|
|
38
40
|
},
|
|
39
41
|
"./components/ui/*": {
|
|
40
42
|
"types": "./dist/components/ui/*/index.d.ts",
|
|
41
|
-
"svelte": "./dist/components/ui/*/index.js"
|
|
43
|
+
"svelte": "./dist/components/ui/*/index.js",
|
|
44
|
+
"default": "./dist/components/ui/*/index.js"
|
|
42
45
|
},
|
|
43
46
|
"./components/ui/*/index.js": {
|
|
44
47
|
"types": "./dist/components/ui/*/index.d.ts",
|
|
45
|
-
"svelte": "./dist/components/ui/*/index.js"
|
|
48
|
+
"svelte": "./dist/components/ui/*/index.js",
|
|
49
|
+
"default": "./dist/components/ui/*/index.js"
|
|
46
50
|
},
|
|
47
51
|
"./components/brand": {
|
|
48
52
|
"types": "./dist/components/brand/index.d.ts",
|
|
49
|
-
"svelte": "./dist/components/brand/index.js"
|
|
53
|
+
"svelte": "./dist/components/brand/index.js",
|
|
54
|
+
"default": "./dist/components/brand/index.js"
|
|
50
55
|
},
|
|
51
56
|
"./components/brand/index.js": {
|
|
52
57
|
"types": "./dist/components/brand/index.d.ts",
|
|
53
|
-
"svelte": "./dist/components/brand/index.js"
|
|
58
|
+
"svelte": "./dist/components/brand/index.js",
|
|
59
|
+
"default": "./dist/components/brand/index.js"
|
|
54
60
|
}
|
|
55
61
|
},
|
|
56
62
|
"scripts": {
|