keystone_ui 0.15.0 → 0.15.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: cdb61774853355f3b66ae9c1a7d6f4930005216827486777c19b582b3ac775f2
4
- data.tar.gz: a815979ea629c273e43b8b7d39a20a1310908dedee967aec21b326e027784333
3
+ metadata.gz: 60fbc4a896b71babee643443b4583435ffa85d0b1be67324afdc901169807f68
4
+ data.tar.gz: e83753c421f5e7095b552fc39776c982c823273665bd10dee5f5a769df39c204
5
5
  SHA512:
6
- metadata.gz: '0975326ab4b00a0f6ce7f28ae8642e2bee4704e13509046a1c2ad820e50880ace96f0b0d0e66dfd95e29b3d7d56cff68f7e4aef1264c507b2480eb72d3b14c5d'
7
- data.tar.gz: e06fedfeebf535bf2c17ae2dc30938878a05f3cfb918f29df694886538f2c88f97d83d5eb51e9210e4dcdc8bfdbf3b16c8daef006d0bc51f6f93815752c4268c
6
+ metadata.gz: 56fb8e5421b4cb2e9669af2dec0a452ee7c58f316b10f63ce6ea0096ecfd347fbaf01708613a23a00365c9d0e88d7576fbd46c83e13509d5ff9f823f22e9c688
7
+ data.tar.gz: 70375887467d685ddf82dc96074ec99d3ce43694ad53bf022d315083478e9f21238099528924e133d9bdb425410d8727a8873c8db8119531843fa39a3eb97106
@@ -13,6 +13,7 @@ import StatCardInfoController from "keystone_ui/stat_card_info_controller"
13
13
  import AutoSubmitController from "keystone_ui/auto_submit_controller"
14
14
  import LineChartController from "keystone_ui/line_chart_controller"
15
15
  import ThemeToggleController from "keystone_ui/theme_toggle_controller"
16
+ import { keepPageThemeInStep } from "keystone_ui/page_theme"
16
17
 
