@ryanhelsing/ry-ui 1.0.2 → 1.0.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/AGENTS.md +56 -0
- package/README.md +26 -1
- 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-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-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 +620 -148
- package/dist/css/ry-theme.css +456 -180
- package/dist/css/ry-tokens.css +112 -24
- package/dist/css/ry-ui.css +4708 -1059
- package/dist/ry-ui.d.ts +7 -0
- package/dist/ry-ui.d.ts.map +1 -1
- package/dist/ry-ui.js +1071 -713
- 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.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 +86 -0
- package/docs/components/knob.md +42 -0
- package/docs/components/layout.md +189 -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 +5 -3
- package/USING_CDN.md +0 -591
package/dist/themes/dark.css
CHANGED
|
@@ -1,92 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ry-ui Dark Theme
|
|
2
|
+
* ry-ui Dark Theme — DEPRECATED
|
|
3
|
+
*
|
|
4
|
+
* Dark mode is now built into ry-tokens.css via light-dark().
|
|
5
|
+
* To force dark mode: <html data-ry-theme="dark">
|
|
6
|
+
* To respect OS preference: omit data-ry-theme (default behavior).
|
|
7
|
+
*
|
|
8
|
+
* This file is kept for backward compatibility but has no effect.
|
|
3
9
|
*/
|
|
4
|
-
|
|
5
|
-
[data-ry-theme="dark"] {
|
|
6
|
-
/* Colors */
|
|
7
|
-
--ry-color-primary: #60a5fa;
|
|
8
|
-
--ry-color-primary-hover: #3b82f6;
|
|
9
|
-
--ry-color-primary-active: #2563eb;
|
|
10
|
-
|
|
11
|
-
--ry-color-secondary: #94a3b8;
|
|
12
|
-
--ry-color-secondary-hover: #cbd5e1;
|
|
13
|
-
--ry-color-secondary-active: #e2e8f0;
|
|
14
|
-
|
|
15
|
-
/* Text */
|
|
16
|
-
--ry-color-text: #f1f5f9;
|
|
17
|
-
--ry-color-text-muted: #94a3b8;
|
|
18
|
-
--ry-color-text-inverse: #0f172a;
|
|
19
|
-
|
|
20
|
-
/* Background */
|
|
21
|
-
--ry-color-bg: #0f172a;
|
|
22
|
-
--ry-color-bg-subtle: #1e293b;
|
|
23
|
-
--ry-color-bg-muted: #334155;
|
|
24
|
-
|
|
25
|
-
/* Border */
|
|
26
|
-
--ry-color-border: #334155;
|
|
27
|
-
--ry-color-border-strong: #475569;
|
|
28
|
-
|
|
29
|
-
/* Overlay */
|
|
30
|
-
--ry-color-overlay: rgba(0, 0, 0, 0.7);
|
|
31
|
-
|
|
32
|
-
/* Shadows (more subtle in dark mode) */
|
|
33
|
-
--ry-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
|
|
34
|
-
--ry-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);
|
|
35
|
-
--ry-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4);
|
|
36
|
-
--ry-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.5);
|
|
37
|
-
|
|
38
|
-
/* Focus */
|
|
39
|
-
--ry-focus-ring: 0 0 0 3px rgba(96, 165, 250, 0.5);
|
|
40
|
-
|
|
41
|
-
/* Code block - Vibrant (using theme colors) */
|
|
42
|
-
--ry-code-bg: #0f172a;
|
|
43
|
-
--ry-code-header-bg: #1e293b;
|
|
44
|
-
--ry-code-text-color: #f1f5f9;
|
|
45
|
-
--ry-code-title-color: #94a3b8;
|
|
46
|
-
--ry-code-icon-color: #64748b;
|
|
47
|
-
--ry-code-icon-hover-bg: #334155;
|
|
48
|
-
--ry-code-icon-hover-color: #f1f5f9;
|
|
49
|
-
--ry-code-line-number-color: rgba(71, 85, 105, 0.6);
|
|
50
|
-
--ry-code-line-border-color: #334155;
|
|
51
|
-
--ry-code-color-preview-border: rgba(241, 245, 249, 0.3);
|
|
52
|
-
/* Syntax - theme button colors */
|
|
53
|
-
--ry-code-keyword: #ef4444;
|
|
54
|
-
--ry-code-property: #60a5fa;
|
|
55
|
-
--ry-code-value: #f59e0b;
|
|
56
|
-
--ry-code-string: #22c55e;
|
|
57
|
-
--ry-code-number: #f59e0b;
|
|
58
|
-
--ry-code-comment: #94a3b8;
|
|
59
|
-
--ry-code-selector: #06b6d4;
|
|
60
|
-
--ry-code-punctuation: #94a3b8;
|
|
61
|
-
--ry-code-tag: #06b6d4;
|
|
62
|
-
--ry-code-attribute: #60a5fa;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/* Alert overrides for dark mode */
|
|
66
|
-
[data-ry-theme="dark"] .ry-alert--info,
|
|
67
|
-
[data-ry-theme="dark"] ry-alert[type="info"] {
|
|
68
|
-
background-color: #164e63;
|
|
69
|
-
border-color: #06b6d4;
|
|
70
|
-
color: #a5f3fc;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
[data-ry-theme="dark"] .ry-alert--success,
|
|
74
|
-
[data-ry-theme="dark"] ry-alert[type="success"] {
|
|
75
|
-
background-color: #14532d;
|
|
76
|
-
border-color: #22c55e;
|
|
77
|
-
color: #bbf7d0;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
[data-ry-theme="dark"] .ry-alert--warning,
|
|
81
|
-
[data-ry-theme="dark"] ry-alert[type="warning"] {
|
|
82
|
-
background-color: #78350f;
|
|
83
|
-
border-color: #f59e0b;
|
|
84
|
-
color: #fef3c7;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
[data-ry-theme="dark"] .ry-alert--danger,
|
|
88
|
-
[data-ry-theme="dark"] ry-alert[type="danger"] {
|
|
89
|
-
background-color: #7f1d1d;
|
|
90
|
-
border-color: #ef4444;
|
|
91
|
-
color: #fecaca;
|
|
92
|
-
}
|
package/dist/themes/light.css
CHANGED
|
@@ -1,38 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ry-ui Light Theme
|
|
2
|
+
* ry-ui Light Theme — DEPRECATED
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Light mode is the default in ry-tokens.css via light-dark().
|
|
5
|
+
* To force light mode: <html data-ry-theme="light">
|
|
6
|
+
* To respect OS preference: omit data-ry-theme (default behavior).
|
|
7
|
+
*
|
|
8
|
+
* This file is kept for backward compatibility but has no effect.
|
|
6
9
|
*/
|
|
7
|
-
|
|
8
|
-
[data-ry-theme="light"] {
|
|
9
|
-
/* Light theme is the default, so minimal overrides needed */
|
|
10
|
-
--ry-color-bg: #ffffff;
|
|
11
|
-
--ry-color-bg-subtle: #f8fafc;
|
|
12
|
-
--ry-color-bg-muted: #f1f5f9;
|
|
13
|
-
--ry-color-text: #1e293b;
|
|
14
|
-
--ry-color-text-muted: #64748b;
|
|
15
|
-
|
|
16
|
-
/* Code block - Cool/Minimal (GitHub style) */
|
|
17
|
-
--ry-code-bg: #f6f8fa;
|
|
18
|
-
--ry-code-header-bg: #eaeef2;
|
|
19
|
-
--ry-code-text-color: #24292f;
|
|
20
|
-
--ry-code-title-color: #57606a;
|
|
21
|
-
--ry-code-icon-color: #8c959f;
|
|
22
|
-
--ry-code-icon-hover-bg: #d0d7de;
|
|
23
|
-
--ry-code-icon-hover-color: #24292f;
|
|
24
|
-
--ry-code-line-number-color: rgba(140, 149, 159, 0.6);
|
|
25
|
-
--ry-code-line-border-color: #d0d7de;
|
|
26
|
-
--ry-code-color-preview-border: rgba(36, 41, 47, 0.3);
|
|
27
|
-
/* Syntax */
|
|
28
|
-
--ry-code-keyword: #cf222e;
|
|
29
|
-
--ry-code-property: #0550ae;
|
|
30
|
-
--ry-code-value: #0a3069;
|
|
31
|
-
--ry-code-string: #0a3069;
|
|
32
|
-
--ry-code-number: #0550ae;
|
|
33
|
-
--ry-code-comment: #6e7781;
|
|
34
|
-
--ry-code-selector: #116329;
|
|
35
|
-
--ry-code-punctuation: #24292f;
|
|
36
|
-
--ry-code-tag: #116329;
|
|
37
|
-
--ry-code-attribute: #0550ae;
|
|
38
|
-
}
|
package/dist/themes/ocean.css
CHANGED
|
@@ -6,43 +6,39 @@
|
|
|
6
6
|
|
|
7
7
|
[data-ry-theme="ocean"] {
|
|
8
8
|
/* Primary - ocean blues */
|
|
9
|
-
--ry-color-primary:
|
|
10
|
-
--ry-color-primary-hover:
|
|
11
|
-
--ry-color-primary-active:
|
|
9
|
+
--ry-color-primary: oklch(0.685 0.148 237.3);
|
|
10
|
+
--ry-color-primary-hover: oklch(0.588 0.139 242);
|
|
11
|
+
--ry-color-primary-active: oklch(0.5 0.119 242.8);
|
|
12
12
|
|
|
13
13
|
/* Secondary - teal */
|
|
14
|
-
--ry-color-secondary:
|
|
15
|
-
--ry-color-secondary-hover:
|
|
16
|
-
--ry-color-secondary-active:
|
|
14
|
+
--ry-color-secondary: oklch(0.715 0.126 215.2);
|
|
15
|
+
--ry-color-secondary-hover: oklch(0.609 0.111 221.7);
|
|
16
|
+
--ry-color-secondary-active: oklch(0.52 0.094 223.1);
|
|
17
17
|
|
|
18
18
|
/* Text */
|
|
19
|
-
--ry-color-text:
|
|
20
|
-
--ry-color-text-muted:
|
|
21
|
-
--ry-color-text-inverse:
|
|
19
|
+
--ry-color-text: oklch(0.391 0.085 240.9);
|
|
20
|
+
--ry-color-text-muted: oklch(0.554 0.041 257.4);
|
|
21
|
+
--ry-color-text-inverse: oklch(1 0 0);
|
|
22
22
|
|
|
23
23
|
/* Background - light blues */
|
|
24
|
-
--ry-color-bg:
|
|
25
|
-
--ry-color-bg-subtle:
|
|
26
|
-
--ry-color-bg-muted:
|
|
24
|
+
--ry-color-bg: oklch(0.977 0.013 236.8);
|
|
25
|
+
--ry-color-bg-subtle: oklch(0.951 0.025 236.9);
|
|
26
|
+
--ry-color-bg-muted: oklch(0.901 0.056 230.9);
|
|
27
27
|
|
|
28
28
|
/* Border */
|
|
29
|
-
--ry-color-border:
|
|
30
|
-
--ry-color-border-strong:
|
|
29
|
+
--ry-color-border: oklch(0.828 0.101 230.3);
|
|
30
|
+
--ry-color-border-strong: oklch(0.753 0.139 232.7);
|
|
31
31
|
|
|
32
32
|
/* Shadows with blue tint */
|
|
33
|
-
--ry-shadow-sm: 0 1px 2px 0
|
|
34
|
-
--ry-shadow-md: 0 4px 6px -1px
|
|
35
|
-
--ry-shadow-lg: 0 10px 15px -3px
|
|
36
|
-
--ry-shadow-xl: 0 20px 25px -5px
|
|
33
|
+
--ry-shadow-sm: 0 1px 2px 0 oklch(0.685 0.148 237.3 / 0.1);
|
|
34
|
+
--ry-shadow-md: 0 4px 6px -1px oklch(0.685 0.148 237.3 / 0.15);
|
|
35
|
+
--ry-shadow-lg: 0 10px 15px -3px oklch(0.685 0.148 237.3 / 0.15);
|
|
36
|
+
--ry-shadow-xl: 0 20px 25px -5px oklch(0.685 0.148 237.3 / 0.2);
|
|
37
37
|
|
|
38
38
|
/* Focus */
|
|
39
|
-
--ry-focus-ring: 0 0 0 3px
|
|
40
|
-
}
|
|
39
|
+
--ry-focus-ring: 0 0 0 3px oklch(0.685 0.148 237.3 / 0.5);
|
|
41
40
|
|
|
42
|
-
/*
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
background-color: #e0f2fe;
|
|
46
|
-
border-color: #0ea5e9;
|
|
47
|
-
color: #0369a1;
|
|
41
|
+
/* Alerts */
|
|
42
|
+
--ry-color-info-bg: oklch(0.951 0.025 236.9);
|
|
43
|
+
--ry-color-info-text: oklch(0.5 0.119 242.8);
|
|
48
44
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Accordion
|
|
2
|
+
|
|
3
|
+
## `<ry-accordion>`
|
|
4
|
+
|
|
5
|
+
| Attribute (on accordion-item) | Values | Description |
|
|
6
|
+
|-------------------------------|--------|-------------|
|
|
7
|
+
| `title` | string | Header text |
|
|
8
|
+
| `open` | boolean | Initially expanded |
|
|
9
|
+
|
|
10
|
+
Events: `ry:toggle` on item — `e.detail.open` (boolean)
|
|
11
|
+
|
|
12
|
+
```html
|
|
13
|
+
<ry-accordion>
|
|
14
|
+
<ry-accordion-item title="Section 1" open>Content here.</ry-accordion-item>
|
|
15
|
+
<ry-accordion-item title="Section 2">More content.</ry-accordion-item>
|
|
16
|
+
</ry-accordion>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
JS:
|
|
20
|
+
```js
|
|
21
|
+
const item = document.querySelector('ry-accordion-item');
|
|
22
|
+
|
|
23
|
+
item.addEventListener('ry:toggle', (e) => {
|
|
24
|
+
console.log(e.detail.open); // true or false
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Programmatic
|
|
28
|
+
item.open = true;
|
|
29
|
+
item.open = false;
|
|
30
|
+
item.toggle();
|
|
31
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Button
|
|
2
|
+
|
|
3
|
+
## `<ry-button>`
|
|
4
|
+
|
|
5
|
+
| Attribute | Values | Description |
|
|
6
|
+
|-----------|--------|-------------|
|
|
7
|
+
| `variant` | primary \| secondary \| outline \| ghost \| danger | Style (default: primary) |
|
|
8
|
+
| `size` | sm \| md \| lg | Size |
|
|
9
|
+
| `modal` | string | Opens modal with this ID |
|
|
10
|
+
| `drawer` | string | Opens drawer with this ID |
|
|
11
|
+
| `disabled` | boolean | Disable |
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<ry-button>Primary</ry-button>
|
|
15
|
+
<ry-button variant="outline">Outline</ry-button>
|
|
16
|
+
<ry-button variant="danger" size="sm">Delete</ry-button>
|
|
17
|
+
<ry-button modal="confirm">Open Modal</ry-button>
|
|
18
|
+
<ry-button drawer="nav">Open Drawer</ry-button>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## `<ry-toggle-button>`
|
|
22
|
+
|
|
23
|
+
Selectable button. Same-name buttons form a radio group (only one pressed).
|
|
24
|
+
|
|
25
|
+
| Attribute | Values | Description |
|
|
26
|
+
|-----------|--------|-------------|
|
|
27
|
+
| `name` | string | Group name (same name = single selection) |
|
|
28
|
+
| `value` | string | Value when selected |
|
|
29
|
+
| `pressed` | boolean | Currently pressed |
|
|
30
|
+
| `block` | boolean | Full-width |
|
|
31
|
+
| `size` | sm \| md \| lg | Size |
|
|
32
|
+
| `disabled` | boolean | Disable |
|
|
33
|
+
|
|
34
|
+
Events: `ry:change` — `e.detail.pressed`, `e.detail.value`
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<ry-cluster>
|
|
38
|
+
<ry-toggle-button name="size" value="s">S</ry-toggle-button>
|
|
39
|
+
<ry-toggle-button name="size" value="m" pressed>M</ry-toggle-button>
|
|
40
|
+
<ry-toggle-button name="size" value="l">L</ry-toggle-button>
|
|
41
|
+
</ry-cluster>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Full-width card-style selection:
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
<ry-grid cols="3">
|
|
48
|
+
<ry-toggle-button name="plan" value="free" block>
|
|
49
|
+
<strong>Free</strong><br><b>$0</b>/month
|
|
50
|
+
</ry-toggle-button>
|
|
51
|
+
<ry-toggle-button name="plan" value="pro" block pressed>
|
|
52
|
+
<strong>Pro</strong><br><b>$10</b>/month
|
|
53
|
+
</ry-toggle-button>
|
|
54
|
+
</ry-grid>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
JS:
|
|
58
|
+
```js
|
|
59
|
+
// Get selected value from a group
|
|
60
|
+
const selected = document.querySelector('ry-toggle-button[name="plan"][pressed]');
|
|
61
|
+
selected?.value; // "pro"
|
|
62
|
+
|
|
63
|
+
// Set programmatically
|
|
64
|
+
button.pressed = true;
|
|
65
|
+
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Color Components
|
|
2
|
+
|
|
3
|
+
## `<ry-color-picker>`
|
|
4
|
+
|
|
5
|
+
Full color picker with saturation/hue panel.
|
|
6
|
+
|
|
7
|
+
| Attribute | Values | Description |
|
|
8
|
+
|-----------|--------|-------------|
|
|
9
|
+
| `value` | color string | Initial color (hex, rgb, hsl) |
|
|
10
|
+
| `format` | hex \| rgb \| hsl | Output format (default: hex) |
|
|
11
|
+
| `inline` | boolean | Always visible (no dropdown) |
|
|
12
|
+
| `opacity` | boolean | Enable alpha channel |
|
|
13
|
+
| `swatches` | string | Preset colors separated by `;` |
|
|
14
|
+
| `disabled` | boolean | Disable |
|
|
15
|
+
|
|
16
|
+
Events: `ry:input` (during drag), `ry:change` (on release)
|
|
17
|
+
API: `.value`, `.rgb`, `.hsl`, `.hsv`, `.setColor(str)`
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<ry-color-picker value="#3b82f6"></ry-color-picker>
|
|
21
|
+
<ry-color-picker value="#3b82f6" opacity inline swatches="#ef4444;#22c55e;#3b82f6"></ry-color-picker>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
JS:
|
|
25
|
+
```js
|
|
26
|
+
const picker = document.querySelector('ry-color-picker');
|
|
27
|
+
|
|
28
|
+
picker.addEventListener('ry:input', (e) => {
|
|
29
|
+
console.log(e.detail.value); // "#3b82f6"
|
|
30
|
+
console.log(e.detail.rgb); // { r: 59, g: 130, b: 246 }
|
|
31
|
+
console.log(e.detail.hsv); // { h: 217, s: 76, v: 96 }
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
picker.value = '#ff0000';
|
|
35
|
+
picker.setColor('hsl(200, 100%, 50%)');
|
|
36
|
+
picker.rgb; // { r, g, b }
|
|
37
|
+
picker.hsl; // { h, s, l }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## `<ry-color-input>`
|
|
41
|
+
|
|
42
|
+
Compact swatch + editable hex input.
|
|
43
|
+
|
|
44
|
+
| Attribute | Values | Description |
|
|
45
|
+
|-----------|--------|-------------|
|
|
46
|
+
| `value` | color string | Initial color |
|
|
47
|
+
| `format` | hex \| rgb \| hsl | Output format |
|
|
48
|
+
| `opacity` | boolean | Enable alpha |
|
|
49
|
+
| `disabled` | boolean | Disable |
|
|
50
|
+
|
|
51
|
+
Events: `ry:change` — `e.detail.value`
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<ry-color-input value="#3b82f6"></ry-color-input>
|
|
55
|
+
<ry-color-input value="rgba(139, 92, 246, 0.8)" opacity></ry-color-input>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## `<ry-gradient-picker>`
|
|
59
|
+
|
|
60
|
+
CSS gradient editor with draggable color stops.
|
|
61
|
+
|
|
62
|
+
| Attribute | Values | Description |
|
|
63
|
+
|-----------|--------|-------------|
|
|
64
|
+
| `value` | CSS gradient string | Initial gradient |
|
|
65
|
+
| `output` | boolean | Show CSS output |
|
|
66
|
+
| `disabled` | boolean | Disable |
|
|
67
|
+
|
|
68
|
+
Events: `ry:input`, `ry:change` — `e.detail.value`, `e.detail.stops`, `e.detail.type`, `e.detail.angle`
|
|
69
|
+
API: `.value`, `.type`, `.angle`, `.stops`, `.addStop(color, pos)`, `.removeStop(id)`
|
|
70
|
+
|
|
71
|
+
```html
|
|
72
|
+
<ry-gradient-picker value="linear-gradient(90deg, #3b82f6 0%, #8b5cf6 100%)"></ry-gradient-picker>
|
|
73
|
+
<ry-gradient-picker value="radial-gradient(circle, #fbbf24 0%, #dc2626 100%)"></ry-gradient-picker>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
JS:
|
|
77
|
+
```js
|
|
78
|
+
const picker = document.querySelector('ry-gradient-picker');
|
|
79
|
+
picker.value; // "linear-gradient(90deg, ...)"
|
|
80
|
+
picker.type; // "linear" | "radial"
|
|
81
|
+
picker.angle; // 0-360
|
|
82
|
+
picker.stops; // [{ id, color, position }, ...]
|
|
83
|
+
picker.addStop('#ff00ff', 50);
|
|
84
|
+
```
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Display Components
|
|
2
|
+
|
|
3
|
+
## `<ry-badge>`
|
|
4
|
+
|
|
5
|
+
| Attribute | Values | Description |
|
|
6
|
+
|-----------|--------|-------------|
|
|
7
|
+
| `variant` | default \| primary \| success \| warning \| danger | Color |
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<ry-badge>Default</ry-badge>
|
|
11
|
+
<ry-badge variant="success">Active</ry-badge>
|
|
12
|
+
<ry-badge variant="danger">Offline</ry-badge>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## `<ry-alert>`
|
|
16
|
+
|
|
17
|
+
| Attribute | Values | Description |
|
|
18
|
+
|-----------|--------|-------------|
|
|
19
|
+
| `type` | info \| success \| warning \| danger | Style |
|
|
20
|
+
| `title` | string | Heading |
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<ry-alert type="info" title="Info">Informational message.</ry-alert>
|
|
24
|
+
<ry-alert type="danger" title="Error">Something went wrong.</ry-alert>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## `<ry-icon>`
|
|
28
|
+
|
|
29
|
+
| Attribute | Values | Description |
|
|
30
|
+
|-----------|--------|-------------|
|
|
31
|
+
| `name` | close, check, chevron-down, chevron-up, chevron-left, chevron-right, copy, sun, moon, info, warning, error, success, search, menu, plus, minus, settings, user, heart, star, trash, edit, external-link, download, upload | Icon |
|
|
32
|
+
| `size` | number | Pixels (default: 24) |
|
|
33
|
+
| `label` | string | Accessible label |
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<ry-icon name="heart" size="16"></ry-icon>
|
|
37
|
+
<ry-icon name="settings"></ry-icon>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## `<ry-code>`
|
|
41
|
+
|
|
42
|
+
Use `<ry-code>` with prefix even inside `<ry>` to avoid conflict with native `<code>`.
|
|
43
|
+
|
|
44
|
+
| Attribute | Values | Description |
|
|
45
|
+
|-----------|--------|-------------|
|
|
46
|
+
| `language` | js \| css \| html \| json | Highlighting |
|
|
47
|
+
| `title` | string | Header |
|
|
48
|
+
| `line-numbers` | boolean | Show line numbers |
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<ry-code language="js" title="app.js">
|
|
52
|
+
const x = 1;
|
|
53
|
+
console.log(x);
|
|
54
|
+
</ry-code>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Table (native HTML)
|
|
58
|
+
|
|
59
|
+
Standard `<table>` elements are styled automatically by the ry-ui theme.
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<table>
|
|
63
|
+
<thead><tr><th>Name</th><th>Role</th></tr></thead>
|
|
64
|
+
<tbody>
|
|
65
|
+
<tr><td>Alice</td><td>Engineer</td></tr>
|
|
66
|
+
<tr><td>Bob</td><td>Designer</td></tr>
|
|
67
|
+
</tbody>
|
|
68
|
+
</table>
|
|
69
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Drawer
|
|
2
|
+
|
|
3
|
+
## `<ry-drawer>`
|
|
4
|
+
|
|
5
|
+
| Attribute | Values | Description |
|
|
6
|
+
|-----------|--------|-------------|
|
|
7
|
+
| `id` | string | Identifier (match button's `drawer` attr) |
|
|
8
|
+
| `side` | left \| right \| bottom | Slide direction |
|
|
9
|
+
|
|
10
|
+
Events: `ry:open`, `ry:close`
|
|
11
|
+
API: `.open()`, `.close()`, `.state`
|
|
12
|
+
|
|
13
|
+
```html
|
|
14
|
+
<ry-button drawer="nav">Menu</ry-button>
|
|
15
|
+
|
|
16
|
+
<ry-drawer id="nav" side="left">
|
|
17
|
+
<h3>Navigation</h3>
|
|
18
|
+
<ry-stack>
|
|
19
|
+
<a href="/">Home</a>
|
|
20
|
+
<a href="/about">About</a>
|
|
21
|
+
</ry-stack>
|
|
22
|
+
</ry-drawer>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
JS:
|
|
26
|
+
```js
|
|
27
|
+
const drawer = document.querySelector('ry-drawer');
|
|
28
|
+
|
|
29
|
+
drawer.addEventListener('ry:open', () => console.log('opened'));
|
|
30
|
+
drawer.addEventListener('ry:close', () => console.log('closed'));
|
|
31
|
+
|
|
32
|
+
// Programmatic
|
|
33
|
+
drawer.open();
|
|
34
|
+
drawer.close();
|
|
35
|
+
drawer.state; // "open" or "closed"
|
|
36
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Dropdown
|
|
2
|
+
|
|
3
|
+
## `<ry-dropdown>`
|
|
4
|
+
|
|
5
|
+
Use `slot="trigger"` on the trigger element. Menu items go inside `<ry-menu>`.
|
|
6
|
+
|
|
7
|
+
Events: `ry:select` — `e.detail.value`
|
|
8
|
+
API: `.open()`, `.close()`
|
|
9
|
+
|
|
10
|
+
```html
|
|
11
|
+
<ry-dropdown>
|
|
12
|
+
<ry-button slot="trigger">Options</ry-button>
|
|
13
|
+
<ry-menu>
|
|
14
|
+
<ry-menu-item>Edit</ry-menu-item>
|
|
15
|
+
<ry-menu-item>Duplicate</ry-menu-item>
|
|
16
|
+
<ry-divider></ry-divider>
|
|
17
|
+
<ry-menu-item>Delete</ry-menu-item>
|
|
18
|
+
</ry-menu>
|
|
19
|
+
</ry-dropdown>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
JS:
|
|
23
|
+
```js
|
|
24
|
+
const dropdown = document.querySelector('ry-dropdown');
|
|
25
|
+
|
|
26
|
+
dropdown.addEventListener('ry:select', (e) => {
|
|
27
|
+
console.log(e.detail.value); // "Edit", "Delete", etc.
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Programmatic
|
|
31
|
+
dropdown.open();
|
|
32
|
+
dropdown.close();
|
|
33
|
+
```
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Form Components
|
|
2
|
+
|
|
3
|
+
## `<ry-field>`
|
|
4
|
+
|
|
5
|
+
Wraps native `<input>` / `<textarea>` with label and optional error.
|
|
6
|
+
|
|
7
|
+
| Attribute | Values | Description |
|
|
8
|
+
|-----------|--------|-------------|
|
|
9
|
+
| `label` | string | Label text |
|
|
10
|
+
| `error` | string | Error message |
|
|
11
|
+
|
|
12
|
+
```html
|
|
13
|
+
<ry-field label="Email">
|
|
14
|
+
<input type="email" placeholder="you@example.com">
|
|
15
|
+
</ry-field>
|
|
16
|
+
<ry-field label="Bio" error="Required">
|
|
17
|
+
<textarea rows="3"></textarea>
|
|
18
|
+
</ry-field>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## `<ry-select>`
|
|
22
|
+
|
|
23
|
+
| Attribute | Values | Description |
|
|
24
|
+
|-----------|--------|-------------|
|
|
25
|
+
| `placeholder` | string | Placeholder text |
|
|
26
|
+
| `name` | string | Form field name |
|
|
27
|
+
|
|
28
|
+
Events: `ry:change` — `e.detail.value`, `e.detail.label`
|
|
29
|
+
API: `.value`, `.open()`, `.close()`
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<ry-select placeholder="Country" name="country">
|
|
33
|
+
<ry-option value="us">United States</ry-option>
|
|
34
|
+
<ry-option value="uk">United Kingdom</ry-option>
|
|
35
|
+
</ry-select>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
JS:
|
|
39
|
+
```js
|
|
40
|
+
const select = document.querySelector('ry-select');
|
|
41
|
+
select.addEventListener('ry:change', (e) => {
|
|
42
|
+
console.log(e.detail.value); // "us"
|
|
43
|
+
console.log(e.detail.label); // "United States"
|
|
44
|
+
});
|
|
45
|
+
select.value = 'uk';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## `<ry-switch>`
|
|
49
|
+
|
|
50
|
+
| Attribute | Values | Description |
|
|
51
|
+
|-----------|--------|-------------|
|
|
52
|
+
| `name` | string | Form field name |
|
|
53
|
+
| `checked` | boolean | Initially on |
|
|
54
|
+
| `disabled` | boolean | Disable |
|
|
55
|
+
|
|
56
|
+
Events: `ry:change` — `e.detail.checked`, `e.detail.name`
|
|
57
|
+
API: `.checked`
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<ry-switch name="notifications" checked>Email notifications</ry-switch>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
JS:
|
|
64
|
+
```js
|
|
65
|
+
const sw = document.querySelector('ry-switch');
|
|
66
|
+
sw.addEventListener('ry:change', (e) => {
|
|
67
|
+
console.log(e.detail.checked); // true or false
|
|
68
|
+
});
|
|
69
|
+
sw.checked = false;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Checkbox & Radio
|
|
73
|
+
|
|
74
|
+
Standard HTML, auto-styled by ry-ui theme. No custom elements needed.
|
|
75
|
+
|
|
76
|
+
```html
|
|
77
|
+
<ry-stack gap="sm">
|
|
78
|
+
<label><input type="checkbox" checked> Accept terms</label>
|
|
79
|
+
<label><input type="checkbox"> Newsletter</label>
|
|
80
|
+
</ry-stack>
|
|
81
|
+
|
|
82
|
+
<ry-stack gap="sm">
|
|
83
|
+
<label><input type="radio" name="plan" value="free" checked> Free</label>
|
|
84
|
+
<label><input type="radio" name="plan" value="pro"> Pro</label>
|
|
85
|
+
</ry-stack>
|
|
86
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Knob
|
|
2
|
+
|
|
3
|
+
## `<ry-knob>`
|
|
4
|
+
|
|
5
|
+
Rotary dial control. Great for audio/settings UIs.
|
|
6
|
+
|
|
7
|
+
| Attribute | Values | Description |
|
|
8
|
+
|-----------|--------|-------------|
|
|
9
|
+
| `min` | number | Minimum (default: 0) |
|
|
10
|
+
| `max` | number | Maximum (default: 100) |
|
|
11
|
+
| `step` | number | Step (default: 0 = smooth) |
|
|
12
|
+
| `value` | number | Current value |
|
|
13
|
+
| `label` | string | Label below knob |
|
|
14
|
+
| `labels` | string | Comma-separated labels for discrete steps |
|
|
15
|
+
| `description` | string | Tooltip on hover |
|
|
16
|
+
| `color` | primary \| secondary \| success \| warning \| danger | Track color |
|
|
17
|
+
| `size` | sm \| lg | Size |
|
|
18
|
+
| `disabled` | boolean | Disable |
|
|
19
|
+
|
|
20
|
+
Events: `ry:input` (during drag), `ry:change` (on release)
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<ry-knob min="0" max="100" value="50" label="Volume"></ry-knob>
|
|
24
|
+
<ry-knob min="0" max="3" step="1" value="1" labels="Off,Low,Med,High" label="Mode"></ry-knob>
|
|
25
|
+
<ry-knob value="60" color="warning" label="Warning"></ry-knob>
|
|
26
|
+
<ry-knob size="sm" value="25" label="Small"></ry-knob>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
JS:
|
|
30
|
+
```js
|
|
31
|
+
const knob = document.querySelector('ry-knob');
|
|
32
|
+
|
|
33
|
+
knob.addEventListener('ry:input', (e) => {
|
|
34
|
+
updateVolume(e.detail.value); // fires during drag
|
|
35
|
+
});
|
|
36
|
+
knob.addEventListener('ry:change', (e) => {
|
|
37
|
+
saveSettings({ volume: e.detail.value }); // fires on release
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
knob.value; // 50
|
|
41
|
+
knob.value = 75;
|
|
42
|
+
```
|