super_settings 2.5.0 → 2.6.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/CHANGELOG.md +6 -0
- data/README.md +7 -6
- data/VERSION +1 -1
- data/app/helpers/super_settings/settings_helper.rb +1 -0
- data/lib/super_settings/application/helper.rb +8 -0
- data/lib/super_settings/application/layout.html.erb +56 -0
- data/lib/super_settings/application/layout_styles.css +37 -0
- data/lib/super_settings/application/layout_vars.css.erb +5 -1
- data/lib/super_settings/application/style_vars.css.erb +4 -2
- data/lib/super_settings/application.rb +6 -3
- data/lib/super_settings/configuration.rb +27 -5
- data/lib/super_settings/controller_actions.rb +7 -2
- data/lib/super_settings/rack_application.rb +11 -3
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3c33c68388f12bb6216f928e778f5a4965bf11f263bc315f0a9ce9261f9d4637
|
|
4
|
+
data.tar.gz: fc7e9bd62a5412843c0da1a2accf93812869ae85cf91c8b7accd0eb496c9cf00
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d85f6b31e1757e36fbfe6486851ee2ccfdf10b13bca742ed90910898761c2215ca053ee2a91ad204b65913d765b66084b03e802544985c3d3c263d692c54480d
|
|
7
|
+
data.tar.gz: 17a61ebac8696d0d2b1ca09229b0826d8885853e858f3ebcb2956cad00d56cf35f9e0928afc4c4e0987d270be3b9b23ab52cf18c91c91874281e3ac2239e81ad
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## 2.6.0
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added `SuperSettings::Application#dark_mode_selector` configuration option that allows you to specify a CSS selector that sets dark mode when it matches an element in the page. This is an alternative to using the `color_scheme` option and allows for more flexible control of when dark mode is enabled.
|
|
12
|
+
|
|
7
13
|
## 2.5.0
|
|
8
14
|
|
|
9
15
|
### Added
|
data/README.md
CHANGED
|
@@ -308,6 +308,13 @@ SuperSettings.configure do |config|
|
|
|
308
308
|
# Set the color scheme to use for the Web UI. Options are :light (default), :dark, or :system.
|
|
309
309
|
config.controller.color_scheme = :dark
|
|
310
310
|
|
|
311
|
+
# Set a CSS selector for enabling dark mode. When the selector matches an element on the page,
|
|
312
|
+
# dark mode styles will be applied. A theme toggle button will also be rendered in the header
|
|
313
|
+
# allowing users to switch between light and dark modes (persisted via localStorage).
|
|
314
|
+
# This is an alternative to the color_scheme option. If neither color_scheme nor dark_mode_selector
|
|
315
|
+
# is set, it defaults to "[data-theme=dark]" which enables the toggle automatically.
|
|
316
|
+
config.controller.dark_mode_selector = "[data-theme=dark]"
|
|
317
|
+
|
|
311
318
|
# Add additional code to the controller. In this case we are adding code to ensure only
|
|
312
319
|
# admins can access the functionality and changing the layout to use one defined by the application.
|
|
313
320
|
config.controller.enhance do
|
|
@@ -464,12 +471,6 @@ This will work out of the box with the defaults for the storage engines when run
|
|
|
464
471
|
- `S3_URL` - `s3://accesskey:secretkey@region-1/settings/settings.json` (the S3 endpoint will be set to `http://localhost:9000`)
|
|
465
472
|
- `MONGODB_URL` - `mongodb://localhost:27017/super_settings`
|
|
466
473
|
|
|
467
|
-
Finally, you can run the application in dark mode by setting the `COLOR_SCHEME` environment variable.
|
|
468
|
-
|
|
469
|
-
```bash
|
|
470
|
-
COLOR_SCHEME=dark bundle exec rackup
|
|
471
|
-
```
|
|
472
|
-
|
|
473
474
|
## License
|
|
474
475
|
|
|
475
476
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.6.0
|
|
@@ -29,6 +29,7 @@ module SuperSettings
|
|
|
29
29
|
application_dir = File.expand_path(File.join("..", "..", "..", "lib", "super_settings", "application"), __dir__)
|
|
30
30
|
erb = ERB.new(File.read(File.join(application_dir, "layout_vars.css.erb")))
|
|
31
31
|
color_scheme = SuperSettings.configuration.controller.color_scheme
|
|
32
|
+
dark_mode_selector = SuperSettings.configuration.controller.dark_mode_selector
|
|
32
33
|
erb.result(binding).html_safe
|
|
33
34
|
end
|
|
34
35
|
end
|
|
@@ -222,6 +222,14 @@ module SuperSettings
|
|
|
222
222
|
@color_scheme if defined?(@color_scheme)
|
|
223
223
|
end
|
|
224
224
|
|
|
225
|
+
# A CSS selector that sets dark mode when it matches an element in the page.
|
|
226
|
+
# This is an alternative to using the color_scheme option.
|
|
227
|
+
#
|
|
228
|
+
# @return [String, nil]
|
|
229
|
+
def dark_mode_selector
|
|
230
|
+
@dark_mode_selector if defined?(@dark_mode_selector)
|
|
231
|
+
end
|
|
232
|
+
|
|
225
233
|
# Whether the application is in read-only mode.
|
|
226
234
|
#
|
|
227
235
|
# @return [Boolean]
|
|
@@ -8,6 +8,18 @@
|
|
|
8
8
|
<meta name="format-detection" content="telephone=no email=no date=no address=no">
|
|
9
9
|
<meta name="robots" content="noindex, nofollow">
|
|
10
10
|
<meta name="referrer" content="no-referrer-when-downgrade">
|
|
11
|
+
<% if dark_mode_selector %>
|
|
12
|
+
<script>
|
|
13
|
+
(function() {
|
|
14
|
+
try {
|
|
15
|
+
if (localStorage.getItem("super_settings_theme") === "dark") {
|
|
16
|
+
document.documentElement.setAttribute("data-theme", "dark");
|
|
17
|
+
}
|
|
18
|
+
} catch (e) {
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
21
|
+
</script>
|
|
22
|
+
<% end %>
|
|
11
23
|
<%= layout_style_tag %>
|
|
12
24
|
<%= add_to_head %>
|
|
13
25
|
</head>
|
|
@@ -16,6 +28,24 @@
|
|
|
16
28
|
<header class="super-settings-page-header">
|
|
17
29
|
<div class="super-settings-page-header-inner">
|
|
18
30
|
<%= application_header %>
|
|
31
|
+
<% if dark_mode_selector %>
|
|
32
|
+
<button type="button" class="super-settings-theme-toggle" id="super-settings-theme-toggle" aria-label="Toggle dark mode">
|
|
33
|
+
<svg class="super-settings-theme-icon super-settings-theme-icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
34
|
+
<circle cx="12" cy="12" r="4"></circle>
|
|
35
|
+
<path d="M12 2v2"></path>
|
|
36
|
+
<path d="M12 20v2"></path>
|
|
37
|
+
<path d="m4.93 4.93 1.41 1.41"></path>
|
|
38
|
+
<path d="m17.66 17.66 1.41 1.41"></path>
|
|
39
|
+
<path d="M2 12h2"></path>
|
|
40
|
+
<path d="M20 12h2"></path>
|
|
41
|
+
<path d="m6.34 17.66-1.41 1.41"></path>
|
|
42
|
+
<path d="m19.07 4.93-1.41 1.41"></path>
|
|
43
|
+
</svg>
|
|
44
|
+
<svg class="super-settings-theme-icon super-settings-theme-icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
45
|
+
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"></path>
|
|
46
|
+
</svg>
|
|
47
|
+
</button>
|
|
48
|
+
<% end %>
|
|
19
49
|
</div>
|
|
20
50
|
</header>
|
|
21
51
|
|
|
@@ -72,5 +102,31 @@
|
|
|
72
102
|
</details>
|
|
73
103
|
</footer>
|
|
74
104
|
<% end %>
|
|
105
|
+
<% if dark_mode_selector %>
|
|
106
|
+
<script>
|
|
107
|
+
(function() {
|
|
108
|
+
var toggle = document.getElementById("super-settings-theme-toggle");
|
|
109
|
+
if (!toggle) return;
|
|
110
|
+
|
|
111
|
+
var html = document.documentElement;
|
|
112
|
+
toggle.addEventListener("click", function() {
|
|
113
|
+
var isDark = html.getAttribute("data-theme") === "dark";
|
|
114
|
+
if (isDark) {
|
|
115
|
+
html.removeAttribute("data-theme");
|
|
116
|
+
try {
|
|
117
|
+
localStorage.removeItem("super_settings_theme");
|
|
118
|
+
} catch (e) {
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
html.setAttribute("data-theme", "dark");
|
|
122
|
+
try {
|
|
123
|
+
localStorage.setItem("super_settings_theme", "dark");
|
|
124
|
+
} catch (e) {
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
})();
|
|
129
|
+
</script>
|
|
130
|
+
<% end %>
|
|
75
131
|
</body>
|
|
76
132
|
</html>
|
|
@@ -112,6 +112,43 @@ a:visited {
|
|
|
112
112
|
justify-content: flex-end;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
.super-settings-theme-toggle {
|
|
116
|
+
display: flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
justify-content: center;
|
|
119
|
+
width: 36px;
|
|
120
|
+
height: 36px;
|
|
121
|
+
border: 1px solid transparent;
|
|
122
|
+
border-radius: 8px;
|
|
123
|
+
background: transparent;
|
|
124
|
+
color: #9ca3af;
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
flex-shrink: 0;
|
|
127
|
+
transition: color 0.2s, border-color 0.2s;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.super-settings-theme-toggle:hover {
|
|
131
|
+
color: var(--link-color);
|
|
132
|
+
border-color: var(--link-color);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.super-settings-theme-icon {
|
|
136
|
+
width: 18px;
|
|
137
|
+
height: 18px;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.super-settings-theme-icon-moon {
|
|
141
|
+
display: none;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
[data-theme="dark"] .super-settings-theme-icon-sun {
|
|
145
|
+
display: none;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
[data-theme="dark"] .super-settings-theme-icon-moon {
|
|
149
|
+
display: block;
|
|
150
|
+
}
|
|
151
|
+
|
|
115
152
|
/* ══════════════════════════════════════════
|
|
116
153
|
LANGUAGE MENU (in footer)
|
|
117
154
|
══════════════════════════════════════════ */
|
|
@@ -13,7 +13,11 @@
|
|
|
13
13
|
<% end %>
|
|
14
14
|
<% if color_scheme == :system || color_scheme == :dark %>
|
|
15
15
|
:root {
|
|
16
|
-
|
|
16
|
+
<% elsif dark_mode_selector %>
|
|
17
|
+
:root<%= dark_mode_selector %> {
|
|
18
|
+
<% end %>
|
|
19
|
+
<% if color_scheme == :system || color_scheme == :dark || dark_mode_selector %>
|
|
20
|
+
--text-color: #eef0f8;
|
|
17
21
|
--background-color: #1a1d23;
|
|
18
22
|
--header-background-color: #21252b;
|
|
19
23
|
--link-color: #2dd4bf;
|
|
@@ -71,8 +71,10 @@
|
|
|
71
71
|
|
|
72
72
|
<% if color_scheme == :system %>
|
|
73
73
|
@media (prefers-color-scheme: dark) {
|
|
74
|
+
<% elsif dark_mode_selector %>
|
|
75
|
+
<%= dark_mode_selector %> {
|
|
74
76
|
<% end %>
|
|
75
|
-
<% if color_scheme == :system || color_scheme == :dark %>
|
|
77
|
+
<% if color_scheme == :system || color_scheme == :dark || dark_mode_selector %>
|
|
76
78
|
.super-settings {
|
|
77
79
|
/* Canvas */
|
|
78
80
|
--bg-page: #1a1d23;
|
|
@@ -128,6 +130,6 @@
|
|
|
128
130
|
--icon-disabled-color: #4b5563;
|
|
129
131
|
}
|
|
130
132
|
<% end %>
|
|
131
|
-
<% if color_scheme == :system %>
|
|
133
|
+
<% if color_scheme == :system || dark_mode_selector %>
|
|
132
134
|
}
|
|
133
135
|
<% end %>
|
|
@@ -8,14 +8,16 @@ module SuperSettings
|
|
|
8
8
|
include Helper
|
|
9
9
|
|
|
10
10
|
# @param layout [String, Symbol] path to an ERB template to use as the layout around the application UI. You can
|
|
11
|
-
#
|
|
11
|
+
# pass the symbol +:default+ to use the default layout that ships with the gem.
|
|
12
12
|
# @param add_to_head [String] HTML code to add to the <head> element on the page.
|
|
13
13
|
# @param api_base_url [String] the base URL for the REST API.
|
|
14
14
|
# @param color_scheme [Symbol] whether to use dark mode for the application UI. If +nil+, the user's system
|
|
15
|
-
#
|
|
15
|
+
# preference will be used.
|
|
16
|
+
# @param dark_mode_selector [String] a CSS selector that sets dark mode when it matches an element in the page.
|
|
17
|
+
# This is an alternative to using the color_scheme option.
|
|
16
18
|
# @param read_only [Boolean] whether to render the application in read-only mode (edit controls hidden).
|
|
17
19
|
# @param locale [String] the locale code for translations (default: "en").
|
|
18
|
-
def initialize(layout: nil, add_to_head: nil, api_base_url: nil, color_scheme: nil, read_only: false, locale: nil)
|
|
20
|
+
def initialize(layout: nil, add_to_head: nil, api_base_url: nil, color_scheme: nil, dark_mode_selector: nil, read_only: false, locale: nil)
|
|
19
21
|
if layout
|
|
20
22
|
layout = File.expand_path(File.join("application", "layout.html.erb"), __dir__) if layout == :default
|
|
21
23
|
@layout = ERB.new(File.read(layout)) if layout
|
|
@@ -27,6 +29,7 @@ module SuperSettings
|
|
|
27
29
|
|
|
28
30
|
@api_base_url = api_base_url
|
|
29
31
|
@color_scheme = color_scheme&.to_sym
|
|
32
|
+
@dark_mode_selector = dark_mode_selector
|
|
30
33
|
@read_only = !!read_only
|
|
31
34
|
@locale = locale || SuperSettings::MiniI18n::DEFAULT_LOCALE
|
|
32
35
|
end
|
|
@@ -12,6 +12,8 @@ module SuperSettings
|
|
|
12
12
|
|
|
13
13
|
# Configuration for the controller.
|
|
14
14
|
class Controller
|
|
15
|
+
VALID_COLOR_SCHEMES = [:light, :dark, :system].freeze
|
|
16
|
+
|
|
15
17
|
# @api private
|
|
16
18
|
attr_reader :enhancement
|
|
17
19
|
|
|
@@ -25,12 +27,13 @@ module SuperSettings
|
|
|
25
27
|
def initialize
|
|
26
28
|
@superclass = nil
|
|
27
29
|
@web_ui_enabled = true
|
|
28
|
-
@color_scheme =
|
|
30
|
+
@color_scheme = nil
|
|
29
31
|
@changed_by_block = nil
|
|
30
32
|
@enhancement = nil
|
|
31
33
|
@application_name = nil
|
|
32
34
|
@application_logo = nil
|
|
33
35
|
@application_link = nil
|
|
36
|
+
@dark_mode_selector = nil
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
def superclass
|
|
@@ -41,10 +44,10 @@ module SuperSettings
|
|
|
41
44
|
end
|
|
42
45
|
end
|
|
43
46
|
|
|
44
|
-
#
|
|
47
|
+
# Optional name of the application displayed in the view.
|
|
45
48
|
attr_accessor :application_name
|
|
46
49
|
|
|
47
|
-
# Optional
|
|
50
|
+
# Optional image URL for the application logo.
|
|
48
51
|
attr_accessor :application_logo
|
|
49
52
|
|
|
50
53
|
# Optional URL for a link back to the rest of the application.
|
|
@@ -69,11 +72,30 @@ module SuperSettings
|
|
|
69
72
|
end
|
|
70
73
|
|
|
71
74
|
# Set dark mode for the web UI. Possible values are :light, :dark, or :system.
|
|
72
|
-
#
|
|
75
|
+
# When the value is not set (or is invalid), theme selection is left dynamic.
|
|
73
76
|
attr_writer :color_scheme
|
|
74
77
|
|
|
78
|
+
# Return the configured color scheme.
|
|
79
|
+
#
|
|
80
|
+
# @return [Symbol, nil]
|
|
75
81
|
def color_scheme
|
|
76
|
-
|
|
82
|
+
scheme = @color_scheme&.to_sym
|
|
83
|
+
VALID_COLOR_SCHEMES.include?(scheme) ? scheme : nil
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Set a CSS selector that sets dark mode. This is an alternative to using the color_scheme
|
|
87
|
+
# option and can be used if you have a custom implementation for dark mode in your application.
|
|
88
|
+
# Dark mode will be enabled in the settings web UI when the selector matches an element in the page.
|
|
89
|
+
attr_accessor :dark_mode_selector
|
|
90
|
+
|
|
91
|
+
# Return the selector used to enable dark mode from host page state.
|
|
92
|
+
#
|
|
93
|
+
# @return [String, nil]
|
|
94
|
+
def resolved_dark_mode_selector
|
|
95
|
+
return @dark_mode_selector if @dark_mode_selector
|
|
96
|
+
return "[data-theme=dark]" if color_scheme.nil?
|
|
97
|
+
|
|
98
|
+
nil
|
|
77
99
|
end
|
|
78
100
|
|
|
79
101
|
# Enhance the controller. You can define methods or call controller class methods like
|
|
@@ -19,8 +19,13 @@ module SuperSettings
|
|
|
19
19
|
|
|
20
20
|
# Render the HTML application for managing settings.
|
|
21
21
|
def root
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
application = SuperSettings::Application.new(
|
|
23
|
+
read_only: super_settings_read_only?,
|
|
24
|
+
locale: I18n.locale,
|
|
25
|
+
color_scheme: SuperSettings.configuration.controller.color_scheme,
|
|
26
|
+
dark_mode_selector: SuperSettings.configuration.controller.resolved_dark_mode_selector
|
|
27
|
+
)
|
|
28
|
+
render html: application.render.html_safe, layout: true
|
|
24
29
|
end
|
|
25
30
|
|
|
26
31
|
# API endpoint for getting active settings. See SuperSettings::RestAPI for details.
|
|
@@ -104,9 +104,9 @@ module SuperSettings
|
|
|
104
104
|
# Subclasses can override this method to return the path to an ERB file to use as the layout
|
|
105
105
|
# for the HTML application. The layout can use any of the methods defined in SuperSettings::Application::Helper.
|
|
106
106
|
#
|
|
107
|
-
# @return [String]
|
|
107
|
+
# @return [String, Symbol]
|
|
108
108
|
def layout
|
|
109
|
-
|
|
109
|
+
:default
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
# Subclasses can override this method to add custom HTML to the <head> element in the HTML application.
|
|
@@ -186,7 +186,15 @@ module SuperSettings
|
|
|
186
186
|
if lang && SuperSettings::MiniI18n.available_locales.include?(lang)
|
|
187
187
|
headers["set-cookie"] = "super_settings_locale=#{lang}; path=/; SameSite=Lax"
|
|
188
188
|
end
|
|
189
|
-
|
|
189
|
+
application = Application.new(
|
|
190
|
+
layout: layout,
|
|
191
|
+
add_to_head: add_to_head(request),
|
|
192
|
+
color_scheme: SuperSettings.configuration.controller.color_scheme,
|
|
193
|
+
dark_mode_selector: SuperSettings.configuration.controller.resolved_dark_mode_selector,
|
|
194
|
+
read_only: read_only,
|
|
195
|
+
locale: locale
|
|
196
|
+
)
|
|
197
|
+
[200, headers, [application.render]]
|
|
190
198
|
end
|
|
191
199
|
|
|
192
200
|
if [401, 403].include?(response.first)
|