17
18
  export function registerControllers(application) {
18
19
  application.register("color-picker", ColorPickerController)
@@ -30,6 +31,7 @@ export function registerControllers(application) {
30
31
  application.register("auto-submit", AutoSubmitController)
31
32
  application.register("line-chart", LineChartController)
32
33
  application.register("theme-toggle", ThemeToggleController)
34
+ keepPageThemeInStep()
33
35
  }
34
36
 
35
37
  export { ColorPickerController, MultiSelectController, SwipeDeckController, ColumnPickerController, FileUploadController, DropdownController, DismissController, ModalController, ClipboardController, TabSwitcherController, AccordionController, StatCardInfoController, AutoSubmitController, LineChartController }
@@ -0,0 +1,13 @@
1
+ export function keepPageThemeInStep(page = document) {
2
+ page.addEventListener("turbo:before-render", ({ detail }) => {
3
+ const next = detail.newBody.closest("html")
4
+ if (!next) return
5
+
6
+ const theme = next.dataset.theme
7
+ if (theme) {
8
+ page.documentElement.dataset.theme = theme
9
+ } else {
10
+ delete page.documentElement.dataset.theme
11
+ }
12
+ })
13
+ }
@@ -19,8 +19,8 @@ module Keystone
19
19
  attr_reader :goal, :actual, :label
20
20
 
21
21
  def initialize(goal:, actual:, label: nil, over: :success)
22
- @goal = goal
23
- @actual = actual
22
+ @goal = number(:goal, goal)
23
+ @actual = number(:actual, actual)
24
24
  @label = label
25
25
  @over_fill_classes = OVER_GOAL_FILL_CLASSES.fetch(over)
26
26
  end
@@ -65,6 +65,12 @@ module Keystone
65
65
 
66
66
  private
67
67
 
68
+ def number(name, value)
69
+ return value if value.is_a?(Numeric)
70
+
71
+ raise ArgumentError, "#{name} must be a number, got #{value.inspect}"
72
+ end
73
+
68
74
  def fill_color_classes
69
75
  return @over_fill_classes if actual > goal
70
76
 
data/config/importmap.rb CHANGED
@@ -14,6 +14,7 @@ pin "keystone_ui/stat_card_info_controller", to: "keystone_ui/stat_card_info_con
14
14
  pin "keystone_ui/auto_submit_controller", to: "keystone_ui/auto_submit_controller.js"
15
15
  pin "keystone_ui/line_chart_controller", to: "keystone_ui/line_chart_controller.js"
16
16
  pin "keystone_ui/theme_toggle_controller", to: "keystone_ui/theme_toggle_controller.js"
17
+ pin "keystone_ui/page_theme", to: "keystone_ui/page_theme.js"
17
18
 
18
19
  # Chart.js for the line-chart controller, so host apps don't pin it themselves.
19
20
  # Vendored as a single self-contained bundle (deps inlined, no external imports).
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KeystoneUi
4
- VERSION = "0.15.0"
4
+ VERSION = "0.15.1"
5
5
  end
@@ -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 — 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, 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
  ---
@@ -89,6 +89,12 @@ outer element. See Conventions before using it.
89
89
  - `ui_mobile_actions` — no keywords, takes a block. An ellipsis dropdown for
90
90
  mobile actions; the block holds the menu items. Hidden above `lg:`.
91
91
  - `ui_settings_link(label:, href:)` — a full-width settings row with a chevron.
92
+ - `ui_theme_toggle` — no keywords, no block. A row of three buttons, Light, Dark
93
+ and System, that switches the page's theme at once and remembers the choice in
94
+ the `keystone_theme` cookie for a year. System follows the operating system.
95
+ The button for the page's current mode renders pressed. When the current mode
96
+ is a custom palette supplied by another gem, no button is pressed, because the
97
+ toggle does not offer custom.
92
98
 
93
99
  ### Forms
94
100
 
@@ -231,8 +237,12 @@ outer element. See Conventions before using it.
231
237
  - `ui_bucket(goal:, actual:, label: nil, over: :success)` — an upright container
232
238
  for one target, filled from the bottom toward `goal:`. It shows the optional
233
239
  `label` on top, then `goal`, the container, `actual`, and the percent reached.
234
- `goal` and `actual` are printed exactly as given, so pass numbers already
235
- formatted as needed. The percent is `actual / goal * 100` rounded and **not**
240
+ `goal` and `actual` must be numbers: a string such as `"9,000"`, or `nil`,
241
+ raises `ArgumentError` at render time. They are printed as Ruby prints them,
242
+ with no thousands separators, so `9000` shows as `9000` and `9000.0` as
243
+ `9000.0`. A value read from a decimal column is a `BigDecimal`, which prints
244
+ as `0.9e4`, so convert it with `to_i` or `to_f` first. The percent is
245
+ `actual / goal * 100` rounded and **not**
236
246
  clamped (so 150% shows as 150%), and it is 0 when `goal` is zero. The fill
237
247
  stops at the top once the goal is reached. Within the goal the fill uses the
238
248
  accent colour; over it the fill turns green with `over: :success` or amber with
@@ -303,7 +313,15 @@ outer element. See Conventions before using it.
303
313
  routes or a persistence strategy — put the choice to the developer, then
304
314
  implement what they pick.
305
315
 
306
- 8. Read back what you wrote and delete every Tailwind class and inline `style`
316
+ 8. To let users pick light or dark, place `ui_theme_toggle`. Where it goes — a
317
+ settings screen, the navbar's `desktop_right` or a mobile menu — is the
318
+ developer's choice, so ask before placing it. It only stays correct across
319
+ page loads and Turbo visits when the app's layout already writes the theme
320
+ onto its `html` tag and the gem's Stimulus controllers are registered. If the
321
+ layout's `<html` tag carries nothing for the theme, stop and hand that part to
322
+ `keystone_ui-install`.
323
+
324
+ 9. Read back what you wrote and delete every Tailwind class and inline `style`
307
325
  you added. If the result still needs one, that is a signal the wrong helper
308
326
  was chosen — go back to step 5. Bring it to the developer only if no helper
309
327
  fits.
@@ -47,8 +47,9 @@ holds the catalog.
47
47
 
48
48
  ## Conventions
49
49
 
50
- - **Helpers, not classes.** Every entry point is a view helper prefixed `ui_`,
51
- called from ERB. Components live under the `Keystone::Ui` namespace, but a
50
+ - **Helpers, not classes.** Every piece of UI is a view helper prefixed `ui_`,
51
+ called from ERB. The one layout helper that is not prefixed `ui_` writes the
52
+ theme onto the page's `html` tag, and it belongs to the install local. Components live under the `Keystone::Ui` namespace, but a
52
53
  host app does not name a component class directly. The one exception is the
53
54
  table column value object, which is passed as an argument and renders nothing.
54
55
  - **Containers take blocks, leaves take keywords.** Helpers that wrap content
@@ -63,6 +64,9 @@ holds the catalog.
63
64
  different symbols, and the develop local carries the real values. Most
64
65
  components raise on a symbol they do not know, so a wrong guess fails at
65
66
  render time.
67
+ - **Figures are numbers.** Components that measure or compare values, such as
68
+ progress bars, funnels and buckets, do arithmetic on them. Pass a number, not
69
+ a formatted string such as `"9,000"`. A bucket raises on one.
66
70
  - **Semantic color, not literal color.** The themed hue is `accent-*` and the
67
71
  themed neutral family is `surface-*`, both CSS custom properties whose
68
72
  defaults (blue and zinc) come from the keystone_ui-styles gem. Retheming an
@@ -75,7 +79,11 @@ holds the catalog.
75
79
  cookie, then a mode another gem supplies, then light. System leaves the page
76
80
  to follow the operating system. Custom marks the page for a palette another
77
81
  gem defines. The theme toggle does not offer it, so a page reaches it when
78
- another gem supplies it.
82
+ another gem supplies it. On a Turbo visit, the page being shown sets the
83
+ theme, so a change to the mode on the server shows up without a full reload.
84
+ Marking the layout with the theme is set up through
85
+ the install local, and placing the toggle on a screen goes through the develop
86
+ local.
79
87
  - **Tailwind classes are static strings.** Class names are never interpolated,
80
88
  so Tailwind's scanner can find them. Widths and heights that depend on data,
81
89
  such as a progress bar or a bucket's fill, are set with an inline style
@@ -24,6 +24,11 @@ built on ViewComponent; hook it in before building any screen with those helpers
24
24
  custom mode),
