keystone_ui-colors 0.2.0 → 0.3.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/README.md +42 -12
- data/app/controllers/concerns/keystone_ui/colors/current_palette.rb +30 -11
- data/app/controllers/keystone_ui/colors/settings_controller.rb +9 -26
- data/app/javascript/keystone_ui/colors/theme_settings_controller.js +4 -1
- data/app/models/keystone_ui/colors/custom_colours.rb +26 -0
- data/app/models/keystone_ui/colors/forget_the_theme_choice.rb +15 -0
- data/app/models/keystone_ui/colors/kept.rb +11 -0
- data/app/models/keystone_ui/colors/pick_colours.rb +39 -0
- data/app/models/keystone_ui/colors/refusal.rb +15 -0
- data/app/models/keystone_ui/colors/theme_preference.rb +2 -1
- data/app/views/keystone_ui/colors/settings/_picker.html.erb +107 -0
- data/app/views/keystone_ui/colors/settings/show.html.erb +1 -93
- data/lib/generators/keystone_ui/colors/install/templates/create_keystone_ui_colors_theme_preferences.rb.erb +1 -0
- data/lib/generators/keystone_ui/colors/update/templates/add_text_to_keystone_ui_colors_theme_preferences.rb.erb +5 -0
- data/lib/generators/keystone_ui/colors/update/update_generator.rb +7 -0
- data/lib/keystone_ui/colors/configuration.rb +3 -1
- data/lib/keystone_ui/colors/engine.rb +4 -0
- data/lib/keystone_ui/colors/templates.rb +12 -0
- data/lib/keystone_ui/colors/version.rb +1 -1
- metadata +12 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 56e2aecbc1dd2315bbc0add8ae80c083a23e42aa0e59fd8b05828d9cd4f93860
|
|
4
|
+
data.tar.gz: 19f53163686417b9b497fa0ffb27bc69946d3b46a84fc0efb6961561a13b2706
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d85fa52f7c4552d4196bcf36d4bf517358f89adeb55bdcdd5fa8491629782a64945e0e15124eef204b9297ed3b2149831aeedf29f68586803a34c91bb49644c7
|
|
7
|
+
data.tar.gz: c4bcbef319b118827f8812c9c230761179817fd258582fa21356f1a611f832d89b3793a10f3105d748f805b60280856f683c54fdb0b0867fade78b799a80a2be
|
data/README.md
CHANGED
|
@@ -82,7 +82,9 @@ KeystoneUi::Colors.configure do |config|
|
|
|
82
82
|
config.default_template = :ocean # Fallback theme
|
|
83
83
|
config.default_accent = "blue" # Fallback accent color
|
|
84
84
|
config.default_surface = "zinc" # Fallback surface color
|
|
85
|
-
config.default_mode = "light" # Fallback theme mode: "light", "dark" or "
|
|
85
|
+
config.default_mode = "light" # Fallback theme mode: "light", "dark", "system" or "custom"
|
|
86
|
+
config.default_background = "#ffffff" # Custom mode background when nothing else sets one
|
|
87
|
+
config.default_text = "#18181b" # Custom mode text colour when nothing else sets one
|
|
86
88
|
config.layout = "application" # Layout for settings page
|
|
87
89
|
end
|
|
88
90
|
```
|
|
@@ -91,8 +93,8 @@ All values shown are defaults and can be omitted.
|
|
|
91
93
|
|
|
92
94
|
## Light and Dark Mode
|
|
93
95
|
|
|
94
|
-
Users choose Light, Dark or
|
|
95
|
-
with their palette. keystone_ui renders each page in, strongest first:
|
|
96
|
+
Users choose Light, Dark, System or Custom on the settings page, and the choice is
|
|
97
|
+
saved with their palette. keystone_ui renders each page in, strongest first:
|
|
96
98
|
|
|
97
99
|
1. The choice made with keystone_ui's `ui_theme_toggle` in this browser.
|
|
98
100
|
2. The mode the signed-in user saved.
|
|
@@ -102,16 +104,44 @@ Saving a mode on the settings page clears the toggle's choice in that browser, s
|
|
|
102
104
|
saved mode takes effect. Pages are marked through keystone_ui's
|
|
103
105
|
`keystone_theme_attributes` helper on the layout's `html` tag.
|
|
104
106
|
|
|
107
|
+
## Custom Mode
|
|
108
|
+
|
|
109
|
+
A page in Custom mode is drawn from a background colour and a text colour, which
|
|
110
|
+
the gem writes as `--color-custom-background` and `--color-custom-text` with the
|
|
111
|
+
rest of the palette. keystone_ui-styles draws white in the background and every
|
|
112
|
+
gray and zinc shade as a blend of the text into it.
|
|
113
|
+
|
|
114
|
+
- A preset theme supplies both colours.
|
|
115
|
+
- With custom colours, the surface colour the user picks is the background and
|
|
116
|
+
the Text Color picker sets the text.
|
|
117
|
+
- Anything not set falls back to `config.default_background` and
|
|
118
|
+
`config.default_text`.
|
|
119
|
+
|
|
120
|
+
## Keeping a Page on the Host's Colours
|
|
121
|
+
|
|
122
|
+
A controller that declares `keystone_host_colors` renders its pages in the host's
|
|
123
|
+
configured accent, surface, custom colours and mode, whatever the signed-in user
|
|
124
|
+
saved. It takes the same `only:` and `except:` options as `before_action`.
|
|
125
|
+
|
|
126
|
+
```ruby
|
|
127
|
+
class HomeController < ApplicationController
|
|
128
|
+
keystone_host_colors
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
A choice made with keystone_ui's `ui_theme_toggle` in that browser still sets
|
|
133
|
+
light or dark on these pages.
|
|
134
|
+
|
|
105
135
|
## Preset Themes
|
|
106
136
|
|
|
107
|
-
| Name | Accent | Surface | Description |
|
|
108
|
-
|
|
109
|
-
| Default | *(configured)* | *(configured)* | Uses config defaults |
|
|
110
|
-
| Ocean | blue | slate | Cool blues with slate undertones |
|
|
111
|
-
| Forest | emerald | stone | Natural greens with warm stone |
|
|
112
|
-
| Twilight | violet | zinc | Deep violet with clean zinc |
|
|
113
|
-
| Coral | rose | neutral | Warm rose with neutral balance |
|
|
114
|
-
| Arctic | cyan | gray | Bright cyan with crisp gray |
|
|
137
|
+
| Name | Accent | Surface | Custom background | Custom text | Description |
|
|
138
|
+
|----------|---------|---------|-------------------|-------------|--------------------------------|
|
|
139
|
+
| Default | *(configured)* | *(configured)* | *(configured)* | *(configured)* | Uses config defaults |
|
|
140
|
+
| Ocean | blue | slate | `#e0f2fe` | `#0c4a6e` | Cool blues with slate undertones |
|
|
141
|
+
| Forest | emerald | stone | `#ecfdf5` | `#064e3b` | Natural greens with warm stone |
|
|
142
|
+
| Twilight | violet | zinc | `#1e1b4b` | `#ede9fe` | Deep violet with clean zinc |
|
|
143
|
+
| Coral | rose | neutral | `#fff1f2` | `#4c0519` | Warm rose with neutral balance |
|
|
144
|
+
| Arctic | cyan | gray | `#ecfeff` | `#164e63` | Bright cyan with crisp gray |
|
|
115
145
|
|
|
116
146
|
## Available Colors
|
|
117
147
|
|
|
@@ -187,7 +217,7 @@ Accepts named colors (`"blue"`) or hex values (`"#3b82f6"`) for `accent` and `su
|
|
|
187
217
|
|
|
188
218
|
## Updating
|
|
189
219
|
|
|
190
|
-
Run the update generator to get the latest Stimulus controller and any new migrations, then migrate:
|
|
220
|
+
Run the update generator to get the latest Stimulus controller and any new migrations (such as the text colour column), then migrate:
|
|
191
221
|
|
|
192
222
|
```bash
|
|
193
223
|
bin/rails generate keystone_ui:colors:update
|
|
@@ -11,23 +11,26 @@ module KeystoneUi
|
|
|
11
11
|
helper_method :keystone_palette_css, :keystone_theme_mode if respond_to?(:helper_method)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
class_methods do
|
|
15
|
+
def keystone_host_colors(**options)
|
|
16
|
+
before_action :apply_host_palette, **options
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
14
20
|
def set_current_palette
|
|
15
21
|
owner = send(KeystoneUi::Colors.configuration.current_owner_method)
|
|
16
22
|
|
|
17
|
-
unless owner
|
|
18
|
-
@keystone_theme_mode = KeystoneUi::Colors.configuration.default_mode
|
|
19
|
-
build_palette_css(
|
|
20
|
-
KeystoneUi::Colors.configuration.default_accent,
|
|
21
|
-
KeystoneUi::Colors.configuration.default_surface
|
|
22
|
-
)
|
|
23
|
-
return
|
|
24
|
-
end
|
|
23
|
+
return apply_host_palette unless owner
|
|
25
24
|
|
|
26
25
|
cached = session[:keystone_ui_colors_palette]
|
|
27
26
|
|
|
28
27
|
if cached && !stale_cache?(owner, cached)
|
|
29
28
|
@keystone_theme_mode = cached[:mode] || KeystoneUi::Colors.configuration.default_mode
|
|
30
|
-
build_palette_css(
|
|
29
|
+
build_palette_css(
|
|
30
|
+
cached[:accent],
|
|
31
|
+
cached[:surface],
|
|
32
|
+
KeystoneUi::Colors::CustomColours.new(template_name: cached[:template_name], surface: cached[:surface], text: cached[:text])
|
|
33
|
+
)
|
|
31
34
|
return
|
|
32
35
|
end
|
|
33
36
|
|
|
@@ -36,18 +39,30 @@ module KeystoneUi
|
|
|
36
39
|
accent = preference&.accent || KeystoneUi::Colors.configuration.default_accent
|
|
37
40
|
surface = preference&.surface || KeystoneUi::Colors.configuration.default_surface
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
custom = KeystoneUi::Colors::CustomColours.new(template_name: preference&.template_name, surface: surface, text: preference&.text)
|
|
43
|
+
build_palette_css(accent, surface, custom)
|
|
40
44
|
|
|
41
45
|
if preference
|
|
42
46
|
session[:keystone_ui_colors_palette] = {
|
|
43
47
|
accent: preference.accent,
|
|
44
48
|
surface: preference.surface,
|
|
45
49
|
mode: preference.mode,
|
|
50
|
+
template_name: preference.template_name,
|
|
51
|
+
text: preference.text,
|
|
46
52
|
updated_at: preference.updated_at.to_i
|
|
47
53
|
}
|
|
48
54
|
end
|
|
49
55
|
end
|
|
50
56
|
|
|
57
|
+
def apply_host_palette
|
|
58
|
+
@keystone_theme_mode = KeystoneUi::Colors.configuration.default_mode
|
|
59
|
+
build_palette_css(
|
|
60
|
+
KeystoneUi::Colors.configuration.default_accent,
|
|
61
|
+
KeystoneUi::Colors.configuration.default_surface,
|
|
62
|
+
KeystoneUi::Colors::CustomColours.new(template_name: nil, surface: nil, text: nil)
|
|
63
|
+
)
|
|
64
|
+
end
|
|
65
|
+
|
|
51
66
|
def keystone_palette_css
|
|
52
67
|
@keystone_palette_css
|
|
53
68
|
end
|
|
@@ -58,13 +73,15 @@ module KeystoneUi
|
|
|
58
73
|
|
|
59
74
|
private
|
|
60
75
|
|
|
61
|
-
def build_palette_css(accent, surface)
|
|
76
|
+
def build_palette_css(accent, surface, custom = nil)
|
|
62
77
|
accent_shades = resolve_shades(accent, :accent)
|
|
63
78
|
surface_shades = resolve_shades(surface, :surface)
|
|
64
79
|
|
|
65
80
|
lines = []
|
|
66
81
|
accent_shades.each { |shade, hex| lines << " --color-accent-#{shade}: #{hex};" }
|
|
67
82
|
surface_shades.each { |shade, hex| lines << " --color-surface-#{shade}: #{hex};" }
|
|
83
|
+
lines << " --color-custom-background: #{custom.background};" if custom
|
|
84
|
+
lines << " --color-custom-text: #{custom.text};" if custom
|
|
68
85
|
|
|
69
86
|
@keystone_palette_css = ":root {\n#{lines.join("\n")}\n}"
|
|
70
87
|
end
|
|
@@ -78,6 +95,8 @@ module KeystoneUi
|
|
|
78
95
|
end
|
|
79
96
|
|
|
80
97
|
def stale_cache?(owner, cached)
|
|
98
|
+
return true unless cached.key?(:text)
|
|
99
|
+
|
|
81
100
|
updated_at = KeystoneUi::Colors::ThemePreference
|
|
82
101
|
.where(owner: owner)
|
|
83
102
|
.pick(:updated_at)
|
|
@@ -4,7 +4,6 @@ module KeystoneUi
|
|
|
4
4
|
module Colors
|
|
5
5
|
class SettingsController < ApplicationController
|
|
6
6
|
def show
|
|
7
|
-
@preference = theme_preference
|
|
8
7
|
end
|
|
9
8
|
|
|
10
9
|
def destroy
|
|
@@ -13,40 +12,24 @@ module KeystoneUi
|
|
|
13
12
|
end
|
|
14
13
|
|
|
15
14
|
def update
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
surface: template[:surface].to_s,
|
|
23
|
-
template_name: preference_params[:template_name],
|
|
24
|
-
mode: preference_params[:mode]
|
|
25
|
-
)
|
|
26
|
-
else
|
|
27
|
-
@preference.assign_attributes(preference_params)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
if @preference.save
|
|
31
|
-
cookies.delete(KeystoneUi::ThemeChoice::COOKIE)
|
|
32
|
-
redirect_to keystone_ui_colors.settings_path, notice: "Color settings updated."
|
|
33
|
-
else
|
|
34
|
-
render :show, status: :unprocessable_entity
|
|
35
|
-
end
|
|
15
|
+
result = PickColours.new(person: current_owner, account: nil, values: preference_params).call
|
|
16
|
+
|
|
17
|
+
return render :show, status: :unprocessable_entity unless result.ok?
|
|
18
|
+
|
|
19
|
+
ForgetTheThemeChoice.new(controller: self).call
|
|
20
|
+
redirect_to keystone_ui_colors.settings_path, notice: "Color settings updated."
|
|
36
21
|
end
|
|
37
22
|
|
|
38
23
|
private
|
|
39
24
|
|
|
25
|
+
helper_method :current_owner
|
|
26
|
+
|
|
40
27
|
def current_owner
|
|
41
28
|
send(KeystoneUi::Colors.configuration.current_owner_method)
|
|
42
29
|
end
|
|
43
30
|
|
|
44
|
-
def theme_preference
|
|
45
|
-
ThemePreference.find_or_initialize_by(owner: current_owner)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
31
|
def preference_params
|
|
49
|
-
params.
|
|
32
|
+
params.permit(:accent, :surface, :text, :template_name, :mode).to_h.symbolize_keys
|
|
50
33
|
end
|
|
51
34
|
end
|
|
52
35
|
end
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Controller } from "@hotwired/stimulus"
|
|
2
2
|
|
|
3
3
|
export default class extends Controller {
|
|
4
|
-
static targets = ["accentPicker", "surfacePicker", "customRadio", "templateLabel"]
|
|
4
|
+
static targets = ["accentPicker", "surfacePicker", "textPicker", "customRadio", "templateLabel"]
|
|
5
5
|
|
|
6
6
|
connect() {
|
|
7
7
|
this.accentPickerTarget.addEventListener("change", () => this.customColorChanged())
|
|
8
8
|
this.surfacePickerTarget.addEventListener("change", () => this.customColorChanged())
|
|
9
|
+
this.textPickerTarget.addEventListener("change", () => this.customColorChanged())
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
selectTemplate(event) {
|
|
@@ -13,9 +14,11 @@ export default class extends Controller {
|
|
|
13
14
|
const label = input.closest("[data-template]")
|
|
14
15
|
const accentHex = input.dataset.accentHex
|
|
15
16
|
const surfaceHex = input.dataset.surfaceHex
|
|
17
|
+
const textHex = input.dataset.textHex
|
|
16
18
|
|
|
17
19
|
this.setPickerValue(this.accentPickerTarget, accentHex)
|
|
18
20
|
this.setPickerValue(this.surfacePickerTarget, surfaceHex)
|
|
21
|
+
this.setPickerValue(this.textPickerTarget, textHex)
|
|
19
22
|
|
|
20
23
|
this.highlightTemplate(label.dataset.template)
|
|
21
24
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KeystoneUi
|
|
4
|
+
module Colors
|
|
5
|
+
class CustomColours
|
|
6
|
+
def initialize(template_name:, surface:, text:)
|
|
7
|
+
@template_name = template_name
|
|
8
|
+
@surface = surface
|
|
9
|
+
@text = text
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def background
|
|
13
|
+
return Templates[@template_name][:background] if @template_name.present?
|
|
14
|
+
return @surface if @surface&.start_with?("#")
|
|
15
|
+
|
|
16
|
+
KeystoneUi::Colors.configuration.default_background
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def text
|
|
20
|
+
return Templates[@template_name][:text] if @template_name.present?
|
|
21
|
+
|
|
22
|
+
@text.presence || KeystoneUi::Colors.configuration.default_text
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KeystoneUi
|
|
4
|
+
module Colors
|
|
5
|
+
class ForgetTheThemeChoice
|
|
6
|
+
def initialize(controller:)
|
|
7
|
+
@controller = controller
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call
|
|
11
|
+
@controller.request.cookie_jar.delete(KeystoneUi::ThemeChoice::COOKIE)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KeystoneUi
|
|
4
|
+
module Colors
|
|
5
|
+
class PickColours
|
|
6
|
+
def initialize(values:, person: nil, account: nil, owner: nil)
|
|
7
|
+
@owner = person || owner
|
|
8
|
+
@account = account
|
|
9
|
+
@values = values
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call
|
|
13
|
+
preference.assign_attributes(chosen_colours)
|
|
14
|
+
|
|
15
|
+
return Refusal.new(preference.errors.full_messages.first) unless preference.save
|
|
16
|
+
|
|
17
|
+
Kept.new
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def preference
|
|
23
|
+
@preference ||= ThemePreference.find_or_initialize_by(owner: @owner)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def chosen_colours
|
|
27
|
+
return { accent: @values[:accent], surface: @values[:surface], text: @values[:text], mode: @values[:mode] }.compact if @values[:template_name].blank?
|
|
28
|
+
|
|
29
|
+
template = Templates[@values[:template_name]]
|
|
30
|
+
{
|
|
31
|
+
accent: template[:accent].to_s,
|
|
32
|
+
surface: template[:surface].to_s,
|
|
33
|
+
template_name: @values[:template_name],
|
|
34
|
+
mode: @values[:mode]
|
|
35
|
+
}.compact
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -13,12 +13,13 @@ module KeystoneUi
|
|
|
13
13
|
|
|
14
14
|
HEX_COLOR = /\A#[0-9a-fA-F]{6}\z/
|
|
15
15
|
|
|
16
|
-
MODES = %w[light dark system].freeze
|
|
16
|
+
MODES = %w[light dark system custom].freeze
|
|
17
17
|
|
|
18
18
|
validate :accent_is_valid
|
|
19
19
|
validate :surface_is_valid
|
|
20
20
|
validates :template_name, inclusion: { in: Templates.names.map(&:to_s) }, allow_blank: true
|
|
21
21
|
validates :mode, inclusion: { in: MODES }, allow_nil: true
|
|
22
|
+
validates :text, format: { with: HEX_COLOR }, allow_blank: true
|
|
22
23
|
|
|
23
24
|
def apply_template!(name)
|
|
24
25
|
template = Templates[name]
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<%
|
|
2
|
+
preference = KeystoneUi::Colors::ThemePreference.find_or_initialize_by(owner: person)
|
|
3
|
+
|
|
4
|
+
current_accent_hex = if preference.accent&.start_with?("#")
|
|
5
|
+
preference.accent
|
|
6
|
+
else
|
|
7
|
+
KeystoneUi::Colors::Palettes.accent(preference.accent || "blue")[500]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
current_surface_hex = if preference.surface&.start_with?("#")
|
|
11
|
+
preference.surface
|
|
12
|
+
else
|
|
13
|
+
KeystoneUi::Colors::Palettes.surface(preference.surface || "zinc")[500]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
current_text_hex = KeystoneUi::Colors::CustomColours.new(
|
|
17
|
+
template_name: preference.template_name,
|
|
18
|
+
surface: preference.surface,
|
|
19
|
+
text: preference.text
|
|
20
|
+
).text
|
|
21
|
+
|
|
22
|
+
selected_template = preference.template_name
|
|
23
|
+
custom_selected = preference.accent&.start_with?("#") || (selected_template.blank? && preference.persisted?)
|
|
24
|
+
%>
|
|
25
|
+
|
|
26
|
+
<%= ui_panel(padding: :lg) do %>
|
|
27
|
+
<%= form_with(
|
|
28
|
+
url: submit_url,
|
|
29
|
+
method: :patch,
|
|
30
|
+
data: { turbo: false, controller: "keystone-ui--colors--theme-settings", selected_template: selected_template }
|
|
31
|
+
) do |form| %>
|
|
32
|
+
<div style="display: flex; flex-direction: column; gap: 2rem;">
|
|
33
|
+
<%= ui_section(title: "Theme", spacing: :sm) do %>
|
|
34
|
+
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
|
|
35
|
+
<% KeystoneUi::Colors::Templates.names.each do |name| %>
|
|
36
|
+
<% template = KeystoneUi::Colors::Templates[name] %>
|
|
37
|
+
<% accent_hex = KeystoneUi::Colors::Palettes.accent(template[:accent])[500] %>
|
|
38
|
+
<% surface_hex = KeystoneUi::Colors::Palettes.surface(template[:surface])[500] %>
|
|
39
|
+
<%= ui_option_card(
|
|
40
|
+
name: "template_name",
|
|
41
|
+
value: name,
|
|
42
|
+
selected: selected_template == name.to_s,
|
|
43
|
+
input_data: {
|
|
44
|
+
action: "keystone-ui--colors--theme-settings#selectTemplate",
|
|
45
|
+
"accent-hex": accent_hex,
|
|
46
|
+
"surface-hex": surface_hex,
|
|
47
|
+
"text-hex": template[:text]
|
|
48
|
+
},
|
|
49
|
+
label_data: {
|
|
50
|
+
"keystone-ui--colors--theme-settings-target": "templateLabel",
|
|
51
|
+
template: name
|
|
52
|
+
}
|
|
53
|
+
) do %>
|
|
54
|
+
<span style="display: inline-block; width: 1rem; height: 1rem; border-radius: 9999px; background-color: <%= accent_hex %>;"></span>
|
|
55
|
+
<span style="display: inline-block; width: 1rem; height: 1rem; border-radius: 0.25rem; background-color: <%= surface_hex %>;"></span>
|
|
56
|
+
<span><%= template[:label] %></span>
|
|
57
|
+
<% end %>
|
|
58
|
+
<% end %>
|
|
59
|
+
<%= ui_option_card(
|
|
60
|
+
name: "template_name",
|
|
61
|
+
value: "",
|
|
62
|
+
selected: custom_selected,
|
|
63
|
+
input_data: {
|
|
64
|
+
"keystone-ui--colors--theme-settings-target": "customRadio"
|
|
65
|
+
},
|
|
66
|
+
label_data: {
|
|
67
|
+
"keystone-ui--colors--theme-settings-target": "templateLabel",
|
|
68
|
+
template: "custom"
|
|
69
|
+
}
|
|
70
|
+
) do %>
|
|
71
|
+
<span>Custom</span>
|
|
72
|
+
<% end %>
|
|
73
|
+
</div>
|
|
74
|
+
<% end %>
|
|
75
|
+
|
|
76
|
+
<%= ui_section(title: "Accent Color", spacing: :sm) do %>
|
|
77
|
+
<div data-keystone-ui--colors--theme-settings-target="accentPicker">
|
|
78
|
+
<%= ui_color_picker(name: "accent", value: current_accent_hex) %>
|
|
79
|
+
</div>
|
|
80
|
+
<% end %>
|
|
81
|
+
|
|
82
|
+
<%= ui_section(title: "Surface", spacing: :sm) do %>
|
|
83
|
+
<div data-keystone-ui--colors--theme-settings-target="surfacePicker">
|
|
84
|
+
<%= ui_color_picker(name: "surface", value: current_surface_hex) %>
|
|
85
|
+
</div>
|
|
86
|
+
<% end %>
|
|
87
|
+
|
|
88
|
+
<%= ui_section(title: "Text Color", spacing: :sm) do %>
|
|
89
|
+
<div data-keystone-ui--colors--theme-settings-target="textPicker">
|
|
90
|
+
<%= ui_color_picker(name: "text", value: current_text_hex) %>
|
|
91
|
+
</div>
|
|
92
|
+
<% end %>
|
|
93
|
+
|
|
94
|
+
<%= ui_section(title: "Mode", spacing: :sm) do %>
|
|
95
|
+
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
|
|
96
|
+
<% KeystoneUi::Colors::ThemePreference::MODES.each do |mode| %>
|
|
97
|
+
<%= ui_radio_card(name: "mode", value: mode, label: mode.capitalize, checked: (preference.mode || KeystoneUi::Colors.configuration.default_mode) == mode) %>
|
|
98
|
+
<% end %>
|
|
99
|
+
</div>
|
|
100
|
+
<% end %>
|
|
101
|
+
|
|
102
|
+
<div>
|
|
103
|
+
<%= ui_button(label: "Save", type: :submit) %>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
<% end %>
|
|
107
|
+
<% end %>
|
|
@@ -4,96 +4,4 @@
|
|
|
4
4
|
<%= ui_alert(message: flash[:notice], type: :success) %>
|
|
5
5
|
<% end %>
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
current_accent_hex = if @preference.accent&.start_with?("#")
|
|
9
|
-
@preference.accent
|
|
10
|
-
else
|
|
11
|
-
KeystoneUi::Colors::Palettes.accent(@preference.accent || "blue")[500]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
current_surface_hex = if @preference.surface&.start_with?("#")
|
|
15
|
-
@preference.surface
|
|
16
|
-
else
|
|
17
|
-
KeystoneUi::Colors::Palettes.surface(@preference.surface || "zinc")[500]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
selected_template = @preference.template_name
|
|
21
|
-
custom_selected = @preference.accent&.start_with?("#") || (selected_template.blank? && @preference.persisted?)
|
|
22
|
-
%>
|
|
23
|
-
|
|
24
|
-
<%= ui_panel(padding: :lg) do %>
|
|
25
|
-
<%= form_with(
|
|
26
|
-
url: keystone_ui_colors.settings_path,
|
|
27
|
-
method: :patch,
|
|
28
|
-
scope: :theme_preference,
|
|
29
|
-
data: { turbo: false, controller: "keystone-ui--colors--theme-settings", selected_template: selected_template }
|
|
30
|
-
) do |form| %>
|
|
31
|
-
<div style="display: flex; flex-direction: column; gap: 2rem;">
|
|
32
|
-
<%= ui_section(title: "Theme", spacing: :sm) do %>
|
|
33
|
-
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
|
|
34
|
-
<% KeystoneUi::Colors::Templates.names.each do |name| %>
|
|
35
|
-
<% template = KeystoneUi::Colors::Templates[name] %>
|
|
36
|
-
<% accent_hex = KeystoneUi::Colors::Palettes.accent(template[:accent])[500] %>
|
|
37
|
-
<% surface_hex = KeystoneUi::Colors::Palettes.surface(template[:surface])[500] %>
|
|
38
|
-
<%= ui_option_card(
|
|
39
|
-
name: "theme_preference[template_name]",
|
|
40
|
-
value: name,
|
|
41
|
-
selected: selected_template == name.to_s,
|
|
42
|
-
input_data: {
|
|
43
|
-
action: "keystone-ui--colors--theme-settings#selectTemplate",
|
|
44
|
-
"accent-hex": accent_hex,
|
|
45
|
-
"surface-hex": surface_hex
|
|
46
|
-
},
|
|
47
|
-
label_data: {
|
|
48
|
-
"keystone-ui--colors--theme-settings-target": "templateLabel",
|
|
49
|
-
template: name
|
|
50
|
-
}
|
|
51
|
-
) do %>
|
|
52
|
-
<span style="display: inline-block; width: 1rem; height: 1rem; border-radius: 9999px; background-color: <%= accent_hex %>;"></span>
|
|
53
|
-
<span style="display: inline-block; width: 1rem; height: 1rem; border-radius: 0.25rem; background-color: <%= surface_hex %>;"></span>
|
|
54
|
-
<span><%= template[:label] %></span>
|
|
55
|
-
<% end %>
|
|
56
|
-
<% end %>
|
|
57
|
-
<%= ui_option_card(
|
|
58
|
-
name: "theme_preference[template_name]",
|
|
59
|
-
value: "",
|
|
60
|
-
selected: custom_selected,
|
|
61
|
-
input_data: {
|
|
62
|
-
"keystone-ui--colors--theme-settings-target": "customRadio"
|
|
63
|
-
},
|
|
64
|
-
label_data: {
|
|
65
|
-
"keystone-ui--colors--theme-settings-target": "templateLabel",
|
|
66
|
-
template: "custom"
|
|
67
|
-
}
|
|
68
|
-
) do %>
|
|
69
|
-
<span>Custom</span>
|
|
70
|
-
<% end %>
|
|
71
|
-
</div>
|
|
72
|
-
<% end %>
|
|
73
|
-
|
|
74
|
-
<%= ui_section(title: "Accent Color", spacing: :sm) do %>
|
|
75
|
-
<div data-keystone-ui--colors--theme-settings-target="accentPicker">
|
|
76
|
-
<%= ui_color_picker(name: "theme_preference[accent]", value: current_accent_hex) %>
|
|
77
|
-
</div>
|
|
78
|
-
<% end %>
|
|
79
|
-
|
|
80
|
-
<%= ui_section(title: "Surface", spacing: :sm) do %>
|
|
81
|
-
<div data-keystone-ui--colors--theme-settings-target="surfacePicker">
|
|
82
|
-
<%= ui_color_picker(name: "theme_preference[surface]", value: current_surface_hex) %>
|
|
83
|
-
</div>
|
|
84
|
-
<% end %>
|
|
85
|
-
|
|
86
|
-
<%= ui_section(title: "Mode", spacing: :sm) do %>
|
|
87
|
-
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
|
|
88
|
-
<% KeystoneUi::Colors::ThemePreference::MODES.each do |mode| %>
|
|
89
|
-
<%= ui_radio_card(name: "theme_preference[mode]", value: mode, label: mode.capitalize, checked: (@preference.mode || KeystoneUi::Colors.configuration.default_mode) == mode) %>
|
|
90
|
-
<% end %>
|
|
91
|
-
</div>
|
|
92
|
-
<% end %>
|
|
93
|
-
|
|
94
|
-
<div>
|
|
95
|
-
<%= ui_button(label: "Save", type: :submit) %>
|
|
96
|
-
</div>
|
|
97
|
-
</div>
|
|
98
|
-
<% end %>
|
|
99
|
-
<% end %>
|
|
7
|
+
<%= render partial: "keystone_ui/colors/settings/picker", locals: {person: current_owner, account: nil, submit_url: keystone_ui_colors.settings_path} %>
|
|
@@ -20,6 +20,13 @@ module KeystoneUi
|
|
|
20
20
|
)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
def add_text_migration
|
|
24
|
+
migration_template(
|
|
25
|
+
File.expand_path("templates/add_text_to_keystone_ui_colors_theme_preferences.rb.erb", __dir__),
|
|
26
|
+
"db/migrate/add_text_to_keystone_ui_colors_theme_preferences.rb"
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
23
30
|
def copy_stimulus_controller
|
|
24
31
|
copy_file "theme_settings_controller.js",
|
|
25
32
|
"app/javascript/controllers/keystone_ui/colors/theme_settings_controller.js"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module KeystoneUi
|
|
4
4
|
module Colors
|
|
5
5
|
class Configuration
|
|
6
|
-
attr_accessor :current_owner_method, :authentication_method, :default_template, :default_accent, :default_surface, :default_mode, :layout
|
|
6
|
+
attr_accessor :current_owner_method, :authentication_method, :default_template, :default_accent, :default_surface, :default_mode, :default_background, :default_text, :layout
|
|
7
7
|
|
|
8
8
|
def initialize
|
|
9
9
|
@current_owner_method = :current_user
|
|
@@ -12,6 +12,8 @@ module KeystoneUi
|
|
|
12
12
|
@default_accent = "blue"
|
|
13
13
|
@default_surface = "zinc"
|
|
14
14
|
@default_mode = "light"
|
|
15
|
+
@default_background = "#ffffff"
|
|
16
|
+
@default_text = "#18181b"
|
|
15
17
|
@layout = "application"
|
|
16
18
|
end
|
|
17
19
|
end
|
|
@@ -13,6 +13,10 @@ module KeystoneUi
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
initializer "keystone_ui.colors.tailwind" do
|
|
17
|
+
KeystoneUi.configuration.tailwind_sources << root.join("app/views/**/*.erb").to_s
|
|
18
|
+
end
|
|
19
|
+
|
|
16
20
|
initializer "keystone_ui.colors.url_helpers" do
|
|
17
21
|
ActiveSupport.on_load(:action_controller) do
|
|
18
22
|
helper Rails.application.routes.url_helpers
|
|
@@ -7,30 +7,40 @@ module KeystoneUi
|
|
|
7
7
|
ocean: {
|
|
8
8
|
accent: :blue,
|
|
9
9
|
surface: :slate,
|
|
10
|
+
background: "#e0f2fe",
|
|
11
|
+
text: "#0c4a6e",
|
|
10
12
|
label: "Ocean",
|
|
11
13
|
description: "Cool blues with slate undertones"
|
|
12
14
|
},
|
|
13
15
|
forest: {
|
|
14
16
|
accent: :emerald,
|
|
15
17
|
surface: :stone,
|
|
18
|
+
background: "#ecfdf5",
|
|
19
|
+
text: "#064e3b",
|
|
16
20
|
label: "Forest",
|
|
17
21
|
description: "Natural greens with warm stone"
|
|
18
22
|
},
|
|
19
23
|
twilight: {
|
|
20
24
|
accent: :violet,
|
|
21
25
|
surface: :zinc,
|
|
26
|
+
background: "#1e1b4b",
|
|
27
|
+
text: "#ede9fe",
|
|
22
28
|
label: "Twilight",
|
|
23
29
|
description: "Deep violet with clean zinc"
|
|
24
30
|
},
|
|
25
31
|
coral: {
|
|
26
32
|
accent: :rose,
|
|
27
33
|
surface: :neutral,
|
|
34
|
+
background: "#fff1f2",
|
|
35
|
+
text: "#4c0519",
|
|
28
36
|
label: "Coral",
|
|
29
37
|
description: "Warm rose with neutral balance"
|
|
30
38
|
},
|
|
31
39
|
arctic: {
|
|
32
40
|
accent: :cyan,
|
|
33
41
|
surface: :gray,
|
|
42
|
+
background: "#ecfeff",
|
|
43
|
+
text: "#164e63",
|
|
34
44
|
label: "Arctic",
|
|
35
45
|
description: "Bright cyan with crisp gray"
|
|
36
46
|
}
|
|
@@ -54,6 +64,8 @@ module KeystoneUi
|
|
|
54
64
|
{
|
|
55
65
|
accent: KeystoneUi::Colors.configuration.default_accent,
|
|
56
66
|
surface: KeystoneUi::Colors.configuration.default_surface,
|
|
67
|
+
background: KeystoneUi::Colors.configuration.default_background,
|
|
68
|
+
text: KeystoneUi::Colors.configuration.default_text,
|
|
57
69
|
label: "Default",
|
|
58
70
|
description: "Default theme"
|
|
59
71
|
}
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: keystone_ui-colors
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tyler Schneider
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: keystone_ui
|
|
@@ -16,14 +15,14 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.
|
|
18
|
+
version: 0.11.0
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.
|
|
25
|
+
version: 0.11.0
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: railties
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -83,12 +82,19 @@ files:
|
|
|
83
82
|
- app/helpers/keystone_ui/colors/palette_helper.rb
|
|
84
83
|
- app/javascript/keystone_ui/colors/theme_settings_controller.js
|
|
85
84
|
- app/models/keystone_ui/colors/application_record.rb
|
|
85
|
+
- app/models/keystone_ui/colors/custom_colours.rb
|
|
86
|
+
- app/models/keystone_ui/colors/forget_the_theme_choice.rb
|
|
87
|
+
- app/models/keystone_ui/colors/kept.rb
|
|
88
|
+
- app/models/keystone_ui/colors/pick_colours.rb
|
|
89
|
+
- app/models/keystone_ui/colors/refusal.rb
|
|
86
90
|
- app/models/keystone_ui/colors/theme_preference.rb
|
|
91
|
+
- app/views/keystone_ui/colors/settings/_picker.html.erb
|
|
87
92
|
- app/views/keystone_ui/colors/settings/show.html.erb
|
|
88
93
|
- config/routes.rb
|
|
89
94
|
- lib/generators/keystone_ui/colors/install/install_generator.rb
|
|
90
95
|
- lib/generators/keystone_ui/colors/install/templates/create_keystone_ui_colors_theme_preferences.rb.erb
|
|
91
96
|
- lib/generators/keystone_ui/colors/update/templates/add_mode_to_keystone_ui_colors_theme_preferences.rb.erb
|
|
97
|
+
- lib/generators/keystone_ui/colors/update/templates/add_text_to_keystone_ui_colors_theme_preferences.rb.erb
|
|
92
98
|
- lib/generators/keystone_ui/colors/update/update_generator.rb
|
|
93
99
|
- lib/keystone_ui-colors.rb
|
|
94
100
|
- lib/keystone_ui/colors.rb
|
|
@@ -107,7 +113,6 @@ metadata:
|
|
|
107
113
|
bug_tracker_uri: https://github.com/DYB-Development/keystone_ui-colors/issues
|
|
108
114
|
documentation_uri: https://github.com/DYB-Development/keystone_ui-colors#readme
|
|
109
115
|
rubygems_mfa_required: 'true'
|
|
110
|
-
post_install_message:
|
|
111
116
|
rdoc_options: []
|
|
112
117
|
require_paths:
|
|
113
118
|
- lib
|
|
@@ -122,8 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
122
127
|
- !ruby/object:Gem::Version
|
|
123
128
|
version: '0'
|
|
124
129
|
requirements: []
|
|
125
|
-
rubygems_version:
|
|
126
|
-
signing_key:
|
|
130
|
+
rubygems_version: 4.0.20
|
|
127
131
|
specification_version: 4
|
|
128
132
|
summary: Per-user color palette settings for Keystone UI.
|
|
129
133
|
test_files: []
|