@ryanhelsing/ry-ui 1.0.3 → 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.
@@ -0,0 +1,36 @@
1
+ # Button Group
2
+
3
+ ## `<ry-button-group>`
4
+
5
+ Segmented control with radio-group behavior. Only one child button can be selected at a time.
6
+
7
+ | Attribute | Values | Description |
8
+ |-----------|--------|-------------|
9
+ | `name` | string | Optional group name |
10
+ | `value` | string | Currently selected button value |
11
+
12
+ Events: `ry:change` — `e.detail.value`
13
+
14
+ Child buttons must have a `value` attribute to participate. Clicking a button sets `pressed` + `aria-pressed="true"` on it and clears the others.
15
+
16
+ ```html
17
+ <ry-button-group name="billing" value="monthly">
18
+ <ry-button value="monthly">Monthly</ry-button>
19
+ <ry-button value="annually">Annually</ry-button>
20
+ </ry-button-group>
21
+
22
+ <ry-button-group name="mode" value="terminal">
23
+ <ry-button value="direct">Direct</ry-button>
24
+ <ry-button value="terminal">Terminal</ry-button>
25
+ <ry-button value="release">Release</ry-button>
26
+ </ry-button-group>
27
+ ```
28
+
29
+ JS:
30
+ ```js
31
+ const group = document.querySelector('ry-button-group');
32
+ group.addEventListener('ry:change', (e) => {
33
+ console.log(e.detail.value); // "monthly" | "annually"
34
+ });
35
+ group.value = 'annually'; // programmatic selection
36
+ ```
@@ -2,20 +2,24 @@
2
2
 
3
3
  ## `<ry-field>`
4
4
 
5
- Wraps native `<input>` / `<textarea>` with label and optional error.
5
+ Wraps native `<input>` / `<textarea>` / `<select>` with auto-generated label, error, and hint. Handles accessibility linking (aria-describedby, aria-invalid) automatically.
6
6
 
7
7
  | Attribute | Values | Description |
8
8
  |-----------|--------|-------------|
9
9
  | `label` | string | Label text |
10
- | `error` | string | Error message |
10
+ | `error` | string | Error message (hides hint when set) |
11
+ | `hint` | string | Helper text shown below input |
11
12
 
12
13
  ```html
13
- <ry-field label="Email">
14
+ <ry-field label="Email" hint="We'll never share your email">
14
15
  <input type="email" placeholder="you@example.com">
15
16
  </ry-field>
16
- <ry-field label="Bio" error="Required">
17
- <textarea rows="3"></textarea>
17
+
18
+ <ry-field label="Password" error="Must be at least 8 characters">
19
+ <input type="password">
18
20
  </ry-field>
21
+
22
+ <!-- Setting error="" clears the error and shows hint again -->
19
23
  ```
20
24
 
21
25
  ## `<ry-select>`
@@ -112,15 +112,43 @@ Sidebar / secondary content block.
112
112
 
113
113
  ## `<ry-split>`
114
114
 
115
- Two-pane layout: content (flexible) + sidebar (300px). Stacks vertically on mobile (<768px).
115
+ Two-pane layout: content (flexible) + sidebar (fixed). Stacks vertically on mobile (<768px).
116
+
117
+ | Attribute | Values | Description |
118
+ |-----------|--------|-------------|
119
+ | `resizable` | boolean | Enables drag handle between panes |
120
+ | `persist` | string | localStorage key — saves/restores width as `ry-split:{key}` |
121
+
122
+ CSS custom properties:
123
+
124
+ | Property | Default | Description |
125
+ |----------|---------|-------------|
126
+ | `--ry-split-width` | `300px` | Sidebar width |
127
+ | `--ry-split-min-width` | `100px` | Minimum width during resize |
128
+ | `--ry-split-max-width` | `80%` | Maximum width during resize |
129
+
130
+ Events: `ry:resize` — `e.detail.width`
116
131
 
117
132
  ```html
133
+ <!-- Basic -->
118
134
  <ry-split>
119
135
  <div>Main content (flex: 1)</div>
120
136
  <div>Sidebar (300px)</div>
121
137
  </ry-split>
138
+
139
+ <!-- Resizable with persistence -->
140
+ <ry-split resizable persist="sidebar" style="--ry-split-width: 400px">
141
+ <main>Content</main>
142
+ <aside>Resizable sidebar</aside>
143
+ </ry-split>
122
144
  ```
123
145
 
146
+ Resize interaction:
147
+ - **Drag** handle between panes (mouse + touch)
148
+ - **Arrow keys** ±10px, **Shift+Arrow** ±50px
149
+ - **Home/End** jump to min/max
150
+ - **Double-click** handle to reset to default
151
+
124
152
  ## `<ry-center>`
125
153
 
126
154
  Centers content both horizontally and vertically.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryanhelsing/ry-ui",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Framework-agnostic, Light DOM web components. CSS is the source of truth.",
5
5
  "type": "module",
6
6
  "main": "./dist/ry-ui.js",
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "files": [
18
18
  "dist",
19
+ "AGENT.md",
19
20
  "AGENTS.md",
20
21
  "docs/components",
21
22
  "docs/theming.md"
@@ -26,7 +27,8 @@
26
27
  "build:types": "tsc --emitDeclarationOnly",
27
28
  "build:css": "mkdir -p dist/css && node -e \"const fs=require('fs'); const files=['src/css/ry-tokens.css','src/css/ry-structure.css','src/css/ry-theme.css']; const out=files.map(f=>fs.readFileSync(f,'utf8')).join('\\n'); fs.writeFileSync('dist/css/ry-ui.css',out);\" && cp src/css/ry-tokens.css src/css/ry-structure.css src/css/ry-theme.css dist/css/ && mkdir -p dist/themes && cp src/themes/*.css dist/themes/",
28
29
  "preview": "vite preview",
29
- "typecheck": "tsc --noEmit"
30
+ "typecheck": "tsc --noEmit",
31
+ "release": "npm run build && git add -A && git diff-index --quiet HEAD || git commit -m 'new build' && npm version patch && npm publish --access public"
30
32
  },
31
33
  "devDependencies": {
32
34
  "typescript": "^5.7.2",