odt-ui-rails 2.2.0 → 2.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c416abbfe135945909d7c97c21418c19144c604fb323ca5ca662b0b260a5815
4
- data.tar.gz: ac191c2750c483638f6c33b93f7cf81b1593ddab6fe8cd1e4abcc8e7e20cf021
3
+ metadata.gz: c6a3351e3c566a02e0cc281f7c75d8ff5aee3b9c790b49a360907aeb5118ef67
4
+ data.tar.gz: c46e7e26fb322d840b5a569589d3c4d1d6ff4fa67e1215850aaff860d8ca82e0
5
5
  SHA512:
6
- metadata.gz: be8a662988ae007208ba5b64f3630ff758320f81945243aa9566e785c468c1b908fa1b6e2a19d48c36c15746f8a4f4b860bcbb568dc3e45024d8b4b370c1066d
7
- data.tar.gz: 5b5a450963c984812f4e9b90d73d65117318495e52422c9e7bad624f6f5e24f708cb22b3aa878c5c3780c26660905256615e94eaf350d72dd8d44b08d692d298
6
+ metadata.gz: 91490c4a98b07b40e122526c78b79baed1559f84a75edf07438a0cf1febe3b11026089a68ac76de7a86e15f1d1c9f79a5dc0bf7e69f53c79eee07867c669714d
7
+ data.tar.gz: 41c74c909825e0431a27e69775ec9d7e3c61576ee2e03f0c2fbf1d27219a9a139c2f662ea17a5b75a042702aad30bf65b807aff36bf2c5d0e7115633bdbd4e3a
data/README.md CHANGED
@@ -1,36 +1,91 @@
1
- # ODT-UI for Ruby on Rails (`odt-ui-rails`)
1
+ <div align="center">
2
2
 
