@rip-lang/ui 0.3.29 → 0.3.31
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/README.md +68 -27
- package/index.rip +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Headless, accessible UI components written in Rip. Zero dependencies.
|
|
4
4
|
Every widget exposes `$` attributes (compiled to `data-*`) for styling and
|
|
5
5
|
handles keyboard interactions per WAI-ARIA Authoring Practices. Style with
|
|
6
|
-
Tailwind
|
|
6
|
+
Tailwind using `data-[attr]:` variants.
|
|
7
7
|
|
|
8
8
|
Components are plain `.rip` source files — no build step. The browser compiles
|
|
9
9
|
them on the fly.
|
|
@@ -17,7 +17,7 @@ Add the components directory to your serve middleware:
|
|
|
17
17
|
```coffee
|
|
18
18
|
use serve
|
|
19
19
|
dir: dir
|
|
20
|
-
|
|
20
|
+
bundle: ['components', '../../../packages/ui']
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
All widgets become available by name (`Select`, `Dialog`, `Grid`, etc.) in the
|
|
@@ -31,8 +31,8 @@ rip server
|
|
|
31
31
|
Every widget:
|
|
32
32
|
- Handles all keyboard interactions per WAI-ARIA Authoring Practices
|
|
33
33
|
- Sets correct ARIA attributes automatically
|
|
34
|
-
- Exposes state via `$` sigil (`$open`, `$selected`)
|
|
35
|
-
- Ships no CSS —
|
|
34
|
+
- Exposes state via `$` sigil (`$open`, `$selected`) — style with Tailwind's `data-[attr]:` variants
|
|
35
|
+
- Ships no CSS — you bring Tailwind classes
|
|
36
36
|
- Uses Rip's reactive primitives for all state management
|
|
37
37
|
|
|
38
38
|
---
|
|
@@ -54,6 +54,7 @@ to know to use these widgets:
|
|
|
54
54
|
| `ref:` | DOM ref | `ref: "_panel"` — saves DOM element reference |
|
|
55
55
|
| `slot` | Children | Projects parent-provided content into the component |
|
|
56
56
|
| `offer` / `accept` | Context | Share reactive state between ancestor and descendant components |
|
|
57
|
+
| `::` | Type | `@variant:: string := "default"` — typed prop (enables IDE completions + diagnostics) |
|
|
57
58
|
|
|
58
59
|
Two-way binding example — React vs Rip:
|
|
59
60
|
|
|
@@ -79,7 +80,7 @@ input value <=> @name
|
|
|
79
80
|
| Component count | ~40 | 54 |
|
|
80
81
|
| Total source | ShadCN wrappers (~3K LOC) atop Radix (~20K+ LOC) | 5,191 SLOC — everything included |
|
|
81
82
|
| Build step | Required (Next.js, Vite, etc.) | None — browser compiles `.rip` source |
|
|
82
|
-
| Styling | Pre-wired Tailwind (ShadCN) or unstyled (Radix) | Headless — `data-*` contract,
|
|
83
|
+
| Styling | Pre-wired Tailwind (ShadCN) or unstyled (Radix) | Headless — `data-*` contract, styled with Tailwind |
|
|
83
84
|
| Controlled components | `value` + `onChange` callback pair | `<=>` two-way binding |
|
|
84
85
|
| Shared state | React Context + Provider wrappers | `offer` / `accept` keywords |
|
|
85
86
|
| Reactivity | `useState` + `useEffect` + dependency arrays | `:=` / `~=` / `~>` — language-level |
|
|
@@ -105,11 +106,7 @@ development, save and see — SSE-based hot reload.
|
|
|
105
106
|
**Source as distribution.** Components are served as `.rip` source files.
|
|
106
107
|
Read them, understand them, modify them.
|
|
107
108
|
|
|
108
|
-
###
|
|
109
|
-
|
|
110
|
-
Radix and Base UI implement proven WAI-ARIA patterns, but they require
|
|
111
|
-
React. Rip reimplements the same behavioral patterns using its own
|
|
112
|
-
primitives:
|
|
109
|
+
### Component Primitives
|
|
113
110
|
|
|
114
111
|
| Capability | React | Rip |
|
|
115
112
|
|-----------|-------|-----|
|
|
@@ -119,42 +116,86 @@ primitives:
|
|
|
119
116
|
| Two-way binding | `value` + `onChange` pair | `<=>` operator |
|
|
120
117
|
| Reactivity | Hooks + dependency arrays | `:=` / `~=` / `~>` |
|
|
121
118
|
|
|
122
|
-
This lets Rip use the **right pattern for each widget**: single-component
|
|
123
|
-
for data-driven widgets (Select, Combobox, Menu), compositional via
|
|
124
|
-
`offer`/`accept` when children contain complex content the parent shouldn't
|
|
125
|
-
own.
|
|
126
|
-
|
|
127
119
|
---
|
|
128
120
|
|
|
129
|
-
## Styling
|
|
121
|
+
## Styling with Tailwind
|
|
122
|
+
|
|
123
|
+
Widgets are headless — they ship no CSS. Each widget exposes semantic state
|
|
124
|
+
through `$` attributes that compile to `data-*` in HTML. Style them with
|
|
125
|
+
Tailwind's data attribute variants.
|
|
126
|
+
|
|
127
|
+
### Setup
|
|
130
128
|
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
```html
|
|
130
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### The `data-*` Contract
|
|
134
|
+
|
|
135
|
+
Widgets set `data-*` attributes to reflect their state. Tailwind targets
|
|
136
|
+
these with `data-[attr]:` variants:
|
|
133
137
|
|
|
134
138
|
```coffee
|
|
135
|
-
# Widget
|
|
139
|
+
# Widget source — behavior only, zero styling
|
|
136
140
|
button $open: open?!, $disabled: @disabled?!
|
|
141
|
+
div $highlighted: (idx is highlightedIndex)?!
|
|
142
|
+
div $selected: (@value is current)?!
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```html
|
|
146
|
+
<!-- Your markup — Tailwind classes -->
|
|
147
|
+
<button class="border border-gray-300 rounded-lg px-4 py-2
|
|
148
|
+
data-[open]:border-blue-500 data-[open]:ring-2 data-[open]:ring-blue-200
|
|
149
|
+
data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed">
|
|
137
150
|
```
|
|
138
151
|
|
|
139
|
-
|
|
152
|
+
### Common Patterns
|
|
153
|
+
|
|
154
|
+
**Button:**
|
|
140
155
|
|
|
141
156
|
```html
|
|
142
|
-
<button class="
|
|
157
|
+
<button class="inline-flex items-center gap-2 px-4 py-2 rounded-lg
|
|
158
|
+
bg-blue-600 text-white font-medium
|
|
159
|
+
hover:bg-blue-700 active:scale-[0.98] transition
|
|
160
|
+
data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed">
|
|
143
161
|
```
|
|
144
162
|
|
|
145
|
-
|
|
163
|
+
**Select trigger:**
|
|
146
164
|
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
|
|
165
|
+
```html
|
|
166
|
+
<button class="inline-flex items-center justify-between w-full px-3 py-2
|
|
167
|
+
border border-gray-300 rounded-lg bg-white
|
|
168
|
+
data-[open]:border-blue-500 data-[open]:ring-2 data-[open]:ring-blue-200">
|
|
150
169
|
```
|
|
151
170
|
|
|
152
|
-
|
|
171
|
+
**Select option:**
|
|
153
172
|
|
|
154
173
|
```html
|
|
155
|
-
<
|
|
174
|
+
<div class="px-3 py-2 rounded cursor-pointer
|
|
175
|
+
data-[highlighted]:bg-gray-100
|
|
176
|
+
data-[selected]:font-semibold data-[selected]:text-blue-600">
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Dialog overlay:**
|
|
180
|
+
|
|
181
|
+
```html
|
|
182
|
+
<div class="fixed inset-0 bg-black/50 flex items-center justify-center">
|
|
183
|
+
<div class="bg-white rounded-xl shadow-xl p-6 max-w-md w-full">
|
|
156
184
|
```
|
|
157
185
|
|
|
186
|
+
### Dark Mode
|
|
187
|
+
|
|
188
|
+
Use Tailwind's `dark:` variant with a class-based toggle:
|
|
189
|
+
|
|
190
|
+
```html
|
|
191
|
+
<html class="dark">
|
|
192
|
+
<!-- dark:bg-gray-900 dark:text-gray-100 etc. -->
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Or define semantic color tokens in your Tailwind config and reference them
|
|
196
|
+
throughout — `bg-surface`, `text-primary`, `border-muted` — so dark mode
|
|
197
|
+
is a single token swap, not per-element `dark:` classes.
|
|
198
|
+
|
|
158
199
|
---
|
|
159
200
|
|
|
160
201
|
## Code Density
|
package/index.rip
CHANGED
|
@@ -5,7 +5,7 @@ import { serve } from '@rip-lang/server/middleware'
|
|
|
5
5
|
|
|
6
6
|
dir = import.meta.dir
|
|
7
7
|
|
|
8
|
-
use serve dir: dir,
|
|
8
|
+
use serve dir: dir, bundle: ['.'], watch: true
|
|
9
9
|
|
|
10
10
|
get '/*.rip', -> @send "#{dir}/#{@req.path.slice(1)}"
|
|
11
11
|
get '/*.css', -> @send "#{dir}/#{@req.path.slice(1)}", 'text/css; charset=UTF-8'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rip-lang/ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.31",
|
|
4
4
|
"description": "Headless, accessible UI components written in Rip — zero CSS, zero dependencies",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"author": "Steve Shreeve <steve.shreeve@gmail.com>",
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"rip-lang": ">=3.13.
|
|
34
|
+
"rip-lang": ">=3.13.86"
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
37
|
"*.rip",
|