my-you-eye 0.2.0 → 0.2.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.
- package/COMPONENTS.md +111 -0
- package/README.md +119 -74
- package/SKILL.md +64 -0
- package/bin/my-you-eye.mjs +97 -0
- package/components.json +841 -0
- package/dist/index.d.ts +66 -11
- package/dist/index.js +1614 -673
- package/package.json +14 -5
package/COMPONENTS.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Components
|
|
2
|
+
|
|
3
|
+
> Auto-generated from `*.showcase.tsx` by `scripts/gen-manifest.mjs`. Do not edit by hand.
|
|
4
|
+
|
|
5
|
+
All components import from the package root:
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Button, Card } from "my-you-eye";
|
|
9
|
+
import "my-you-eye/styles.css";
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
**53 components** across 9 groups.
|
|
13
|
+
|
|
14
|
+
## canvas
|
|
15
|
+
|
|
16
|
+
| Component | Variants | Demos |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `Canvas` | — | Empty grid |
|
|
19
|
+
| `Edge` | variant: bezier / stepped / straight<br>state: connected | Path variants, Edge states |
|
|
20
|
+
| `Graph` | type: button | Pipeline editor (drag nodes, connect ports, delete selected) |
|
|
21
|
+
| `GraphNode` | variant: muted / selected | Variants |
|
|
22
|
+
| `Port` | state: connected / default / highlighted | States |
|
|
23
|
+
|
|
24
|
+
## data
|
|
25
|
+
|
|
26
|
+
| Component | Variants | Demos |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `CellType` | type: array / audio / badge / boolean / bytes / currency / date-human / date-system / datetime-tz / duration / email / image / json / null / number / percentage / signed / status / text / tree / url | Data Types, Project X, Project X, Numeric types |
|
|
29
|
+
| `DataTable` | variant: striped<br>density: compact | Alice, Bob, Charlie, Diana, Eve, Frank, Grace, Ivy, Leo, Olivia, Default, Striped, Scrolling + sticky header, Truncation |
|
|
30
|
+
| `List` | variant: compact | Default & Compact, Striped, Scrolling |
|
|
31
|
+
| `TreeView` | type: button<br>variant: condensed | Default vs Condensed, Depth-based expand, Controlled expand state, Leading icons (click a row, then use arrow keys), Messy nested payload (hover to trace depth guides) |
|
|
32
|
+
|
|
33
|
+
## display
|
|
34
|
+
|
|
35
|
+
| Component | Variants | Demos |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `Avatar` | size: lg / md / sm | Sizes, Fallback variants, With image, With ring, With status dot |
|
|
38
|
+
| `Badge` | variant: danger / neutral / primary / success / warning<br>style: soft | Variants (solid), Variants (soft) |
|
|
39
|
+
| `Card` | variant: danger / default / elevated / ghost / outlined<br>size: sm | Variants, With footer actions |
|
|
40
|
+
| `CodeBlock` | variant: elevated | Bare (no header, no language), Language-only (badge overlay, no header bar), With header + language, Elevated, Line numbers, No wrap (horizontal scroll) |
|
|
41
|
+
| `EmptyState` | variant: secondary | Default, With icon and action |
|
|
42
|
+
| `Image` | — | Fit modes, Border radius, Aspect ratio, Styles, With caption |
|
|
43
|
+
| `Kbd` | — | Default, Combinations |
|
|
44
|
+
| `Markdown` | — | Rendered markdown |
|
|
45
|
+
| `ScrollArea` | — | Vertical scroll, Horizontal scroll |
|
|
46
|
+
| `Separator` | orientation: vertical | Horizontal, Vertical |
|
|
47
|
+
| `StatusDot` | variant: danger / info / neutral / success / warning<br>size: md / sm | Variants, Sizes, Pulsing |
|
|
48
|
+
|
|
49
|
+
## feedback
|
|
50
|
+
|
|
51
|
+
| Component | Variants | Demos |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `Alert` | variant: danger / info / success / warning | Variants, With title, With icon |
|
|
54
|
+
| `Progress` | variant: danger / default / success / warning | Variants, No label |
|
|
55
|
+
| `Saved` | variant: danger / secondary | Trigger toasts |
|
|
56
|
+
| `Skeleton` | shape: circle / rect / text | Shapes |
|
|
57
|
+
| `Spinner` | size: lg / md / sm | Sizes |
|
|
58
|
+
|
|
59
|
+
## inputs
|
|
60
|
+
|
|
61
|
+
| Component | Variants | Demos |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `Button` | variant: danger / ghost / primary / secondary<br>size: lg / md / sm | Variants, Sizes, Disabled & loading |
|
|
64
|
+
| `Checkbox` | size: md / sm | Sizes, States |
|
|
65
|
+
| `Combobox` | — | Basic, Disabled |
|
|
66
|
+
| `FileDrop` | — | Default, Single image only |
|
|
67
|
+
| `Input` | variant: filled<br>size: md / sm | Variants, Sizes, States |
|
|
68
|
+
| `Label` | — | Default |
|
|
69
|
+
| `MultiSelect` | — | Basic, Empty, Disabled |
|
|
70
|
+
| `RadioGroup` | — | Default |
|
|
71
|
+
| `Select` | size: md / sm | Sizes, States, No indicator |
|
|
72
|
+
| `Slider` | — | Basic slider |
|
|
73
|
+
| `Switch` | size: md / sm | Sizes, States |
|
|
74
|
+
| `Textarea` | variant: filled | Variants, States |
|
|
75
|
+
|
|
76
|
+
## navigation
|
|
77
|
+
|
|
78
|
+
| Component | Variants | Demos |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| `Breadcrumbs` | — | Default, Custom separator |
|
|
81
|
+
| `Pagination` | — | Default (10 pages), Few pages |
|
|
82
|
+
| `Tabs` | variant: filing / pills / underline | Underline, Pills, Filing |
|
|
83
|
+
|
|
84
|
+
## overlay
|
|
85
|
+
|
|
86
|
+
| Component | Variants | Demos |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `CommandPalette` | variant: secondary | Basic, With groups |
|
|
89
|
+
| `Dialog` | size: lg / md / sm<br>variant: ghost | Sizes, Form example |
|
|
90
|
+
| `Drawer` | side: left / right<br>size: md / sm<br>variant: secondary | Left & Right |
|
|
91
|
+
| `DropdownMenu` | variant: secondary | Default |
|
|
92
|
+
| `Popover` | variant: secondary<br>size: sm | Default |
|
|
93
|
+
| `Tooltip` | side: bottom / left / right / top<br>variant: secondary | Directions |
|
|
94
|
+
|
|
95
|
+
## patterns
|
|
96
|
+
|
|
97
|
+
| Component | Variants | Demos |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `ConfirmDialog` | variant: danger / secondary | Variants |
|
|
100
|
+
| `FormField` | type: password | Default, With hint, Required with error |
|
|
101
|
+
| `PageShell` | variant: secondary | Default, With actions |
|
|
102
|
+
| `StatCard` | — | Default |
|
|
103
|
+
| `TexturedSurface` | variant: elevated / ghost / primary / surface<br>size: sm | Tuner, Paper grain, Frosted glass, Brushed aluminium, Paper grain — full matrix, Frosted glass — full matrix, Brushed aluminium — full matrix, Theme-driven, Composed |
|
|
104
|
+
| `Toolbar` | size: sm<br>variant: primary / secondary<br>style: soft | All slots filled, With leading label, Result count + removable filter chips, Narrow / responsive collapse |
|
|
105
|
+
|
|
106
|
+
## typography
|
|
107
|
+
|
|
108
|
+
| Component | Variants | Demos |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| `Typography & Tokens` | — | Font families, Text sizes, Colors, Radius & spacing |
|
|
111
|
+
|
package/README.md
CHANGED
|
@@ -1,109 +1,154 @@
|
|
|
1
|
-
#
|
|
1
|
+
# my-you-eye
|
|
2
2
|
|
|
3
|
-
A
|
|
4
|
-
|
|
5
|
-
without
|
|
3
|
+
A themeable, AI-maintainable UI component library — primitives, rich data components, and a
|
|
4
|
+
full **node-based canvas editor** — built so that agents (even cheap ones) can reuse and extend
|
|
5
|
+
it without drifting from the house style.
|
|
6
6
|
|
|
7
|
-
>
|
|
8
|
-
> It is the binding ruleset. Nothing in this README overrides it.**
|
|
7
|
+
<sub>Radix · Tailwind v4 · CVA · shadcn-style owned components · 50+ components · light/dark + swappable themes</sub>
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
each with a small fixed set of approved design variants.
|
|
14
|
-
- A **showcase app** (`src/showcase/`) that renders every component and every variant,
|
|
15
|
-
auto-discovered from `*.showcase.tsx` files — nothing is registered by hand.
|
|
16
|
-
- A **validation pipeline** (`npm run validate`) that makes rule violations a red build
|
|
17
|
-
instead of something a human has to discover later.
|
|
18
|
-
|
|
19
|
-
## What this repo is NOT
|
|
20
|
-
|
|
21
|
-
- Not a general component library for the world. It is *our* house standard.
|
|
22
|
-
- Not a place for app business logic. Components here are presentation + interaction only.
|
|
23
|
-
- Not a parts bin of one-off styles. Every visual decision flows from tokens and variants.
|
|
24
|
-
|
|
25
|
-
## Stack
|
|
9
|
+
```tsx
|
|
10
|
+
import { Button, Card, Table } from "my-you-eye";
|
|
11
|
+
import "my-you-eye/styles.css";
|
|
26
12
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
| Build/dev | Vite + React 18 + TypeScript (strict) | Simple SPA, no SSR footguns, fast |
|
|
30
|
-
| Styling | Tailwind CSS v4 (local build, no CDN) | Compiled at build time, zero runtime remote deps |
|
|
31
|
-
| Behavior primitives | Radix UI (per-component packages) | Mature accessibility (focus, keyboard, ARIA) |
|
|
32
|
-
| Variants | `class-variance-authority` (CVA) | Declarative, enforceable variant sets |
|
|
33
|
-
| Class merging | `clsx` + `tailwind-merge` via `cn()` | Predictable `className` overrides |
|
|
34
|
-
| Library build | `tsup` (runs on `prepare`) | Consumable via `npm install` from a git URL |
|
|
13
|
+
<Button variant="primary">Save</Button>
|
|
14
|
+
```
|
|
35
15
|
|
|
36
|
-
|
|
37
|
-
and owned here. There is no upstream component dependency that can break or restyle us.
|
|
16
|
+
---
|
|
38
17
|
|
|
39
|
-
##
|
|
18
|
+
## Highlights
|
|
40
19
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
index.ts # re-exports
|
|
54
|
-
...
|
|
55
|
-
patterns/ # composed components (built FROM primitives)
|
|
56
|
-
form-field/
|
|
57
|
-
...
|
|
58
|
-
showcase/ # showcase app shell (dev-only, not exported)
|
|
59
|
-
App.tsx # glob-discovers *.showcase.tsx, renders group tabs
|
|
60
|
-
types.ts # ShowcaseEntry contract
|
|
61
|
-
scripts/
|
|
62
|
-
check-showcase.mjs # fails if any component folder lacks a showcase file
|
|
63
|
-
AGENTS.md # binding rules for AI agents
|
|
64
|
-
TODO.md # bootstrap plan + component backlog
|
|
65
|
-
```
|
|
20
|
+
- **50+ components** — inputs, overlays, feedback, navigation, and rich data (`Table`,
|
|
21
|
+
`TreeView`, `CellValue`, `DataList`, `CodeBlock`, `Markdown`). Full list:
|
|
22
|
+
**[COMPONENTS.md](./COMPONENTS.md)**.
|
|
23
|
+
- **Canvas / data-orchestration editor** — `Canvas`, `GraphNode`, `Port`, `Edge`, plus an
|
|
24
|
+
`Orchestrator` pattern with node drag, grid snapping, port-to-port connections, pan/zoom,
|
|
25
|
+
selection, and delete.
|
|
26
|
+
- **Themes without forks** — every color, radius, spacing, font, and border value is a CSS
|
|
27
|
+
token. A theme is a token-override block; `data-theme` + `.dark` swap the entire look. No
|
|
28
|
+
component is restyled per theme.
|
|
29
|
+
- **Guardrails, not vibes** — `npm run validate` turns rule violations into a red build: no
|
|
30
|
+
styled native elements outside `src/ui/`, no hardcoded colors, every component has a showcase,
|
|
31
|
+
every theme defines the full token set.
|
|
66
32
|
|
|
67
|
-
##
|
|
33
|
+
## Install
|
|
68
34
|
|
|
69
35
|
```bash
|
|
70
|
-
npm install github
|
|
36
|
+
npm install github:sadigaxund/my-you-eye
|
|
71
37
|
```
|
|
72
38
|
|
|
73
39
|
```tsx
|
|
74
|
-
|
|
40
|
+
// once, at your app root
|
|
75
41
|
import "my-you-eye/styles.css";
|
|
42
|
+
// anywhere
|
|
43
|
+
import { Dialog, TreeView } from "my-you-eye";
|
|
76
44
|
```
|
|
77
45
|
|
|
78
|
-
To pick up changes
|
|
46
|
+
To pick up changes: bump the tag here, then `npm update` in each app.
|
|
79
47
|
|
|
80
|
-
##
|
|
48
|
+
## Customize — three channels, in order of preference
|
|
81
49
|
|
|
82
|
-
1. **Theme tokens** — global restyle
|
|
83
|
-
|
|
50
|
+
1. **Theme tokens** — global restyle, zero code. Override the CSS variables at your root, or
|
|
51
|
+
set `data-theme="neon"` / `class="dark"` on `<html>`.
|
|
84
52
|
```css
|
|
85
53
|
:root {
|
|
86
|
-
--
|
|
87
|
-
--ui
|
|
54
|
+
--color-primary: oklch(0.6 0.2 25);
|
|
55
|
+
--radius-ui: 4px;
|
|
88
56
|
}
|
|
89
57
|
```
|
|
90
|
-
2. **Variant props** — per-
|
|
58
|
+
2. **Variant props** — per-use choice from the approved set (see [COMPONENTS.md](./COMPONENTS.md)):
|
|
91
59
|
```tsx
|
|
92
60
|
<Button variant="danger" size="sm">Delete</Button>
|
|
93
61
|
```
|
|
94
|
-
3. **`className`** — one-off *layout*
|
|
62
|
+
3. **`className`** — one-off *layout* only (width, margin), never a redesign:
|
|
95
63
|
```tsx
|
|
96
64
|
<Button className="w-full">Submit</Button>
|
|
97
65
|
```
|
|
98
66
|
|
|
99
|
-
If a `className` tweak keeps recurring, it
|
|
67
|
+
If a `className` tweak keeps recurring, it should become a variant in this repo — see
|
|
68
|
+
[AGENTS.md](./AGENTS.md).
|
|
69
|
+
|
|
70
|
+
## Discovering components (humans and agents)
|
|
71
|
+
|
|
72
|
+
`components.json` and [COMPONENTS.md](./COMPONENTS.md) are **auto-generated** from the showcase
|
|
73
|
+
files on every commit and every library build, so they never drift. An agent working in a
|
|
74
|
+
consuming app should read `components.json` and follow [SKILL.md](./SKILL.md) before building
|
|
75
|
+
any UI.
|
|
76
|
+
|
|
77
|
+
## CLI
|
|
78
|
+
|
|
79
|
+
The package ships a tiny Node CLI (`my-you-eye`) for project setup:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
my-you-eye init Copy SKILL.md + components.json to skills/
|
|
83
|
+
my-you-eye list Print table of all components with groups and variants
|
|
84
|
+
my-you-eye sync Re-copy SKILL.md + components.json (overwrite)
|
|
85
|
+
my-you-eye --help Show usage
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
All file paths resolve from the package location, not the caller's cwd. The CLI has zero external dependencies.
|
|
89
|
+
|
|
90
|
+
## The showcase
|
|
100
91
|
|
|
101
|
-
|
|
92
|
+
Every component and every variant renders in a live showcase with light/dark, font, and theme
|
|
93
|
+
switches — the source of truth for how things actually look.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npm run dev # http://localhost:5173
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## What this is / is not
|
|
100
|
+
|
|
101
|
+
- **Is** a curated house standard: primitives in `src/ui/`, compositions in `src/ui/patterns/`,
|
|
102
|
+
each with a small fixed set of approved variants.
|
|
103
|
+
- **Is not** a general-purpose library for the world, a home for business logic or data
|
|
104
|
+
fetching, or a parts bin of one-off styles.
|
|
105
|
+
|
|
106
|
+
## For contributors and agents
|
|
107
|
+
|
|
108
|
+
> **If you are an AI agent working in this repo, read [AGENTS.md](./AGENTS.md) first.** It is
|
|
109
|
+
> the binding ruleset; nothing here overrides it.
|
|
102
110
|
|
|
103
111
|
```bash
|
|
104
112
|
npm install
|
|
105
|
-
npm run dev # showcase
|
|
106
|
-
npm run validate # typecheck + lint +
|
|
113
|
+
npm run dev # showcase
|
|
114
|
+
npm run validate # typecheck + lint + coverage + themes + build — the definition of done
|
|
115
|
+
npm run audit # non-blocking drift report
|
|
116
|
+
npm run manifest # regenerate components.json + COMPONENTS.md
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
| Concern | Choice | Why |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| Build/dev | Vite + React + TypeScript (strict) | Simple SPA, no SSR footguns |
|
|
122
|
+
| Styling | Tailwind CSS v4 (local build, no CDN) | Compiled at build time, no remote deps |
|
|
123
|
+
| Behavior | Radix UI (per-component packages) | Mature accessibility: focus, keyboard, ARIA |
|
|
124
|
+
| Variants | `class-variance-authority` | Declarative, enforceable variant sets |
|
|
125
|
+
| Class merging | `clsx` + `tailwind-merge` via `cn()` | Predictable `className` overrides |
|
|
126
|
+
| Library build | `tsup` | Consumable via `npm install` from a git URL |
|
|
127
|
+
|
|
128
|
+
Components follow the **shadcn/ui pattern**: code is copied in and owned here, so no upstream
|
|
129
|
+
dependency can break or restyle us.
|
|
130
|
+
|
|
131
|
+
### Layout
|
|
132
|
+
|
|
107
133
|
```
|
|
134
|
+
src/
|
|
135
|
+
index.ts # public API — the ONLY entry consuming apps import from
|
|
136
|
+
lib/cn.ts # clsx + tailwind-merge helper
|
|
137
|
+
styles/
|
|
138
|
+
tokens.css # ALL base design tokens
|
|
139
|
+
themes/*.css # per-theme token overrides (dark, neon, contrast, …)
|
|
140
|
+
globals.css # tailwind entry, global scrollbar, base styles
|
|
141
|
+
ui/<component>/ # Component.tsx + Component.showcase.tsx + index.ts
|
|
142
|
+
ui/patterns/ # compositions built FROM primitives (FormField, Orchestrator, …)
|
|
143
|
+
showcase/ # dev-only showcase app (glob-discovers *.showcase.tsx)
|
|
144
|
+
scripts/
|
|
145
|
+
check-showcase.mjs # every component folder has a showcase + export
|
|
146
|
+
check-themes.mjs # every theme defines the full token set
|
|
147
|
+
gen-manifest.mjs # regenerates components.json + COMPONENTS.md
|
|
148
|
+
audit.mjs # non-blocking drift report
|
|
149
|
+
AGENTS.md · SKILL.md · TODO.md · CHANGELOG.md
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## License
|
|
108
153
|
|
|
109
|
-
|
|
154
|
+
See [LICENSE](./LICENSE).
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: my-you-eye
|
|
3
|
+
description: Use the my-you-eye UI component library. Invoke before building ANY UI — buttons, inputs, cards, dialogs, tables, tree views, canvas/graph/pipeline editors — in a project that depends on this package, so you reuse an existing component instead of hand-rolling native HTML. Read the manifest first.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# my-you-eye — UI component library
|
|
7
|
+
|
|
8
|
+
This project ships a fixed set of themeable, accessible UI components. **Never hand-roll a
|
|
9
|
+
styled `<button>`, `<input>`, `<select>`, `<table>`, `<a>`, or a bespoke card/dialog/menu.**
|
|
10
|
+
There is almost certainly already a component for it.
|
|
11
|
+
|
|
12
|
+
## Step 1 — find the component (always do this first)
|
|
13
|
+
|
|
14
|
+
Read `components.json` (or the human-readable `COMPONENTS.md`) at the package root. It is
|
|
15
|
+
auto-generated from the library's showcases and lists **every** component, its group, and its
|
|
16
|
+
variant props. Pick the component whose name/group matches what you need.
|
|
17
|
+
|
|
18
|
+
### inputs
|
|
19
|
+
Button, Checkbox, Combobox, FileDrop, Input, Label, MultiSelect, RadioGroup, Select, Slider, Switch, Textarea
|
|
20
|
+
|
|
21
|
+
### display
|
|
22
|
+
Avatar, Badge, Card, CodeBlock, DataList, EmptyState, Image, Kbd, Markdown, ScrollArea, Separator, Skeleton, StatusDot, Typography
|
|
23
|
+
|
|
24
|
+
### feedback
|
|
25
|
+
Alert, Progress, Spinner, Toast
|
|
26
|
+
|
|
27
|
+
### overlay
|
|
28
|
+
CommandPalette, Dialog, Drawer, DropdownMenu, Popover, Tooltip
|
|
29
|
+
|
|
30
|
+
### navigation
|
|
31
|
+
Breadcrumbs, Pagination, Tabs
|
|
32
|
+
|
|
33
|
+
### canvas
|
|
34
|
+
Canvas, ConnectionLine, Edge, GraphNode, Orchestrator, Port
|
|
35
|
+
|
|
36
|
+
### data
|
|
37
|
+
CellValue, Table, TreeView
|
|
38
|
+
|
|
39
|
+
### patterns
|
|
40
|
+
ConfirmDialog, DataTable, FormField, PageShell, StatCard, Toolbar
|
|
41
|
+
|
|
42
|
+
## Step 2 — use it
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { Button, Card, Table } from "my-you-eye";
|
|
46
|
+
import "my-you-eye/styles.css"; // once, at the app root
|
|
47
|
+
|
|
48
|
+
<Button variant="primary" size="md">Save</Button>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Pick behavior with **variant props** from the manifest's allowed set. Use `className` only for
|
|
52
|
+
one-off **layout** (width, margin) — never to restyle. If you keep re-adding the same
|
|
53
|
+
`className`, the right fix is a new variant in the library, not a local override.
|
|
54
|
+
|
|
55
|
+
## Step 3 — customize by theme, not by fork
|
|
56
|
+
|
|
57
|
+
All color, radius, spacing, typography, border, and surface values come from CSS variables.
|
|
58
|
+
To restyle globally, override the tokens at your app root or set `data-theme="<name>"` /
|
|
59
|
+
`.dark` on `<html>` — do not copy component code or wrap components in style overrides.
|
|
60
|
+
|
|
61
|
+
## If a component genuinely does not exist
|
|
62
|
+
|
|
63
|
+
It belongs in the library, not in the consuming app. Add it upstream in `src/ui/` following
|
|
64
|
+
that repo's `AGENTS.md`, then consume it here. Do not inline a new primitive locally.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
4
|
+
import { join, dirname } from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
|
|
7
|
+
const ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
8
|
+
const SKILL = join(ROOT, "SKILL.md");
|
|
9
|
+
const COMPONENTS_JSON = join(ROOT, "components.json");
|
|
10
|
+
|
|
11
|
+
function usage(exitCode = 0) {
|
|
12
|
+
console.log(`my-you-eye v0.2.0 — UI Component Toolkit
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
my-you-eye init [--force] Copy SKILL.md + components.json to skills/
|
|
16
|
+
my-you-eye list List all components with groups and variants
|
|
17
|
+
my-you-eye sync Re-copy SKILL.md + components.json (overwrite)
|
|
18
|
+
|
|
19
|
+
Options:
|
|
20
|
+
--help Show this help
|
|
21
|
+
--force Overwrite existing files (init only)`);
|
|
22
|
+
process.exit(exitCode);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function cmdInit(force) {
|
|
26
|
+
const sourceFiles = [
|
|
27
|
+
{ src: SKILL, name: "SKILL.md" },
|
|
28
|
+
{ src: COMPONENTS_JSON, name: "components.json" },
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
const targetDir = join(process.cwd(), "skills");
|
|
32
|
+
if (!existsSync(targetDir)) {
|
|
33
|
+
mkdirSync(targetDir, { recursive: true });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for (const file of sourceFiles) {
|
|
37
|
+
const target = join(targetDir, file.name);
|
|
38
|
+
if (existsSync(target) && !force) {
|
|
39
|
+
console.log(` skipped ${file.name} (already exists, use --force to overwrite)`);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const content = readFileSync(file.src, "utf-8");
|
|
43
|
+
writeFileSync(target, content, "utf-8");
|
|
44
|
+
console.log(` written ${target}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function cmdList() {
|
|
49
|
+
const raw = readFileSync(COMPONENTS_JSON, "utf-8");
|
|
50
|
+
const { components } = JSON.parse(raw);
|
|
51
|
+
|
|
52
|
+
const groups = {};
|
|
53
|
+
for (const c of components) {
|
|
54
|
+
(groups[c.group] ??= []).push(c);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const groupOrder = ["inputs", "display", "feedback", "overlay", "navigation", "canvas", "data", "patterns"];
|
|
58
|
+
|
|
59
|
+
for (const group of groupOrder) {
|
|
60
|
+
if (!groups[group]) continue;
|
|
61
|
+
console.log(`\n ${group}`);
|
|
62
|
+
console.log(` ${"-".repeat(group.length)}`);
|
|
63
|
+
for (const c of groups[group]) {
|
|
64
|
+
const variants = Object.entries(c.variants)
|
|
65
|
+
.map(([k, v]) => `${k}: ${v.join(" | ")}`)
|
|
66
|
+
.join(", ");
|
|
67
|
+
console.log(` ${c.name}${variants ? ` (${variants})` : ""}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function cmdSync() {
|
|
73
|
+
cmdInit(true);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const args = process.argv.slice(2);
|
|
77
|
+
const force = args.includes("--force");
|
|
78
|
+
const cmd = args.find((a) => a !== "--force");
|
|
79
|
+
|
|
80
|
+
if (!cmd || cmd === "--help") {
|
|
81
|
+
usage(cmd === "--help" ? 0 : 1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
switch (cmd) {
|
|
85
|
+
case "init":
|
|
86
|
+
await cmdInit(force);
|
|
87
|
+
break;
|
|
88
|
+
case "list":
|
|
89
|
+
cmdList();
|
|
90
|
+
break;
|
|
91
|
+
case "sync":
|
|
92
|
+
cmdSync();
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
console.error(`Unknown command: ${cmd}`);
|
|
96
|
+
usage(1);
|
|
97
|
+
}
|