@ryanhelsing/ry-ui 1.0.10 → 1.0.12

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.
@@ -1,253 +0,0 @@
1
- @use "sass:list";
2
- @use "sass:map";
3
-
4
- // mixins
5
- @mixin coords-to-property($pixel-size,$coord-array,$property) {
6
- $value-sets: ();
7
-
8
- @each $coords in $coord-array {
9
- $x: $pixel-size * map.get($coords,"x");
10
- $y: $pixel-size * map.get($coords,"y");
11
- $value-sets: list.append($value-sets,($x $y),comma);
12
- }
13
- @if $property == "box-shadow" {
14
- box-shadow: $value-sets;
15
- }
16
- @else if $property == "clip-path" {
17
- clip-path: polygon($value-sets);
18
- }
19
- }
20
- @mixin range-thumb($pixel-size) {
21
- background-color: transparent;
22
- border: 0;
23
- border-radius: 0;
24
- box-shadow: none;
25
- cursor: pointer;
26
- width: $pixel-size * 5;
27
- height: $pixel-size * 21;
28
- }
29
-
30
- // normal styles
31
- * {
32
- border: 0;
33
- box-sizing: border-box;
34
- margin: 0;
35
- padding: 0;
36
- }
37
- :root {
38
- --hue: 223;
39
- --sat: 10%;
40
- --bg: hsl(var(--hue),var(--sat),30%);
41
- --fg: hsl(var(--hue),var(--sat),90%);
42
- font-size: 12px;
43
- }
44
- body,
45
- input {
46
- font: 1em/1.5 sans-serif;
47
- }
48
- body {
49
- background-color: var(--bg);
50
- color: var(--fg);
51
- display: flex;
52
- height: 100vh;
53
- }
54
- input {
55
- outline: transparent;
56
- -webkit-appearance: none;
57
- appearance: none;
58
- -webkit-tap-highlight-color: transparent;
59
- }
60
- main {
61
- display: flex;
62
- overflow-x: hidden;
63
- padding: 1.5em 0;
64
- width: 100vw;
65
- height: 100vh;
66
- }
67
- .grid {
68
- display: grid;
69
- gap: 1.5em;
70
- grid-template-columns: repeat(2,1fr);
71
- margin: auto;
72
- }
73
- .led-control {
74
- $border:
75
- ("x": 2, "y": 0),
76
- ("x": 19, "y": 0),
77
- ("x": 19, "y": 1),
78
- ("x": 20, "y": 1),
79
- ("x": 20, "y": 2),
80
- ("x": 21, "y": 2),
81
- ("x": 21, "y": 42),
82
- ("x": 20, "y": 42),
83
- ("x": 20, "y": 42),
84
- ("x": 20, "y": 43),
85
- ("x": 19, "y": 43),
86
- ("x": 19, "y": 44),
87
- ("x": 2, "y": 44),
88
- ("x": 2, "y": 43),
89
- ("x": 1, "y": 43),
90
- ("x": 1, "y": 42),
91
- ("x": 0, "y": 42),
92
- ("x": 0, "y": 2),
93
- ("x": 1, "y": 2),
94
- ("x": 1, "y": 1),
95
- ("x": 2, "y": 1);
96
- $sprites: (
97
- "audio":
98
- ("x": 5, "y": 1)
99
- ("x": 4, "y": 2)
100
- ("x": 5, "y": 2)
101
- ("x": 3, "y": 3)
102
- ("x": 4, "y": 3)
103
- ("x": 5, "y": 3)
104
- ("x": 9, "y": 3)
105
- ("x": 1, "y": 4)
106
- ("x": 2, "y": 4)
107
- ("x": 3, "y": 4)
108
- ("x": 4, "y": 4)
109
- ("x": 5, "y": 4)
110
- ("x": 8, "y": 4)
111
- ("x": 1, "y": 5)
112
- ("x": 2, "y": 5)
113
- ("x": 3, "y": 5)
114
- ("x": 4, "y": 5)
115
- ("x": 5, "y": 5)
116
- ("x": 9, "y": 5)
117
- ("x": 1, "y": 6)
118
- ("x": 2, "y": 6)
119
- ("x": 3, "y": 6)
120
- ("x": 4, "y": 6)
121
- ("x": 5, "y": 6)
122
- ("x": 8, "y": 6)
123
- ("x": 3, "y": 7)
124
- ("x": 4, "y": 7)
125
- ("x": 5, "y": 7)
126
- ("x": 9, "y": 7)
127
- ("x": 4, "y": 8)
128
- ("x": 5, "y": 8)
129
- ("x": 5, "y": 9),
130
- "sun":
131
- ("x": 5, "y": 0)
132
- ("x": 1, "y": 1)
133
- ("x": 5, "y": 1)
134
- ("x": 9, "y": 1)
135
- ("x": 2, "y": 2)
136
- ("x": 4, "y": 2)
137
- ("x": 5, "y": 2)
138
- ("x": 6, "y": 2)
139
- ("x": 8, "y": 2)
140
- ("x": 3, "y": 3)
141
- ("x": 7, "y": 3)
142
- ("x": 2, "y": 4)
143
- ("x": 8, "y": 4)
144
- ("x": 0, "y": 5)
145
- ("x": 1, "y": 5)
146
- ("x": 2, "y": 5)
147
- ("x": 8, "y": 5)
148
- ("x": 9, "y": 5)
149
- ("x": 10, "y": 5)
150
- ("x": 2, "y": 6)
151
- ("x": 8, "y": 6)
152
- ("x": 3, "y": 7)
153
- ("x": 7, "y": 7)
154
- ("x": 2, "y": 8)
155
- ("x": 4, "y": 8)
156
- ("x": 5, "y": 8)
157
- ("x": 6, "y": 8)
158
- ("x": 8, "y": 8)
159
- ("x": 1, "y": 9)
160
- ("x": 5, "y": 9)
161
- ("x": 9, "y": 9)
162
- ("x": 5, "y": 10)
163
- );
164
- $pixel-size: 0.5em;
165
- margin: auto;
166
- position: relative;
167
- width: $pixel-size * 21;
168
- height: $pixel-size * 44;
169
-
170
- &__icon {
171
- color: #eee;
172
- bottom: $pixel-size * 5;
173
- left: $pixel-size * 5;
174
- width: $pixel-size * 11;
175
- height: $pixel-size * 11;
176
-
177
- &,
178
- &:before {
179
- position: absolute;
180
- }
181
- &:before {
182
- $dot-size: $pixel-size * 0.75;
183
- $dot-margin: $pixel-size * 0.125;
184
- border-radius: 50%;
185
- content: "";
186
- display: block;
187
- // clean up artifacts on non-retina screens caused by layer overlap
188
- filter:
189
- drop-shadow(1px 1px var(--bg))
190
- drop-shadow(-1px 0 var(--bg))
191
- drop-shadow(0 -1px var(--bg));
192
- top: $dot-margin;
193
- left: $dot-margin;
194
- width: $dot-size;
195
- height: $dot-size;
196
- }
197
- @each $name, $pixels in $sprites {
198
- &--#{$name} {
199
- &:before {
200
- @include coords-to-property($pixel-size,$pixels,"box-shadow");
201
- }
202
- }
203
- }
204
- }
205
- &__input,
206
- &__label,
207
- &__layer,
208
- &__layer-wrap {
209
- position: absolute;
210
- }
211
- &__input {
212
- background-color: transparent;
213
- box-shadow: 0 0 0 0.25em transparent;
214
- top: 50%;
215
- left: 50%;
216
- transform: translate(-50%,-50%) rotate(-90deg);
217
- width: $pixel-size * 44;
218
- height: $pixel-size * 21;
219
-
220
- &:focus-visible {
221
- box-shadow: 0 0 0 0.25em var(--fg);
222
- }
223
- &::-webkit-slider-thumb {
224
- @include range-thumb($pixel-size);
225
- -webkit-appearance: none;
226
- }
227
- &::-moz-range-thumb {
228
- @include range-thumb($pixel-size);
229
- }
230
- }
231
- &__label {
232
- overflow: hidden;
233
- width: 1px;
234
- height: 1px;
235
- }
236
- &__layer {
237
- background: url("data:image/svg+xml,<svg viewBox='0 0 8 8' xmlns='http://www.w3.org/2000/svg'><circle fill='%23111' cx='4' cy='4' r='3' /></svg>") (0 0) / ($pixel-size $pixel-size);
238
-
239
- &,
240
- &-wrap {
241
- inset: 0;
242
- }
243
- &-wrap {
244
- @include coords-to-property($pixel-size,$border,"clip-path");
245
- }
246
- }
247
- &__layer--inverted {
248
- background-image: url("data:image/svg+xml,<svg viewBox='0 0 8 8' xmlns='http://www.w3.org/2000/svg'><circle fill='%23eee' cx='4' cy='4' r='3' /></svg>");
249
- }
250
- &__layer--inverted &__icon {
251
- color: #111;
252
- }
253
- }
package/llms.txt DELETED
@@ -1,346 +0,0 @@
1
- # ry-ui
2
-
3
- > Framework-agnostic Light DOM web components. Zero dependencies. CSS is the source of truth.
4
-
5
- ## Setup (2 lines)
6
-
7
- ```html
8
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ryanhelsing/ry-ui/dist/css/ry-ui.css">
9
- <script type="module" src="https://cdn.jsdelivr.net/npm/@ryanhelsing/ry-ui/dist/ry-ui.js"></script>
10
- ```
11
-
12
- Set theme on `<html>`: `data-ry-theme="light"` or `"dark"`. Omit for OS preference.
13
- Set body colors: `<body style="background: var(--ry-color-bg); color: var(--ry-color-text);">`
14
-
15
- ## DON'T / DO
16
-
17
- DON'T write flexbox/grid CSS for page layout.
18
- DO: `<ry-page><ry-header>H</ry-header><ry-main>M</ry-main><ry-footer>F</ry-footer></ry-page>`
19
-
20
- DON'T write a custom modal with backdrop, focus trap, escape handling.
21
- DO: `<ry-button modal="m">Open</ry-button><ry-modal id="m" title="T">Content</ry-modal>`
22
-
23
- DON'T write a slide-out drawer with CSS transforms.
24
- DO: `<ry-button drawer="d">Open</ry-button><ry-drawer id="d" side="left">Content</ry-drawer>`
25
-
26
- DON'T write tab switching logic or CSS.
27
- DO: `<ry-tabs><ry-tab title="A" active>A</ry-tab><ry-tab title="B">B</ry-tab></ry-tabs>`
28
-
29
- DON'T write a custom select dropdown with keyboard navigation.
30
- DO: `<ry-select placeholder="Pick"><ry-option value="a">A</ry-option></ry-select>`
31
-
32
- DON'T write CSS variables for colors, spacing, shadows.
33
- DO: Use `--ry-color-*`, `--ry-space-*`, `--ry-radius-*`, `--ry-shadow-*` tokens.
34
-
35
- DON'T write button styles with hover/active/focus states.
36
- DO: `<ry-button variant="primary">Click</ry-button>`
37
-
38
- DON'T write toast/notification CSS and JS.
39
- DO: `RyToast.success('Saved!')` / `RyToast.error('Failed')`
40
-
41
- DON'T write accordion expand/collapse logic.
42
- DO: `<ry-accordion><ry-accordion-item title="Q" open>A</ry-accordion-item></ry-accordion>`
43
-
44
- DON'T write a toggle switch from scratch.
45
- DO: `<ry-switch name="notify" checked></ry-switch>`
46
-
47
- ## Full Page Template
48
-
49
- ```html
50
- <!DOCTYPE html>
51
- <html lang="en" data-ry-theme="light">
52
- <head>
53
- <meta charset="UTF-8">
54
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
55
- <title>My App</title>
56
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ryanhelsing/ry-ui/dist/css/ry-ui.css">
57
- </head>
58
- <body style="background: var(--ry-color-bg); color: var(--ry-color-text);">
59
- <ry-page>
60
- <ry-header sticky>
61
- <ry-cluster>
62
- <strong>My App</strong>
63
- <ry-nav>
64
- <a href="/" aria-current="page">Home</a>
65
- <a href="/about">About</a>
66
- </ry-nav>
67
- </ry-cluster>
68
- <ry-actions>
69
- <ry-theme-toggle themes="light,dark"></ry-theme-toggle>
70
- </ry-actions>
71
- </ry-header>
72
-
73
- <ry-main>
74
- <ry-section>
75
- <h1>Hello World</h1>
76
- <p>Your content here.</p>
77
- </ry-section>
78
- </ry-main>
79
-
80
- <ry-footer>Built with ry-ui</ry-footer>
81
- </ry-page>
82
-
83
- <script type="module" src="https://cdn.jsdelivr.net/npm/@ryanhelsing/ry-ui/dist/ry-ui.js"></script>
84
- </body>
85
- </html>
86
- ```
87
-
88
- ## Components — Copy-Paste Reference
89
-
90
- ### Layout (CSS-only, no JS needed)
91
-
92
- ```html
93
- <ry-page>
94
- <ry-header sticky>Header</ry-header>
95
- <ry-main><ry-section>Content</ry-section></ry-main>
96
- <ry-footer>Footer</ry-footer>
97
- </ry-page>
98
-
99
- <ry-grid cols="3">
100
- <div>1</div><div>2</div><div>3</div>
101
- </ry-grid>
102
-
103
- <!-- Responsive: cols-sm="1" cols-md="2" cols-lg="3" -->
104
- <ry-grid cols="4" cols-sm="1" cols-md="2">...</ry-grid>
105
-
106
- <ry-stack gap="md">Vertical stack</ry-stack>
107
- <ry-cluster gap="sm">Horizontal row, wraps</ry-cluster>
108
- <ry-center>Centered both axes</ry-center>
109
- <ry-card>Card container (lifts on hover)</ry-card>
110
- <ry-divider></ry-divider>
111
- ```
112
-
113
- ### Buttons
114
-
115
- ```html
116
- <ry-button>Default</ry-button>
117
- <ry-button variant="primary">Primary</ry-button>
118
- <ry-button variant="secondary">Secondary</ry-button>
119
- <ry-button variant="outline">Outline</ry-button>
120
- <ry-button variant="ghost">Ghost</ry-button>
121
- <ry-button variant="danger">Danger</ry-button>
122
- <ry-button variant="accent">Accent</ry-button>
123
- <ry-button size="sm">Small</ry-button>
124
- <ry-button size="lg">Large</ry-button>
125
- <ry-button disabled>Disabled</ry-button>
126
- <ry-button modal="modal-id">Opens modal</ry-button>
127
- <ry-button drawer="drawer-id">Opens drawer</ry-button>
128
- ```
129
-
130
- ### Modal
131
-
132
- ```html
133
- <ry-button modal="my-modal">Open Modal</ry-button>
134
- <ry-modal id="my-modal" title="Confirm">
135
- <p>Are you sure?</p>
136
- <ry-cluster>
137
- <ry-button variant="danger">Delete</ry-button>
138
- <ry-button variant="ghost">Cancel</ry-button>
139
- </ry-cluster>
140
- </ry-modal>
141
- ```
142
-
143
- ### Drawer
144
-
145
- ```html
146
- <ry-button drawer="my-drawer">Open Drawer</ry-button>
147
- <ry-drawer id="my-drawer" side="left" title="Menu">
148
- <!-- side: left | right | bottom -->
149
- <nav>Navigation content</nav>
150
- </ry-drawer>
151
- ```
152
-
153
- ### Tabs
154
-
155
- ```html
156
- <ry-tabs>
157
- <ry-tab title="Overview" active>First tab content</ry-tab>
158
- <ry-tab title="Settings">Second tab content</ry-tab>
159
- <ry-tab title="Logs">Third tab content</ry-tab>
160
- </ry-tabs>
161
- ```
162
-
163
- ### Accordion
164
-
165
- ```html
166
- <ry-accordion>
167
- <ry-accordion-item title="Section One" open>Content</ry-accordion-item>
168
- <ry-accordion-item title="Section Two">Content</ry-accordion-item>
169
- </ry-accordion>
170
- ```
171
-
172
- ### Select
173
-
174
- ```html
175
- <ry-select placeholder="Choose country" name="country">
176
- <ry-option value="us">United States</ry-option>
177
- <ry-option value="uk">United Kingdom</ry-option>
178
- <ry-option value="ca">Canada</ry-option>
179
- </ry-select>
180
- ```
181
-
182
- ### Forms
183
-
184
- ```html
185
- <ry-field label="Email" hint="We'll never share it">
186
- <input type="email" placeholder="you@example.com">
187
- </ry-field>
188
-
189
- <ry-field label="Password" error="Must be at least 8 characters">
190
- <input type="password">
191
- </ry-field>
192
-
193
- <ry-switch name="notifications" checked></ry-switch>
194
- ```
195
-
196
- ### Dropdown Menu
197
-
198
- ```html
199
- <ry-dropdown>
200
- <ry-button slot="trigger">Actions</ry-button>
201
- <ry-menu>
202
- <ry-menu-item>Edit</ry-menu-item>
203
- <ry-menu-item>Duplicate</ry-menu-item>
204
- <ry-menu-item>Delete</ry-menu-item>
205
- </ry-menu>
206
- </ry-dropdown>
207
- ```
208
-
209
- ### Toast (JS only — no HTML needed)
210
-
211
- ```javascript
212
- RyToast.success('Saved successfully!');
213
- RyToast.error('Something went wrong');
214
- RyToast.info('FYI...');
215
- RyToast.warning('Be careful');
216
- RyToast.show({ message: 'Custom', variant: 'info', duration: 5000 });
217
- ```
218
-
219
- ### Display
220
-
221
- ```html
222
- <ry-alert type="info">Informational message</ry-alert>
223
- <ry-alert type="success">Operation completed</ry-alert>
224
- <ry-alert type="warning">Proceed with caution</ry-alert>
225
- <ry-alert type="danger" dismissible>Something went wrong</ry-alert>
226
-
227
- <ry-badge>Default</ry-badge>
228
- <ry-badge variant="success">Active</ry-badge>
229
- <ry-badge variant="danger">Error</ry-badge>
230
-
231
- <ry-tooltip content="Help text" position="top">
232
- <span>Hover me</span>
233
- </ry-tooltip>
234
- ```
235
-
236
- ### Slider & Knob
237
-
238
- ```html
239
- <ry-slider min="0" max="100" value="50" step="1"></ry-slider>
240
- <ry-slider range start="20" end="80"></ry-slider>
241
- <ry-knob min="0" max="100" value="50" label="Volume"></ry-knob>
242
- ```
243
-
244
- ### Split Layout (resizable sidebar)
245
-
246
- ```html
247
- <ry-split resizable persist="sidebar">
248
- <div>Main content</div>
249
- <div>Sidebar</div>
250
- </ry-split>
251
- ```
252
-
253
- ### Button Group (segmented control)
254
-
255
- ```html
256
- <ry-button-group name="billing" value="monthly">
257
- <ry-button value="monthly">Monthly</ry-button>
258
- <ry-button value="annually">Annually</ry-button>
259
- </ry-button-group>
260
- ```
261
-
262
- ### Nav Bar Pattern
263
-
264
- ```html
265
- <ry-header sticky>
266
- <ry-cluster>
267
- <ry-logo>MyApp</ry-logo>
268
- <ry-divider vertical></ry-divider>
269
- <ry-nav>
270
- <a href="/" aria-current="page">Home</a>
271
- <a href="/docs">Docs</a>
272
- </ry-nav>
273
- </ry-cluster>
274
- <ry-actions>
275
- <ry-button variant="ghost" size="sm">Login</ry-button>
276
- <ry-button size="sm">Sign Up</ry-button>
277
- </ry-actions>
278
- </ry-header>
279
- ```
280
-
281
- ### Interactive Card Grid
282
-
283
- ```html
284
- <ry-grid cols="3">
285
- <ry-card interactive>
286
- <h3>Feature A</h3>
287
- <p>Description of feature A</p>
288
- </ry-card>
289
- <ry-card interactive>
290
- <h3>Feature B</h3>
291
- <p>Description of feature B</p>
292
- </ry-card>
293
- </ry-grid>
294
- ```
295
-
296
- ## Events
297
-
298
- All events are prefixed with `ry:`:
299
-
300
- ```javascript
301
- element.addEventListener('ry:change', (e) => console.log(e.detail));
302
- element.addEventListener('ry:open', () => {});
303
- element.addEventListener('ry:close', () => {});
304
- element.addEventListener('ry:click', () => {});
305
- ```
306
-
307
- ## Programmatic Control
308
-
309
- ```javascript
310
- document.querySelector('ry-modal').open();
311
- document.querySelector('ry-modal').close();
312
- document.querySelector('ry-drawer').toggle();
313
- document.querySelector('ry-select').value = 'new-value';
314
- ```
315
-
316
- ## Theming
317
-
318
- Override tokens in your own CSS — no build step needed:
319
-
320
- ```css
321
- :root {
322
- --ry-color-primary: oklch(0.541 0.218 293);
323
- --ry-color-primary-hover: oklch(0.491 0.234 292);
324
- --ry-radius-md: 0;
325
- }
326
- ```
327
-
328
- Key tokens: `--ry-color-{primary,secondary,accent,success,warning,danger,info}`,
329
- `--ry-color-{text,text-muted,bg,bg-subtle,border}`, `--ry-space-{1-20}`,
330
- `--ry-radius-{sm,md,lg,xl,full}`, `--ry-shadow-{sm,md,lg,xl}`,
331
- `--ry-font-{sans,mono}`, `--ry-text-{xs,sm,base,lg,xl,2xl,3xl,4xl}`
332
-
333
- ## Vendoring (no npm required)
334
-
335
- Copy files into your project instead of using CDN:
336
-
337
- ```bash
338
- npm pack @ryanhelsing/ry-ui && tar -xf ryanhelsing-ry-ui-*.tgz
339
- cp -r package/dist ./vendor/ry-ui && rm -rf package ryanhelsing-ry-ui-*.tgz
340
- ```
341
-
342
- Then use local paths:
343
- ```html
344
- <link rel="stylesheet" href="/vendor/ry-ui/css/ry-ui.css">
345
- <script type="module" src="/vendor/ry-ui/ry-ui.js"></script>
346
- ```