25
25
  and the `tailwind_imports` and `tailwind_sources` lists (extra CSS files and
26
26
  scan paths added to the Tailwind build).
27
+ - `keystone_theme_attributes` — a layout helper placed inside the `<html>` tag.
28
+ It writes `data-theme="light"`, `data-theme="dark"` or `data-theme="custom"`
29
+ for the page's mode, and writes nothing for system so the page follows the
30
+ operating system. The mode is the `keystone_theme` cookie's choice, then the
31
+ configured `theme_mode_supplier`, then light.
27
32
 
28
33
  ## How to use it
29
34
 
@@ -61,8 +66,9 @@ built on ViewComponent; hook it in before building any screen with those helpers
61
66
  `import { registerControllers } from "keystone_ui/index"` and
62
67
  `registerControllers(application)`.
63
68
  - `app/views/layouts/application.html.erb` — adds
64
- `<%= keystone_theme_attributes %>` inside the `<html` tag, which writes the
65
- light, dark or custom mode onto the page.
69
+ `<%= keystone_theme_attributes %>` directly after the first `<html` in the
70
+ file, so the tag reads `<html <%= keystone_theme_attributes %> ...>`. A
71
+ layout that already contains the call is left unchanged.
66
72
 
67
73
  Read its output for two warnings:
68
74
 
@@ -70,6 +76,9 @@ built on ViewComponent; hook it in before building any screen with those helpers
70
76
  the Stimulus application is set up and add those two lines there. Without
71
77
  them, dropdowns, modals, file uploads, the column picker, the theme toggle
72
78
  and the other interactive components do nothing.
79
+ `registerControllers(application)` also copies `data-theme` from each page
80
+ Turbo renders onto the `<html>` tag. Without it, a Turbo visit keeps the
81
+ theme of the first page loaded.
73
82
  - `app/views/layouts/application.html.erb not found` — ask the developer which
74
83
  layout the app renders and add `<%= keystone_theme_attributes %>` to its
75
84
  `<html>` tag. Without it, a saved light or dark choice is not applied when
@@ -3,6 +3,7 @@ scope: UI — pages, forms, tables, navigation, dashboards
3
3
  install:
4
4
  - bin/rails generate keystone:install
5
5
  - KeystoneUi.configure
6
+ - keystone_theme_attributes
6
7
 
7
8
  develop:
8
9
  - ui_accordion
@@ -56,11 +57,13 @@ develop:
56
57
  - ui_pipeline
57
58
  - ui_code
58
59
  - ui_disclosure
60
+ - ui_theme_toggle
59
61
  - Keystone::Ui::Column
60
62
 
61
63
  sources:
62
64
  - lib/generators/keystone/install_generator.rb
63
65
  - lib/keystone_ui/configuration.rb
66
+ - lib/keystone_ui/theme_choice.rb
64
67
  - app/helpers/keystone_ui_helper.rb
65
68
  - app/components/keystone/ui/accordion_component.rb
66
69
  - app/components/keystone/ui/alert_component.rb
@@ -105,6 +108,7 @@ sources:
105
108
  - app/components/keystone/ui/page_header_component.rb
106
109
  - app/components/keystone/ui/panel_component.rb
107
110
  - app/components/keystone/ui/pipeline_component.rb
111
+ - app/components/keystone/ui/theme_toggle_component.rb
108
112
  - app/components/keystone/ui/progress_component.rb
109
113
  - app/components/keystone/ui/radio_card_component.rb
110
114
  - app/components/keystone/ui/section_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.15.0
4
+ version: 0.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Schneider
@@ -64,6 +64,7 @@ files:
64
64
  - app/assets/javascripts/keystone_ui/line_chart_controller.js
65
65
  - app/assets/javascripts/keystone_ui/modal_controller.js
66
66
  - app/assets/javascripts/keystone_ui/multi_select_controller.js
67
+ - app/assets/javascripts/keystone_ui/page_theme.js
67
68
  - app/assets/javascripts/keystone_ui/stat_card_info_controller.js
68
69
  - app/assets/javascripts/keystone_ui/swipe_deck_controller.js
69
70
  - app/assets/javascripts/keystone_ui/tab_switcher_controller.js