keystone_ui 0.7.0 → 0.8.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/assets/javascripts/keystone_ui/index.js +2 -0
- data/app/assets/javascripts/keystone_ui/theme_toggle_controller.js +25 -0
- data/app/components/keystone/ui/button_component.rb +7 -7
- data/app/components/keystone/ui/form_field_component.html.erb +1 -1
- data/app/components/keystone/ui/form_field_component.rb +5 -5
- data/app/components/keystone/ui/input_component.rb +3 -5
- data/app/components/keystone/ui/panel_component.rb +1 -1
- data/app/components/keystone/ui/select_component.rb +3 -5
- data/app/components/keystone/ui/textarea_component.rb +3 -5
- data/app/components/keystone/ui/theme_toggle_component.html.erb +10 -0
- data/app/components/keystone/ui/theme_toggle_component.rb +23 -0
- data/app/helpers/keystone_ui_helper.rb +8 -0
- data/config/importmap.rb +1 -0
- data/lib/generators/keystone/install_generator.rb +25 -0
- data/lib/generators/keystone/layout_theme_attributes.rb +17 -0
- data/lib/keystone_ui/engine.rb +3 -15
- data/lib/keystone_ui/safelist.rb +2 -1
- data/lib/keystone_ui/source_css.rb +31 -0
- data/lib/keystone_ui/theme_choice.rb +20 -0
- data/lib/keystone_ui/version.rb +1 -1
- data/lib/keystone_ui.rb +2 -0
- metadata +22 -3
- data/app/assets/tailwind/keystone_ui_engine/theme.css +0 -32
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9007e4cf813a277f78f01bdf10df84d28856a5eaf1e7460c51e77db5d8b13143
|
|
4
|
+
data.tar.gz: a31771c5217f422c78000dc895be2314e9ecac0de206155f3d3a123b3da362af
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d5649e25777890bf3bd01be1f42260c92038b66cef09c71f1b6e4655658f6d602102d0adcef0bd4b063edb837490818df7734c84b3f0e0198e2a859a83b2ea10
|
|
7
|
+
data.tar.gz: 52bce90d7e68c9ead4e459f71376c16257b235b1418ef92c156bd8d7fb1bd2b33a17cf7111bcb0412d19d79e6ad0626ce8d2aa72db8fe00988fbaae41705151d
|
|
@@ -12,6 +12,7 @@ import AccordionController from "keystone_ui/accordion_controller"
|
|
|
12
12
|
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
|
+
import ThemeToggleController from "keystone_ui/theme_toggle_controller"
|
|
15
16
|
|
|
16
17
|
export function registerControllers(application) {
|
|
17
18
|
application.register("color-picker", ColorPickerController)
|
|
@@ -28,6 +29,7 @@ export function registerControllers(application) {
|
|
|
28
29
|
application.register("stat-card-info", StatCardInfoController)
|
|
29
30
|
application.register("auto-submit", AutoSubmitController)
|
|
30
31
|
application.register("line-chart", LineChartController)
|
|
32
|
+
application.register("theme-toggle", ThemeToggleController)
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
export { ColorPickerController, MultiSelectController, SwipeDeckController, ColumnPickerController, FileUploadController, DropdownController, DismissController, ModalController, ClipboardController, TabSwitcherController, AccordionController, StatCardInfoController, AutoSubmitController, LineChartController }
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
|
2
|
+
|
|
3
|
+
const COOKIE = "keystone_theme"
|
|
4
|
+
const ONE_YEAR = 60 * 60 * 24 * 365
|
|
5
|
+
|
|
6
|
+
export default class extends Controller {
|
|
7
|
+
choose({ params: { mode } }) {
|
|
8
|
+
const page = this.element.ownerDocument
|
|
9
|
+
this.#showPressed(mode)
|
|
10
|
+
|
|
11
|
+
if (mode === "system") {
|
|
12
|
+
delete page.documentElement.dataset.theme
|
|
13
|
+
page.cookie = `${COOKIE}=; path=/; max-age=0; samesite=lax`
|
|
14
|
+
} else {
|
|
15
|
+
page.documentElement.dataset.theme = mode
|
|
16
|
+
page.cookie = `${COOKIE}=${mode}; path=/; max-age=${ONE_YEAR}; samesite=lax`
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
#showPressed(mode) {
|
|
21
|
+
this.element.querySelectorAll("[data-theme-toggle-mode-param]").forEach((option) => {
|
|
22
|
+
option.setAttribute("aria-pressed", String(option.dataset.themeToggleModeParam === mode))
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
module Keystone
|
|
4
4
|
module Ui
|
|
5
5
|
class ButtonComponent < ViewComponent::Base
|
|
6
|
-
BASE_CLASSES = "
|
|
6
|
+
BASE_CLASSES = "ks-button"
|
|
7
7
|
|
|
8
8
|
VARIANT_CLASSES = {
|
|
9
|
-
secondary: "
|
|
10
|
-
danger: "
|
|
9
|
+
secondary: "ks-button-secondary",
|
|
10
|
+
danger: "ks-button-danger"
|
|
11
11
|
}.freeze
|
|
12
12
|
|
|
13
13
|
SIZE_CLASSES = {
|
|
14
|
-
sm: "
|
|
15
|
-
md: "
|
|
16
|
-
lg: "
|
|
14
|
+
sm: "ks-button-sm",
|
|
15
|
+
md: "ks-button-md",
|
|
16
|
+
lg: "ks-button-lg"
|
|
17
17
|
}.freeze
|
|
18
18
|
|
|
19
19
|
def initialize(label:, href: nil, variant: :primary, size: :md, type: :submit, data: nil)
|
|
@@ -27,7 +27,7 @@ module Keystone
|
|
|
27
27
|
|
|
28
28
|
def classes
|
|
29
29
|
variant_css = if @variant == :primary
|
|
30
|
-
"
|
|
30
|
+
"ks-button-primary"
|
|
31
31
|
else
|
|
32
32
|
VARIANT_CLASSES.fetch(@variant)
|
|
33
33
|
end
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<% elsif textarea? %>
|
|
15
15
|
<textarea name="<%= @attribute %>" rows="3" class="<%= Keystone::Ui::TextareaComponent::BASE_CLASSES %>"<% if @placeholder %> placeholder="<%= @placeholder %>"<% end %>><%= @value %></textarea>
|
|
16
16
|
<% elsif select? %>
|
|
17
|
-
<select name="<%= @attribute %>" class="<%= Keystone::Ui::SelectComponent::BASE_CLASSES %>
|
|
17
|
+
<select name="<%= @attribute %>" class="<%= Keystone::Ui::SelectComponent::BASE_CLASSES %>">
|
|
18
18
|
<% unless required? %><option value=""></option><% end %>
|
|
19
19
|
<% select_options.each do |label, value| %>
|
|
20
20
|
<option value="<%= value %>" <%= "selected" if @value.to_s == value.to_s %>><%= label %></option>
|
|
@@ -4,11 +4,11 @@ module Keystone
|
|
|
4
4
|
module Ui
|
|
5
5
|
class FormFieldComponent < ViewComponent::Base
|
|
6
6
|
WRAPPER_CLASSES = "space-y-1"
|
|
7
|
-
LABEL_CLASSES = "
|
|
8
|
-
REQUIRED_CLASSES = "
|
|
9
|
-
HINT_CLASSES = "
|
|
10
|
-
ERROR_CLASSES = "
|
|
11
|
-
CHECKBOX_CLASSES = "
|
|
7
|
+
LABEL_CLASSES = "ks-label"
|
|
8
|
+
REQUIRED_CLASSES = "ks-required"
|
|
9
|
+
HINT_CLASSES = "ks-hint"
|
|
10
|
+
ERROR_CLASSES = "ks-error"
|
|
11
|
+
CHECKBOX_CLASSES = "ks-checkbox"
|
|
12
12
|
CHECKBOX_WRAPPER_CLASSES = "flex items-center gap-2"
|
|
13
13
|
|
|
14
14
|
def initialize(attribute:, label: nil, type: :text, required: false, hint: nil, placeholder: nil, min: nil, max: nil, step: nil, value: nil, options: [], errors: [])
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
module Keystone
|
|
4
4
|
module Ui
|
|
5
5
|
class InputComponent < ViewComponent::Base
|
|
6
|
-
BASE_CLASSES = "
|
|
6
|
+
BASE_CLASSES = "ks-input"
|
|
7
7
|
|
|
8
|
-
DISABLED_CLASSES = "
|
|
8
|
+
DISABLED_CLASSES = "ks-input-disabled"
|
|
9
9
|
|
|
10
10
|
TYPE_MAP = {
|
|
11
11
|
text: "text",
|
|
@@ -26,10 +26,8 @@ module Keystone
|
|
|
26
26
|
@step = step
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
FOCUS_CLASSES = "focus:border-accent-500 focus:ring-accent-500 dark:focus:border-accent-400 dark:focus:ring-accent-400"
|
|
30
|
-
|
|
31
29
|
def classes
|
|
32
|
-
tokens = [ BASE_CLASSES
|
|
30
|
+
tokens = [ BASE_CLASSES ]
|
|
33
31
|
tokens << DISABLED_CLASSES if @disabled
|
|
34
32
|
tokens.join(" ")
|
|
35
33
|
end
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
module Keystone
|
|
4
4
|
module Ui
|
|
5
5
|
class SelectComponent < ViewComponent::Base
|
|
6
|
-
BASE_CLASSES = "
|
|
6
|
+
BASE_CLASSES = "ks-input"
|
|
7
7
|
|
|
8
|
-
DISABLED_CLASSES = "
|
|
8
|
+
DISABLED_CLASSES = "ks-input-disabled"
|
|
9
9
|
|
|
10
10
|
attr_reader :options, :selected, :include_blank
|
|
11
11
|
|
|
@@ -17,10 +17,8 @@ module Keystone
|
|
|
17
17
|
@disabled = disabled
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
FOCUS_CLASSES = "focus:border-accent-500 focus:ring-accent-500 dark:focus:border-accent-400 dark:focus:ring-accent-400"
|
|
21
|
-
|
|
22
20
|
def classes
|
|
23
|
-
tokens = [ BASE_CLASSES
|
|
21
|
+
tokens = [ BASE_CLASSES ]
|
|
24
22
|
tokens << DISABLED_CLASSES if @disabled
|
|
25
23
|
tokens.join(" ")
|
|
26
24
|
end
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
module Keystone
|
|
4
4
|
module Ui
|
|
5
5
|
class TextareaComponent < ViewComponent::Base
|
|
6
|
-
BASE_CLASSES = "
|
|
6
|
+
BASE_CLASSES = "ks-input"
|
|
7
7
|
|
|
8
|
-
DISABLED_CLASSES = "
|
|
8
|
+
DISABLED_CLASSES = "ks-input-disabled"
|
|
9
9
|
|
|
10
10
|
def initialize(name:, value: nil, rows: 3, placeholder: nil, disabled: false)
|
|
11
11
|
@name = name
|
|
@@ -15,10 +15,8 @@ module Keystone
|
|
|
15
15
|
@disabled = disabled
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
FOCUS_CLASSES = "focus:border-accent-500 focus:ring-accent-500 dark:focus:border-accent-400 dark:focus:ring-accent-400"
|
|
19
|
-
|
|
20
18
|
def classes
|
|
21
|
-
tokens = [ BASE_CLASSES
|
|
19
|
+
tokens = [ BASE_CLASSES ]
|
|
22
20
|
tokens << DISABLED_CLASSES if @disabled
|
|
23
21
|
tokens.join(" ")
|
|
24
22
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<div class="<%= GROUP_CLASSES %>" role="group" aria-label="Theme" data-controller="theme-toggle">
|
|
2
|
+
<% options.each do |label, mode| %>
|
|
3
|
+
<button
|
|
4
|
+
type="button"
|
|
5
|
+
class="<%= OPTION_CLASSES %>"
|
|
6
|
+
aria-pressed="<%= pressed?(mode) %>"
|
|
7
|
+
data-action="theme-toggle#choose"
|
|
8
|
+
data-theme-toggle-mode-param="<%= mode %>"><%= label %></button>
|
|
9
|
+
<% end %>
|
|
10
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Keystone
|
|
4
|
+
module Ui
|
|
5
|
+
class ThemeToggleComponent < ViewComponent::Base
|
|
6
|
+
OPTIONS = [ [ "Light", "light" ], [ "Dark", "dark" ], [ "System", "system" ] ].freeze
|
|
7
|
+
GROUP_CLASSES = "inline-flex gap-1"
|
|
8
|
+
OPTION_CLASSES = "ks-button ks-button-sm ks-button-secondary aria-pressed:bg-accent-600 aria-pressed:hover:bg-accent-500"
|
|
9
|
+
|
|
10
|
+
def initialize(current: nil)
|
|
11
|
+
@current = current
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def options
|
|
15
|
+
OPTIONS
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def pressed?(mode)
|
|
19
|
+
mode == (KeystoneUi::ThemeChoice::MODES.include?(@current) ? @current : "system")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -41,6 +41,14 @@ module KeystoneUiHelper
|
|
|
41
41
|
render Keystone::Ui::BadgeComponent.new(**args)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def ui_theme_toggle
|
|
45
|
+
render Keystone::Ui::ThemeToggleComponent.new(current: cookies[KeystoneUi::ThemeChoice::COOKIE])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def keystone_theme_attributes
|
|
49
|
+
KeystoneUi::ThemeChoice.new(cookies[KeystoneUi::ThemeChoice::COOKIE]).html_attributes_markup.html_safe
|
|
50
|
+
end
|
|
51
|
+
|
|
44
52
|
def ui_copy_button(**args)
|
|
45
53
|
render Keystone::Ui::CopyButtonComponent.new(**args)
|
|
46
54
|
end
|
data/config/importmap.rb
CHANGED
|
@@ -13,6 +13,7 @@ pin "keystone_ui/accordion_controller", to: "keystone_ui/accordion_controller.js
|
|
|
13
13
|
pin "keystone_ui/stat_card_info_controller", to: "keystone_ui/stat_card_info_controller.js"
|
|
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
|
+
pin "keystone_ui/theme_toggle_controller", to: "keystone_ui/theme_toggle_controller.js"
|
|
16
17
|
|
|
17
18
|
# Chart.js for the line-chart controller, so host apps don't pin it themselves.
|
|
18
19
|
# Vendored as a single self-contained bundle (deps inlined, no external imports).
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "layout_theme_attributes"
|
|
4
|
+
|
|
3
5
|
module Keystone
|
|
4
6
|
class InstallGenerator < Rails::Generators::Base
|
|
5
7
|
desc "Set up Keystone UI in your Rails application"
|
|
@@ -11,6 +13,8 @@ module Keystone
|
|
|
11
13
|
JS_IMPORT = 'import { registerControllers } from "keystone_ui/index"'
|
|
12
14
|
JS_REGISTER = "registerControllers(application)"
|
|
13
15
|
|
|
16
|
+
LAYOUT_PATH = "app/views/layouts/application.html.erb"
|
|
17
|
+
|
|
14
18
|
def setup_tailwind
|
|
15
19
|
say ""
|
|
16
20
|
say "Keystone UI — setup", :green
|
|
@@ -86,5 +90,26 @@ module Keystone
|
|
|
86
90
|
append_to_file js_path, "\n#{JS_IMPORT}\n#{JS_REGISTER}\n"
|
|
87
91
|
say " ✔ Registered Keystone UI controllers", :green
|
|
88
92
|
end
|
|
93
|
+
|
|
94
|
+
def setup_theme
|
|
95
|
+
say ""
|
|
96
|
+
say "Wiring the Keystone UI theme toggle...", :green
|
|
97
|
+
|
|
98
|
+
layout_path = Rails.root.join(LAYOUT_PATH)
|
|
99
|
+
unless layout_path.exist?
|
|
100
|
+
say " ⚠ #{LAYOUT_PATH} not found — add `<%= keystone_theme_attributes %>` to your <html> tag manually.", :yellow
|
|
101
|
+
return
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
layout = layout_path.read
|
|
105
|
+
updated = Keystone::LayoutThemeAttributes.new(layout).apply
|
|
106
|
+
|
|
107
|
+
if updated == layout
|
|
108
|
+
say " ✔ Layout already marks the theme", :green
|
|
109
|
+
else
|
|
110
|
+
File.write(layout_path, updated)
|
|
111
|
+
say " ✔ Added the theme attributes to the layout's html tag", :green
|
|
112
|
+
end
|
|
113
|
+
end
|
|
89
114
|
end
|
|
90
115
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Keystone
|
|
4
|
+
class LayoutThemeAttributes
|
|
5
|
+
HELPER_CALL = "<%= keystone_theme_attributes %>"
|
|
6
|
+
|
|
7
|
+
def initialize(layout)
|
|
8
|
+
@layout = layout
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def apply
|
|
12
|
+
return @layout if @layout.include?(HELPER_CALL)
|
|
13
|
+
|
|
14
|
+
@layout.sub(/<html\b/, "<html #{HELPER_CALL}")
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/keystone_ui/engine.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "keystone_ui/source_css"
|
|
4
|
+
|
|
3
5
|
module KeystoneUi
|
|
4
6
|
class Engine < ::Rails::Engine
|
|
5
7
|
config.autoload_paths << root.join("app/components")
|
|
@@ -27,21 +29,7 @@ module KeystoneUi
|
|
|
27
29
|
keystone_import = '@import "./keystone_source.css";'
|
|
28
30
|
next unless css_path.read.include?(keystone_import)
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
lines = [ %(@source "#{root}/app/components/**/*.{erb,rb}";) ]
|
|
32
|
-
|
|
33
|
-
# Import theme CSS (accent + surface custom property defaults)
|
|
34
|
-
theme_css = root.join("app/assets/tailwind/keystone_ui_engine/theme.css")
|
|
35
|
-
lines << %(@import "#{theme_css}";) if theme_css.exist?
|
|
36
|
-
|
|
37
|
-
# Import component CSS files shipped with the gem
|
|
38
|
-
nav_css = root.join("app/assets/tailwind/keystone_ui_engine/nav.css")
|
|
39
|
-
lines << %(@import "#{nav_css}";) if nav_css.exist?
|
|
40
|
-
|
|
41
|
-
color_picker_css = root.join("app/assets/tailwind/keystone_ui_engine/color_picker.css")
|
|
42
|
-
lines << %(@import "#{color_picker_css}";) if color_picker_css.exist?
|
|
43
|
-
|
|
44
|
-
source_css.write(lines.join("\n") + "\n")
|
|
32
|
+
tailwind_dir.join("keystone_source.css").write(KeystoneUi::SourceCss.new(root).to_s)
|
|
45
33
|
end
|
|
46
34
|
end
|
|
47
35
|
end
|
data/lib/keystone_ui/safelist.rb
CHANGED
|
@@ -52,7 +52,8 @@ module Keystone
|
|
|
52
52
|
Keystone::Ui::FunnelComponent,
|
|
53
53
|
Keystone::Ui::PipelineComponent,
|
|
54
54
|
Keystone::Ui::CodeComponent,
|
|
55
|
-
Keystone::Ui::DisclosureComponent
|
|
55
|
+
Keystone::Ui::DisclosureComponent,
|
|
56
|
+
Keystone::Ui::ThemeToggleComponent
|
|
56
57
|
].freeze
|
|
57
58
|
|
|
58
59
|
# Constants that hold non-CSS values (e.g. HTML input type maps)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pathname"
|
|
4
|
+
require "keystone_ui/styles"
|
|
5
|
+
|
|
6
|
+
module KeystoneUi
|
|
7
|
+
class SourceCss
|
|
8
|
+
def initialize(root)
|
|
9
|
+
@root = Pathname.new(root)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_s
|
|
13
|
+
lines.join("\n") + "\n"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def styles_entry
|
|
19
|
+
KeystoneUi::Styles::Engine.root.join("app/assets/tailwind/keystone_ui_styles/engine.css")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def lines
|
|
23
|
+
[
|
|
24
|
+
%(@import "#{styles_entry}";),
|
|
25
|
+
%(@source "#{@root}/app/components/**/*.{erb,rb}";),
|
|
26
|
+
%(@import "#{@root}/app/assets/tailwind/keystone_ui_engine/nav.css";),
|
|
27
|
+
%(@import "#{@root}/app/assets/tailwind/keystone_ui_engine/color_picker.css";)
|
|
28
|
+
]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KeystoneUi
|
|
4
|
+
class ThemeChoice
|
|
5
|
+
COOKIE = "keystone_theme"
|
|
6
|
+
MODES = %w[light dark].freeze
|
|
7
|
+
|
|
8
|
+
def initialize(mode)
|
|
9
|
+
@mode = mode
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def html_attributes
|
|
13
|
+
MODES.include?(@mode) ? { "data-theme" => @mode } : {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def html_attributes_markup
|
|
17
|
+
html_attributes.map { |name, value| %(#{name}="#{value}") }.join(" ")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/keystone_ui/version.rb
CHANGED
data/lib/keystone_ui.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: keystone_ui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tyler Schneider
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: keystone_ui-styles
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.1.0
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 0.1.0
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: view_component
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -54,10 +68,10 @@ files:
|
|
|
54
68
|
- app/assets/javascripts/keystone_ui/stat_card_info_controller.js
|
|
55
69
|
- app/assets/javascripts/keystone_ui/swipe_deck_controller.js
|
|
56
70
|
- app/assets/javascripts/keystone_ui/tab_switcher_controller.js
|
|
71
|
+
- app/assets/javascripts/keystone_ui/theme_toggle_controller.js
|
|
57
72
|
- app/assets/tailwind/keystone_ui_engine/color_picker.css
|
|
58
73
|
- app/assets/tailwind/keystone_ui_engine/engine.css
|
|
59
74
|
- app/assets/tailwind/keystone_ui_engine/nav.css
|
|
60
|
-
- app/assets/tailwind/keystone_ui_engine/theme.css
|
|
61
75
|
- app/components/keystone/ui/accordion_component.html.erb
|
|
62
76
|
- app/components/keystone/ui/accordion_component.rb
|
|
63
77
|
- app/components/keystone/ui/alert_component.html.erb
|
|
@@ -155,13 +169,18 @@ files:
|
|
|
155
169
|
- app/components/keystone/ui/tab_switcher_component.rb
|
|
156
170
|
- app/components/keystone/ui/textarea_component.html.erb
|
|
157
171
|
- app/components/keystone/ui/textarea_component.rb
|
|
172
|
+
- app/components/keystone/ui/theme_toggle_component.html.erb
|
|
173
|
+
- app/components/keystone/ui/theme_toggle_component.rb
|
|
158
174
|
- app/helpers/keystone_ui_helper.rb
|
|
159
175
|
- config/importmap.rb
|
|
160
176
|
- lib/generators/keystone/install_generator.rb
|
|
177
|
+
- lib/generators/keystone/layout_theme_attributes.rb
|
|
161
178
|
- lib/keystone_ui.rb
|
|
162
179
|
- lib/keystone_ui/configuration.rb
|
|
163
180
|
- lib/keystone_ui/engine.rb
|
|
164
181
|
- lib/keystone_ui/safelist.rb
|
|
182
|
+
- lib/keystone_ui/source_css.rb
|
|
183
|
+
- lib/keystone_ui/theme_choice.rb
|
|
165
184
|
- lib/keystone_ui/version.rb
|
|
166
185
|
- the_local/agents/keystone_ui-develop.md
|
|
167
186
|
- the_local/agents/keystone_ui-info.md
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/* Keystone UI theme — defines accent and surface color tokens as CSS custom properties.
|
|
2
|
-
Apps override these variables to customize the color palette. */
|
|
3
|
-
|
|
4
|
-
@theme {
|
|
5
|
-
/* Accent — defaults to blue */
|
|
6
|
-
--color-accent-50: #eff6ff;
|
|
7
|
-
--color-accent-100: #dbeafe;
|
|
8
|
-
--color-accent-200: #bfdbfe;
|
|
9
|
-
--color-accent-300: #93c5fd;
|
|
10
|
-
--color-accent-400: #60a5fa;
|
|
11
|
-
--color-accent-500: #3b82f6;
|
|
12
|
-
--color-accent-600: #2563eb;
|
|
13
|
-
--color-accent-700: #1d4ed8;
|
|
14
|
-
--color-accent-800: #1e40af;
|
|
15
|
-
--color-accent-900: #1e3a8a;
|
|
16
|
-
|
|
17
|
-
/* Surface — defaults to zinc */
|
|
18
|
-
--color-surface-50: #fafafa;
|
|
19
|
-
--color-surface-100: #f4f4f5;
|
|
20
|
-
--color-surface-200: #e4e4e7;
|
|
21
|
-
--color-surface-300: #d4d4d8;
|
|
22
|
-
--color-surface-400: #a1a1aa;
|
|
23
|
-
--color-surface-500: #71717a;
|
|
24
|
-
--color-surface-600: #52525b;
|
|
25
|
-
--color-surface-700: #3f3f46;
|
|
26
|
-
--color-surface-800: #27272a;
|
|
27
|
-
--color-surface-900: #18181b;
|
|
28
|
-
--color-surface-950: #09090b;
|
|
29
|
-
|
|
30
|
-
/* Accent — darkest shade */
|
|
31
|
-
--color-accent-950: #172554;
|
|
32
|
-
}
|