stimulus_plumbers 0.4.3 → 0.4.5
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/app/assets/javascripts/stimulus-plumbers/{stimulus-plumbers-controllers.es.js → index.es.js} +2 -0
- data/app/assets/javascripts/stimulus-plumbers/index.es.js.map +1 -0
- data/app/assets/javascripts/stimulus-plumbers/{stimulus-plumbers-controllers.umd.js → index.umd.js} +2 -1
- data/app/assets/javascripts/stimulus-plumbers/index.umd.js.map +1 -0
- data/docs/architecture.md +33 -0
- data/docs/component/avatar.md +84 -0
- data/docs/component/button.md +135 -0
- data/docs/component/calendar.md +223 -0
- data/docs/component/card.md +92 -0
- data/docs/component/combobox.md +254 -0
- data/docs/component/dispatcher.md +76 -0
- data/docs/component/divider.md +47 -0
- data/docs/component/form.md +238 -0
- data/docs/component/icon.md +44 -0
- data/docs/component/link.md +90 -0
- data/docs/component/list.md +161 -0
- data/docs/component/modal.md +19 -0
- data/docs/component/plumber.md +183 -0
- data/docs/component/popover.md +138 -0
- data/docs/component/theme.md +188 -0
- data/docs/component/timeline.md +138 -0
- data/lib/stimulus_plumbers/version.rb +1 -1
- data/vendor/controllers.manifest.json +386 -0
- metadata +23 -3
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Button
|
|
2
|
+
|
|
3
|
+
Rails helpers for rendering themed, accessible buttons and links.
|
|
4
|
+
|
|
5
|
+
## Helpers
|
|
6
|
+
|
|
7
|
+
### `sp_button`
|
|
8
|
+
|
|
9
|
+
```erb
|
|
10
|
+
<%= sp_button "Save" %>
|
|
11
|
+
<%= sp_button(icon_leading: "check") { "Confirm" } %>
|
|
12
|
+
<%= sp_button "Delete", type: :default, variant: :destructive, size: :sm %>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
| Option | Default | Description |
|
|
16
|
+
| ---------------- | ---------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| `content` | `nil` | Button label — positional arg or block |
|
|
18
|
+
| `type` | `:default` | Visual style — `:default` \| `:outline` \| `:ghost` \| `:fab` \| `:fab_outline` \| `:dashed` \| `:card` |
|
|
19
|
+
| `variant` | `:primary` | Color source — `:primary` \| `:secondary` \| `:tertiary` \| `:success` \| `:destructive` \| `:warning` \| `:info` |
|
|
20
|
+
| `size` | `:md` | Size — `:xs` \| `:sm` \| `:md` \| `:lg` \| `:xl` (ignored when `type: :card`) |
|
|
21
|
+
| `icon_leading` | `nil` | Icon rendered **before** the label — icon name (string or symbol) or callable |
|
|
22
|
+
| `icon_trailing` | `nil` | Icon rendered **after** the label — icon name (string or symbol) or callable |
|
|
23
|
+
| `**html_options` | — | Forwarded to the `<button>` element |
|
|
24
|
+
|
|
25
|
+
**`type:` — visual style**
|
|
26
|
+
|
|
27
|
+
| Value | Appearance |
|
|
28
|
+
| -------------- | ------------------------------------------------------------------------------ |
|
|
29
|
+
| `:default` | Filled — solid background from `variant` color |
|
|
30
|
+
| `:outline` | Surface background, colored border and text; subtle tint on hover |
|
|
31
|
+
| `:ghost` | Transparent, no border; subtle tint on hover |
|
|
32
|
+
| `:fab` | Floating action button — `rounded-full`, elevated shadow, filled |
|
|
33
|
+
| `:fab_outline` | Floating action button — `rounded-full`, elevated shadow, fills solid on hover |
|
|
34
|
+
| `:dashed` | Dashed border, surface background |
|
|
35
|
+
| `:card` | Full-padding card — `flex-1`, `justify-start`; `size:` ignored |
|
|
36
|
+
|
|
37
|
+
**`variant:` — color source**
|
|
38
|
+
|
|
39
|
+
| Value | Color tokens used |
|
|
40
|
+
| -------------- | ------------------------------ |
|
|
41
|
+
| `:primary` | `--sp-color-primary-*` |
|
|
42
|
+
| `:secondary` | `--sp-color-secondary-*` |
|
|
43
|
+
| `:tertiary` | `--sp-color-muted-*` (neutral) |
|
|
44
|
+
| `:success` | `--sp-color-success-*` |
|
|
45
|
+
| `:destructive` | `--sp-color-destructive-*` |
|
|
46
|
+
| `:warning` | `--sp-color-warning-*` |
|
|
47
|
+
| `:info` | `--sp-color-info-*` |
|
|
48
|
+
|
|
49
|
+
**Icon values:**
|
|
50
|
+
|
|
51
|
+
- String or symbol — resolved by name through the active theme's icon registry, rendered via `sp_icon` with `button_icon` theme classes applied
|
|
52
|
+
- Callable (e.g. `-> { tag.span "★" }`) — rendered as-is, no theme applied
|
|
53
|
+
|
|
54
|
+
### `sp_button_group`
|
|
55
|
+
|
|
56
|
+
Wraps buttons in a themed container `<div>`.
|
|
57
|
+
|
|
58
|
+
```erb
|
|
59
|
+
<%= sp_button_group do %>
|
|
60
|
+
<%= sp_button "Cancel", type: :outline %>
|
|
61
|
+
<%= sp_button "Save" %>
|
|
62
|
+
<% end %>
|
|
63
|
+
|
|
64
|
+
<%= sp_button_group(layout: :stacked) do %>
|
|
65
|
+
...
|
|
66
|
+
<% end %>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Option | Default | Description |
|
|
70
|
+
| ---------------- | --------- | ------------------------------------------ |
|
|
71
|
+
| `layout` | `:inline` | Layout direction — `:inline` \| `:stacked` |
|
|
72
|
+
| `**html_options` | — | Forwarded to the wrapper `<div>` |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Rendered HTML Structure
|
|
77
|
+
|
|
78
|
+
### Button (action)
|
|
79
|
+
|
|
80
|
+
Text content is always wrapped in a `<span>`:
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<button type="button" class="[theme classes]"><span>Save</span></button>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### With icons
|
|
87
|
+
|
|
88
|
+
Icons are rendered **inside** the `<button>`, before or after the label `<span>`:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<button type="button" class="[theme classes]">
|
|
92
|
+
<svg aria-hidden="true" class="[button_icon theme classes]">
|
|
93
|
+
<!-- icon svg -->
|
|
94
|
+
</svg>
|
|
95
|
+
<span>Confirm</span>
|
|
96
|
+
</button>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<button type="button" class="[theme classes]">
|
|
101
|
+
<span>Next</span>
|
|
102
|
+
<svg aria-hidden="true" class="[button_icon theme classes]">
|
|
103
|
+
<!-- icon svg -->
|
|
104
|
+
</svg>
|
|
105
|
+
</button>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Icon only
|
|
109
|
+
|
|
110
|
+
When no text is provided, no `<span>` is rendered. The theme uses `:has(> span)` to detect this and applies `aspect-square` + `px-0`, making the button square (or a circle for `type: :fab` / `:fab_outline`):
|
|
111
|
+
|
|
112
|
+
```html
|
|
113
|
+
<button type="button" aria-label="Add" class="[theme classes]">
|
|
114
|
+
<svg aria-hidden="true" class="[button_icon theme classes]">
|
|
115
|
+
<!-- icon svg -->
|
|
116
|
+
</svg>
|
|
117
|
+
</button>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Button group
|
|
121
|
+
|
|
122
|
+
```html
|
|
123
|
+
<div role="group" class="[button_group theme classes]">
|
|
124
|
+
<button type="button">Cancel</button>
|
|
125
|
+
<button type="button">Save</button>
|
|
126
|
+
</div>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## ARIA
|
|
132
|
+
|
|
133
|
+
- `<button>` always has `type="button"` to prevent accidental form submission.
|
|
134
|
+
- Icon-only buttons must supply an accessible label via `aria: { label: "..." }` in `html_options`.
|
|
135
|
+
- For navigation actions (links), use `sp_link` instead — it renders an `<a>` element.
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Calendar
|
|
2
|
+
|
|
3
|
+
Rails helpers for rendering calendar grids. Two rendering modes are supported:
|
|
4
|
+
|
|
5
|
+
- **CSR (Stimulus)** — JS controller renders the month grid client-side; drill-down (year/decade views) driven by `combobox-date`.
|
|
6
|
+
- **SSR (Turbo)** — Server renders each view as a Turbo Frame; controller handles navigation via Turbo Drive.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## CSR — Stimulus calendar
|
|
11
|
+
|
|
12
|
+
### Setup
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
module ApplicationHelper
|
|
16
|
+
include StimulusPlumbers::Helpers::CalendarHelper
|
|
17
|
+
end
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Usage
|
|
21
|
+
|
|
22
|
+
```erb
|
|
23
|
+
<%# Current month (defaults to today) %>
|
|
24
|
+
<%= sp_calendar_month %>
|
|
25
|
+
|
|
26
|
+
<%# Navigate to a specific month %>
|
|
27
|
+
<%= sp_calendar_month(date: Date.new(2024, 2, 1)) %>
|
|
28
|
+
|
|
29
|
+
<%# Inside a combobox-date wrapper for drill-down navigation %>
|
|
30
|
+
<div data-controller="combobox-date"
|
|
31
|
+
data-combobox-date-calendar-month-outlet="[data-controller~='calendar-month']">
|
|
32
|
+
<%= sp_calendar_month(date: @date) %>
|
|
33
|
+
</div>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Option | Description |
|
|
37
|
+
| ---------------- | ------------------------------------------------------------------------------------ |
|
|
38
|
+
| `date` | `Date` — sets `year-value`, `month-value` (0-indexed), `day-value` on the controller |
|
|
39
|
+
| `**html_options` | Forwarded to the `calendar-month` controller root element |
|
|
40
|
+
|
|
41
|
+
For the JS controller API (targets, values, keyboard behaviour), see the [JS package docs](../../../stimulus-plumbers/docs/component/calendar.md).
|
|
42
|
+
|
|
43
|
+
### Rendered HTML structure
|
|
44
|
+
|
|
45
|
+
`sp_calendar_month` renders a `calendar-month` controller shell. The JS controller populates the day/week grids on connect and on each navigation. Year/decade drill-down views are separate controllers wired by `combobox-date` — see the [JS package docs](../../../stimulus-plumbers/docs/component/calendar.md).
|
|
46
|
+
|
|
47
|
+
```html
|
|
48
|
+
<!-- sp_calendar_month(date: Date.new(2024, 2, 15)) -->
|
|
49
|
+
<div
|
|
50
|
+
data-controller="calendar-month"
|
|
51
|
+
data-calendar-month-year-value="2024"
|
|
52
|
+
data-calendar-month-month-value="1"
|
|
53
|
+
data-calendar-month-day-value="15"
|
|
54
|
+
role="grid"
|
|
55
|
+
>
|
|
56
|
+
<!-- days-of-week header row (JS-populated) -->
|
|
57
|
+
<div data-calendar-month-target="daysOfWeek"></div>
|
|
58
|
+
|
|
59
|
+
<!-- days-of-month body (JS-populated) -->
|
|
60
|
+
<div role="rowgroup" data-calendar-month-target="daysOfMonth"></div>
|
|
61
|
+
</div>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## SSR — Turbo calendar
|
|
67
|
+
|
|
68
|
+
### Setup
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
module ApplicationHelper
|
|
72
|
+
include StimulusPlumbers::Helpers::CalendarTurboHelper
|
|
73
|
+
end
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Usage
|
|
77
|
+
|
|
78
|
+
`sp_calendar_turbo` renders all three view frames at once (month visible, year/decade hidden). Each frame is a `<turbo-frame>` targeted by `combobox-date`.
|
|
79
|
+
|
|
80
|
+
```erb
|
|
81
|
+
<%= sp_calendar_turbo(date: @date, today: @today, selectable: true) %>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Individual view helpers render a single view (used for Turbo Frame responses). They accept the same common options plus extras:
|
|
85
|
+
|
|
86
|
+
```erb
|
|
87
|
+
<%# Month view (days grid) %>
|
|
88
|
+
<%= sp_calendar_turbo_month(date: @date, today: @today, weekday_format: :narrow) %>
|
|
89
|
+
|
|
90
|
+
<%# Year view (months grid) %>
|
|
91
|
+
<%= sp_calendar_turbo_year(date: @date, today: @today, month_format: :long) %>
|
|
92
|
+
|
|
93
|
+
<%# Decade view (years grid) %>
|
|
94
|
+
<%= sp_calendar_turbo_decade(date: @date, today: @today) %>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
| Helper | Extra option | Description |
|
|
98
|
+
| ------------------------- | ---------------- | ------------------------------------------------------------------ |
|
|
99
|
+
| `sp_calendar_turbo_month` | `weekday_format` | `:short` (default) \| `:long` \| `:narrow` — weekday header format |
|
|
100
|
+
| `sp_calendar_turbo_year` | `month_format` | `:short` (default) \| `:long` \| `:narrow` — month button format |
|
|
101
|
+
|
|
102
|
+
**Common options** (all helpers and `sp_calendar_turbo`):
|
|
103
|
+
|
|
104
|
+
| Option | Description |
|
|
105
|
+
| ------------------- | -------------------------------------------------------- |
|
|
106
|
+
| `date` | `Date` — the month/year being displayed |
|
|
107
|
+
| `today` | `Date` — used to mark today and aria-current |
|
|
108
|
+
| `selectable` | `true` renders day cells as `<button>` (month only) |
|
|
109
|
+
| `selected_date` | `Date` — marks the selected cell with aria-selected |
|
|
110
|
+
| `show_other_months` | `true` shows padding days from adjacent months |
|
|
111
|
+
| `since` | `Date` — minimum selectable date (disables earlier days) |
|
|
112
|
+
| `till` | `Date` — maximum selectable date (disables later days) |
|
|
113
|
+
| `disabled_months` | Array — month numbers/names to disable in the year view |
|
|
114
|
+
| `disabled_years` | Array — years to disable in the decade view |
|
|
115
|
+
|
|
116
|
+
### Rendered HTML structure
|
|
117
|
+
|
|
118
|
+
#### Month view (`sp_calendar_turbo_month`)
|
|
119
|
+
|
|
120
|
+
```html
|
|
121
|
+
<!-- sp_calendar_turbo_month(date: @date, today: @today, selectable: true) -->
|
|
122
|
+
<div role="grid" data-controller="calendar-month-selector">
|
|
123
|
+
<!-- weekday column headers -->
|
|
124
|
+
<div role="row">
|
|
125
|
+
<span role="columnheader">Su</span>
|
|
126
|
+
<!-- … -->
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
<!-- day cells -->
|
|
130
|
+
<div role="rowgroup">
|
|
131
|
+
<div role="row">
|
|
132
|
+
<!-- selectable: true → <button>; selectable: false → <span> -->
|
|
133
|
+
<button role="gridcell" tabindex="0" aria-selected="false">
|
|
134
|
+
<time datetime="2024-02-01">1</time>
|
|
135
|
+
</button>
|
|
136
|
+
<!-- … -->
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Year view (`sp_calendar_turbo_year`)
|
|
143
|
+
|
|
144
|
+
Displays 12 month buttons in a 4-column grid. Used when drilling up from the month view.
|
|
145
|
+
|
|
146
|
+
```html
|
|
147
|
+
<!-- sp_calendar_turbo_year(date: @date, today: @today) -->
|
|
148
|
+
<div
|
|
149
|
+
role="grid"
|
|
150
|
+
aria-label="Year view"
|
|
151
|
+
data-controller="calendar-year-selector"
|
|
152
|
+
>
|
|
153
|
+
<div role="rowgroup">
|
|
154
|
+
<div role="row">
|
|
155
|
+
<button
|
|
156
|
+
role="gridcell"
|
|
157
|
+
data-month="1"
|
|
158
|
+
aria-current="month"
|
|
159
|
+
aria-selected="false"
|
|
160
|
+
>
|
|
161
|
+
Jan
|
|
162
|
+
</button>
|
|
163
|
+
<!-- … 11 more months … -->
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Decade view (`sp_calendar_turbo_decade`)
|
|
170
|
+
|
|
171
|
+
Displays 10 year buttons in a 4-column grid (plus 2 buffer cells, disabled). Used when drilling up from the year view.
|
|
172
|
+
|
|
173
|
+
```html
|
|
174
|
+
<!-- sp_calendar_turbo_decade(date: @date, today: @today) -->
|
|
175
|
+
<div
|
|
176
|
+
role="grid"
|
|
177
|
+
aria-label="Decade view"
|
|
178
|
+
data-controller="calendar-decade-selector"
|
|
179
|
+
>
|
|
180
|
+
<div role="rowgroup">
|
|
181
|
+
<div role="row">
|
|
182
|
+
<button
|
|
183
|
+
role="gridcell"
|
|
184
|
+
data-year="2020"
|
|
185
|
+
aria-current="year"
|
|
186
|
+
aria-selected="false"
|
|
187
|
+
>
|
|
188
|
+
2020
|
|
189
|
+
</button>
|
|
190
|
+
<!-- … 9 more years … -->
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### Full Turbo setup (`sp_calendar_turbo`)
|
|
197
|
+
|
|
198
|
+
Renders all three frames. Used inside a `combobox-date` controller for drill-down navigation.
|
|
199
|
+
|
|
200
|
+
```html
|
|
201
|
+
<!-- month view frame — visible by default -->
|
|
202
|
+
<turbo-frame id="calendar-month-frame" data-combobox-date-target="monthView">
|
|
203
|
+
<!-- sp_calendar_turbo_month output -->
|
|
204
|
+
</turbo-frame>
|
|
205
|
+
|
|
206
|
+
<!-- year view frame — hidden until drill-up -->
|
|
207
|
+
<turbo-frame
|
|
208
|
+
id="calendar-year-frame"
|
|
209
|
+
hidden
|
|
210
|
+
data-combobox-date-target="yearView"
|
|
211
|
+
>
|
|
212
|
+
<!-- sp_calendar_turbo_year output -->
|
|
213
|
+
</turbo-frame>
|
|
214
|
+
|
|
215
|
+
<!-- decade view frame — hidden until drill-up twice -->
|
|
216
|
+
<turbo-frame
|
|
217
|
+
id="calendar-decade-frame"
|
|
218
|
+
hidden
|
|
219
|
+
data-combobox-date-target="decadeView"
|
|
220
|
+
>
|
|
221
|
+
<!-- sp_calendar_turbo_decade output -->
|
|
222
|
+
</turbo-frame>
|
|
223
|
+
```
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Card
|
|
2
|
+
|
|
3
|
+
Rails helper for rendering a themed card with optional icon, title, body, and action slots.
|
|
4
|
+
|
|
5
|
+
## Helper
|
|
6
|
+
|
|
7
|
+
### `sp_card`
|
|
8
|
+
|
|
9
|
+
```erb
|
|
10
|
+
<%# Minimal %>
|
|
11
|
+
<%= sp_card do |card| %>
|
|
12
|
+
<% card.with_body { "Simple content." } %>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
<%# With title and icon %>
|
|
16
|
+
<%= sp_card(title_tag: :h3) do |card| %>
|
|
17
|
+
<% card.with_icon("user") %>
|
|
18
|
+
<% card.with_title("Account") %>
|
|
19
|
+
<% card.with_body { "Your account is active." } %>
|
|
20
|
+
<% end %>
|
|
21
|
+
|
|
22
|
+
<%# With action link %>
|
|
23
|
+
<%= sp_card do |card| %>
|
|
24
|
+
<% card.with_title("Settings") %>
|
|
25
|
+
<% card.with_action("Manage", url: settings_path) %>
|
|
26
|
+
<% end %>
|
|
27
|
+
|
|
28
|
+
<%# With action button (no url) %>
|
|
29
|
+
<%= sp_card do |card| %>
|
|
30
|
+
<% card.with_action("Open") %>
|
|
31
|
+
<% end %>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
| Option | Default | Description |
|
|
35
|
+
| ---------------- | ----------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
36
|
+
| `variant:` | `:tertiary` | Theme variant — `:primary` \| `:secondary` \| `:tertiary` \| `:success` \| `:destructive` \| `:warning` \| `:info` |
|
|
37
|
+
| `title_tag:` | `:h2` | HTML tag used by `with_title` |
|
|
38
|
+
| `**html_options` | — | Forwarded to the outer `<div>` |
|
|
39
|
+
|
|
40
|
+
### Slot methods (yielded as `card`)
|
|
41
|
+
|
|
42
|
+
| Slot method | Description |
|
|
43
|
+
| ---------------------------------- | ---------------------------------------------------------------------------- |
|
|
44
|
+
| `card.with_icon(name_or_html)` | Icon before the title — string/symbol resolves via `Icon`; HTML passed as-is |
|
|
45
|
+
| `card.with_title(text)` | Title text rendered as `title_tag` |
|
|
46
|
+
| `card.with_body { content }` | Body content — block required |
|
|
47
|
+
| `card.with_action(text, url: nil)` | Action link (`<a>`) when `url:` present; `<button>` otherwise |
|
|
48
|
+
|
|
49
|
+
`with_action` raises `ArgumentError` when `url:` is given but no content (text or block).
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Rendered HTML Structure
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<div class="[card theme classes]">
|
|
57
|
+
<!-- header: rendered when icon or title is present -->
|
|
58
|
+
<div class="[card_header theme classes]">
|
|
59
|
+
<svg aria-hidden="true" class="[card_icon theme classes]">...</svg>
|
|
60
|
+
<h2 class="[card_title theme classes]">Account</h2>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<!-- body -->
|
|
64
|
+
<div class="[card_body theme classes]">Your account is active.</div>
|
|
65
|
+
|
|
66
|
+
<!-- action -->
|
|
67
|
+
<div class="[card_action theme classes]">
|
|
68
|
+
<a href="/settings">Manage</a>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Theme keys
|
|
76
|
+
|
|
77
|
+
| Key | Element | Variants |
|
|
78
|
+
| ------------- | ----------------------------------- | --------------------------------------------- |
|
|
79
|
+
| `card` | Outer `<div>` | `variant: :primary\|:secondary\|:tertiary\|…` |
|
|
80
|
+
| `card_header` | Header wrapper `<div>` (icon+title) | — |
|
|
81
|
+
| `card_icon` | Icon inside the header | — |
|
|
82
|
+
| `card_title` | Title element (`h2` etc.) | — |
|
|
83
|
+
| `card_body` | Body `<div>` | — |
|
|
84
|
+
| `card_action` | Action `<div>` | — |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## ARIA
|
|
89
|
+
|
|
90
|
+
- `sp_card` is a layout container — no ARIA roles are added automatically.
|
|
91
|
+
- Supply `role:` or `aria:` via `html_options` when the card plays a semantic role (e.g. `role: "region"`, `aria: { label: "..." }`).
|
|
92
|
+
- For interactive card-style inputs (radio/checkbox), see `f.choice` with `type: :card` in the [form doc](form.md).
|