@skutally/ui-library 0.1.0

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 ADDED
@@ -0,0 +1,514 @@
1
+ # UI Library
2
+
3
+ A ui-style component library for HTML, Tailwind CSS v4, and Stimulus.js. Copy and paste beautifully designed, accessible components into your projects. No npm dependency — the code is yours.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ - [Overview](#overview)
10
+ - [Tech Stack](#tech-stack)
11
+ - [Project Structure](#project-structure)
12
+ - [Getting Started](#getting-started)
13
+ - [Prerequisites](#prerequisites)
14
+ - [Installation](#installation)
15
+ - [Development](#development)
16
+ - [CLI Tool](#cli-tool)
17
+ - [Theming](#theming)
18
+ - [CSS Variables](#css-variables)
19
+ - [Dark Mode](#dark-mode)
20
+ - [Adding Custom Colors](#adding-custom-colors)
21
+ - [Components](#components)
22
+ - [Component List](#component-list)
23
+ - [Component Usage Pattern](#component-usage-pattern)
24
+ - [Component API Reference](#component-api-reference)
25
+ - [Framework Integration](#framework-integration)
26
+ - [Rails (Hotwire)](#rails-hotwire)
27
+ - [Accessibility](#accessibility)
28
+ - [Contributing](#contributing)
29
+
30
+ ---
31
+
32
+ ## Overview
33
+
34
+ This is NOT a traditional component library you install as a dependency. It's a collection of 23 re-usable components that you copy and paste into your apps and customize to your needs.
35
+
36
+ Why copy/paste instead of npm install?
37
+ - Full ownership and control over the code
38
+ - No version conflicts or breaking updates
39
+ - Customize everything — styles, behavior, markup
40
+ - Zero runtime dependency on this library
41
+
42
+ ---
43
+
44
+ ## Tech Stack
45
+
46
+ | Technology | Version | Purpose |
47
+ |---|---|---|
48
+ | Tailwind CSS | v4.2+ | Utility-first styling with `@theme` directive |
49
+ | Stimulus.js | Latest | Lightweight JavaScript behavior via controllers |
50
+ | HTML | 5 | Semantic markup with ARIA attributes |
51
+ | Node.js | 18+ | CLI tool and build scripts |
52
+
53
+ Fonts (from Google Fonts):
54
+ - Inter (400, 500, 600, 700) — UI text
55
+ - JetBrains Mono (400, 500) — Code blocks
56
+
57
+ ---
58
+
59
+ ## Project Structure
60
+
61
+ ui-library/
62
+ ├── bin/
63
+ │ └── cli.js # CLI tool for component management
64
+ ├── src/
65
+ │ ├── base.css # Tailwind v4 theme config + CSS variables
66
+ │ ├── controllers.js # Demo page controller aggregator
67
+ │ └── controllers/ # Stimulus.js controllers (19 files)
68
+ │ ├── accordion.js
69
+ │ ├── alert.js
70
+ │ ├── badge.js
71
+ │ ├── button.js
72
+ │ ├── card.js
73
+ │ ├── checkbox.js
74
+ │ ├── dropdown.js
75
+ │ ├── input.js
76
+ │ ├── modal.js
77
+ │ ├── popover.js
78
+ │ ├── progress.js
79
+ │ ├── radio.js
80
+ │ ├── sheet.js
81
+ │ ├── slider.js
82
+ │ ├── table.js
83
+ │ ├── tabs.js
84
+ │ ├── toast.js
85
+ │ ├── toggle.js
86
+ │ └── tooltip.js
87
+ ├── components/ # Component HTML templates (23 files)
88
+ │ ├── accordion.html
89
+ │ ├── alert.html
90
+ │ ├── avatar.html
91
+ │ ├── badge.html
92
+ │ ├── breadcrumb.html
93
+ │ ├── button.html
94
+ │ ├── card.html
95
+ │ ├── checkbox.html
96
+ │ ├── dropdown.html
97
+ │ ├── input.html
98
+ │ ├── modal.html
99
+ │ ├── popover.html
100
+ │ ├── progress.html
101
+ │ ├── radio.html
102
+ │ ├── separator.html
103
+ │ ├── sheet.html
104
+ │ ├── skeleton.html
105
+ │ ├── slider.html
106
+ │ ├── table.html
107
+ │ ├── tabs.html
108
+ │ ├── toast.html
109
+ │ ├── toggle.html
110
+ │ └── tooltip.html
111
+ ├── registry/
112
+ │ └── registry.json # Component metadata & dependency graph
113
+ ├── templates/
114
+ │ └── components.json # Project init template
115
+ ├── dist/
116
+ │ └── output.css # Compiled Tailwind CSS output
117
+ ├── index.html # Component showcase / demo page
118
+ ├── docs.html # Documentation page
119
+ ├── blocks.html # Pre-built page blocks & templates
120
+ └── package.json
121
+
122
+
123
+ ## Getting Started
124
+
125
+ ### Prerequisites
126
+
127
+ - Node.js 18 or higher
128
+ - npm (comes with Node.js)
129
+
130
+ ### Installation
131
+
132
+ Step 1: Create your project
133
+
134
+ mkdir my-project && cd my-project
135
+ npm init -y
136
+
137
+ Step 2: Install Tailwind CSS v4
138
+
139
+ npm install tailwindcss @tailwindcss/cli
140
+
141
+
142
+ Step 3: Add Stimulus.js
143
+
144
+ <!-- Option A: CDN (simplest) -->
145
+ <script src="https://cdn.jsdelivr.net/npm/@hotwired/stimulus/dist/stimulus.umd.js"></script>
146
+
147
+ # Option B: npm
148
+ npm install @hotwired/stimulus
149
+
150
+
151
+ Step 4: Initialize UI Library
152
+
153
+ npx ui-library init
154
+
155
+
156
+ This creates:
157
+ - `components.json` — project configuration
158
+ - `src/base.css` — Tailwind v4 theme with CSS variables
159
+
160
+ Step 5: Add components
161
+
162
+
163
+ npx ui-library add button
164
+ npx ui-library add modal tabs accordion
165
+
166
+
167
+ Step 6: Build CSS and start developing
168
+
169
+ # Watch mode (development)
170
+ npx @tailwindcss/cli -i src/base.css -o dist/output.css --watch
171
+
172
+ # Production build (minified)
173
+ npx @tailwindcss/cli -i src/base.css -o dist/output.css --minify
174
+
175
+
176
+ Step 7: Link CSS and Stimulus in your HTML
177
+
178
+
179
+ ### Development
180
+
181
+ If you cloned this repository directly:
182
+
183
+ # Install dependencies
184
+ npm install
185
+
186
+ # Watch CSS changes during development
187
+ npm run dev
188
+
189
+ # Build for production
190
+ npm run build
191
+
192
+ # Start local server
193
+ npm run serve
194
+
195
+ # Build + serve
196
+
197
+
198
+ ## CLI Tool
199
+
200
+ The CLI (`bin/cli.js`) provides four commands:
201
+
202
+ `ui-library init`
203
+
204
+ Initializes a project with `components.json` and `src/base.css`.
205
+
206
+ npx ui-library init\
207
+
208
+ ### `ui-library add <name> [name...]`
209
+
210
+ Installs components with automatic dependency resolution.
211
+
212
+ npx ui-library add button
213
+ npx ui-library add modal tabs accordion
214
+ npx ui-library add slider checkbox radio
215
+
216
+
217
+ - Copies controller JS to `src/controllers/`
218
+ - Copies HTML template to `components/ui/`
219
+ - Auto-resolves dependencies (e.g., `modal` automatically adds `button`)
220
+ - Prints registration hints after install
221
+
222
+ ### `ui-library list`
223
+
224
+ Lists all 23 available components with descriptions.
225
+
226
+ npx ui-library list
227
+
228
+
229
+ ### `ui-library diff <name>`
230
+
231
+ Checks if your local controller differs from the registry version.
232
+
233
+ npx ui-library diff button
234
+
235
+ ### `components.json` Configuration
236
+
237
+ ```json
238
+ {
239
+ "$schema": "https://ui-library.dev/schema.json",
240
+ "style": "default",
241
+ "tailwind": {
242
+ "version": 4,
243
+ "css": "src/base.css",
244
+ "cssVariables": true
245
+ },
246
+ "aliases": {
247
+ "controllers": "src/controllers",
248
+ "components": "components/ui"
249
+ }
250
+ }
251
+
252
+ | Option | Description |
253
+ |---|---|
254
+ | `style` | Style preset for components. Default: `"default"` |
255
+ | `tailwind.version` | Tailwind CSS version. Currently supports v4 |
256
+ | `tailwind.css` | Path to CSS file with Tailwind v4 theme |
257
+ | `tailwind.cssVariables` | Use CSS variables for theming. Default: `true` |
258
+ | `aliases.controllers` | Directory for Stimulus controllers |
259
+ | `aliases.components` | Directory for component HTML templates |
260
+
261
+ ---
262
+
263
+ ## Theming
264
+
265
+ ### CSS Variables
266
+
267
+ All theming is done via CSS variables in `src/base.css` using Tailwind v4's `@theme` directive. No `tailwind.config.js` needed.
268
+
269
+ Color convention: Each semantic color has a `background` and `foreground` pair:
270
+
271
+ ```css
272
+ :root {
273
+ --background: 0 0% 100%; /* Page background */
274
+ --foreground: 240 10% 3.9%; /* Page text */
275
+
276
+ --card: 0 0% 100%; /* Card background */
277
+ --card-foreground: 240 10% 3.9%;
278
+
279
+ --primary: 240 5.9% 10%; /* Primary actions */
280
+ --primary-foreground: 0 0% 98%;
281
+
282
+ --muted: 240 4.8% 95.9%; /* Muted/subtle elements */
283
+ --muted-foreground: 240 3.8% 46.1%;
284
+
285
+ --accent: 240 4.8% 95.9%; /* Accent/hover states */
286
+ --accent-foreground: 240 5.9% 10%;
287
+
288
+ --destructive: 0 84.2% 60.2%; /* Destructive actions */
289
+ --destructive-foreground: 0 0% 98%;
290
+
291
+ --border: 240 5.9% 90%; /* Border color */
292
+ --input: 240 5.9% 90%; /* Input border */
293
+ --ring: 240 5.9% 10%; /* Focus ring */
294
+ --radius: 0.5rem; /* Border radius */
295
+ }
296
+ ```
297
+
298
+ These are mapped to Tailwind classes via `@theme`:
299
+
300
+ ```css
301
+ @theme {
302
+ --font-sans: "Inter", "system-ui", "-apple-system", "sans-serif";
303
+ --font-mono: "JetBrains Mono", "Fira Code", "monospace";
304
+
305
+ --color-background: hsl(var(--background));
306
+ --color-foreground: hsl(var(--foreground));
307
+ --color-primary: hsl(var(--primary));
308
+ --color-primary-foreground: hsl(var(--primary-foreground));
309
+ /* ... etc */
310
+
311
+ --radius-lg: var(--radius);
312
+ --radius-md: calc(var(--radius) - 2px);
313
+ --radius-sm: calc(var(--radius) - 4px);
314
+ }
315
+ ```
316
+
317
+ ### Dark Mode
318
+
319
+ Dark mode uses the `.dark` class on `<html>`. All CSS variables automatically switch:
320
+
321
+ ```css
322
+ .dark {
323
+ --background: 240 10% 3.9%;
324
+ --foreground: 0 0% 98%;
325
+ --primary: 0 0% 98%;
326
+ --primary-foreground: 240 5.9% 10%;
327
+ --muted: 240 3.7% 15.9%;
328
+ --muted-foreground: 240 5% 64.9%;
329
+ --accent: 240 3.7% 15.9%;
330
+ --accent-foreground: 0 0% 98%;
331
+ --destructive: 0 62.8% 30.6%;
332
+ --destructive-foreground: 0 0% 98%;
333
+ --border: 240 3.7% 15.9%;
334
+ --input: 240 3.7% 15.9%;
335
+ --ring: 240 4.9% 83.9%;
336
+ }
337
+ ```
338
+
339
+ Toggle implementation:
340
+
341
+ ```javascript
342
+ // Toggle dark mode
343
+ function toggleDarkMode() {
344
+ document.documentElement.classList.toggle('dark')
345
+ const isDark = document.documentElement.classList.contains('dark')
346
+ localStorage.setItem('theme', isDark ? 'dark' : 'light')
347
+ }
348
+
349
+ // Load saved preference on page load (place in <head> to prevent FOUC)
350
+ if (localStorage.getItem('theme') === 'dark' ||
351
+ (!localStorage.getItem('theme') &&
352
+ window.matchMedia('(prefers-color-scheme: dark)').matches)) {
353
+ document.documentElement.classList.add('dark')
354
+ }
355
+ ```
356
+
357
+ ### Adding Custom Colors
358
+
359
+ 1. Define the variable in `:root`:
360
+
361
+ :root {
362
+ --warning: 38 92% 50%;
363
+ --warning-foreground: 48 96% 89%;
364
+ }
365
+
366
+ 2. Add to the `@theme` block:
367
+
368
+ @theme {
369
+ --color-warning: hsl(var(--warning));
370
+ --color-warning-foreground: hsl(var(--warning-foreground));
371
+ }
372
+
373
+ 3. Use in HTML:
374
+
375
+ <div class="bg-warning text-warning-foreground">Warning message</div>
376
+
377
+
378
+ ## Components
379
+
380
+ ### Component List
381
+
382
+ | Component | Has JS Controller | Dependencies | Description |
383
+ |---|---|---|---|
384
+ | Accordion | Yes | — | Vertically stacked interactive headings that reveal content |
385
+ | Alert | Yes | — | Callout for important messages (info, success, warning, danger) |
386
+ | Avatar | No | — | Image element with fallback for user profiles |
387
+ | Badge | Yes | — | Small status descriptor with variant styles |
388
+ | Breadcrumb | No | — | Path hierarchy navigation |
389
+ | Button | Yes | — | Clickable button with 8 variants and 6 sizes |
390
+ | Card | Yes | — | Container with border and shadow |
391
+ | Checkbox | Yes | — | Toggle between checked/unchecked states |
392
+ | Dropdown | Yes | — | Menu triggered by a button click |
393
+ | Input | Yes | — | Text input with variants and icon support |
394
+ | Modal | Yes | button | Dialog overlay requiring user interaction |
395
+ | Popover | Yes | — | Floating panel anchored to trigger element |
396
+ | Progress | Yes | — | Horizontal completion progress bar |
397
+ | Radio | Yes | — | Mutually exclusive option group |
398
+ | Separator | No | — | Visual divider between content sections |
399
+ | Sheet | Yes | button | Panel that slides from screen edge |
400
+ | Skeleton | No | — | Placeholder animation while loading |
401
+ | Slider | Yes | — | Draggable input for selecting numeric value |
402
+ | Table | Yes | — | Data table with sortable column headers |
403
+ | Tabs | Yes | — | Layered sections displaying one panel at a time |
404
+ | Toast | Yes | — | Temporary notification with auto-dismiss |
405
+ | Toggle | Yes | — | Switch control (on/off) |
406
+ | Tooltip | Yes | — | Popup showing info on hover |
407
+
408
+ ### Component Usage Pattern
409
+
410
+ All components follow the same Stimulus.js conventions:
411
+
412
+ 1. Attach a controller:
413
+
414
+
415
+ <button data-controller="button">Click me</button>
416
+
417
+
418
+ 2. Configure with values:
419
+
420
+
421
+ <button data-controller="button"
422
+ data-button-variant-value="destructive"
423
+ data-button-size-value="lg">
424
+ Delete
425
+ </button>
426
+
427
+
428
+ 3. Bind actions:
429
+
430
+ <div data-controller="modal">
431
+ <button data-action="click->modal#open">Open Modal</button>
432
+ <div data-modal-target="overlay" class="hidden">
433
+ <!-- modal content -->
434
+ </div>
435
+ </div>
436
+
437
+ 4. Register controllers in your app:
438
+
439
+ ```javascript
440
+ import { Application } from "@hotwired/stimulus"
441
+ import ButtonController from "./src/controllers/button.js"
442
+ import ModalController from "./src/controllers/modal.js"
443
+
444
+ const app = Application.start()
445
+ app.register("button", ButtonController)
446
+ app.register("modal", ModalController)
447
+
448
+
449
+ ## Accessibility
450
+
451
+ Built-in accessibility features across all components:
452
+
453
+ - ARIA roles: `role="button"`, `role="dialog"`, `role="tabpanel"`, `role="switch"`, `role="progressbar"`
454
+ - ARIA attributes: `aria-checked`, `aria-valuenow`, `aria-valuemin`, `aria-valuemax`
455
+ - Keyboard navigation: Escape to close modals, dropdowns, sheets, and popovers
456
+ - Focus management: Auto-focus on first input in modals, visible focus rings (`focus-visible:ring-2`)
457
+ - Semantic HTML: Proper use of `<button>`, `<input>`, `<label>`, `<nav>`, `<table>`
458
+ - Disabled states: `disabled:opacity-50 disabled:pointer-events-none`
459
+
460
+ ---
461
+
462
+ ## Key Styling Patterns
463
+
464
+ | Pattern | Implementation |
465
+ |---|---|
466
+ | Utility-first | All Tailwind classes, no custom CSS |
467
+ | CSS Variables | Semantic colors via custom properties |
468
+ | Dark Mode | `.dark` class toggle on `<html>` |
469
+ | Transitions | `duration-200`, `transition-all`, `transition-opacity` |
470
+ | Focus States | `focus-visible:ring-2 focus-visible:ring-ring` |
471
+ | Disabled States | `disabled:opacity-50 disabled:pointer-events-none` |
472
+ | Responsive | Mobile-first with `sm:`, `md:`, `lg:` breakpoints |
473
+
474
+ ---
475
+
476
+ ## Data Attributes Quick Reference
477
+
478
+ ```html
479
+ <!-- Controller binding -->
480
+ <div data-controller="component-name">
481
+
482
+ <!-- Action binding -->
483
+ <button data-action="click->controller#method">
484
+
485
+ <!-- Target binding -->
486
+ <div data-controller-target="targetName">
487
+
488
+ <!-- Value binding -->
489
+ <div data-controller-name-value="value">
490
+
491
+ <!-- Action params -->
492
+ <button data-action="click->toast#show"
493
+ data-toast-type-param="success"
494
+ data-toast-title-param="Saved!">
495
+ ```
496
+
497
+ ---
498
+
499
+ ## Contributing
500
+
501
+ 1. Clone the repository
502
+ 2. Run `npm install`
503
+ 3. Run `npm run dev` to watch CSS changes
504
+ 4. Open `index.html` in your browser (or run `npm run serve`)
505
+ 5. Edit components in `components/` and controllers in `src/controllers/`
506
+ 6. Update `registry/registry.json` if adding new components
507
+
508
+ ---
509
+
510
+ ## License
511
+
512
+ MIT — Free to use for personal and commercial projects. No attribution required.
513
+
514
+ Built with Stimulus.js + Tailwind CSS. Inspired by [shadcn/ui](https://ui.shadcn.com).