nitro_rails 0.1.0 → 0.1.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 +4 -4
- data/README.md +18 -0
- data/app/assets/audio/mousetap.mp3 +0 -0
- data/app/assets/config/nitro_rails_manifest.js +2 -0
- data/app/assets/javascript/nitro_rails/application.js +4 -0
- data/app/assets/javascript/nitro_rails/controllers/application.js +9 -0
- data/app/assets/javascript/nitro_rails/controllers/audio_controller.js +16 -0
- data/app/assets/javascript/nitro_rails/controllers/clock_controller.js +21 -0
- data/app/assets/javascript/nitro_rails/controllers/editable_text_controller.js +61 -0
- data/app/assets/javascript/nitro_rails/controllers/index.js +21 -0
- data/app/assets/javascript/nitro_rails/controllers/nitro_collection_controller.js +127 -0
- data/app/assets/javascript/nitro_rails/controllers/nitro_controller.js +35 -0
- data/app/assets/javascript/nitro_rails/controllers/nitro_form_controller.js +81 -0
- data/app/assets/javascript/nitro_rails/controllers/panel_controller.js +70 -0
- data/app/assets/javascript/nitro_rails/controllers/panel_manager_controller.js +89 -0
- data/app/assets/javascript/nitro_rails/controllers/tabs_controller.js +81 -0
- data/app/assets/javascript/nitro_rails/controllers/time_zone_controller.js +47 -0
- data/app/assets/javascript/nitro_rails/controllers/togglable_checkbox_controller.js +9 -0
- data/app/assets/javascript/nitro_rails/helpers/device_info_helper.js +99 -0
- data/app/assets/javascript/nitro_rails/helpers/screen_info_helper.js +20 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/clear_errors.js +22 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/focus.js +8 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/index.js +8 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/insert.js +10 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/redirect.js +10 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/refresh_frame.js +9 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/render_errors.js +26 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/toggle_checkbox.js +9 -0
- data/app/assets/javascript/nitro_rails/turbo_streams/toggle_class.js +14 -0
- data/app/assets/stylesheets/nitro_rails/__reset.css +25 -0
- data/app/assets/stylesheets/nitro_rails/_base/_color.css +24 -0
- data/app/assets/stylesheets/nitro_rails/_base/_font.css +35 -0
- data/app/assets/stylesheets/nitro_rails/_base/_format.css +38 -0
- data/app/assets/stylesheets/nitro_rails/_base/_grayscale.css +79 -0
- data/app/assets/stylesheets/nitro_rails/_base/_utility.css +34 -0
- data/app/assets/stylesheets/nitro_rails/application.css +23 -0
- data/app/assets/stylesheets/nitro_rails/modules/action-navigation.css +24 -0
- data/app/assets/stylesheets/nitro_rails/modules/alert.css +31 -0
- data/app/assets/stylesheets/nitro_rails/modules/btn.css +57 -0
- data/app/assets/stylesheets/nitro_rails/modules/checkbox.css +42 -0
- data/app/assets/stylesheets/nitro_rails/modules/clickable.css +9 -0
- data/app/assets/stylesheets/nitro_rails/modules/clock.css +0 -0
- data/app/assets/stylesheets/nitro_rails/modules/editable-text.css +45 -0
- data/app/assets/stylesheets/nitro_rails/modules/forms.css +108 -0
- data/app/assets/stylesheets/nitro_rails/modules/hover-reveal.css +11 -0
- data/app/assets/stylesheets/nitro_rails/modules/inline-svg.css +14 -0
- data/app/assets/stylesheets/nitro_rails/modules/list.css +29 -0
- data/app/assets/stylesheets/nitro_rails/modules/main-navigation.css +20 -0
- data/app/assets/stylesheets/nitro_rails/modules/nitro-checkbox.css +42 -0
- data/app/assets/stylesheets/nitro_rails/modules/resource-collection.css +12 -0
- data/app/assets/stylesheets/nitro_rails/modules/search-bar.css +36 -0
- data/app/assets/stylesheets/nitro_rails/modules/settings.css +33 -0
- data/app/assets/stylesheets/nitro_rails/modules/tabs.css +38 -0
- data/app/assets/stylesheets/nitro_rails/modules/toggle-switch.css +60 -0
- data/app/assets/stylesheets/nitro_rails/panels/bound-card-dropdown-panel.css +0 -0
- data/app/assets/stylesheets/nitro_rails/panels/card-panel.css +0 -0
- data/app/assets/stylesheets/nitro_rails/panels/embedded-panel.css +31 -0
- data/app/assets/stylesheets/nitro_rails/panels/panel-display.css +111 -0
- data/app/assets/stylesheets/nitro_rails/panels/popup-panel.css +123 -0
- data/app/assets/stylesheets/nitro_rails/panels/side-panel.css +0 -0
- data/app/controllers/nitro_rails/sequence_controller.rb +64 -0
- data/app/helpers/nitro_rails/application_helper.rb +42 -1
- data/app/helpers/nitro_rails/color_helper.rb +23 -0
- data/app/helpers/nitro_rails/components_helper.rb +49 -0
- data/app/helpers/nitro_rails/inline_edit_helper.rb +48 -0
- data/app/helpers/nitro_rails/nitro_action_helper.rb +178 -0
- data/app/helpers/nitro_rails/nitro_collection_helper.rb +87 -0
- data/app/helpers/nitro_rails/nitro_edit_helper.rb +15 -0
- data/app/helpers/nitro_rails/nitro_form_helper.rb +104 -0
- data/app/helpers/nitro_rails/nitro_options_helper.rb +78 -0
- data/app/helpers/nitro_rails/nitro_tag_helper.rb +183 -0
- data/app/helpers/nitro_rails/panel_helper.rb +65 -0
- data/app/helpers/nitro_rails/resource_collection_helper.rb +66 -0
- data/app/helpers/nitro_rails/tabs_helper.rb +51 -0
- data/app/helpers/nitro_rails/turbo_stream_helper.rb +46 -0
- data/app/lib/nitro_rails/local_time.rb +51 -0
- data/app/lib/nitro_rails/performable_routes.rb +24 -0
- data/app/lib/nitro_rails/resource_collection.rb +183 -0
- data/app/lib/nitro_rails/sequential_routes.rb +36 -0
- data/app/lib/nitro_rails/time_interval.rb +88 -0
- data/app/lib/nitro_rails/time_string.rb +22 -0
- data/app/models/nitro_rails/broadcast.rb +76 -0
- data/app/models/nitro_rails/broadcastable_model.rb +91 -0
- data/app/models/nitro_rails/broadcastable_record.rb +118 -0
- data/app/models/nitro_rails/default_broadcasts.rb +149 -0
- data/app/models/nitro_rails/record.rb +50 -0
- data/app/pseudocode/nitro.html.erb +18 -0
- data/app/view_components/nitro_rails/nitro_collection/batch_selectable.rb +24 -0
- data/app/view_components/nitro_rails/nitro_collection.rb +66 -0
- data/app/view_components/nitro_rails/view_component.rb +9 -0
- data/app/views/layouts/nitro_rails/application.html.erb +3 -5
- data/app/views/nitro_rails/_editable_text.html.erb +32 -0
- data/app/views/nitro_rails/_nitro_checkbox.html.erb +5 -0
- data/app/views/nitro_rails/_nitro_form.html.erb +10 -0
- data/app/views/nitro_rails/_panel_frame_tag.html.erb +8 -0
- data/app/views/nitro_rails/_panel_template.html.erb +40 -0
- data/app/views/nitro_rails/_togglable_checkbox.html.erb +16 -0
- data/config/importmap.rb +1 -0
- data/config/initializers/date_formatters.rb +9 -0
- data/lib/nitro_rails/engine.rb +25 -0
- data/lib/nitro_rails/version.rb +1 -1
- metadata +165 -3
- data/app/models/nitro_rails/application_record.rb +0 -5
@@ -0,0 +1,47 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static values = { serverTime: String}
|
5
|
+
|
6
|
+
connect() {
|
7
|
+
this.setTimezoneCookies();
|
8
|
+
}
|
9
|
+
|
10
|
+
setTimezoneCookies() {
|
11
|
+
const currentClientTime = new Date()
|
12
|
+
const currentServerTime = new Date(Date.parse(this.serverTimeValue));
|
13
|
+
|
14
|
+
const browserTimezoneLocation = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
15
|
+
const browserShortTimezone = new Intl.DateTimeFormat('en-US', {timeZoneName: 'short'}).formatToParts(currentClientTime).find(part => part.type === 'timeZoneName').value;
|
16
|
+
const browserLongTimeZone = new Intl.DateTimeFormat('en-US', {timeZoneName: 'long'}).formatToParts(currentClientTime).find(part => part.type === 'timeZoneName').value;
|
17
|
+
const browserTimezoneOffset = currentClientTime.getTimezoneOffset() * -1;
|
18
|
+
const clientOffsetFromServer = Math.floor((currentClientTime - currentServerTime) / 1000 / 60 / 60);
|
19
|
+
|
20
|
+
if(browserTimezoneLocation !== this.getCookieByName('client_timezone_location')) {
|
21
|
+
document.cookie = `client_timezone_location=${browserTimezoneLocation}; path=/`
|
22
|
+
}
|
23
|
+
|
24
|
+
if(browserShortTimezone !== this.getCookieByName('client_short_timezone')) {
|
25
|
+
document.cookie = `client_short_timezone=${browserShortTimezone}; path=/`
|
26
|
+
}
|
27
|
+
|
28
|
+
if(browserLongTimeZone !== this.getCookieByName('client_long_timezone')) {
|
29
|
+
document.cookie = `client_long_timezone=${browserLongTimeZone}; path=/`
|
30
|
+
}
|
31
|
+
|
32
|
+
if(browserTimezoneOffset !== this.getCookieByName('client_utc_offset')) {
|
33
|
+
document.cookie = `client_utc_offset=${browserTimezoneOffset}; path=/`
|
34
|
+
}
|
35
|
+
|
36
|
+
if(clientOffsetFromServer !== this.getCookieByName('client_offset_from_server')) {
|
37
|
+
document.cookie = `client_offset_from_server=${clientOffsetFromServer}; path=/`
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
getCookieByName(name) {
|
42
|
+
const value = `; ${document.cookie}`;
|
43
|
+
const parts = value.split(`; ${name}=`);
|
44
|
+
if (parts.length === 2) return parts.pop().split(';').shift();
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
@@ -0,0 +1,99 @@
|
|
1
|
+
class DeviceInfoHelper {
|
2
|
+
constructor() {
|
3
|
+
this.userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
4
|
+
}
|
5
|
+
|
6
|
+
// Operating Systems
|
7
|
+
isIOS() {
|
8
|
+
return /iPhone|iPad|iPod/.test(this.userAgent);
|
9
|
+
}
|
10
|
+
|
11
|
+
isAndroid() {
|
12
|
+
return /Android/.test(this.userAgent);
|
13
|
+
}
|
14
|
+
|
15
|
+
isWindows() {
|
16
|
+
return /Windows/.test(this.userAgent);
|
17
|
+
}
|
18
|
+
|
19
|
+
isMac() {
|
20
|
+
return /Mac/.test(this.userAgent);
|
21
|
+
}
|
22
|
+
|
23
|
+
isLinux() {
|
24
|
+
return /Linux/.test(this.userAgent);
|
25
|
+
}
|
26
|
+
|
27
|
+
// Devices
|
28
|
+
|
29
|
+
isIPad() {
|
30
|
+
return /iPad/.test(this.userAgent);
|
31
|
+
}
|
32
|
+
|
33
|
+
isIPhone() {
|
34
|
+
return /iPhone/.test(this.userAgent);
|
35
|
+
}
|
36
|
+
|
37
|
+
isMobileDevice() {
|
38
|
+
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(this.userAgent);
|
39
|
+
}
|
40
|
+
|
41
|
+
isTablet() {
|
42
|
+
return /iPad/.test(this.userAgent);
|
43
|
+
}
|
44
|
+
|
45
|
+
isDesktop() {
|
46
|
+
return !this.isMobileDevice();
|
47
|
+
}
|
48
|
+
|
49
|
+
// Browsers
|
50
|
+
|
51
|
+
isSafari() {
|
52
|
+
return /Safari/.test(this.userAgent);
|
53
|
+
}
|
54
|
+
|
55
|
+
isChrome() {
|
56
|
+
return /Chrome/.test(this.userAgent);
|
57
|
+
}
|
58
|
+
|
59
|
+
isFirefox() {
|
60
|
+
return /Firefox/.test(this.userAgent);
|
61
|
+
}
|
62
|
+
|
63
|
+
isOpera() {
|
64
|
+
return /Opera/.test(this.userAgent);
|
65
|
+
}
|
66
|
+
|
67
|
+
isIE() {
|
68
|
+
return /MSIE/.test(this.userAgent);
|
69
|
+
}
|
70
|
+
|
71
|
+
isEdge() {
|
72
|
+
return /Edge/.test(this.userAgent);
|
73
|
+
}
|
74
|
+
|
75
|
+
// Native Apps
|
76
|
+
|
77
|
+
isNativeApp() {
|
78
|
+
return this.isIOSApp() || this.isAndroidApp() || this.isWindowsApp() || this.isMacApp();
|
79
|
+
}
|
80
|
+
|
81
|
+
isIOSApp() {
|
82
|
+
return !window.external && /iPhone|iPod|iPad.*AppleWebKit(?!.*Safari)/i.test(this.userAgent);
|
83
|
+
}
|
84
|
+
|
85
|
+
isAndroidApp() {
|
86
|
+
return /Android.*AppleWebKit(?!.*Safari)/i.test(this.userAgent);
|
87
|
+
}
|
88
|
+
|
89
|
+
isWindowsApp() {
|
90
|
+
return /Windows.*AppleWebKit(?!.*Safari)/i.test(this.userAgent);
|
91
|
+
}
|
92
|
+
|
93
|
+
isMacApp() {
|
94
|
+
return /Mac.*AppleWebKit(?!.*Safari)/i.test(this.userAgent);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
const deviceInfoHelper = new DeviceInfoHelper();
|
99
|
+
export { deviceInfoHelper };
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class ScreenInfoHelper {
|
2
|
+
constructor() {
|
3
|
+
this.userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
4
|
+
}
|
5
|
+
|
6
|
+
isMobileSize() {
|
7
|
+
return window.innerWidth < 500;
|
8
|
+
}
|
9
|
+
|
10
|
+
isTabletSize() {
|
11
|
+
return window.innerWidth < 768 && window.innerWidth >= 500;
|
12
|
+
}
|
13
|
+
|
14
|
+
isDesktopSize() {
|
15
|
+
return window.innerWidth >= 768;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
const screenInfoHelper = new ScreenInfoHelper();
|
20
|
+
export { screenInfoHelper };
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { Turbo } from "@hotwired/turbo-rails"
|
2
|
+
|
3
|
+
Turbo.StreamActions.clear_errors = function() {
|
4
|
+
const authenticityToken = this.getAttribute('authenticity_token');
|
5
|
+
|
6
|
+
// MAJOR HACK - Come up with a better system some time
|
7
|
+
const authenticityQuery = `[name="authenticity_token"][value="${authenticityToken}"]`;
|
8
|
+
const editableTextContainer = document.querySelector(authenticityQuery).closest(".editable-text-container");
|
9
|
+
|
10
|
+
const messageTarget = editableTextContainer.querySelector(`[data-attribute-error-message-id]`)
|
11
|
+
const badgeTarget = editableTextContainer.querySelector(`[data-attribute-error-count-id]`);
|
12
|
+
|
13
|
+
if (messageTarget) {
|
14
|
+
messageTarget.classList.remove("visible");
|
15
|
+
messageTarget.textContent = "";
|
16
|
+
}
|
17
|
+
|
18
|
+
if (badgeTarget) {
|
19
|
+
badgeTarget.classList.remove("visible");
|
20
|
+
badgeTarget.textContent = "";
|
21
|
+
}
|
22
|
+
};
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { Turbo } from "@hotwired/turbo-rails"
|
2
|
+
|
3
|
+
Turbo.StreamActions.focus = function() {
|
4
|
+
setTimeout(() => {
|
5
|
+
// Should we use "data-broadcast-focal-point?"
|
6
|
+
document.querySelector(this.getAttribute('target')).querySelector('[data-focal-point]').focus();
|
7
|
+
}, 500);
|
8
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { Turbo } from "@hotwired/turbo-rails"
|
2
|
+
|
3
|
+
Turbo.StreamActions.insert = function() {
|
4
|
+
const positionIndex = this.getAttribute("position");
|
5
|
+
const target = this.getAttribute("target");
|
6
|
+
const template = document.createElement("template");
|
7
|
+
|
8
|
+
template.innerHTML = this.targetBody;
|
9
|
+
const content = template.content;
|
10
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { Turbo } from "@hotwired/turbo-rails"
|
2
|
+
|
3
|
+
Turbo.StreamActions.redirect = function() {
|
4
|
+
const redirectPath = this.getAttribute('to');
|
5
|
+
const onPath = this.getAttribute('on');
|
6
|
+
|
7
|
+
if (redirectPath && onPath === window.location.pathname) {
|
8
|
+
window.location.replace(redirectPath);
|
9
|
+
}
|
10
|
+
};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { Turbo } from "@hotwired/turbo-rails"
|
2
|
+
|
3
|
+
Turbo.StreamActions.refresh_frame = function() {
|
4
|
+
document.querySelectorAll(`turbo-frame${this.getAttribute('targets')}`).forEach((frame) => {
|
5
|
+
console.log(frame.dataset.broadcastReload);
|
6
|
+
frame.src = frame.dataset.broadcastReload;
|
7
|
+
// frame.reload();
|
8
|
+
});
|
9
|
+
};
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { Turbo } from "@hotwired/turbo-rails"
|
2
|
+
|
3
|
+
Turbo.StreamActions.render_errors = function() {
|
4
|
+
const authenticityToken = this.getAttribute('authenticity_token');
|
5
|
+
const errorMessage = this.getAttribute('error_message');
|
6
|
+
const errorLength = this.getAttribute('error_length');
|
7
|
+
const attributeID = this.getAttribute('attribute_id');
|
8
|
+
|
9
|
+
// MAJOR HACK - Come up with a better system some time
|
10
|
+
const authenticityQuery = `[name="authenticity_token"][value="${authenticityToken}"]`;
|
11
|
+
const editableTextContainer = document.querySelector(authenticityQuery).closest(".editable-text-container");
|
12
|
+
|
13
|
+
const messageTarget = editableTextContainer.querySelector(`[data-attribute-error-message-id="${attributeID}"]`);
|
14
|
+
const badgeTarget = editableTextContainer.querySelector(`[data-attribute-error-count-id="${attributeID}"]`);
|
15
|
+
|
16
|
+
|
17
|
+
if (messageTarget) {
|
18
|
+
messageTarget.classList.add("visible");
|
19
|
+
messageTarget.textContent = `${errorMessage}`;
|
20
|
+
}
|
21
|
+
|
22
|
+
if (badgeTarget) {
|
23
|
+
badgeTarget.classList.add("visible");
|
24
|
+
badgeTarget.textContent = `${errorLength}`;
|
25
|
+
}
|
26
|
+
};
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { Turbo } from "@hotwired/turbo-rails"
|
2
|
+
|
3
|
+
Turbo.StreamActions.toggle_class = function() {
|
4
|
+
const className = this.getAttribute("class");
|
5
|
+
const status = this.getAttribute("status");
|
6
|
+
|
7
|
+
this.targetElements.forEach((element) => {
|
8
|
+
if (status === "true") {
|
9
|
+
element.classList.add(className);
|
10
|
+
} else {
|
11
|
+
element.classList.remove(className);
|
12
|
+
}
|
13
|
+
});
|
14
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
*, h1, h2, h3, h4, h5, h6 {
|
2
|
+
margin: 0;
|
3
|
+
padding: 0;
|
4
|
+
}
|
5
|
+
|
6
|
+
ul, ol, li {
|
7
|
+
list-style-type: none;
|
8
|
+
}
|
9
|
+
|
10
|
+
button,
|
11
|
+
[type="submit"],
|
12
|
+
a {
|
13
|
+
border: none;
|
14
|
+
background: none;
|
15
|
+
text-decoration: none;
|
16
|
+
color: inherit;
|
17
|
+
padding: 0;
|
18
|
+
width: fit-content;
|
19
|
+
cursor: pointer;
|
20
|
+
font-weight: inherit;
|
21
|
+
}
|
22
|
+
|
23
|
+
button {
|
24
|
+
text-transform: inherit;
|
25
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
:root {
|
2
|
+
/* Default Theme Accent */
|
3
|
+
--theme-accent: #4A96FF;;
|
4
|
+
--accent: var(--theme-accent);
|
5
|
+
|
6
|
+
caret-color: var(--theme-accent);
|
7
|
+
}
|
8
|
+
|
9
|
+
::-moz-selection { /* Code for Firefox */
|
10
|
+
background: var(--theme-accent);;
|
11
|
+
}
|
12
|
+
|
13
|
+
::selection {
|
14
|
+
background: var(--theme-accent);;
|
15
|
+
}
|
16
|
+
|
17
|
+
.danger {
|
18
|
+
--accent: red;
|
19
|
+
}
|
20
|
+
|
21
|
+
body {
|
22
|
+
--theme-accent: #4A96FF;
|
23
|
+
--accent: var(--theme-accent);
|
24
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
:root {
|
2
|
+
font-size: 20px;
|
3
|
+
|
4
|
+
--side-padding: 30px;
|
5
|
+
|
6
|
+
--small-fs-3: 0.7rem;
|
7
|
+
--small-fs-2: 0.8rem;
|
8
|
+
--small-fs: 0.9rem;
|
9
|
+
--normal-fs: 1rem;
|
10
|
+
--large-fs: 1.25rem;
|
11
|
+
--large-fs-2: 1.5rem;
|
12
|
+
--large-fs-3: 2rem;
|
13
|
+
}
|
14
|
+
|
15
|
+
.small-fs-3 { font-size: var(--small-fs-3); }
|
16
|
+
.small-fs-2 { font-size: var(--small-fs-2); }
|
17
|
+
.small-fs { font-size: var(--small-fs); }
|
18
|
+
.normal-fs { font-size: var(--normal-fs); }
|
19
|
+
.large-fs { font-size: var(--large-fs); }
|
20
|
+
.large-fs-2 { font-size: var(--large-fs-2); }
|
21
|
+
.large-fs-3 { font-size: var(--large-fs-3); }
|
22
|
+
|
23
|
+
body {
|
24
|
+
--default-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
25
|
+
font-family: var(--default-font);
|
26
|
+
font-weight: 300;
|
27
|
+
|
28
|
+
-webkit-font-smoothing: antialiased;
|
29
|
+
-moz-osx-font-smoothing: grayscale;
|
30
|
+
}
|
31
|
+
|
32
|
+
[placeholder]:empty:before {
|
33
|
+
content: attr(placeholder);
|
34
|
+
color: var(--gray);
|
35
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
div,
|
2
|
+
li,
|
3
|
+
ul,
|
4
|
+
ol,
|
5
|
+
section,
|
6
|
+
main,
|
7
|
+
body,
|
8
|
+
footer,
|
9
|
+
nav,
|
10
|
+
header,
|
11
|
+
form,
|
12
|
+
turbo-frame {
|
13
|
+
display: flex;
|
14
|
+
flex-direction: inherit;
|
15
|
+
box-sizing: border-box;
|
16
|
+
}
|
17
|
+
|
18
|
+
body {
|
19
|
+
min-height: 100vh;
|
20
|
+
flex-direction: column;
|
21
|
+
}
|
22
|
+
|
23
|
+
:root {
|
24
|
+
--side-padding: 40px;
|
25
|
+
}
|
26
|
+
|
27
|
+
@media only screen and (max-width: 768px) {
|
28
|
+
:root {
|
29
|
+
--side-padding: 20px;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
.content {
|
34
|
+
padding: 20px var(--side-padding);
|
35
|
+
gap: 20px;
|
36
|
+
box-sizing: border-box;
|
37
|
+
}
|
38
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
:root {
|
2
|
+
--black: #000000;
|
3
|
+
--black-offset-1: #0b0b0b;
|
4
|
+
--black-offset-2: #1b1b1b;
|
5
|
+
--black-offset-3: #2b2b2b;
|
6
|
+
--dark-gray-1: #333333;
|
7
|
+
--dark-gray-2: #3b3b3b;
|
8
|
+
--semi-dark-gray-1: #555555;
|
9
|
+
--semi-dark-gray-2: #6b6b6b;
|
10
|
+
--semi-dark-gray-3: #7f7f7f;
|
11
|
+
--gray: #999999;
|
12
|
+
--semi-light-gray-3: #a6a6a6;
|
13
|
+
--semi-light-gray-2: #b3b3b3;
|
14
|
+
--semi-light-gray-1: #dadcdf;
|
15
|
+
--light-gray-2: #e0e0e0;
|
16
|
+
--light-gray-1: #e9ecef;
|
17
|
+
--white-offset-3: #f1f2f5;
|
18
|
+
--white-offset-2: #f7f8f9;
|
19
|
+
--white-offset-1: #f8f9fa;
|
20
|
+
--white: #FFFFFF;
|
21
|
+
|
22
|
+
--backdrop-1: var(--white);
|
23
|
+
--backdrop-2: var(--white-offset-1);
|
24
|
+
--backdrop-3: var(--white-offset-2);
|
25
|
+
--backdrop-4: var(--white-offset-3);
|
26
|
+
--backdrop-5: var(--light-gray-1);
|
27
|
+
--backdrop-6: var(--light-gray-2);
|
28
|
+
--backdrop-7: var(--semi-light-gray-1);
|
29
|
+
--backdrop-8: var(--semi-light-gray-2);
|
30
|
+
--backdrop-9: var(--semi-light-gray-3);
|
31
|
+
|
32
|
+
--foreground-1: var(--black);
|
33
|
+
--foreground-2: var(--black-offset-1);
|
34
|
+
--foreground-3: var(--black-offset-2);
|
35
|
+
--foreground-4: var(--black-offset-3);
|
36
|
+
--foreground-5: var(--dark-gray-1);
|
37
|
+
--foreground-6: var(--dark-gray-2);
|
38
|
+
--foreground-7: var(--semi-dark-gray-1);
|
39
|
+
--foreground-8: var(--semi-dark-gray-2);
|
40
|
+
--foreground-9: var(--semi-dark-gray-3);
|
41
|
+
|
42
|
+
--light-border-color-1: rgba(255,255,255, 0.05);
|
43
|
+
--light-border-color-2: rgba(255,255,255, 0.15);
|
44
|
+
--light-border-color-3: rgba(255,255,255, 0.25);
|
45
|
+
|
46
|
+
--dark-border-color-1: rgba(0,0,0, 0.05);
|
47
|
+
--dark-border-color-2: rgba(0,0,0, 0.15);
|
48
|
+
--dark-border-color-3: rgba(0,0,0, 0.25);
|
49
|
+
|
50
|
+
--standard-border: 2px solid var(--light-border-color-1);
|
51
|
+
--standard-color-border: 2px solid var(--light-border-color-3);
|
52
|
+
}
|
53
|
+
|
54
|
+
.dark-mode {
|
55
|
+
--backdrop-1: var(--black);
|
56
|
+
--backdrop-2: var(--black-offset-1);
|
57
|
+
--backdrop-3: var(--black-offset-2);
|
58
|
+
--backdrop-4: var(--black-offset-3);
|
59
|
+
--backdrop-5: var(--dark-gray-1);
|
60
|
+
--backdrop-6: var(--dark-gray-2);
|
61
|
+
--backdrop-7: var(--semi-dark-gray-1);
|
62
|
+
--backdrop-8: var(--semi-dark-gray-2);
|
63
|
+
--backdrop-9: var(--semi-dark-gray-3);
|
64
|
+
|
65
|
+
--foreground-1: var(--white);
|
66
|
+
--foreground-2: var(--white-offset-1);
|
67
|
+
--foreground-3: var(--white-offset-2);
|
68
|
+
--foreground-4: var(--white-offset-3);
|
69
|
+
--foreground-5: var(--light-gray-1);
|
70
|
+
--foreground-6: var(--light-gray-2);
|
71
|
+
--foreground-7: var(--semi-light-gray-1);
|
72
|
+
--foreground-8: var(--semi-light-gray-2);
|
73
|
+
--foreground-9: var(--semi-light-gray-3);
|
74
|
+
}
|
75
|
+
|
76
|
+
body {
|
77
|
+
background-color: var(--backdrop-1);
|
78
|
+
color: var(--foreground-1);
|
79
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
.flex {
|
2
|
+
display: flex;
|
3
|
+
flex-direction: inherit;
|
4
|
+
}
|
5
|
+
|
6
|
+
.flex-column {
|
7
|
+
display: flex;
|
8
|
+
flex-direction: column;
|
9
|
+
}
|
10
|
+
|
11
|
+
.flex-row {
|
12
|
+
display: flex;
|
13
|
+
flex-direction: row;
|
14
|
+
}
|
15
|
+
|
16
|
+
.split-right {
|
17
|
+
margin-left: auto;
|
18
|
+
}
|
19
|
+
|
20
|
+
.h-stack {
|
21
|
+
display: flex;
|
22
|
+
flex-direction: row;
|
23
|
+
align-items: center;
|
24
|
+
gap: 5px;
|
25
|
+
}
|
26
|
+
|
27
|
+
.v-stack {
|
28
|
+
display: flex;
|
29
|
+
flex-direction: column;
|
30
|
+
}
|
31
|
+
|
32
|
+
.hidden {
|
33
|
+
display: none;
|
34
|
+
}
|
@@ -10,6 +10,29 @@
|
|
10
10
|
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
11
|
* It is generally better to create a new file per style scope.
|
12
12
|
*
|
13
|
+
*= require normalize-rails
|
14
|
+
*= require font-awesome
|
13
15
|
*= require_tree .
|
14
16
|
*= require_self
|
15
17
|
*/
|
18
|
+
|
19
|
+
.nitro-form-submit {
|
20
|
+
cursor: pointer;
|
21
|
+
}
|
22
|
+
|
23
|
+
[data-action="click->nitro#link"] {
|
24
|
+
cursor: pointer;
|
25
|
+
position: relative;
|
26
|
+
}
|
27
|
+
|
28
|
+
[data-action="click->nitro#link"]:hover:before {
|
29
|
+
content: "";
|
30
|
+
position: absolute;
|
31
|
+
top: -2px;
|
32
|
+
left: -5px;
|
33
|
+
right: -5px;
|
34
|
+
bottom: -2px;
|
35
|
+
border-radius: 5px;
|
36
|
+
background-color: var(--backdrop-4);
|
37
|
+
z-index: -1;
|
38
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
.action-navigation {
|
2
|
+
display: flex;
|
3
|
+
flex-direction: row;
|
4
|
+
gap: 10px;
|
5
|
+
font-weight: 400;
|
6
|
+
align-items: center;
|
7
|
+
}
|
8
|
+
|
9
|
+
.action-navigation a:hover {
|
10
|
+
text-decoration: underline;
|
11
|
+
}
|
12
|
+
|
13
|
+
.action-navigation a.active {
|
14
|
+
color: var(--foreground-8);
|
15
|
+
pointer-events: none;
|
16
|
+
}
|
17
|
+
|
18
|
+
.action-navigation a.active:hover {
|
19
|
+
text-decoration: none;
|
20
|
+
}
|
21
|
+
|
22
|
+
.danger {
|
23
|
+
color: red;
|
24
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
/* Maybe call like AlertBar or NotificationBar or something */
|
2
|
+
.alert {
|
3
|
+
padding: 10px var(--side-padding);
|
4
|
+
background-color: var(--accent);
|
5
|
+
color: white;
|
6
|
+
font-weight: 600;
|
7
|
+
animation-name: hideAlert;
|
8
|
+
animation-duration: 4s;
|
9
|
+
margin-top: -43px;
|
10
|
+
}
|
11
|
+
|
12
|
+
@keyframes hideAlert {
|
13
|
+
0% {
|
14
|
+
margin-top: -43px;
|
15
|
+
filter: brightness(1);
|
16
|
+
}
|
17
|
+
20% {
|
18
|
+
margin-top: 0;
|
19
|
+
filter: brightness(1);
|
20
|
+
}
|
21
|
+
50% {
|
22
|
+
filter: brightness(1.1);
|
23
|
+
}
|
24
|
+
80% {
|
25
|
+
filter: brightness(1);
|
26
|
+
margin-top: 0;
|
27
|
+
}
|
28
|
+
100% {
|
29
|
+
margin-top: -43px;
|
30
|
+
}
|
31
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
/* Buttons */
|
2
|
+
|
3
|
+
.btn {
|
4
|
+
padding: 10px 15px;
|
5
|
+
background-color: var(--accent);
|
6
|
+
border-radius: 3px;
|
7
|
+
color: white;
|
8
|
+
font-size: var(--small-fs-2);
|
9
|
+
font-weight: bold;
|
10
|
+
text-transform: uppercase;
|
11
|
+
--accent: var(--theme-accent);
|
12
|
+
}
|
13
|
+
|
14
|
+
.btn:hover {
|
15
|
+
filter: brightness(0.8);
|
16
|
+
}
|
17
|
+
|
18
|
+
.btn-danger {
|
19
|
+
--accent: red;
|
20
|
+
}
|
21
|
+
|
22
|
+
/* .btn-new {
|
23
|
+
height: 50px;
|
24
|
+
width: 50px;
|
25
|
+
|
26
|
+
background-color: var(--accent);
|
27
|
+
color: white;
|
28
|
+
font-weight: bold;
|
29
|
+
border-radius: 50px;
|
30
|
+
|
31
|
+
text-align: center;
|
32
|
+
line-height: 50px;
|
33
|
+
|
34
|
+
font-size: var(--small-fs);
|
35
|
+
} */
|
36
|
+
|
37
|
+
.btn-new {
|
38
|
+
height: auto;
|
39
|
+
width: fit-content;
|
40
|
+
display: inline-block;
|
41
|
+
padding: 10px 15px;
|
42
|
+
|
43
|
+
background-color: var(--accent);
|
44
|
+
color: white;
|
45
|
+
font-weight: bold;
|
46
|
+
border-radius: 5px;
|
47
|
+
|
48
|
+
text-align: center;
|
49
|
+
text-transform: uppercase;
|
50
|
+
/* line-height: auto; */
|
51
|
+
|
52
|
+
font-size: var(--small-fs);
|
53
|
+
}
|
54
|
+
|
55
|
+
.btn-new:hover {
|
56
|
+
filter: brightness(0.8);
|
57
|
+
}
|