keystone_ui 0.23.0 → 0.24.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.
- checksums.yaml +4 -4
- data/app/components/keystone/ui/action_menu_component.html.erb +11 -0
- data/app/components/keystone/ui/action_menu_component.rb +12 -0
- data/app/components/keystone/ui/action_menu_item_component.rb +21 -0
- data/app/components/keystone/ui/data_table_component.html.erb +3 -1
- data/app/components/keystone/ui/section_component.html.erb +7 -0
- data/app/components/keystone/ui/section_component.rb +2 -1
- data/app/helpers/keystone_ui_helper.rb +8 -0
- data/lib/keystone_ui/safelist.rb +2 -0
- data/lib/keystone_ui/version.rb +1 -1
- data/the_local/agents/keystone_ui-develop.md +28 -5
- data/the_local/agents/keystone_ui-info.md +8 -1
- data/the_local/agents/keystone_ui-install.md +4 -4
- data/the_local/interface.yml +6 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0ebdae8cec6c4c1ac5a5d9e0ba2c2f81af46ac2bcd2d1537dce3ac039287a895
|
|
4
|
+
data.tar.gz: 3729bc3f9486e0adca2a21482bf493c832506d36c0e5bb9e98a50bba7a70e49a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1091cd7bb197a64a0ceb327906932e191e11e19bbcdc2559283cfde82573a7ad36adc4a6b1c2e430fef41eeb421642e6d3779ca1879a172d009098e98a4cfbba
|
|
7
|
+
data.tar.gz: 2d532adcf2a254df72de1e82383f4f373a520c03503adbf31c9c45b881c2a0f8296348bb0f581b3360e8b7ff505fd22431a41f7fef6042fc15681cbf97242833
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div class="<%= WRAPPER_CLASSES %>" data-controller="dropdown">
|
|
2
|
+
<button type="button"
|
|
3
|
+
data-action="click->dropdown#toggle click@window->dropdown#hide"
|
|
4
|
+
class="<%= BUTTON_CLASSES %>"
|
|
5
|
+
aria-label="Actions">
|
|
6
|
+
<%= ELLIPSIS_ICON.html_safe %>
|
|
7
|
+
</button>
|
|
8
|
+
<div data-dropdown-target="menu" class="<%= DROPDOWN_CLASSES %>">
|
|
9
|
+
<%= content %>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Keystone
|
|
4
|
+
module Ui
|
|
5
|
+
class ActionMenuComponent < ViewComponent::Base
|
|
6
|
+
WRAPPER_CLASSES = "relative inline-block"
|
|
7
|
+
BUTTON_CLASSES = MobileActionsComponent::BUTTON_CLASSES
|
|
8
|
+
DROPDOWN_CLASSES = MobileActionsComponent::DROPDOWN_CLASSES
|
|
9
|
+
ELLIPSIS_ICON = MobileActionsComponent::ELLIPSIS_ICON
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Keystone
|
|
4
|
+
module Ui
|
|
5
|
+
class ActionMenuItemComponent < ViewComponent::Base
|
|
6
|
+
ITEM_CLASSES = "ks-menu-option block w-full text-left"
|
|
7
|
+
|
|
8
|
+
def initialize(label:, href:, method: :get)
|
|
9
|
+
@label = label
|
|
10
|
+
@href = href
|
|
11
|
+
@method = method.to_sym
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call
|
|
15
|
+
return link_to(@label, @href, class: ITEM_CLASSES) if @method == :get
|
|
16
|
+
|
|
17
|
+
button_to(@href, method: @method, class: ITEM_CLASSES) { @label }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -43,7 +43,9 @@
|
|
|
43
43
|
<% end %>
|
|
44
44
|
<% if actions? %>
|
|
45
45
|
<td class="<%= Keystone::Ui::DataTableComponent::ROW_CLASSES_LAST %>">
|
|
46
|
-
<%=
|
|
46
|
+
<%= render Keystone::Ui::ActionMenuComponent.new do %>
|
|
47
|
+
<%= capture(item, &@actions_block) %>
|
|
48
|
+
<% end %>
|
|
47
49
|
</td>
|
|
48
50
|
<% end %>
|
|
49
51
|
</tr>
|
|
@@ -12,6 +12,13 @@
|
|
|
12
12
|
<%= @action[:label] %>
|
|
13
13
|
</a>
|
|
14
14
|
<% end %>
|
|
15
|
+
<% if @menu.any? %>
|
|
16
|
+
<%= render Keystone::Ui::ActionMenuComponent.new do %>
|
|
17
|
+
<% @menu.each do |item| %>
|
|
18
|
+
<%= render Keystone::Ui::ActionMenuItemComponent.new(**item) %>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
|
21
|
+
<% end %>
|
|
15
22
|
</div>
|
|
16
23
|
<% end %>
|
|
17
24
|
<%= content %>
|
|
@@ -9,10 +9,11 @@ module Keystone
|
|
|
9
9
|
SUBTITLE_CLASSES = "ks-section-subtitle"
|
|
10
10
|
ACTION_CLASSES = "ks-section-action"
|
|
11
11
|
|
|
12
|
-
def initialize(title: nil, subtitle: nil, action: nil, spacing: :md, class: nil)
|
|
12
|
+
def initialize(title: nil, subtitle: nil, action: nil, menu: [], spacing: :md, class: nil)
|
|
13
13
|
@title = title
|
|
14
14
|
@subtitle = subtitle
|
|
15
15
|
@action = action
|
|
16
|
+
@menu = menu
|
|
16
17
|
@spacing = spacing
|
|
17
18
|
@extra_classes = binding.local_variable_get(:class)
|
|
18
19
|
end
|
|
@@ -125,6 +125,14 @@ module KeystoneUiHelper
|
|
|
125
125
|
render Keystone::Ui::MobileHeaderComponent.new(**args)
|
|
126
126
|
end
|
|
127
127
|
|
|
128
|
+
def ui_action_menu(**args, &block)
|
|
129
|
+
render Keystone::Ui::ActionMenuComponent.new(**args), &block
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def ui_action_menu_item(**args)
|
|
133
|
+
render Keystone::Ui::ActionMenuItemComponent.new(**args)
|
|
134
|
+
end
|
|
135
|
+
|
|
128
136
|
def ui_mobile_actions(**args, &block)
|
|
129
137
|
render Keystone::Ui::MobileActionsComponent.new(**args), &block
|
|
130
138
|
end
|
data/lib/keystone_ui/safelist.rb
CHANGED
|
@@ -6,6 +6,8 @@ module Keystone
|
|
|
6
6
|
# The safelist_spec verifies this list matches Keystone::Ui components.
|
|
7
7
|
COMPONENTS = [
|
|
8
8
|
Keystone::Ui::AccordionComponent,
|
|
9
|
+
Keystone::Ui::ActionMenuComponent,
|
|
10
|
+
Keystone::Ui::ActionMenuItemComponent,
|
|
9
11
|
Keystone::Ui::TabSwitcherComponent,
|
|
10
12
|
Keystone::Ui::StatCardComponent,
|
|
11
13
|
Keystone::Ui::ChartCardComponent,
|
data/lib/keystone_ui/version.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: keystone_ui-develop
|
|
3
|
-
description: Use PROACTIVELY for building or editing screens in a Rails app that has Keystone UI — pages, forms, tables, navigation, dashboards, charts, marketing sections, a light/dark theme switch — MUST BE USED instead of hand-writing ERB and Tailwind for UI.
|
|
3
|
+
description: Use PROACTIVELY for building or editing screens in a Rails app that has Keystone UI — pages, forms, tables, navigation, action menus for a record's Edit and Delete, dashboards, charts, marketing sections, a light/dark theme switch — MUST BE USED instead of hand-writing ERB and Tailwind for UI.
|
|
4
4
|
tools: Read, Write, Edit, Grep
|
|
5
5
|
scope: UI — pages, forms, tables, navigation, dashboards
|
|
6
6
|
---
|
|
@@ -45,9 +45,13 @@ outer element. See Conventions before using it.
|
|
|
45
45
|
`:lg` `:xl` to clear a fixed navbar. When `ui_form_page` or `ui_show_page` was
|
|
46
46
|
called earlier on the same screen, `ui_page` renders their back link or
|
|
47
47
|
breadcrumbs, and the form page's title, at its top, above the block.
|
|
48
|
-
- `ui_section(title: nil, subtitle: nil, action: nil, spacing: :md, class: nil)`
|
|
48
|
+
- `ui_section(title: nil, subtitle: nil, action: nil, menu: [], spacing: :md, class: nil)`
|
|
49
49
|
— takes a block. A titled block of content with an optional right-aligned
|
|
50
50
|
link. `action:` is `{ label:, href: }`; `spacing:` `:sm` `:md` `:lg`.
|
|
51
|
+
`menu:` is `[{ label:, href:, method: }, ...]`, each hash taking the keywords
|
|
52
|
+
of `ui_action_menu_item`, and renders an action menu at the right of the
|
|
53
|
+
header. The header, and with it `action:` and `menu:`, renders only when
|
|
54
|
+
`title:` is given.
|
|
51
55
|
- `ui_panel(padding: :md, radius: :lg, shadow: true)` — takes a block. A bordered
|
|
52
56
|
card surface. `padding:` `:sm` `:md` `:lg`; `radius:` `:md` `:lg` `:xl`.
|
|
53
57
|
- `ui_grid(cols: { default: 1 }, gap: :md, gap_x: nil, gap_y: nil)` — takes a
|
|
@@ -113,8 +117,18 @@ outer element. See Conventions before using it.
|
|
|
113
117
|
- `ui_mobile_header(title:, back_url:, subtitle: nil)` — a back chevron plus
|
|
114
118
|
centered title for mobile; hidden above `lg:`. Place it in the navbar's
|
|
115
119
|
`mobile_left` slot.
|
|
120
|
+
- `ui_action_menu` — no keywords, takes a block. An ellipsis (⋯) button that
|
|
121
|
+
opens a dropdown of actions, shown at every screen size. Fill the block with
|
|
122
|
+
`ui_action_menu_item` calls.
|
|
123
|
+
- `ui_action_menu_item(label:, href:, method: :get)` — one entry in an action
|
|
124
|
+
menu. With `method: :get` it is a link to `href`. Any other method, such as
|
|
125
|
+
`:post`, `:patch` or `:delete`, renders a button inside its own small form
|
|
126
|
+
that sends that method to `href`, so never place such an item inside a
|
|
127
|
+
`ui_form` block, since a form cannot contain another form. It asks for no
|
|
128
|
+
confirmation before sending.
|
|
116
129
|
- `ui_mobile_actions` — no keywords, takes a block. An ellipsis dropdown for
|
|
117
|
-
mobile actions; the block holds the menu items. Hidden above `lg:`.
|
|
130
|
+
mobile actions; the block holds the menu items. Hidden above `lg:`. Use
|
|
131
|
+
`ui_action_menu` instead when the actions must also be reachable on desktop.
|
|
118
132
|
- `ui_settings_link(label:, href:)` — a full-width settings row with a chevron.
|
|
119
133
|
- `ui_theme_toggle` — no keywords, no block. A row of three buttons, Light, Dark
|
|
120
134
|
and System, that switches the page's theme at once and remembers the choice in
|
|
@@ -180,7 +194,9 @@ outer element. See Conventions before using it.
|
|
|
180
194
|
`columns:` accepts plain `{ key: "Label" }` hashes or `Keystone::Ui::Column`
|
|
181
195
|
objects. In the block, `table.link(:column_key) { |item| url }` turns that
|
|
182
196
|
column's cells into links and `table.actions { |item| ... }` appends a
|
|
183
|
-
right-aligned actions column.
|
|
197
|
+
right-aligned actions column. Each row's actions render inside an action
|
|
198
|
+
menu, so the `actions` block holds `ui_action_menu_item` calls and nothing
|
|
199
|
+
else, never buttons or bare links. Sorting requires all three of `sort:` (the
|
|
184
200
|
current column key), `sort_direction:` (`:asc`/`:desc`), and `sort_url:` (a
|
|
185
201
|
lambda taking `(column_key, direction)` and returning a URL); headers then
|
|
186
202
|
render as links that flip direction. `hidden_columns:` drops columns
|
|
@@ -362,6 +378,12 @@ outer element. See Conventions before using it.
|
|
|
362
378
|
To show the arithmetic behind a figure, put `ui_calculation` under it rather
|
|
363
379
|
than a hand-built list. Which lines and groups to show is the app's own
|
|
364
380
|
calculation, so ask the developer which steps a reader needs to see.
|
|
381
|
+
Put the actions on a record, such as Edit and Delete, in an action menu
|
|
382
|
+
rather than in a row of buttons: `menu:` on the `ui_section` that shows the
|
|
383
|
+
record, `table.actions` for a table row, or `ui_action_menu` anywhere else.
|
|
384
|
+
An item that deletes or changes data sends without asking for
|
|
385
|
+
confirmation, so ask the developer whether that action needs a confirmation
|
|
386
|
+
step before adding it.
|
|
365
387
|
|
|
366
388
|
6. For a table, decide how columns are declared. Use `{ key: "Label" }` hashes
|
|
367
389
|
when every column is plain. Switch the whole set to `Keystone::Ui::Column`
|
|
@@ -421,7 +443,8 @@ outer element. See Conventions before using it.
|
|
|
421
443
|
through it, so anything else emitted inside their block is discarded.
|
|
422
444
|
- **Mobile is not an afterthought.** Several helpers render only on one side of
|
|
423
445
|
the `lg:` (or `sm:`) breakpoint — page headers, mobile headers, mobile actions,
|
|
424
|
-
bottom navigation, breadcrumbs.
|
|
446
|
+
bottom navigation, breadcrumbs. The action menu is the exception and shows at
|
|
447
|
+
every size. A screen needs both treatments; check the small viewport
|
|
425
448
|
before calling it done.
|
|
426
449
|
- Out of scope for this local: installing or upgrading the gem, changing the
|
|
427
450
|
palette or theme defaults, and editing the components themselves. Building a
|
|
@@ -74,6 +74,13 @@ holds the catalog.
|
|
|
74
74
|
that render one thing (a button, a badge, a field, a stat, a bucket) are
|
|
75
75
|
configured entirely by keyword arguments. The navigation bar exposes named
|
|
76
76
|
slots instead of a single block.
|
|
77
|
+
- **Action menus.** An action menu is an ellipsis button that opens a dropdown
|
|
78
|
+
of actions, shown at every screen size. The mobile action menu is the one
|
|
79
|
+
hidden from `lg:` up. Each action is a label, an address and an HTTP method.
|
|
80
|
+
A plain visit renders as a link. Any other method renders as a button that
|
|
81
|
+
sends that method, so an action that changes data is never a bare link. A
|
|
82
|
+
data table puts each row's actions in one action menu at the end of the row,
|
|
83
|
+
and a section can carry an action menu in its header beside its title.
|
|
77
84
|
- **Options are symbols, and each component accepts its own set.** Appearance is
|
|
78
85
|
chosen by name — `variant:`, `size:`, `type:`, `padding:`, `spacing:`,
|
|
79
86
|
`max_width:`, `radius:` — on a size scale (`:sm` … `:xl`) or a short list of
|
|
@@ -100,7 +107,7 @@ holds the catalog.
|
|
|
100
107
|
keystone_ui-styles 0.6.0 or later: corner radius, font, label weight, border
|
|
101
108
|
width, padding and colours. Each colour variable has a `-dark` partner read
|
|
102
109
|
on a dark page. Buttons, panels, cards, alerts, badges, form fields, the
|
|
103
|
-
modal, the mobile action menu, the column picker, multi select, copy button,
|
|
110
|
+
modal, the action menu, the mobile action menu, the column picker, multi select, copy button,
|
|
104
111
|
theme toggle, checkbox row, radio card, option card, file upload and colour
|
|
105
112
|
picker read these variables. So do the data display components: stat card,
|
|
106
113
|
chart card, card link, CTA banner, feature grid, hero, data table, code,
|
|
@@ -83,9 +83,9 @@ built on ViewComponent; hook it in before building any screen with those helpers
|
|
|
83
83
|
the Stimulus application is set up and add those two lines there. Without
|
|
84
84
|
them, dropdowns, modals, file uploads, the column picker, the theme toggle
|
|
85
85
|
and the other interactive components do nothing.
|
|
86
|
-
`registerControllers(application)` also copies `data-theme`
|
|
87
|
-
Turbo renders onto the `<html>` tag. Without it, a Turbo
|
|
88
|
-
theme of the first page loaded.
|
|
86
|
+
`registerControllers(application)` also copies `data-theme` and `data-look`
|
|
87
|
+
from each page Turbo renders onto the `<html>` tag. Without it, a Turbo
|
|
88
|
+
visit keeps the theme and look of the first page loaded.
|
|
89
89
|
- `app/views/layouts/application.html.erb not found` — ask the developer which
|
|
90
90
|
layout the app renders and add `<%= keystone_theme_attributes %>` to its
|
|
91
91
|
`<html>` tag. Without it, a saved light or dark choice is not applied when
|
|
@@ -149,7 +149,7 @@ built on ViewComponent; hook it in before building any screen with those helpers
|
|
|
149
149
|
```
|
|
150
150
|
|
|
151
151
|
Buttons, panels, cards, alerts, badges, form fields, the modal, the mobile
|
|
152
|
-
action menu, the column picker, multi select, copy button, theme toggle,
|
|
152
|
+
action menu, the action menu, the column picker, multi select, copy button, theme toggle,
|
|
153
153
|
checkbox row, radio card, option card, file upload and colour picker read
|
|
154
154
|
these variables. So do the data display components: stat card, chart card,
|
|
155
155
|
card link, CTA banner, feature grid, hero, data table, code, accordion,
|
data/the_local/interface.yml
CHANGED
|
@@ -36,6 +36,8 @@ develop:
|
|
|
36
36
|
- ui_breadcrumbs
|
|
37
37
|
- ui_mobile_header
|
|
38
38
|
- ui_mobile_actions
|
|
39
|
+
- ui_action_menu
|
|
40
|
+
- ui_action_menu_item
|
|
39
41
|
- ui_navbar
|
|
40
42
|
- ui_nav_item
|
|
41
43
|
- ui_nav_dropdown
|
|
@@ -88,6 +90,7 @@ sources:
|
|
|
88
90
|
- app/components/keystone/ui/copy_button_component.rb
|
|
89
91
|
- app/components/keystone/ui/cta_banner_component.rb
|
|
90
92
|
- app/components/keystone/ui/data_table_component.rb
|
|
93
|
+
- app/components/keystone/ui/data_table_component.html.erb
|
|
91
94
|
- app/components/keystone/ui/disclosure_component.rb
|
|
92
95
|
- app/components/keystone/ui/calculation_component.rb
|
|
93
96
|
- app/components/keystone/ui/feature_grid_component.rb
|
|
@@ -108,6 +111,8 @@ sources:
|
|
|
108
111
|
- app/components/keystone/ui/input_component.rb
|
|
109
112
|
- app/components/keystone/ui/line_chart_component.rb
|
|
110
113
|
- app/components/keystone/ui/mobile_actions_component.rb
|
|
114
|
+
- app/components/keystone/ui/action_menu_component.rb
|
|
115
|
+
- app/components/keystone/ui/action_menu_item_component.rb
|
|
111
116
|
- app/components/keystone/ui/mobile_header_component.rb
|
|
112
117
|
- app/components/keystone/ui/modal_component.rb
|
|
113
118
|
- app/components/keystone/ui/multi_select_component.rb
|
|
@@ -124,6 +129,7 @@ sources:
|
|
|
124
129
|
- app/components/keystone/ui/progress_component.rb
|
|
125
130
|
- app/components/keystone/ui/radio_card_component.rb
|
|
126
131
|
- app/components/keystone/ui/section_component.rb
|
|
132
|
+
- app/components/keystone/ui/section_component.html.erb
|
|
127
133
|
- app/components/keystone/ui/select_component.rb
|
|
128
134
|
- app/components/keystone/ui/settings_link_component.rb
|
|
129
135
|
- app/components/keystone/ui/show_page_component.rb
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: keystone_ui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.24.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tyler Schneider
|
|
@@ -73,6 +73,9 @@ files:
|
|
|
73
73
|
- app/assets/tailwind/keystone_ui_engine/grid_safelist.css
|
|
74
74
|
- app/components/keystone/ui/accordion_component.html.erb
|
|
75
75
|
- app/components/keystone/ui/accordion_component.rb
|
|
76
|
+
- app/components/keystone/ui/action_menu_component.html.erb
|
|
77
|
+
- app/components/keystone/ui/action_menu_component.rb
|
|
78
|
+
- app/components/keystone/ui/action_menu_item_component.rb
|
|
76
79
|
- app/components/keystone/ui/alert_component.html.erb
|
|
77
80
|
- app/components/keystone/ui/alert_component.rb
|
|
78
81
|
- app/components/keystone/ui/badge_component.html.erb
|