fvn-ui 0.1.0-alpha.7 → 0.1.0-alpha.71
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 +211 -0
- package/LLM.md +916 -0
- package/README.md +220 -22
- package/RULES.md +240 -0
- package/bin/docs.js +30 -0
- package/dist/ui.esm.js +2835 -0
- package/dist/ui.js +17 -0
- package/package.json +14 -3
- package/src/fvn-ui/LLM.md +922 -112
- package/src/fvn-ui/browser.js +4 -1
- package/src/fvn-ui/components/avatar.css +1 -0
- package/src/fvn-ui/components/button.css +68 -6
- package/src/fvn-ui/components/button.js +85 -7
- package/src/fvn-ui/components/card.css +8 -0
- package/src/fvn-ui/components/card.js +5 -4
- package/src/fvn-ui/components/collapsible.css +4 -0
- package/src/fvn-ui/components/collapsible.js +5 -5
- package/src/fvn-ui/components/confirm.js +6 -4
- package/src/fvn-ui/components/dashboard.js +2 -1
- package/src/fvn-ui/components/dialog.css +9 -4
- package/src/fvn-ui/components/dialog.js +130 -98
- package/src/fvn-ui/components/draggable.css +67 -0
- package/src/fvn-ui/components/draggable.js +204 -0
- package/src/fvn-ui/components/editable.css +125 -0
- package/src/fvn-ui/components/editable.js +1045 -0
- package/src/fvn-ui/components/index.js +96 -23
- package/src/fvn-ui/components/input.css +81 -5
- package/src/fvn-ui/components/input.js +197 -21
- package/src/fvn-ui/components/label.css +2 -0
- package/src/fvn-ui/components/select.css +40 -7
- package/src/fvn-ui/components/select.js +126 -46
- package/src/fvn-ui/components/svg.css +1 -0
- package/src/fvn-ui/components/svg.js +75 -26
- package/src/fvn-ui/components/switch.css +1 -0
- package/src/fvn-ui/components/tabs.css +21 -6
- package/src/fvn-ui/components/tabs.js +22 -19
- package/src/fvn-ui/components/text.css +23 -1
- package/src/fvn-ui/components/text.js +55 -13
- package/src/fvn-ui/components/toggle.css +1 -0
- package/src/fvn-ui/components/toggle.js +6 -3
- package/src/fvn-ui/components/upload.css +119 -0
- package/src/fvn-ui/components/upload.js +461 -0
- package/src/fvn-ui/components/validation.js +158 -0
- package/src/fvn-ui/dom.js +151 -66
- package/src/fvn-ui/index.js +79 -11
- package/src/fvn-ui/style.css +123 -87
package/AGENTS.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# fvn-ui — AI Agent Instructions
|
|
2
|
+
|
|
3
|
+
> **For AI assistants**: This file contains instructions for working with fvn-ui.
|
|
4
|
+
> See `LLM.md` in this package for complete API documentation and examples.
|
|
5
|
+
|
|
6
|
+
## Quick Start
|
|
7
|
+
|
|
8
|
+
```js
|
|
9
|
+
import { ui } from 'fvn-ui'
|
|
10
|
+
|
|
11
|
+
// All components available via ui namespace
|
|
12
|
+
ui.button({ label: 'Click me', variant: 'primary' })
|
|
13
|
+
ui.input({ label: 'Name', placeholder: 'Enter name...' })
|
|
14
|
+
ui.switch({ label: 'Enable feature' })
|
|
15
|
+
ui.card({ title: 'Card', content: [...] })
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Critical Rules
|
|
19
|
+
|
|
20
|
+
1. **Always use `ui.` namespace** — Import `{ ui }` not individual components
|
|
21
|
+
2. **Labels on all inputs** — Every input/select needs a `label` prop
|
|
22
|
+
3. **Use layout helpers** — `ui.row()` and `ui.col()` for structure
|
|
23
|
+
4. **One primary button** — Only one `variant: 'primary'` per view
|
|
24
|
+
5. **Switch for booleans** — Use `ui.switch()` not checkbox for on/off settings
|
|
25
|
+
6. **Placeholder not value** — Use `placeholder` for hints, not `value`
|
|
26
|
+
7. **Zero custom CSS** — fvn-ui provides complete styling (see below)
|
|
27
|
+
|
|
28
|
+
## Event Callbacks
|
|
29
|
+
|
|
30
|
+
All callbacks use consistent `(value, ...context, event)` signature:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
// First arg = unwrapped value, last arg = event
|
|
34
|
+
ui.input({ onInput: (val, e) => console.log(val) })
|
|
35
|
+
ui.checkbox({ onChange: (checked, e) => ... })
|
|
36
|
+
ui.switch({ onChange: (checked, e) => ... })
|
|
37
|
+
ui.radio({ onChange: (value, item, e) => ... })
|
|
38
|
+
ui.select({ onChange: (value, item, e) => ... })
|
|
39
|
+
ui.tabs({ onChange: (value, item, e) => ... })
|
|
40
|
+
|
|
41
|
+
// `this` = element
|
|
42
|
+
ui.input({ onChange(val) { this.dataset.saved = val } })
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## ⚠️ Styling Philosophy — CRITICAL
|
|
46
|
+
|
|
47
|
+
**fvn-ui provides complete styling. Do NOT add custom CSS unless absolutely necessary.**
|
|
48
|
+
|
|
49
|
+
### When Custom CSS is Needed
|
|
50
|
+
- Drag-and-drop visual states (`.dragging`, `.drag-over`)
|
|
51
|
+
- Custom interactive behaviors not in fvn-ui
|
|
52
|
+
- App-level layout constraints (e.g., `max-width` on dashboard)
|
|
53
|
+
|
|
54
|
+
### When Custom CSS is NOT Needed
|
|
55
|
+
- Backgrounds, borders, shadows → use `ui.card()` or `border` prop
|
|
56
|
+
- Spacing/gaps → use `gap` prop on `row()`/`col()`
|
|
57
|
+
- Centering → use `center: true` prop
|
|
58
|
+
- Full-width elements → use `grow: true` prop
|
|
59
|
+
- Padding → use `padding` prop
|
|
60
|
+
- Hover/focus states → fvn-ui components include these
|
|
61
|
+
- Dark mode → fvn-ui handles automatically
|
|
62
|
+
|
|
63
|
+
### Anti-Patterns
|
|
64
|
+
|
|
65
|
+
❌ **Wrong — CSS for layout:**
|
|
66
|
+
```css
|
|
67
|
+
.my-container { display: flex; justify-content: center; }
|
|
68
|
+
```
|
|
69
|
+
```js
|
|
70
|
+
ui.el('div', { class: 'my-container' }, [...])
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
✅ **Correct — Use layout props:**
|
|
74
|
+
```js
|
|
75
|
+
ui.col({ center: true }, [...])
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
❌ **Wrong — CSS for backgrounds/borders:**
|
|
79
|
+
```css
|
|
80
|
+
.toolbar { background: #f9fafb; border: 1px solid #e5e7eb; }
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
✅ **Correct — Use card or clean layout:**
|
|
84
|
+
```js
|
|
85
|
+
ui.row({ gap: 2 }, [...]) // Clean, no background needed
|
|
86
|
+
ui.card({ content: [...] }) // When you need a bordered container
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Minimal CSS Template
|
|
90
|
+
|
|
91
|
+
```css
|
|
92
|
+
/* Only add what fvn-ui cannot do */
|
|
93
|
+
.ui-dashboard { max-width: 1000px; margin: 0 auto; }
|
|
94
|
+
|
|
95
|
+
/* Custom interactive states */
|
|
96
|
+
.draggable.dragging { opacity: 0.5; }
|
|
97
|
+
.draggable.drag-over { border-style: dashed; }
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Component Selection
|
|
101
|
+
|
|
102
|
+
| Need | Use |
|
|
103
|
+
|------|-----|
|
|
104
|
+
| On/off setting | `ui.switch({ label })` |
|
|
105
|
+
| Agreement/terms | `ui.checkbox({ label })` |
|
|
106
|
+
| 2-5 options | `ui.radio({ items: [...] })` |
|
|
107
|
+
| 6+ options | `ui.select({ options: [...] })` |
|
|
108
|
+
| Short text | `ui.input({ label })` |
|
|
109
|
+
| Long text | `ui.input({ label, rows: 4 })` |
|
|
110
|
+
| Validated input | `ui.input({ label, validate: 'email' })` |
|
|
111
|
+
| Action | `ui.button({ label, onClick })` |
|
|
112
|
+
|
|
113
|
+
## Layout Pattern
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
ui.card({
|
|
117
|
+
title: 'Form',
|
|
118
|
+
content: ui.col({ gap: 4 }, [
|
|
119
|
+
ui.input({ label: 'Field 1' }),
|
|
120
|
+
ui.input({ label: 'Field 2' }),
|
|
121
|
+
ui.row({ gap: 2 }, [
|
|
122
|
+
ui.button({ label: 'Cancel', variant: 'ghost' }),
|
|
123
|
+
ui.button({ label: 'Save', variant: 'primary', end: true })
|
|
124
|
+
])
|
|
125
|
+
])
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
// Inputs in a row (rows grow by default now)
|
|
129
|
+
ui.row([
|
|
130
|
+
ui.input({ label: 'First' }),
|
|
131
|
+
ui.input({ label: 'Last' })
|
|
132
|
+
])
|
|
133
|
+
|
|
134
|
+
// Vertically center content in a column
|
|
135
|
+
ui.col({ center: true }, [
|
|
136
|
+
ui.avatar({ name: 'John' })
|
|
137
|
+
])
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Input Validation
|
|
141
|
+
|
|
142
|
+
```js
|
|
143
|
+
// Required fields
|
|
144
|
+
ui.input({ label: 'Name', required: true })
|
|
145
|
+
ui.select({ label: 'Country', required: true, options: countries })
|
|
146
|
+
|
|
147
|
+
// Built-in validators: 'email', 'url', 'phone'
|
|
148
|
+
ui.input({ label: 'Email', validate: 'email', message: 'Invalid email' })
|
|
149
|
+
|
|
150
|
+
// With counter and limits
|
|
151
|
+
ui.input({ label: 'Bio', rows: 4, min: 10, max: 500, counter: true })
|
|
152
|
+
|
|
153
|
+
// Check validation (works with required, validate, min/max)
|
|
154
|
+
const name = ui.input({ label: 'Name', required: true })
|
|
155
|
+
const country = ui.select({ label: 'Country', required: true, options })
|
|
156
|
+
if (name.isValid() && country.isValid()) { /* submit */ }
|
|
157
|
+
|
|
158
|
+
// Manual validation (form validation)
|
|
159
|
+
const field = ui.input({ label: 'Name' })
|
|
160
|
+
field.error('Required') // mark invalid with message
|
|
161
|
+
field.ok() // clear error
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Layout Shorthands
|
|
165
|
+
|
|
166
|
+
| Prop | Effect |
|
|
167
|
+
|------|--------|
|
|
168
|
+
| `center: true` | Center on main axis |
|
|
169
|
+
| `start: true` | Align start (left for row, top for col) |
|
|
170
|
+
| `end: true` | Align end (right for row, bottom for col) |
|
|
171
|
+
| `grow: false` | Shrink to content (default is grow) |
|
|
172
|
+
|
|
173
|
+
**Child props:**
|
|
174
|
+
|
|
175
|
+
| Prop | Effect |
|
|
176
|
+
|------|--------|
|
|
177
|
+
| `end: true` | Push to end (right in row, bottom in col) |
|
|
178
|
+
| `start: true` | Push to start |
|
|
179
|
+
| `self: 'start'` | Align self: `'start'`, `'center'`, `'end'` |
|
|
180
|
+
|
|
181
|
+
## CSS Variables
|
|
182
|
+
|
|
183
|
+
Common variables for custom styling (see `style.css` for full list):
|
|
184
|
+
|
|
185
|
+
| Variable | Description |
|
|
186
|
+
|----------|-------------|
|
|
187
|
+
| `--space-1` to `--space-10` | Spacing scale (gap, padding) |
|
|
188
|
+
| `--back`, `--text`, `--muted` | Background, text, muted colors |
|
|
189
|
+
| `--hover`, `--border` | Hover and border colors |
|
|
190
|
+
| `--radius` | Common border radius |
|
|
191
|
+
|
|
192
|
+
## Custom Icons
|
|
193
|
+
|
|
194
|
+
Extend with icons from [Lucide](https://lucide.dev/icons) or [Feather](https://feathericons.com):
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
// Add icons using SVG inner content (no <svg> wrapper)
|
|
198
|
+
ui.svg.extend({
|
|
199
|
+
github: '<path d="M15 22v-4a4.8..."/>',
|
|
200
|
+
custom: '<circle cx="12" cy="12" r="10"/>'
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
ui.button({ icon: 'github' }) // Now works
|
|
204
|
+
ui.svg.list() // Get all icon names
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Full Documentation
|
|
208
|
+
|
|
209
|
+
For complete API reference, examples, and patterns, read:
|
|
210
|
+
- **LLM.md** — Full component documentation in this package
|
|
211
|
+
- **README.md** — Installation and usage overview
|