@ryanhelsing/ry-ui 1.0.2 → 1.0.4
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/AGENT.md +460 -0
- package/AGENTS.md +57 -0
- package/README.md +45 -1
- package/dist/components/ry-button-group.d.ts +32 -0
- package/dist/components/ry-button-group.d.ts.map +1 -0
- package/dist/components/ry-carousel.d.ts +21 -0
- package/dist/components/ry-carousel.d.ts.map +1 -0
- package/dist/components/ry-feature.d.ts +21 -0
- package/dist/components/ry-feature.d.ts.map +1 -0
- package/dist/components/ry-field.d.ts +7 -1
- package/dist/components/ry-field.d.ts.map +1 -1
- package/dist/components/ry-hero.d.ts +16 -0
- package/dist/components/ry-hero.d.ts.map +1 -0
- package/dist/components/ry-number-select.d.ts.map +1 -1
- package/dist/components/ry-pricing.d.ts +21 -0
- package/dist/components/ry-pricing.d.ts.map +1 -0
- package/dist/components/ry-select.d.ts +8 -1
- package/dist/components/ry-select.d.ts.map +1 -1
- package/dist/components/ry-split.d.ts +28 -0
- package/dist/components/ry-split.d.ts.map +1 -0
- package/dist/components/ry-stat.d.ts +17 -0
- package/dist/components/ry-stat.d.ts.map +1 -0
- package/dist/components/ry-tag-input.d.ts +18 -0
- package/dist/components/ry-tag-input.d.ts.map +1 -0
- package/dist/components/ry-tag.d.ts +19 -0
- package/dist/components/ry-tag.d.ts.map +1 -0
- package/dist/core/ry-transform.d.ts.map +1 -1
- package/dist/css/ry-structure.css +739 -149
- package/dist/css/ry-theme.css +581 -180
- package/dist/css/ry-tokens.css +120 -24
- package/dist/css/ry-ui.css +4965 -1065
- package/dist/ry-ui.d.ts +9 -0
- package/dist/ry-ui.d.ts.map +1 -1
- package/dist/ry-ui.js +1309 -778
- package/dist/ry-ui.js.map +1 -1
- package/dist/themes/dark.css +7 -90
- package/dist/themes/light.css +6 -35
- package/dist/themes/ocean.css +22 -26
- package/docs/components/accordion.md +31 -0
- package/docs/components/button-group.md +36 -0
- package/docs/components/button.md +65 -0
- package/docs/components/color.md +84 -0
- package/docs/components/display.md +69 -0
- package/docs/components/drawer.md +36 -0
- package/docs/components/dropdown.md +33 -0
- package/docs/components/forms.md +90 -0
- package/docs/components/knob.md +42 -0
- package/docs/components/layout.md +217 -0
- package/docs/components/modal.md +38 -0
- package/docs/components/number-select.md +42 -0
- package/docs/components/slider.md +48 -0
- package/docs/components/tabs.md +30 -0
- package/docs/components/theme-toggle.md +36 -0
- package/docs/components/toast.md +27 -0
- package/docs/components/tooltip.md +14 -0
- package/docs/components/tree.md +46 -0
- package/docs/theming.md +182 -0
- package/package.json +8 -4
- package/USING_CDN.md +0 -591
package/AGENT.md
ADDED
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
# ry-ui — Agent Reference
|
|
2
|
+
|
|
3
|
+
> Framework-agnostic Light DOM web components. CSS is the source of truth.
|
|
4
|
+
> This file is for AI agents building apps with ry-ui.
|
|
5
|
+
|
|
6
|
+
## Quick Start
|
|
7
|
+
|
|
8
|
+
```html
|
|
9
|
+
<!-- CDN (full bundle) -->
|
|
10
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ryanhelsing/ry-ui/dist/css/ry-ui.css">
|
|
11
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@ryanhelsing/ry-ui/dist/ry-ui.js"></script>
|
|
12
|
+
|
|
13
|
+
<!-- Or individual layers (for custom themes) -->
|
|
14
|
+
<link rel="stylesheet" href="ry-tokens.css">
|
|
15
|
+
<link rel="stylesheet" href="ry-structure.css">
|
|
16
|
+
<link rel="stylesheet" href="your-theme.css">
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Clean Syntax
|
|
20
|
+
|
|
21
|
+
Wrap markup in `<ry>` to use unprefixed tags:
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<ry>
|
|
25
|
+
<accordion>
|
|
26
|
+
<accordion-item title="FAQ" open>No ry- prefix needed.</accordion-item>
|
|
27
|
+
</accordion>
|
|
28
|
+
</ry>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Component Catalog
|
|
34
|
+
|
|
35
|
+
### Layout (CSS-only, no JS)
|
|
36
|
+
|
|
37
|
+
| Component | Attributes | Description |
|
|
38
|
+
|-----------|-----------|-------------|
|
|
39
|
+
| `<ry-page>` | — | Root page container, flex column, min-height 100dvh, container queries |
|
|
40
|
+
| `<ry-header>` | `sticky` | Flex row, space-between. `sticky` pins to top |
|
|
41
|
+
| `<ry-main>` | — | Content area, max-width 1200px, centered |
|
|
42
|
+
| `<ry-footer>` | — | Footer with border-top |
|
|
43
|
+
| `<ry-section>` | — | Block section with bottom margin, container queries |
|
|
44
|
+
| `<ry-grid>` | `cols="1-6\|auto-fit\|auto-fill"`, `cols-sm="1-3"`, `cols-md="1-4"`, `cols-lg="2-6"` | CSS grid. See [Grid](#grid) |
|
|
45
|
+
| `<ry-stack>` | `gap="sm\|md\|lg\|xl"` | Vertical flex column |
|
|
46
|
+
| `<ry-cluster>` | `gap="sm\|md\|lg"` | Horizontal flex row, wraps |
|
|
47
|
+
| `<ry-split>` | `resizable`, `persist="key"`, CSS vars: `--ry-split-width`, `--ry-split-min-width`, `--ry-split-max-width` | Two-column: flex-1 left + fixed right. Stacks on mobile. Optional drag resize + localStorage persistence |
|
|
48
|
+
| `<ry-center>` | — | Flex center (both axes) |
|
|
49
|
+
| `<ry-nav>` | — | Horizontal nav links. Active: `a[aria-current="page"]` |
|
|
50
|
+
| `<ry-logo>` | — | Inline-flex, bold text |
|
|
51
|
+
| `<ry-actions>` | — | Flex row for action buttons |
|
|
52
|
+
| `<ry-divider>` | `vertical` | Horizontal line; `vertical` for inline separator |
|
|
53
|
+
| `<ry-aside>` | — | Sidebar content area |
|
|
54
|
+
|
|
55
|
+
### Interactive Components
|
|
56
|
+
|
|
57
|
+
| Component | Key Attributes | Events |
|
|
58
|
+
|-----------|---------------|--------|
|
|
59
|
+
| `<ry-button>` | `variant="primary\|secondary\|outline\|ghost\|danger\|accent"`, `size="sm\|lg"`, `disabled`, `pressed`, `icon`, `modal="id"` | `ry:click` |
|
|
60
|
+
| `<ry-button-group>` | `name`, `value` | `ry:change` `{value}` — radio-group behavior for child buttons |
|
|
61
|
+
| `<ry-toggle-button>` | `pressed`, `name`, `value`, `size`, `icon`, `block`, `disabled` | `ry:change` `{pressed, value}` |
|
|
62
|
+
| `<ry-modal>` | `id`, `title` | Trigger with `<ry-button modal="id">`. Centered with backdrop |
|
|
63
|
+
| `<ry-drawer>` | `id`, `position="left\|right"`, `size` | Trigger with `<ry-button drawer="id">` |
|
|
64
|
+
| `<ry-accordion>` | — | Container for accordion-items |
|
|
65
|
+
| `<ry-accordion-item>` | `title`, `open` | Collapsible section |
|
|
66
|
+
| `<ry-tabs>` | — | Container. Children: `<ry-tab title="...">content</ry-tab>` |
|
|
67
|
+
| `<ry-dropdown>` | — | Dropdown trigger + menu |
|
|
68
|
+
| `<ry-select>` | `placeholder`, `name`, `value`, `disabled` | `ry:change` `{value}`. Children: `<ry-option value="...">` |
|
|
69
|
+
| `<ry-switch>` | `checked`, `disabled`, `name` | `ry:change` `{checked}` |
|
|
70
|
+
| `<ry-tooltip>` | `content`, `position` | Hover tooltip |
|
|
71
|
+
| `<ry-toast>` | — | Programmatic: `RyToast.success('msg')`, `.error()`, `.warning()`, `.info()` |
|
|
72
|
+
| `<ry-slider>` | `min`, `max`, `step`, `value`, `color`, `disabled` | `ry:change` `{value}` |
|
|
73
|
+
| `<ry-knob>` | `min`, `max`, `step`, `value`, `color`, `size`, `disabled` | `ry:change` `{value}` |
|
|
74
|
+
| `<ry-number-select>` | `min`, `max`, `step`, `value`, `arrows`, `size`, `prefix`, `suffix`, `label` | `ry:change` `{value}` |
|
|
75
|
+
| `<ry-color-picker>` | `value`, `format` | `ry:change` `{value}` |
|
|
76
|
+
| `<ry-color-input>` | `value`, `format` | `ry:change` `{value}` |
|
|
77
|
+
| `<ry-gradient-picker>` | `value` | `ry:change` `{value}` |
|
|
78
|
+
| `<ry-tree>` | `data` (JSON) | `ry:select`, `ry:move` — file tree with drag-and-drop |
|
|
79
|
+
| `<ry-tag>` | `removable` | `ry:remove` |
|
|
80
|
+
| `<ry-tag-input>` | `name`, `value`, `placeholder` | `ry:change` `{tags}` |
|
|
81
|
+
| `<ry-carousel>` | `autoplay`, `interval` | `ry:change` `{index}` |
|
|
82
|
+
| `<ry-theme-toggle>` | `themes="light,dark"` | Cycles through themes |
|
|
83
|
+
|
|
84
|
+
### Display Components
|
|
85
|
+
|
|
86
|
+
| Component | Key Attributes | Description |
|
|
87
|
+
|-----------|---------------|-------------|
|
|
88
|
+
| `<ry-card>` | — | Bordered card with padding. Put any content inside |
|
|
89
|
+
| `<ry-badge>` | `variant="primary\|success\|warning\|danger\|accent"` | Pill badge. Arbitrary color: `style="--ry-badge-color: #8B5CF6"` |
|
|
90
|
+
| `<ry-alert>` | `type="info\|success\|warning\|danger"` | Alert box with optional `[slot="title"]` |
|
|
91
|
+
| `<ry-field>` | `label`, `error`, `hint` | Form field wrapper. See [Forms](#forms) |
|
|
92
|
+
| `<ry-icon>` | `name` | SVG icon from registry |
|
|
93
|
+
| `<ry-code>` | `language`, `title` | Syntax-highlighted code block |
|
|
94
|
+
| `<ry-hero>` | `size="sm\|lg"`, `full-bleed`, `align="left"` | Marketing hero section. Children: h1, p, buttons |
|
|
95
|
+
| `<ry-stat>` | `size="sm\|lg"` | Stat card with `slot="value"`, `slot="label"`, trend arrows |
|
|
96
|
+
| `<ry-feature>` | `icon` | Feature card with icon from registry |
|
|
97
|
+
| `<ry-feature-grid>` | `cols="2\|3\|4"` | Responsive grid for feature cards |
|
|
98
|
+
| `<ry-pricing>` | — | Container for pricing cards (flex row, responsive) |
|
|
99
|
+
| `<ry-pricing-card>` | `featured` | Pricing tier card. `featured` scales up with bold border |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Patterns
|
|
104
|
+
|
|
105
|
+
### Grid
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<!-- Fixed columns with auto-responsive -->
|
|
109
|
+
<ry-grid cols="3">...</ry-grid>
|
|
110
|
+
<!-- cols 3-6 → 2 at ≤1024px → 1 at ≤640px (automatic) -->
|
|
111
|
+
|
|
112
|
+
<!-- Explicit per-breakpoint -->
|
|
113
|
+
<ry-grid cols="5" cols-md="3" cols-sm="1">...</ry-grid>
|
|
114
|
+
|
|
115
|
+
<!-- Fluid auto-fit (like repeat(auto-fit, minmax(280px, 1fr))) -->
|
|
116
|
+
<ry-grid cols="auto-fit">...</ry-grid>
|
|
117
|
+
|
|
118
|
+
<!-- Custom min-width for auto-fit -->
|
|
119
|
+
<ry-grid cols="auto-fit" style="--ry-grid-min: 240px">...</ry-grid>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Split Layout
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<!-- Default 300px sidebar -->
|
|
126
|
+
<ry-split>
|
|
127
|
+
<div>Main content</div>
|
|
128
|
+
<div>Sidebar</div>
|
|
129
|
+
</ry-split>
|
|
130
|
+
|
|
131
|
+
<!-- Custom width -->
|
|
132
|
+
<ry-split style="--ry-split-width: 600px; --ry-split-min-width: 400px">
|
|
133
|
+
<div>Main</div>
|
|
134
|
+
<div>Panel</div>
|
|
135
|
+
</ry-split>
|
|
136
|
+
|
|
137
|
+
<!-- Resizable with persistence -->
|
|
138
|
+
<ry-split resizable persist="my-panel" style="--ry-split-width: 400px">
|
|
139
|
+
<div>Main</div>
|
|
140
|
+
<div>Resizable panel — drag handle, keyboard arrows, double-click to reset</div>
|
|
141
|
+
</ry-split>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Split resize features:
|
|
145
|
+
- **Drag handle** between panes (mouse + touch)
|
|
146
|
+
- **Keyboard**: Arrow keys (±10px), Shift+Arrow (±50px), Home/End for min/max
|
|
147
|
+
- **Double-click** handle to reset to default width
|
|
148
|
+
- **`persist="key"`**: Saves width to `localStorage` as `ry-split:key`, restores on load
|
|
149
|
+
- **`ry:resize`** event fires with `{ width }` after drag ends
|
|
150
|
+
|
|
151
|
+
### Forms
|
|
152
|
+
|
|
153
|
+
```html
|
|
154
|
+
<ry-field label="Email" hint="We'll never share your email">
|
|
155
|
+
<input type="email" placeholder="you@example.com">
|
|
156
|
+
</ry-field>
|
|
157
|
+
|
|
158
|
+
<ry-field label="Password" error="Must be at least 8 characters">
|
|
159
|
+
<input type="password">
|
|
160
|
+
</ry-field>
|
|
161
|
+
|
|
162
|
+
<!-- Error hides hint automatically. Set error="" to clear and show hint again. -->
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Button Group (Segmented Control)
|
|
166
|
+
|
|
167
|
+
```html
|
|
168
|
+
<!-- Radio-group behavior -->
|
|
169
|
+
<ry-button-group name="billing" value="monthly">
|
|
170
|
+
<ry-button value="monthly">Monthly</ry-button>
|
|
171
|
+
<ry-button value="annually">Annually</ry-button>
|
|
172
|
+
</ry-button-group>
|
|
173
|
+
|
|
174
|
+
<!-- Mode switcher -->
|
|
175
|
+
<ry-button-group name="mode" value="terminal">
|
|
176
|
+
<ry-button value="direct">Direct</ry-button>
|
|
177
|
+
<ry-button value="terminal">Terminal</ry-button>
|
|
178
|
+
<ry-button value="release">Release</ry-button>
|
|
179
|
+
</ry-button-group>
|
|
180
|
+
|
|
181
|
+
<!-- Listen for changes -->
|
|
182
|
+
<script>
|
|
183
|
+
document.querySelector('ry-button-group').addEventListener('ry:change', e => {
|
|
184
|
+
console.log(e.detail.value); // "monthly" | "annually"
|
|
185
|
+
});
|
|
186
|
+
</script>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Button Variants
|
|
190
|
+
|
|
191
|
+
```html
|
|
192
|
+
<ry-button>Primary (default)</ry-button>
|
|
193
|
+
<ry-button variant="secondary">Secondary</ry-button>
|
|
194
|
+
<ry-button variant="outline">Outline</ry-button>
|
|
195
|
+
<ry-button variant="ghost">Ghost</ry-button>
|
|
196
|
+
<ry-button variant="danger">Danger</ry-button>
|
|
197
|
+
<ry-button variant="accent">Accent</ry-button>
|
|
198
|
+
<ry-button pressed>Pressed/Active</ry-button>
|
|
199
|
+
<ry-button size="sm">Small</ry-button>
|
|
200
|
+
<ry-button size="lg">Large</ry-button>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Badge with Arbitrary Color
|
|
204
|
+
|
|
205
|
+
```html
|
|
206
|
+
<ry-badge variant="success">Active</ry-badge>
|
|
207
|
+
<ry-badge variant="accent">Pro</ry-badge>
|
|
208
|
+
<ry-badge style="--ry-badge-color: #8B5CF6">Custom</ry-badge>
|
|
209
|
+
<ry-badge style="--ry-badge-color: oklch(0.7 0.15 200); --ry-badge-text: #000">Custom + text</ry-badge>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Check List (Pricing Features)
|
|
213
|
+
|
|
214
|
+
```html
|
|
215
|
+
<ul class="ry-check-list">
|
|
216
|
+
<li>Unlimited projects</li>
|
|
217
|
+
<li>Priority support</li>
|
|
218
|
+
<li>Custom domains</li>
|
|
219
|
+
</ul>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Nav Bar
|
|
223
|
+
|
|
224
|
+
```html
|
|
225
|
+
<ry-header sticky>
|
|
226
|
+
<ry-cluster>
|
|
227
|
+
<ry-logo>MyApp</ry-logo>
|
|
228
|
+
<ry-divider vertical></ry-divider>
|
|
229
|
+
<ry-nav>
|
|
230
|
+
<a href="/" aria-current="page">Home</a>
|
|
231
|
+
<a href="/docs">Docs</a>
|
|
232
|
+
<a href="/pricing">Pricing</a>
|
|
233
|
+
</ry-nav>
|
|
234
|
+
</ry-cluster>
|
|
235
|
+
<ry-actions>
|
|
236
|
+
<ry-button variant="ghost" size="sm">Login</ry-button>
|
|
237
|
+
<ry-button size="sm">Sign Up</ry-button>
|
|
238
|
+
</ry-actions>
|
|
239
|
+
</ry-header>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Pricing Page
|
|
243
|
+
|
|
244
|
+
```html
|
|
245
|
+
<ry-pricing>
|
|
246
|
+
<ry-pricing-card>
|
|
247
|
+
<h3>Free</h3>
|
|
248
|
+
<div class="ry-pricing__price">$0<span>/mo</span></div>
|
|
249
|
+
<p>For individuals</p>
|
|
250
|
+
<ul class="ry-check-list">
|
|
251
|
+
<li>3 projects</li>
|
|
252
|
+
<li>Basic support</li>
|
|
253
|
+
</ul>
|
|
254
|
+
<ry-button variant="outline">Get Started</ry-button>
|
|
255
|
+
</ry-pricing-card>
|
|
256
|
+
|
|
257
|
+
<ry-pricing-card featured>
|
|
258
|
+
<h3>Pro</h3>
|
|
259
|
+
<div class="ry-pricing__price">$19<span>/mo</span></div>
|
|
260
|
+
<p>For teams</p>
|
|
261
|
+
<ul class="ry-check-list">
|
|
262
|
+
<li>Unlimited projects</li>
|
|
263
|
+
<li>Priority support</li>
|
|
264
|
+
</ul>
|
|
265
|
+
<ry-button>Upgrade</ry-button>
|
|
266
|
+
</ry-pricing-card>
|
|
267
|
+
</ry-pricing>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Hero Section
|
|
271
|
+
|
|
272
|
+
```html
|
|
273
|
+
<ry-hero>
|
|
274
|
+
<h1>Build faster with ry-ui</h1>
|
|
275
|
+
<p>Framework-agnostic components for any app.</p>
|
|
276
|
+
<ry-cluster>
|
|
277
|
+
<ry-button size="lg">Get Started</ry-button>
|
|
278
|
+
<ry-button variant="outline" size="lg">View Docs</ry-button>
|
|
279
|
+
</ry-cluster>
|
|
280
|
+
</ry-hero>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Modal & Drawer
|
|
284
|
+
|
|
285
|
+
```html
|
|
286
|
+
<!-- Modal -->
|
|
287
|
+
<ry-button modal="confirm">Open Modal</ry-button>
|
|
288
|
+
<ry-modal id="confirm" title="Confirm Action">
|
|
289
|
+
<p>Are you sure?</p>
|
|
290
|
+
<ry-cluster>
|
|
291
|
+
<ry-button variant="danger">Delete</ry-button>
|
|
292
|
+
<ry-button variant="ghost">Cancel</ry-button>
|
|
293
|
+
</ry-cluster>
|
|
294
|
+
</ry-modal>
|
|
295
|
+
|
|
296
|
+
<!-- Drawer -->
|
|
297
|
+
<ry-button drawer="settings">Settings</ry-button>
|
|
298
|
+
<ry-drawer id="settings" position="right" size="400px">
|
|
299
|
+
<h3>Settings</h3>
|
|
300
|
+
<!-- content -->
|
|
301
|
+
</ry-drawer>
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## CSS Token System
|
|
307
|
+
|
|
308
|
+
All visual properties use CSS custom properties. Override in your own CSS to customize.
|
|
309
|
+
|
|
310
|
+
### Colors
|
|
311
|
+
|
|
312
|
+
| Token | Purpose |
|
|
313
|
+
|-------|---------|
|
|
314
|
+
| `--ry-color-primary` / `-hover` / `-active` | Primary action color (blue) |
|
|
315
|
+
| `--ry-color-secondary` / `-hover` / `-active` | Secondary muted color |
|
|
316
|
+
| `--ry-color-accent` / `-hover` / `-active` | Accent/highlight color (purple) |
|
|
317
|
+
| `--ry-color-success` | Green for positive states |
|
|
318
|
+
| `--ry-color-warning` | Yellow/orange for caution |
|
|
319
|
+
| `--ry-color-danger` / `-hover` | Red for destructive actions |
|
|
320
|
+
| `--ry-color-info` | Blue for informational |
|
|
321
|
+
| `--ry-color-text` / `-muted` / `-inverse` | Text colors |
|
|
322
|
+
| `--ry-color-bg` / `-subtle` / `-muted` | Background colors |
|
|
323
|
+
| `--ry-color-border` / `-strong` | Border colors |
|
|
324
|
+
| `--ry-color-overlay` | Modal/drawer backdrop |
|
|
325
|
+
|
|
326
|
+
Each color also has `-bg` and `-text` variants for alert/badge backgrounds:
|
|
327
|
+
`--ry-color-{info,success,warning,danger}-bg` / `--ry-color-{info,success,warning,danger}-text`
|
|
328
|
+
|
|
329
|
+
### Spacing
|
|
330
|
+
|
|
331
|
+
`--ry-space-{0,1,2,3,4,5,6,8,10,12,16,20}` — 0 to 5rem
|
|
332
|
+
|
|
333
|
+
### Typography
|
|
334
|
+
|
|
335
|
+
| Token | Value |
|
|
336
|
+
|-------|-------|
|
|
337
|
+
| `--ry-font-sans` | system-ui stack |
|
|
338
|
+
| `--ry-font-mono` | ui-monospace stack |
|
|
339
|
+
| `--ry-text-{xs,sm,base,lg,xl,2xl,3xl,4xl}` | 0.75rem to 2.25rem |
|
|
340
|
+
| `--ry-font-{normal,medium,semibold,bold}` | 400 to 700 |
|
|
341
|
+
| `--ry-leading-{tight,normal,relaxed}` | 1.25 to 1.75 |
|
|
342
|
+
|
|
343
|
+
### Borders & Shadows
|
|
344
|
+
|
|
345
|
+
| Token | Value |
|
|
346
|
+
|-------|-------|
|
|
347
|
+
| `--ry-radius-{none,sm,md,lg,xl,2xl,full}` | 0 to 9999px |
|
|
348
|
+
| `--ry-shadow-{sm,md,lg,xl}` | Elevation shadows |
|
|
349
|
+
| `--ry-border-width` | 1px |
|
|
350
|
+
|
|
351
|
+
### Transitions
|
|
352
|
+
|
|
353
|
+
| Token | Value |
|
|
354
|
+
|-------|-------|
|
|
355
|
+
| `--ry-duration-{fast,normal,slow}` | 100ms, 200ms, 300ms |
|
|
356
|
+
| `--ry-ease` / `-in` / `-out` | Cubic bezier easing |
|
|
357
|
+
|
|
358
|
+
### Z-Index
|
|
359
|
+
|
|
360
|
+
| Token | Value |
|
|
361
|
+
|-------|-------|
|
|
362
|
+
| `--ry-z-dropdown` | 1000 |
|
|
363
|
+
| `--ry-z-sticky` | 1020 |
|
|
364
|
+
| `--ry-z-fixed` | 1030 |
|
|
365
|
+
| `--ry-z-modal-backdrop` | 1040 |
|
|
366
|
+
| `--ry-z-modal` | 1050 |
|
|
367
|
+
| `--ry-z-popover` | 1060 |
|
|
368
|
+
| `--ry-z-tooltip` | 1070 |
|
|
369
|
+
| `--ry-z-toast` | 1080 |
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## CSS Architecture
|
|
374
|
+
|
|
375
|
+
Three layers, ordered by specificity:
|
|
376
|
+
|
|
377
|
+
1. **ry-tokens** — CSS custom properties (colors, spacing, etc.)
|
|
378
|
+
2. **ry-structure** — Pure layout (no colors). Selectors: element names + `[data-ry-target]`
|
|
379
|
+
3. **ry-theme** — All visual styling. Selectors: `.ry-*` classes + element names
|
|
380
|
+
|
|
381
|
+
### Custom Theming
|
|
382
|
+
|
|
383
|
+
Load structure only + your own theme:
|
|
384
|
+
|
|
385
|
+
```html
|
|
386
|
+
<link rel="stylesheet" href="ry-tokens.css"> <!-- or your own tokens -->
|
|
387
|
+
<link rel="stylesheet" href="ry-structure.css">
|
|
388
|
+
<link rel="stylesheet" href="your-theme.css">
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Dark Mode
|
|
392
|
+
|
|
393
|
+
Built into tokens via `light-dark()`. No separate dark.css needed.
|
|
394
|
+
|
|
395
|
+
```html
|
|
396
|
+
<html data-ry-theme="dark"> <!-- force dark -->
|
|
397
|
+
<html data-ry-theme="light"> <!-- force light -->
|
|
398
|
+
<!-- omit attribute for OS preference -->
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Patterns NOT in ry-ui (Keep Custom)
|
|
404
|
+
|
|
405
|
+
These patterns are intentionally outside the design system's scope:
|
|
406
|
+
|
|
407
|
+
| Pattern | Reason | Recommended approach |
|
|
408
|
+
|---------|--------|---------------------|
|
|
409
|
+
| Click-positioned dialog / popover | GSAP animations, cursor anchoring | Use ry-ui tokens inside custom dialog |
|
|
410
|
+
| File drop zone | App-specific UX | Custom component, tokenize colors |
|
|
411
|
+
| Color swatch selector | Too specialized | Custom radio buttons with ry-ui tokens |
|
|
412
|
+
| Terminal / xterm.js wrapper | Third-party integration | Custom container, tokenize colors |
|
|
413
|
+
| Infinite canvas / artboard | Canvas 2D, not DOM | Use `getComputedStyle` to read ry-ui tokens for canvas rendering |
|
|
414
|
+
| Chat / streaming replay | App-specific data format | Custom layout, use ry-ui header/badge/button inside |
|
|
415
|
+
| Floating properties panel | Positioned at coordinates | Use `position: absolute` + ry-ui form components inside |
|
|
416
|
+
|
|
417
|
+
For all of these: **use ry-ui tokens for colors, spacing, and typography** so they match the theme, but keep the structural markup custom.
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## TypeScript
|
|
422
|
+
|
|
423
|
+
```ts
|
|
424
|
+
import { RyElement, RyButton, RyToast } from '@ryanhelsing/ry-ui';
|
|
425
|
+
|
|
426
|
+
// Programmatic toast
|
|
427
|
+
RyToast.success('Saved!');
|
|
428
|
+
RyToast.error('Failed to save');
|
|
429
|
+
|
|
430
|
+
// Listen for component events
|
|
431
|
+
document.querySelector('ry-select')?.addEventListener('ry:change', (e: CustomEvent) => {
|
|
432
|
+
console.log(e.detail.value);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
// Extend components
|
|
436
|
+
class MyWidget extends RyElement {
|
|
437
|
+
setup() {
|
|
438
|
+
this.on(this, 'click', () => this.emit('activate'));
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## Icon Registry
|
|
446
|
+
|
|
447
|
+
```ts
|
|
448
|
+
import { registerIcon, registerIcons } from '@ryanhelsing/ry-ui';
|
|
449
|
+
|
|
450
|
+
// Single icon
|
|
451
|
+
registerIcon('custom', '<svg>...</svg>');
|
|
452
|
+
|
|
453
|
+
// Batch
|
|
454
|
+
registerIcons({
|
|
455
|
+
'app-logo': '<svg>...</svg>',
|
|
456
|
+
'custom-arrow': '<svg>...</svg>'
|
|
457
|
+
});
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
Built-in icons: `settings`, `heart`, `star`, `chevron-up`, `chevron-down`, `chevron-left`, `chevron-right`, `check`, `x`, `plus`, `minus`, `search`, `sun`, `moon`, `copy`, `trash`, `edit`, `eye`, `folder`, `file`, `drag`
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# AGENTS.md — ry-ui
|
|
2
|
+
|
|
3
|
+
> Web components. No framework. Light DOM. CSS is the source of truth.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<link rel="stylesheet" href="https://unpkg.com/@ryanhelsing/ry-ui/css/ry-ui.css">
|
|
9
|
+
<script type="module" src="https://unpkg.com/@ryanhelsing/ry-ui"></script>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Theme: `<html data-ry-theme="light">` — light | dark
|
|
13
|
+
|
|
14
|
+
## Concepts
|
|
15
|
+
|
|
16
|
+
- **Light DOM** — no shadow DOM, your CSS just works
|
|
17
|
+
- **Clean syntax** — `<ry><stack><card>Hi</card></stack></ry>` (drops `ry-` prefix inside `<ry>`)
|
|
18
|
+
- **Tokens** — all visuals via `--ry-*` CSS custom properties, override to customize
|
|
19
|
+
- **Structure vs Theme** — load `ry-structure.css` alone + your own theme for full control
|
|
20
|
+
- **Events** — all prefixed `ry:` — `ry:change`, `ry:input`, `ry:open`, `ry:close`, `ry:toggle`, `ry:select`, `ry:move`
|
|
21
|
+
|
|
22
|
+
## Components
|
|
23
|
+
|
|
24
|
+
| Category | Components |
|
|
25
|
+
|----------|-----------|
|
|
26
|
+
| **Layout** | page, header, main, footer, section, aside, grid, stack, cluster, split, center, card, nav, logo, actions, divider |
|
|
27
|
+
| **Overlays** | modal, drawer, dropdown, tooltip, toast |
|
|
28
|
+
| **Forms** | field, select, switch, button-group, toggle-button, checkbox/radio (native) |
|
|
29
|
+
| **Values** | slider, knob, number-select, color-picker, color-input, gradient-picker |
|
|
30
|
+
| **Display** | badge, alert, icon, code, table (native), tree |
|
|
31
|
+
| **Utility** | theme-toggle |
|
|
32
|
+
|
|
33
|
+
## Docs
|
|
34
|
+
|
|
35
|
+
Pull the page you need for full attributes, events, JS API, and examples:
|
|
36
|
+
|
|
37
|
+
| Doc | What's in it |
|
|
38
|
+
|-----|-------------|
|
|
39
|
+
| [docs/components/layout.md](docs/components/layout.md) | page, header, main, footer, section, aside, grid, stack, cluster, split, center, card, nav, logo, actions, divider |
|
|
40
|
+
| [docs/components/button.md](docs/components/button.md) | button, toggle-button |
|
|
41
|
+
| [docs/components/button-group.md](docs/components/button-group.md) | button-group (segmented control) |
|
|
42
|
+
| [docs/components/accordion.md](docs/components/accordion.md) | accordion, accordion-item |
|
|
43
|
+
| [docs/components/tabs.md](docs/components/tabs.md) | tabs, tab |
|
|
44
|
+
| [docs/components/modal.md](docs/components/modal.md) | modal |
|
|
45
|
+
| [docs/components/drawer.md](docs/components/drawer.md) | drawer |
|
|
46
|
+
| [docs/components/dropdown.md](docs/components/dropdown.md) | dropdown, menu, menu-item |
|
|
47
|
+
| [docs/components/tooltip.md](docs/components/tooltip.md) | tooltip |
|
|
48
|
+
| [docs/components/toast.md](docs/components/toast.md) | toast (programmatic) |
|
|
49
|
+
| [docs/components/forms.md](docs/components/forms.md) | field, select, switch, checkbox, radio |
|
|
50
|
+
| [docs/components/slider.md](docs/components/slider.md) | slider |
|
|
51
|
+
| [docs/components/knob.md](docs/components/knob.md) | knob |
|
|
52
|
+
| [docs/components/number-select.md](docs/components/number-select.md) | number-select |
|
|
53
|
+
| [docs/components/color.md](docs/components/color.md) | color-picker, color-input, gradient-picker |
|
|
54
|
+
| [docs/components/tree.md](docs/components/tree.md) | tree, tree-item |
|
|
55
|
+
| [docs/components/display.md](docs/components/display.md) | badge, alert, icon, code, table |
|
|
56
|
+
| [docs/components/theme-toggle.md](docs/components/theme-toggle.md) | theme-toggle |
|
|
57
|
+
| [docs/theming.md](docs/theming.md) | tokens, custom themes, structure-only loading |
|
package/README.md
CHANGED
|
@@ -17,7 +17,18 @@ ry-ui normalizes this. No decisions to make. No architecture to debate. An LLM c
|
|
|
17
17
|
- [x] separate the css minimal structure from the theme
|
|
18
18
|
- [x] separate the component behavior from the design (see `docs/arch/behavior-style-separation.md`)
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
### Next Up — Missing Primitives That Block Real Apps
|
|
21
|
+
|
|
22
|
+
- [ ] **Table / Data Grid** — sorting, column resize, virtual scrolling for large datasets. Highest-value missing component for any dashboard.
|
|
23
|
+
- [ ] **Form** — form orchestration around existing inputs. Validation, error states, submit handling, field grouping.
|
|
24
|
+
- [ ] **Menu / Context Menu** — right-click menus, nested submenus. Required for any desktop-targeting app.
|
|
25
|
+
- [ ] **Command Palette** — Cmd+K pattern. Table stakes for power-user apps and ry-os.
|
|
26
|
+
- [ ] **Toast stacking** — ry-toast exists but needs positioning, stacking multiple toasts, auto-dismiss timers, queue behavior.
|
|
27
|
+
- [ ] **Breadcrumb, Pagination, Stepper** — navigation patterns for any multi-page app.
|
|
28
|
+
|
|
29
|
+
### Backlog
|
|
30
|
+
|
|
31
|
+
- [ ] Placeholder, Step/Wizard, Loader/Progress, Comment/Feed, Statistic/Graph, Hero, Calendar, Rating, Search, Shape, Sticky, dialog/alert, carousel, qr-code, diff, format-bytes-number-currency, mutation-observer and resize observer
|
|
21
32
|
|
|
22
33
|
- [ ] This is a theme on its own: https://codepen.io/oathanrex/pen/EayVMqZ
|
|
23
34
|
|
|
@@ -25,6 +36,7 @@ ry-ui normalizes this. No decisions to make. No architecture to debate. An LLM c
|
|
|
25
36
|
- [ ] cross-platform transpiler - Swift/SwiftUI (see `docs/arch/cross-platform-transpiler.md`)
|
|
26
37
|
- [ ] animation system with GSAP (see `docs/plans/animation-system.md`)
|
|
27
38
|
- [ ] could use to write apps on ry-os lol.. rust based linux DE with html/js/css -> Dioxus -> rust apps / with an llm on device
|
|
39
|
+
- [ ] https://github.com/GrapheneOS — hardened Android, good reference for security-first OS/DE design patterns
|
|
28
40
|
|
|
29
41
|
## Quick Start
|
|
30
42
|
|
|
@@ -42,8 +54,12 @@ ry-ui normalizes this. No decisions to make. No architecture to debate. An LLM c
|
|
|
42
54
|
- `<ry-grid cols="3">` - Responsive grid
|
|
43
55
|
- `<ry-stack>` / `<ry-cluster>` - Flex layouts
|
|
44
56
|
|
|
57
|
+
### Layout
|
|
58
|
+
- `<ry-split>` - Resizable two-column layout with optional `persist` for localStorage-backed width
|
|
59
|
+
|
|
45
60
|
### Interactive
|
|
46
61
|
- `<ry-button>` - Buttons with variants
|
|
62
|
+
- `<ry-button-group>` - Segmented control / radio button group
|
|
47
63
|
- `<ry-modal>` - Modal dialogs
|
|
48
64
|
- `<ry-drawer>` - Slide-out panels
|
|
49
65
|
- `<ry-accordion>` - Collapsible sections
|
|
@@ -54,6 +70,9 @@ ry-ui normalizes this. No decisions to make. No architecture to debate. An LLM c
|
|
|
54
70
|
- `<ry-tooltip>` - Hover tooltips
|
|
55
71
|
- `<ry-toast>` - Notifications
|
|
56
72
|
|
|
73
|
+
### Forms
|
|
74
|
+
- `<ry-field>` - Form field wrapper with auto label, error, and hint
|
|
75
|
+
|
|
57
76
|
### Display
|
|
58
77
|
- `<ry-card>` - Card containers
|
|
59
78
|
- `<ry-badge>` - Status badges
|
|
@@ -90,6 +109,23 @@ Use `<ry>` wrapper to write unprefixed markup:
|
|
|
90
109
|
<ry-option value="uk">United Kingdom</ry-option>
|
|
91
110
|
</ry-select>
|
|
92
111
|
|
|
112
|
+
<!-- Split Panel (resizable, persistent) -->
|
|
113
|
+
<ry-split resizable persist="sidebar">
|
|
114
|
+
<main>Main content</main>
|
|
115
|
+
<aside>Sidebar</aside>
|
|
116
|
+
</ry-split>
|
|
117
|
+
|
|
118
|
+
<!-- Button Group -->
|
|
119
|
+
<ry-button-group value="monthly">
|
|
120
|
+
<ry-button value="monthly">Monthly</ry-button>
|
|
121
|
+
<ry-button value="annually">Annually</ry-button>
|
|
122
|
+
</ry-button-group>
|
|
123
|
+
|
|
124
|
+
<!-- Form Field -->
|
|
125
|
+
<ry-field label="Email" error="Invalid email">
|
|
126
|
+
<input type="email" name="email">
|
|
127
|
+
</ry-field>
|
|
128
|
+
|
|
93
129
|
<!-- Toast (programmatic) -->
|
|
94
130
|
<script>
|
|
95
131
|
RyToast.success('Saved!');
|
|
@@ -152,6 +188,14 @@ npm run build # Production build
|
|
|
152
188
|
npm run typecheck
|
|
153
189
|
```
|
|
154
190
|
|
|
191
|
+
## Publishing
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm run release
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Automatically available on CDN via [unpkg](https://unpkg.com/@ryanhelsing/ry-ui/) and [jsdelivr](https://cdn.jsdelivr.net/npm/@ryanhelsing/ry-ui/).
|
|
198
|
+
|
|
155
199
|
## TypeScript Philosophy
|
|
156
200
|
|
|
157
201
|
ry-ui is written in strict TypeScript with a "vanilla-first" approach:
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <ry-button-group>
|
|
3
|
+
*
|
|
4
|
+
* Segmented control / button group. Groups child buttons with
|
|
5
|
+
* connected borders and optional radio-group behavior.
|
|
6
|
+
*
|
|
7
|
+
* Usage (visual grouping only):
|
|
8
|
+
* <ry-button-group>
|
|
9
|
+
* <ry-button>Left</ry-button>
|
|
10
|
+
* <ry-button>Center</ry-button>
|
|
11
|
+
* <ry-button>Right</ry-button>
|
|
12
|
+
* </ry-button-group>
|
|
13
|
+
*
|
|
14
|
+
* Usage (radio behavior — single selection):
|
|
15
|
+
* <ry-button-group name="mode" value="terminal">
|
|
16
|
+
* <ry-button value="direct">Direct</ry-button>
|
|
17
|
+
* <ry-button value="terminal">Terminal</ry-button>
|
|
18
|
+
* <ry-button value="release">Release</ry-button>
|
|
19
|
+
* </ry-button-group>
|
|
20
|
+
*
|
|
21
|
+
* Emits ry:change with { value } when selection changes.
|
|
22
|
+
*/
|
|
23
|
+
import { RyElement } from '../core/ry-element.js';
|
|
24
|
+
export declare class RyButtonGroup extends RyElement {
|
|
25
|
+
#private;
|
|
26
|
+
static get observedAttributes(): string[];
|
|
27
|
+
get value(): string;
|
|
28
|
+
set value(v: string);
|
|
29
|
+
setup(): void;
|
|
30
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=ry-button-group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ry-button-group.d.ts","sourceRoot":"","sources":["../../src/ts/components/ry-button-group.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,qBAAa,aAAc,SAAQ,SAAS;;IAC1C,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,KAAK,CAAC,CAAC,EAAE,MAAM,EAElB;IAED,KAAK,IAAI,IAAI;IAMb,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAiC/F"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <ry-carousel>
|
|
3
|
+
*
|
|
4
|
+
* Content slider with autoplay, touch/swipe, dots, arrows, keyboard nav.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* <ry-carousel autoplay interval="5000" dots arrows loop>
|
|
8
|
+
* <div>Slide 1</div>
|
|
9
|
+
* <div>Slide 2</div>
|
|
10
|
+
* </ry-carousel>
|
|
11
|
+
*/
|
|
12
|
+
import { RyElement } from '../core/ry-element.js';
|
|
13
|
+
export declare class RyCarousel extends RyElement {
|
|
14
|
+
#private;
|
|
15
|
+
setup(): void;
|
|
16
|
+
goTo(index: number): void;
|
|
17
|
+
next(): void;
|
|
18
|
+
prev(): void;
|
|
19
|
+
teardown(): void;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ry-carousel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ry-carousel.d.ts","sourceRoot":"","sources":["../../src/ts/components/ry-carousel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,qBAAa,UAAW,SAAQ,SAAS;;IAOvC,KAAK,IAAI,IAAI;IAgJb,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IA6BzB,IAAI,IAAI,IAAI;IAIZ,IAAI,IAAI,IAAI;IAIZ,QAAQ,IAAI,IAAI;CAGjB"}
|