3
- Standalone CSS First & Native Ruby on Rails integration for **ODT-Lightweight-UI**. Zero build tools required by host application, with seamless Tailwind CSS v4 support and complete ActionView helpers.
3
+ # ODT UI for Ruby on Rails (`odt-ui-rails`)
4
+
5
+ **Standalone CSS-first design tokens, Hotwire-ready UI components, and ActionView helpers for Ruby on Rails.**
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/odt-ui-rails.svg)](https://badge.fury.io/rb/odt-ui-rails)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
9
+ [![Ruby](https://img.shields.io/badge/Ruby-%3E%3D%203.0-ruby.svg)](https://www.ruby-lang.org)
10
+ [![Rails](https://img.shields.io/badge/Rails-%3E%3D%206.1-red.svg)](https://rubyonrails.org)
11
+ [![Hotwire Ready](https://img.shields.io/badge/Hotwire-Turbo%20%26%20Stimulus-orange.svg)](https://hotwired.dev)
12
+ [![Type Checked](https://img.shields.io/badge/RBS-Type%20Signatures-green.svg)](sig/odt_ui.rbs)
13
+
14
+ </div>
4
15
 
5
16
  ---
6
17
 
7
- ## Features
18
+ ## Overview
8
19
 
9
- - 🎨 **100% Standalone CSS First:** Zero build steps required. Ships pre-compiled `.odt-*` classes and design tokens.
10
- - ⚡ **Tailwind CSS v4 Seamless Interop:** Host apps can use custom Tailwind utility classes via `class: "..."` and include `@theme` color presets.
11
- - 🧩 **Complete Component Set:** Buttons, Badges, Cards, Alerts, Headings, Text, Avatars, Inputs, Textareas, Selects, Checkboxes, Radios, and Form Groups.
12
- - 💎 **Ruby LSP & Solargraph Types:** Full RBS type signatures included.
20
+ `odt-ui-rails` brings the **ODT Design System** directly into Ruby on Rails. It is architected from the ground up to provide a **Standalone CSS First** experience:
21
+
22
+ - 📦 **Zero Host Build Tools Required:** Ships pre-compiled CSS custom properties and `.odt-*` component styles. Works out-of-the-box with Propshaft, Sprockets, or no asset pipeline at all.
23
+ - ⚡ **Seamless Tailwind CSS v4 Interoperability:** Includes a complete `@theme` token configuration for Tailwind v4 projects, allowing custom utility classes (`class: "..."`) to merge effortlessly onto components.
24
+ - 🚀 **Hotwire & Turbo Native:** First-class helpers for Turbo Streams (`odt_toast_stream`), Flash message auto-toasts (`odt_flash_toasts`), and Stimulus-powered Modals (`odt_modal`).
25
+ - 💎 **Strict Type Signatures:** Full RBS definitions included for Ruby LSP, Steep, and Solargraph IDE autocompletion.
26
+
27
+ ---
28
+
29
+ ## Table of Contents
30
+
31
+ - [Installation](#installation)
32
+ - [Asset Pipeline Configuration](#asset-pipeline-configuration)
33
+ - [Component Reference](#component-reference)
34
+ - [Feedback & Overlays](#feedback--overlays)
35
+ - [Toasts & Toaster](#toasts--toaster)
36
+ - [Modals](#modals)
37
+ - [Alerts](#alerts)
38
+ - [Actions & Indicators](#actions--indicators)
39
+ - [Buttons](#buttons)
40
+ - [Badges](#badges)
41
+ - [Form Controls](#form-controls)
42
+ - [Input Field](#input-field)
43
+ - [Textarea](#textarea)
44
+ - [Select Dropdown](#select-dropdown)
45
+ - [Checkbox & Radio](#checkbox--radio)
46
+ - [Form Group](#form-group)
47
+ - [Layout & Typography](#layout--typography)
48
+ - [Cards](#cards)
49
+ - [Typography (Heading & Text)](#typography-heading--text)
50
+ - [Avatars](#avatars)
51
+ - [Theming & Dark Mode](#theming--dark-mode)
52
+ - [License](#license)
13
53
 
14
54
  ---
15
55
 
16
56
  ## Installation
17
57
 
18
- Add to your `Gemfile`:
58
+ Add the gem to your application's `Gemfile`:
19
59
 
20
60
  ```ruby
21
- gem "odt-ui-rails", "~> 2.1.0"
61
+ gem "odt-ui-rails", "~> 2.2.0"
22
62
  ```
23
63
 
24
- Run bundle and install generator:
64
+ Install dependencies:
25
65
 
26
66
  ```bash
27
67
  bundle install
68
+ ```
69
+
70
+ Run the automated install generator:
71
+
72
+ ```bash
28
73
  bin/rails g odt:install
29
74
  ```
30
75
 
31
- ### Manual Stylesheet Setup
76
+ The generator will:
32
77
 
33
- **For Tailwind CSS v4 (`app/assets/tailwind/application.css` or `application.tailwind.css`):**
78
+ 1. Detect your asset pipeline (Tailwind CSS v4, Propshaft, or Sprockets) and safely configure the required `@import` statements.
79
+ 2. Copy `sig/odt_ui.rbs` for Ruby LSP IDE autocompletion.
80
+ 3. Copy Stimulus controllers (`odt_toast_controller.js`, `odt_modal_controller.js`) to `app/javascript/controllers/` if Stimulus is present.
81
+
82
+ ---
83
+
84
+ ## Asset Pipeline Configuration
85
+
86
+ If configuring stylesheets manually, use the configuration below:
87
+
88
+ ### Option A: Tailwind CSS v4 (`app/assets/tailwind/application.css`)
34
89
 
35
90
  ```css
36
91
  @import "tailwindcss";
@@ -39,7 +94,7 @@ bin/rails g odt:install
39
94
  @import "odt_ui/theme.css";
40
95
  ```
41
96
 
42
- **For Standard Rails / Propshaft / Sprockets (`app/assets/stylesheets/application.css`):**
97
+ ### Option B: Propshaft / Sprockets / Standard Rails (`app/assets/stylesheets/application.css`)
43
98
 
44
99
  ```css
45
100
  @import "odt_ui/tokens.css";
@@ -48,68 +103,277 @@ bin/rails g odt:install
48
103
 
49
104
  ---
50
105
 
51
- ## Usage Examples
106
+ ## Component Reference
52
107
 
53
- ### Buttons
108
+ All helpers are globally available in all ERB templates, layouts, and helpers.
109
+
110
+ ---
111
+
112
+ ### Feedback & Overlays
113
+
114
+ #### Toasts & Toaster
115
+
116
+ Provides viewport stacking containers, automated Flash message toasts on redirects, and Turbo Stream responses for async form actions.
54
117
 
55
118
  ```erb
56
- <%= odt_button "Submit", variant: :filled, color: :primary, radius: :full %>
57
- <%= odt_button "Glass Action", variant: :frosted, color: :primary %>
58
- <%= odt_button "New Event", href: new_event_path, icon: "fa-solid fa-plus" %>
59
- <%= odt_button "Saving...", loading: true %>
60
- <%# With custom Tailwind classes %>
61
- <%= odt_button "Full Width", class: "mt-4 w-full shadow-lg" %>
119
+ <%# In app/views/layouts/application.html.erb %>
120
+ <body class="bg-surface text-fg font-sans antialiased">
121
+ <%= odt_toaster position: :top_right do %>
122
+ <%= odt_flash_toasts %>
123
+ <% end %>
124
+
125
+ <%= yield %>
126
+ </body>
62
127
  ```
63
128
 
64
- ### Badges
129
+ **Controller Turbo Stream Action:**
130
+
131
+ ```ruby
132
+ def create
133
+ @todo = Todo.new(todo_params)
134
+ if @todo.save
135
+ respond_to do |format|
136
+ format.turbo_stream do
137
+ render turbo_stream: [
138
+ turbo_stream.prepend("todos", @todo),
139
+ odt_toast_stream("Todo created successfully!", variant: :success)
140
+ ]
141
+ end
142
+ format.html { redirect_to todos_path, notice: "Todo created successfully!" }
143
+ end
144
+ end
145
+ end
146
+ ```
147
+
148
+ **Individual Toast Helper:**
65
149
 
66
150
  ```erb
67
- <%= odt_badge "Active", variant: :subtle, color: :success, dot: true %>
68
- <%= odt_badge "Critical", variant: :filled, color: :danger %>
69
- <%= odt_badge "Date", icon: "fa-regular fa-calendar" %>
151
+ <%= odt_toast "Settings updated", title: "Saved", variant: :success, duration: 4000 %>
152
+ <%= odt_toast "Failed to sync records", variant: :danger %>
70
153
  ```
71
154
 
72
- ### Cards
155
+ | Parameter | Type | Default | Description |
156
+ | :------------ | :-------- | :--------- | :--------------------------------------------------------------------------- |
157
+ | `message` | `String` | `nil` | Toast description or body text |
158
+ | `title` | `String` | `nil` | Optional bold header title |
159
+ | `variant` | `Symbol` | `:success` | `:success`, `:warning`, `:danger`, `:error`, `:info`, `:loading`, `:frosted` |
160
+ | `duration` | `Integer` | `4000` | Auto-dismiss duration in ms (`0` to disable) |
161
+ | `dismissible` | `Boolean` | `true` | Renders close button (`×`) |
162
+
163
+ ---
164
+
165
+ #### Modals
166
+
167
+ Accessible dialog containers with backdrop overlay, ESC key handling, scroll locking, and smooth scale transitions.
73
168
 
74
169
  ```erb
75
- <%= odt_card title: "Analytics Overview", subtitle: "Last 30 days", variant: :elevated, hoverable: true do %>
76
- <p>Your content here</p>
170
+ <%# Trigger Button %>
171
+ <%= odt_button "New Task", color: :primary, data: { action: "click->odt-modal#open" } %>
172
+
173
+ <%# Standard Modal %>
174
+ <%= odt_modal id: "new_task_modal", title: "Create Task", subtitle: "Add a task to your board", size: :md do %>
175
+ <%= render "form", todo: Todo.new %>
77
176
  <% end %>
78
177
 
79
- <%= odt_card variant: :frosted, radius: :"3xl", padding: :xl do %>
80
- <p>Glassmorphic frosted card</p>
178
+ <%# Custom Composition Modal %>
179
+ <%= odt_modal id: "confirm_delete_modal", size: :sm do %>
180
+ <%= odt_modal_header title: "Delete Item?", subtitle: "This action cannot be undone." %>
181
+ <%= odt_modal_body do %>
182
+ <p class="text-sm text-fg-muted">Are you sure you want to permanently remove this record?</p>
183
+ <% end %>
184
+ <%= odt_modal_footer do %>
185
+ <%= odt_button "Cancel", variant: :ghost, data: { action: "click->odt-modal#close" } %>
186
+ <%= odt_button "Delete", color: :danger, data: { turbo_method: :delete } %>
187
+ <% end %>
81
188
  <% end %>
82
189
  ```
83
190
 
84
- ### Alerts
191
+ | Parameter | Type | Default | Description |
192
+ | :----------------------- | :-------- | :------- | :------------------------------------------- |
193
+ | `id` | `String` | `nil` | HTML identifier for Stimulus/Turbo targeting |
194
+ | `title` / `subtitle` | `String` | `nil` | Header titles |
195
+ | `size` | `Symbol` | `:md` | `:sm`, `:md`, `:lg`, `:xl`, `:full` |
196
+ | `radius` | `Symbol` | `:"2xl"` | `:none` to `:"4xl"`, `:full` |
197
+ | `dismissible` | `Boolean` | `true` | Renders close button |
198
+ | `open` | `Boolean` | `false` | Initial visible state |
199
+ | `prevent_backdrop_close` | `Boolean` | `false` | Disables closing on overlay click |
200
+
201
+ ---
202
+
203
+ #### Alerts
204
+
205
+ Inline banners for status notices, warning messages, and form callouts.
85
206
 
86
207
  ```erb
87
- <%= odt_alert "Changes saved successfully!", variant: :success %>
88
- <%= odt_alert "Please verify your email address.", variant: :warning %>
208
+ <%= odt_alert "Your subscription will renew on May 1st.", variant: :info %>
209
+ <%= odt_alert "Payment failed. Please update billing info.", variant: :danger, icon: "fa-solid fa-triangle-exclamation" %>
89
210
  ```
90
211
 
212
+ ---
213
+
214
+ ### Actions & Indicators
215
+
216
+ #### Buttons
217
+
218
+ Versatile action buttons supporting brand colors, frosted glass surfaces, loading states, and icon decorations.
219
+
220
+ ```erb
221
+ <%# Standard Brand Action %>
222
+ <%= odt_button "Save Changes", color: :primary, variant: :filled, radius: :full %>
223
+
224
+ <%# Secondary & Frosted Glass %>
225
+ <%= odt_button "Secondary", variant: :subtle, color: :secondary %>
226
+ <%= odt_button "Frosted Glass", variant: :frosted, color: :primary %>
227
+
228
+ <%# Link as Button %>
229
+ <%= odt_button "View Project", href: project_path(@project), variant: :subtle %>
230
+
231
+ <%# Loading & Icons %>
232
+ <%= odt_button "Add Task", icon: "fa-solid fa-plus", color: :primary %>
233
+ <%= odt_button "Saving...", loading: true %>
234
+ <%= odt_button icon: "fa-solid fa-trash", icon_only: true, color: :danger, variant: :ghost %>
235
+ ```
236
+
237
+ | Option | Type | Default | Description |
238
+ | :-------------------- | :-------- | :--------- | :----------------------------------------------------------------------------------------------------------------- |
239
+ | `variant` | `Symbol` | `:filled` | `:filled`, `:subtle`, `:ghost`, `:outline`, `:capsule`, `:frosted`, `:light` |
240
+ | `color` | `Symbol` | `:primary` | `:primary`, `:secondary`, `:surface`, `:muted`, `:inverse`, `:success`, `:warning`, `:danger`, `:info`, `:neutral` |
241
+ | `size` | `Symbol` | `:md` | `:xs`, `:sm`, `:md`, `:lg`, `:xl` |
242
+ | `radius` | `Symbol` | `:"2xl"` | `:none`, `:xs`, `:sm`, `:md`, `:lg`, `:xl`, `:"2xl"`, `:"3xl"`, `:"4xl"`, `:full` |
243
+ | `icon` / `right_icon` | `String` | `nil` | FontAwesome class or inline SVG string |
244
+ | `icon_only` | `Boolean` | `false` | Square icon button formatting |
245
+ | `loading` | `Boolean` | `false` | Replaces icon with spinning loader |
246
+ | `disabled` | `Boolean` | `false` | HTML disabled state |
247
+ | `full_width` | `Boolean` | `false` | Expands width to 100% |
248
+
249
+ ---
250
+
251
+ #### Badges
252
+
253
+ Compact status indicators with optional indicator dots and icons.
254
+
255
+ ```erb
256
+ <%= odt_badge "Active", variant: :subtle, color: :success, dot: true %>
257
+ <%= odt_badge "High Priority", variant: :filled, color: :danger, radius: :full %>
258
+ <%= odt_badge "Calendar", icon: "fa-regular fa-calendar", variant: :outlined %>
259
+ ```
260
+
261
+ ---
262
+
91
263
  ### Form Controls
92
264
 
265
+ Accessible form components complete with labels, helper text, error validations, icons, and input adornments.
266
+
93
267
  ```erb
94
- <%= odt_input label: "Email Address", type: "email", placeholder: "you@example.com", left_icon: "fa-solid fa-envelope" %>
268
+ <%= form_with model: @user, class: "space-y-4" do |f| %>
269
+ <%# Text Input with Left Icon %>
270
+ <%= odt_input(
271
+ label: "Email Address",
272
+ name: "user[email]",
273
+ value: @user.email,
274
+ type: "email",
275
+ placeholder: "you@example.com",
276
+ left_icon: "fa-solid fa-envelope",
277
+ error: @user.errors[:email].first,
278
+ required: true
279
+ ) %>
280
+
281
+ <%# Textarea %>
282
+ <%= odt_textarea(
283
+ label: "Bio",
284
+ name: "user[bio]",
285
+ value: @user.bio,
286
+ rows: 4,
287
+ helper: "Brief summary for your profile"
288
+ ) %>
289
+
290
+ <%# Select Dropdown %>
291
+ <%= odt_select(
292
+ label: "Country",
293
+ name: "user[country]",
294
+ options: [["Thailand", "TH"], ["United States", "US"], ["Japan", "JP"]],
295
+ selected: @user.country,
296
+ prompt: "Select country"
297
+ ) %>
298
+
299
+ <%# Checkbox %>
300
+ <%= odt_checkbox(
301
+ label: "Subscribe to newsletter",
302
+ description: "Receive product updates once a week",
303
+ name: "user[subscribed]",
304
+ checked: true,
305
+ color: :primary
306
+ ) %>
307
+
308
+ <%# Radio Group %>
309
+ <%= odt_radio label: "Monthly Billing", name: "plan", value: "monthly", checked: true %>
310
+ <%= odt_radio label: "Annual Billing (Save 20%)", name: "plan", value: "annual" %>
311
+
312
+ <%# Custom Slot Form Group %>
313
+ <%= odt_form_group label: "Custom Input", helper: "Unique value required" do %>
314
+ <input type="text" class="odt-input odt-input--outlined odt-input--md" name="custom" />
315
+ <% end %>
316
+ <% end %>
317
+ ```
318
+
319
+ ---
95
320
 
96
- <%= odt_textarea label: "Comments", rows: 4, placeholder: "Type your notes..." %>
321
+ ### Layout & Typography
97
322
 
98
- <%= odt_select label: "Country", options: [["Thailand", "TH"], ["United States", "US"]], prompt: "Select country" %>
323
+ #### Cards
99
324
 
100
- <%= odt_checkbox label: "I agree to terms", description: "Read our privacy policy", color: :primary %>
325
+ Versatile containers supporting header metadata, multiple surface styles, and hover transitions.
101
326
 
102
- <%= odt_radio label: "Option A", name: "choice", value: "a", color: :primary %>
327
+ ```erb
328
+ <%= odt_card title: "Analytics Overview", subtitle: "Monthly performance", variant: :elevated, radius: :"3xl" do %>
329
+ <p class="text-sm text-fg">Dashboard charts and statistics...</p>
330
+ <% end %>
103
331
 
104
- <%= odt_form_group label: "Custom Field", required: true, helper: "Must be unique" do %>
105
- <input type="text" class="odt-input odt-input--outlined odt-input--md" name="custom" />
332
+ <%= odt_card variant: :frosted, radius: :"2xl", hoverable: true do %>
333
+ <span>Interactive frosted glass card</span>
106
334
  <% end %>
107
335
  ```
108
336
 
109
- ### Typography & Avatars
337
+ #### Typography (`odt_heading` & `odt_text`)
338
+
339
+ Standardized typographic elements mapped to the design system scale.
110
340
 
111
341
  ```erb
112
- <%= odt_heading "Dashboard", as: :h1, size: :"4xl" %>
113
- <%= odt_text "Welcome back to your workspace.", color: :muted, size: :lg %>
114
- <%= odt_avatar name: "Korn Chatikavanij", size: :md, color: :secondary %>
342
+ <%= odt_heading "Task Dashboard", as: :h1, size: :"4xl", weight: :bold, color: :strong %>
343
+ <%= odt_heading "Section Title", as: :h3, size: :xl %>
344
+
345
+ <%= odt_text "Manage all project deliverables in one workspace.", size: :sm, color: :muted %>
346
+ <%= odt_text "A very long single-line description...", truncate: true %>
115
347
  ```
348
+
349
+ #### Avatars
350
+
351
+ Renders image avatars or automatically computes two-letter initials from full names.
352
+
353
+ ```erb
354
+ <%# Generates initials avatar "JD" %>
355
+ <%= odt_avatar name: "John Doe", size: :lg, color: :secondary %>
356
+
357
+ <%# Image avatar with fallback %>
358
+ <%= odt_avatar src: "https://avatar.vercel.sh/pixel", size: :md %>
359
+ ```
360
+
361
+ ---
362
+
363
+ ## Theming & Dark Mode
364
+
365
+ The design system is fully dark mode ready. Apply `data-theme="dark"` or the `.dark` class to `<html>` or any sub-container:
366
+
367
+ ```html
368
+ <html data-theme="dark" class="dark">
369
+ ...
370
+ </html>
371
+ ```
372
+
373
+ All design tokens (backgrounds, surfaces, borders, text, and shadows) adapt automatically without custom CSS.
374
+
375
+ ---
376
+
377
+ ## License
378
+
379
+ The gem is available as open source under the terms of the [MIT License](LICENSE).