nitro_rails 0.1.0 → 0.1.2

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -0
  3. data/app/assets/audio/mousetap.mp3 +0 -0
  4. data/app/assets/config/nitro_rails_manifest.js +2 -0
  5. data/app/assets/images/nitro_rails/Aros2.png +0 -0
  6. data/app/assets/javascript/nitro_rails/application.js +4 -0
  7. data/app/assets/javascript/nitro_rails/controllers/application.js +9 -0
  8. data/app/assets/javascript/nitro_rails/controllers/audio_controller.js +16 -0
  9. data/app/assets/javascript/nitro_rails/controllers/clock_controller.js +21 -0
  10. data/app/assets/javascript/nitro_rails/controllers/editable_text_controller.js +61 -0
  11. data/app/assets/javascript/nitro_rails/controllers/index.js +21 -0
  12. data/app/assets/javascript/nitro_rails/controllers/nitro_collection_controller.js +127 -0
  13. data/app/assets/javascript/nitro_rails/controllers/nitro_controller.js +35 -0
  14. data/app/assets/javascript/nitro_rails/controllers/nitro_form_controller.js +81 -0
  15. data/app/assets/javascript/nitro_rails/controllers/panel_controller.js +70 -0
  16. data/app/assets/javascript/nitro_rails/controllers/panel_manager_controller.js +89 -0
  17. data/app/assets/javascript/nitro_rails/controllers/tabs_controller.js +81 -0
  18. data/app/assets/javascript/nitro_rails/controllers/time_zone_controller.js +47 -0
  19. data/app/assets/javascript/nitro_rails/controllers/togglable_checkbox_controller.js +9 -0
  20. data/app/assets/javascript/nitro_rails/helpers/device_info_helper.js +99 -0
  21. data/app/assets/javascript/nitro_rails/helpers/screen_info_helper.js +20 -0
  22. data/app/assets/javascript/nitro_rails/turbo_streams/clear_errors.js +22 -0
  23. data/app/assets/javascript/nitro_rails/turbo_streams/focus.js +8 -0
  24. data/app/assets/javascript/nitro_rails/turbo_streams/index.js +8 -0
  25. data/app/assets/javascript/nitro_rails/turbo_streams/insert.js +10 -0
  26. data/app/assets/javascript/nitro_rails/turbo_streams/redirect.js +10 -0
  27. data/app/assets/javascript/nitro_rails/turbo_streams/refresh_frame.js +9 -0
  28. data/app/assets/javascript/nitro_rails/turbo_streams/render_errors.js +26 -0
  29. data/app/assets/javascript/nitro_rails/turbo_streams/toggle_checkbox.js +9 -0
  30. data/app/assets/javascript/nitro_rails/turbo_streams/toggle_class.js +14 -0
  31. data/app/assets/stylesheets/nitro_rails/__reset.css +25 -0
  32. data/app/assets/stylesheets/nitro_rails/_base/_color.css +24 -0
  33. data/app/assets/stylesheets/nitro_rails/_base/_font.css +35 -0
  34. data/app/assets/stylesheets/nitro_rails/_base/_format.css +38 -0
  35. data/app/assets/stylesheets/nitro_rails/_base/_grayscale.css +79 -0
  36. data/app/assets/stylesheets/nitro_rails/_base/_utility.css +34 -0
  37. data/app/assets/stylesheets/nitro_rails/application.css +23 -0
  38. data/app/assets/stylesheets/nitro_rails/modules/action-navigation.css +24 -0
  39. data/app/assets/stylesheets/nitro_rails/modules/alert.css +31 -0
  40. data/app/assets/stylesheets/nitro_rails/modules/btn.css +57 -0
  41. data/app/assets/stylesheets/nitro_rails/modules/checkbox.css +42 -0
  42. data/app/assets/stylesheets/nitro_rails/modules/clickable.css +9 -0
  43. data/app/assets/stylesheets/nitro_rails/modules/clock.css +0 -0
  44. data/app/assets/stylesheets/nitro_rails/modules/editable-text.css +45 -0
  45. data/app/assets/stylesheets/nitro_rails/modules/forms.css +108 -0
  46. data/app/assets/stylesheets/nitro_rails/modules/hover-reveal.css +11 -0
  47. data/app/assets/stylesheets/nitro_rails/modules/inline-svg.css +14 -0
  48. data/app/assets/stylesheets/nitro_rails/modules/list.css +29 -0
  49. data/app/assets/stylesheets/nitro_rails/modules/main-navigation.css +20 -0
  50. data/app/assets/stylesheets/nitro_rails/modules/nitro-checkbox.css +42 -0
  51. data/app/assets/stylesheets/nitro_rails/modules/resource-collection.css +12 -0
  52. data/app/assets/stylesheets/nitro_rails/modules/search-bar.css +36 -0
  53. data/app/assets/stylesheets/nitro_rails/modules/settings.css +33 -0
  54. data/app/assets/stylesheets/nitro_rails/modules/tabs.css +38 -0
  55. data/app/assets/stylesheets/nitro_rails/modules/toggle-switch.css +60 -0
  56. data/app/assets/stylesheets/nitro_rails/panels/bound-card-dropdown-panel.css +0 -0
  57. data/app/assets/stylesheets/nitro_rails/panels/card-panel.css +0 -0
  58. data/app/assets/stylesheets/nitro_rails/panels/embedded-panel.css +31 -0
  59. data/app/assets/stylesheets/nitro_rails/panels/panel-display.css +111 -0
  60. data/app/assets/stylesheets/nitro_rails/panels/popup-panel.css +123 -0
  61. data/app/assets/stylesheets/nitro_rails/panels/side-panel.css +0 -0
  62. data/app/controllers/nitro_rails/sequence_controller.rb +64 -0
  63. data/app/helpers/nitro_rails/application_helper.rb +42 -1
  64. data/app/helpers/nitro_rails/color_helper.rb +23 -0
  65. data/app/helpers/nitro_rails/components_helper.rb +49 -0
  66. data/app/helpers/nitro_rails/inline_edit_helper.rb +48 -0
  67. data/app/helpers/nitro_rails/nitro_action_helper.rb +178 -0
  68. data/app/helpers/nitro_rails/nitro_collection_helper.rb +87 -0
  69. data/app/helpers/nitro_rails/nitro_edit_helper.rb +15 -0
  70. data/app/helpers/nitro_rails/nitro_form_helper.rb +104 -0
  71. data/app/helpers/nitro_rails/nitro_options_helper.rb +78 -0
  72. data/app/helpers/nitro_rails/nitro_tag_helper.rb +183 -0
  73. data/app/helpers/nitro_rails/panel_helper.rb +65 -0
  74. data/app/helpers/nitro_rails/resource_collection_helper.rb +66 -0
  75. data/app/helpers/nitro_rails/tabs_helper.rb +51 -0
  76. data/app/helpers/nitro_rails/turbo_stream_helper.rb +46 -0
  77. data/app/lib/nitro_rails/local_time.rb +51 -0
  78. data/app/lib/nitro_rails/performable_routes.rb +24 -0
  79. data/app/lib/nitro_rails/resource_collection.rb +183 -0
  80. data/app/lib/nitro_rails/sequential_routes.rb +36 -0
  81. data/app/lib/nitro_rails/time_interval.rb +88 -0
  82. data/app/lib/nitro_rails/time_string.rb +22 -0
  83. data/app/models/nitro_rails/broadcast.rb +76 -0
  84. data/app/models/nitro_rails/broadcastable_model.rb +91 -0
  85. data/app/models/nitro_rails/broadcastable_record.rb +118 -0
  86. data/app/models/nitro_rails/default_broadcasts.rb +149 -0
  87. data/app/models/nitro_rails/record.rb +50 -0
  88. data/app/pseudocode/nitro.html.erb +18 -0
  89. data/app/view_components/nitro_rails/nitro_collection/batch_selectable.rb +24 -0
  90. data/app/view_components/nitro_rails/nitro_collection.rb +66 -0
  91. data/app/view_components/nitro_rails/view_component.rb +9 -0
  92. data/app/views/layouts/nitro_rails/application.html.erb +3 -5
  93. data/app/views/nitro_rails/_editable_text.html.erb +32 -0
  94. data/app/views/nitro_rails/_nitro_checkbox.html.erb +5 -0
  95. data/app/views/nitro_rails/_nitro_form.html.erb +10 -0
  96. data/app/views/nitro_rails/_panel_frame_tag.html.erb +8 -0
  97. data/app/views/nitro_rails/_panel_template.html.erb +40 -0
  98. data/app/views/nitro_rails/_togglable_checkbox.html.erb +16 -0
  99. data/config/importmap.rb +1 -0
  100. data/config/initializers/date_formatters.rb +9 -0
  101. data/lib/nitro_rails/engine.rb +25 -0
  102. data/lib/nitro_rails/version.rb +1 -1
  103. metadata +166 -3
  104. 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,9 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+
3
+ export default class extends Controller {
4
+ static targets = [ "form", "checkbox" ];
5
+
6
+ submit() {
7
+ this.formTarget.requestSubmit();
8
+ }
9
+ }
@@ -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,8 @@
1
+ import './clear_errors'
2
+ import './render_errors'
3
+ import './toggle_class'
4
+ import './redirect'
5
+ import './toggle_checkbox'
6
+ import './insert'
7
+ import './focus'
8
+ import './refresh_frame'
@@ -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,9 @@
1
+ import { Turbo } from "@hotwired/turbo-rails"
2
+
3
+ Turbo.StreamActions.toggle_checkbox = function() {
4
+ const status = this.getAttribute("status");
5
+
6
+ this.targetElements.forEach((element) => {
7
+ element.checked = (status === "true")
8
+ });
9
+ };
@@ -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
+ }