trestle 0.10.0.pre → 0.10.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/.github/workflows/release.yml +26 -0
- data/.github/workflows/rspec.yml +6 -2
- data/Gemfile +14 -5
- data/README.md +1 -1
- data/app/assets/bundle/trestle/admin.css +9 -9
- data/app/assets/bundle/trestle/admin.js +13 -13
- data/app/assets/bundle/trestle/fa-brands-400.ttf +0 -0
- data/app/assets/bundle/trestle/fa-brands-400.woff2 +0 -0
- data/app/assets/bundle/trestle/fa-regular-400.ttf +0 -0
- data/app/assets/bundle/trestle/fa-regular-400.woff2 +0 -0
- data/app/assets/bundle/trestle/fa-solid-900.ttf +0 -0
- data/app/assets/bundle/trestle/fa-solid-900.woff2 +0 -0
- data/app/assets/bundle/trestle/photoswipe-063ce7be40e10b3e6848.digested.js +6 -0
- data/app/assets/sprockets/trestle/icons/font-awesome.css.erb +1 -1
- data/app/controllers/concerns/trestle/controller/modal.rb +3 -1
- data/app/controllers/concerns/trestle/controller/turbo_stream.rb +12 -0
- data/app/controllers/concerns/trestle/resource/controller/actions.rb +3 -3
- data/app/controllers/trestle/application_controller.rb +1 -1
- data/app/helpers/trestle/modal_helper.rb +0 -5
- data/app/helpers/trestle/turbo/frame_helper.rb +29 -0
- data/app/helpers/trestle/turbo/stream_helper.rb +9 -0
- data/app/helpers/trestle/turbo/tag_builder.rb +21 -0
- data/app/helpers/trestle/url_helper.rb +2 -2
- data/app/views/layouts/trestle/admin.html.erb +1 -1
- data/app/views/layouts/trestle/admin.turbo_stream.erb +2 -9
- data/app/views/trestle/application/_header.html.erb +12 -10
- data/app/views/trestle/resource/create.turbo_stream.erb +1 -5
- data/app/views/trestle/resource/destroy.turbo_stream.erb +1 -1
- data/app/views/trestle/resource/edit.html.erb +2 -0
- data/app/views/trestle/resource/index.html.erb +5 -0
- data/app/views/trestle/resource/new.html.erb +5 -0
- data/app/views/trestle/resource/show.html.erb +2 -0
- data/app/views/trestle/resource/update.turbo_stream.erb +1 -5
- data/app/views/trestle/shared/_sidebar.html.erb +2 -2
- data/frontend/css/components/_alerts.scss +22 -20
- data/frontend/css/components/_avatar.scss +12 -12
- data/frontend/css/components/_background.scss +1 -1
- data/frontend/css/components/_breadcrumbs.scss +8 -29
- data/frontend/css/components/_buttons.scss +3 -3
- data/frontend/css/components/_datepicker.scss +3 -3
- data/frontend/css/components/_dropdown.scss +18 -26
- data/frontend/css/components/_forms.scss +4 -4
- data/frontend/css/components/_grid.scss +29 -0
- data/frontend/css/components/_media-grid.scss +1 -1
- data/frontend/css/components/_modal.scss +4 -4
- data/frontend/css/components/_pagination.scss +4 -8
- data/frontend/css/components/_popover.scss +1 -1
- data/frontend/css/components/_scopes.scss +4 -10
- data/frontend/css/components/_select.scss +8 -9
- data/frontend/css/components/_sort.scss +1 -1
- data/frontend/css/components/_table.scss +5 -5
- data/frontend/css/components/_tabs.scss +11 -18
- data/frontend/css/components/_tags.scss +16 -6
- data/frontend/css/components/_toolbars.scss +9 -9
- data/frontend/css/core/_functions.scss +0 -8
- data/frontend/css/core/_theme.scss +3 -0
- data/frontend/css/core/_typography.scss +12 -19
- data/frontend/css/index.scss +3 -1
- data/frontend/css/layout/_base.scss +4 -2
- data/frontend/css/layout/_content-header.scss +71 -0
- data/frontend/css/layout/_footer.scss +5 -7
- data/frontend/css/layout/_main-content.scss +107 -0
- data/frontend/css/layout/_navigation.scss +111 -49
- data/frontend/css/layout/_sidebar.scss +60 -34
- data/frontend/css/variables/_bootstrap.scss +30 -21
- data/frontend/css/variables/_trestle.scss +20 -17
- data/frontend/js/controllers/batch_action_controller.js +59 -0
- data/frontend/js/controllers/checkbox_select_controller.js +3 -0
- data/frontend/js/controllers/confirm_delete_controller.js +4 -4
- data/frontend/js/controllers/gallery_controller.js +2 -0
- data/frontend/js/controllers/lightbox_controller.js +0 -2
- data/lib/trestle/engine.rb +18 -16
- data/lib/trestle/form/renderer.rb +1 -1
- data/lib/trestle/resource/toolbar.rb +18 -8
- data/lib/trestle/sprockets_compressor.rb +16 -0
- data/lib/trestle/toolbar/context.rb +7 -4
- data/lib/trestle/toolbar/menu.rb +8 -5
- data/lib/trestle/version.rb +1 -1
- data/package.json +1 -1
- data/trestle.gemspec +5 -9
- data/yarn.lock +350 -363
- metadata +35 -70
- data/app/assets/bundle/trestle/photoswipe-7aa1aec9c3c1fd65c382.digested.js +0 -6
- data/app/controllers/concerns/trestle/controller/turbo.rb +0 -21
- data/app/helpers/trestle/turbo_frame_helper.rb +0 -34
- data/frontend/css/layout/_content.scss +0 -173
@@ -1,9 +1,19 @@
|
|
1
1
|
@use "sass:math";
|
2
2
|
|
3
|
+
.app-wrapper {
|
4
|
+
--sidebar-width: #{$sidebar-width};
|
5
|
+
--sidebar-width-collapsed: #{$sidebar-width-collapsed};
|
6
|
+
--sidebar-padding: #{$sidebar-padding};
|
7
|
+
--sidebar-padding-collapsed: #{$sidebar-padding-collapsed};
|
8
|
+
--sidebar-transition-duration: #{$sidebar-transition-duration};
|
9
|
+
--sidebar-transition-timing: ease-out;
|
10
|
+
--sidebar-bg: #{$sidebar-bg};
|
11
|
+
}
|
12
|
+
|
3
13
|
.app-sidebar {
|
4
|
-
background:
|
14
|
+
background: var(--sidebar-bg);
|
5
15
|
|
6
|
-
width:
|
16
|
+
width: var(--sidebar-width);
|
7
17
|
padding: 0;
|
8
18
|
|
9
19
|
flex-shrink: 0;
|
@@ -15,6 +25,8 @@
|
|
15
25
|
flex-wrap: nowrap;
|
16
26
|
|
17
27
|
align-items: stretch;
|
28
|
+
|
29
|
+
transition: width var(--sidebar-transition-duration) var(--sidebar-transition-timing);
|
18
30
|
}
|
19
31
|
|
20
32
|
.app-sidebar-header {
|
@@ -25,10 +37,12 @@
|
|
25
37
|
display: flex;
|
26
38
|
align-items: stretch;
|
27
39
|
|
40
|
+
overflow: hidden;
|
41
|
+
|
28
42
|
.navbar-toggler {
|
29
|
-
|
30
|
-
|
31
|
-
|
43
|
+
--#{$prefix}navbar-toggler-bg: #{$sidebar-mobile-toggle-bg};
|
44
|
+
--#{$prefix}navbar-toggler-color: #{$sidebar-mobile-toggle-border-color};
|
45
|
+
--#{$prefix}navbar-toggler-border-color: #{$sidebar-mobile-toggle-border-color};
|
32
46
|
|
33
47
|
outline: none;
|
34
48
|
|
@@ -37,28 +51,29 @@
|
|
37
51
|
margin-left: math.div($grid-gutter-width, 2);
|
38
52
|
margin-right: math.div($grid-gutter-width, 2);
|
39
53
|
|
40
|
-
background: var(
|
54
|
+
background: var(--#{$prefix}navbar-toggler-bg);
|
41
55
|
|
42
56
|
&:hover, &:focus {
|
43
|
-
|
44
|
-
|
57
|
+
--#{$prefix}navbar-toggler-border-color: #{$sidebar-mobile-toggle-active-border-color};
|
58
|
+
--#{$prefix}navbar-toggler-bg: #{$sidebar-mobile-toggle-active-bg};
|
45
59
|
}
|
46
60
|
}
|
47
61
|
|
48
62
|
.navbar-toggler-icon {
|
49
|
-
|
63
|
+
--#{$prefix}navbar-toggler-icon-bg: #{$sidebar-mobile-toggle-icon-bg};
|
50
64
|
}
|
51
65
|
}
|
52
66
|
|
53
67
|
.app-sidebar-title {
|
54
|
-
flex: 1;
|
68
|
+
flex: 1 0 var(--sidebar-width);
|
69
|
+
width: var(--sidebar-width);
|
55
70
|
|
56
71
|
display: flex;
|
57
72
|
align-items: center;
|
58
73
|
|
59
|
-
padding:
|
74
|
+
padding: var(--sidebar-padding);
|
60
75
|
|
61
|
-
font-size: 1.
|
76
|
+
font-size: 1.25rem;
|
62
77
|
font-weight: 500;
|
63
78
|
text-shadow: rgba(black, 0.5) 0 1px 1px;
|
64
79
|
color: white;
|
@@ -72,7 +87,7 @@
|
|
72
87
|
max-height: 100%;
|
73
88
|
|
74
89
|
& + .title-large {
|
75
|
-
margin-left:
|
90
|
+
margin-left: 0.75rem;
|
76
91
|
}
|
77
92
|
}
|
78
93
|
|
@@ -112,8 +127,9 @@
|
|
112
127
|
color: $sidebar-toggle-color;
|
113
128
|
border: none;
|
114
129
|
|
115
|
-
font-size: 1.
|
116
|
-
|
130
|
+
font-size: 1.25rem;
|
131
|
+
width: var(--sidebar-width-collapsed);
|
132
|
+
padding: 0.625rem;
|
117
133
|
|
118
134
|
cursor: pointer;
|
119
135
|
|
@@ -138,19 +154,13 @@
|
|
138
154
|
}
|
139
155
|
|
140
156
|
.app-wrapper {
|
141
|
-
|
142
|
-
margin-right: 0;
|
157
|
+
width: calc(100% + var(--sidebar-width));
|
143
158
|
|
144
|
-
|
145
|
-
|
146
|
-
transition-property: margin-left, margin-right;
|
147
|
-
}
|
148
|
-
}
|
159
|
+
translate: calc(var(--sidebar-width) * -1);
|
160
|
+
transition: translate var(--sidebar-transition-duration) ease-out;
|
149
161
|
|
150
|
-
|
151
|
-
|
152
|
-
margin-left: 0;
|
153
|
-
margin-right: -$sidebar-width;
|
162
|
+
.mobile-nav-expanded & {
|
163
|
+
translate: 0;
|
154
164
|
}
|
155
165
|
}
|
156
166
|
|
@@ -161,14 +171,14 @@
|
|
161
171
|
.app-sidebar-header {
|
162
172
|
position: absolute;
|
163
173
|
top: 0;
|
164
|
-
left:
|
174
|
+
left: var(--sidebar-width);
|
165
175
|
right: 0;
|
166
176
|
z-index: 1;
|
167
177
|
}
|
168
178
|
|
169
179
|
.app-sidebar-title {
|
170
180
|
justify-content: center;
|
171
|
-
padding:
|
181
|
+
padding: var(--sidebar-padding-collapsed);
|
172
182
|
|
173
183
|
// Match right margin with navbar toggler width:
|
174
184
|
// (margin + border + font-size * icon-width + padding)
|
@@ -182,14 +192,17 @@
|
|
182
192
|
|
183
193
|
@include media-breakpoint-between(md, xl) {
|
184
194
|
.app-sidebar {
|
185
|
-
width:
|
195
|
+
width: var(--sidebar-width-collapsed);
|
186
196
|
|
187
197
|
.app-sidebar-header {
|
188
198
|
text-align: center;
|
189
199
|
}
|
190
200
|
|
191
201
|
.app-sidebar-title {
|
192
|
-
|
202
|
+
width: var(--sidebar-width-collapsed);
|
203
|
+
flex-basis: var(--sidebar-width-collapsed);
|
204
|
+
|
205
|
+
padding: var(--sidebar-padding-collapsed);
|
193
206
|
justify-content: center;
|
194
207
|
|
195
208
|
img {
|
@@ -210,14 +223,17 @@
|
|
210
223
|
}
|
211
224
|
|
212
225
|
.sidebar-expanded & {
|
213
|
-
width:
|
226
|
+
width: var(--sidebar-width);
|
214
227
|
|
215
228
|
.app-sidebar-header {
|
216
229
|
text-align: left;
|
217
230
|
}
|
218
231
|
|
219
232
|
.app-sidebar-title {
|
220
|
-
|
233
|
+
width: var(--sidebar-width);
|
234
|
+
flex-basis: var(--sidebar-width);
|
235
|
+
|
236
|
+
padding: var(--sidebar-padding);
|
221
237
|
justify-content: flex-start;
|
222
238
|
|
223
239
|
img {
|
@@ -243,14 +259,17 @@
|
|
243
259
|
@include media-breakpoint-up(xl) {
|
244
260
|
.app-sidebar {
|
245
261
|
.sidebar-collapsed & {
|
246
|
-
width:
|
262
|
+
width: var(--sidebar-width-collapsed);
|
247
263
|
|
248
264
|
.app-sidebar-header {
|
249
265
|
text-align: center;
|
250
266
|
}
|
251
267
|
|
252
268
|
.app-sidebar-title {
|
253
|
-
|
269
|
+
width: var(--sidebar-width-collapsed);
|
270
|
+
flex-basis: var(--sidebar-width-collapsed);
|
271
|
+
|
272
|
+
padding: var(--sidebar-padding-collapsed);
|
254
273
|
justify-content: center;
|
255
274
|
|
256
275
|
img {
|
@@ -272,3 +291,10 @@
|
|
272
291
|
}
|
273
292
|
}
|
274
293
|
}
|
294
|
+
|
295
|
+
@media (prefers-reduced-motion) {
|
296
|
+
.app-sidebar,
|
297
|
+
.app-wrapper {
|
298
|
+
transition: none;
|
299
|
+
}
|
300
|
+
}
|
@@ -23,7 +23,7 @@ $min-contrast-ratio: 1.7;
|
|
23
23
|
$enable-shadows: true;
|
24
24
|
|
25
25
|
// Decrease default grid spacing
|
26
|
-
$grid-gutter-width: 1.
|
26
|
+
$grid-gutter-width: 1.25rem;
|
27
27
|
|
28
28
|
|
29
29
|
// Characters which are escaped by the escape-svg function
|
@@ -49,15 +49,17 @@ $link-decoration: none;
|
|
49
49
|
$headings-font-weight: 400;
|
50
50
|
$headings-margin-bottom: 1rem;
|
51
51
|
|
52
|
-
$
|
53
|
-
|
54
|
-
$
|
55
|
-
$
|
56
|
-
$
|
57
|
-
$
|
52
|
+
$font-size-base: 0.875rem;
|
53
|
+
|
54
|
+
$h1-font-size: 1.75rem;
|
55
|
+
$h2-font-size: 1.5rem;
|
56
|
+
$h3-font-size: 1.25rem;
|
57
|
+
$h4-font-size: 1.125rem;
|
58
|
+
$h5-font-size: 0.95rem;
|
59
|
+
$h6-font-size: 0.875rem;
|
58
60
|
|
59
61
|
$hr-color: rgba(black, 0.375);
|
60
|
-
$hr-margin-y: 1.
|
62
|
+
$hr-margin-y: 1.25rem;
|
61
63
|
|
62
64
|
|
63
65
|
// Navs
|
@@ -80,8 +82,11 @@ $nav-tabs-link-active-color: $body-color;
|
|
80
82
|
|
81
83
|
// Navbar
|
82
84
|
|
83
|
-
$navbar-
|
84
|
-
$navbar-dark-color:
|
85
|
+
$navbar-light-color: rgba(white, 0.75);
|
86
|
+
$navbar-dark-color: rgba(white, 0.75);
|
87
|
+
|
88
|
+
$navbar-toggler-padding-x: 0.375rem;
|
89
|
+
$navbar-toggler-focus-width: 0.25rem;
|
85
90
|
|
86
91
|
|
87
92
|
// Breadcrumbs
|
@@ -94,7 +99,7 @@ $breadcrumb-divider-color: #cccccc;
|
|
94
99
|
|
95
100
|
// Tables
|
96
101
|
|
97
|
-
$table-cell-padding-x: 0.
|
102
|
+
$table-cell-padding-x: 0.5rem;
|
98
103
|
$table-cell-padding-y: 0.375rem;
|
99
104
|
|
100
105
|
$table-bg: transparent;
|
@@ -105,7 +110,7 @@ $table-border-color: rgba(black, 0.13);
|
|
105
110
|
|
106
111
|
// Alerts
|
107
112
|
|
108
|
-
$alert-padding-y: 1.
|
113
|
+
$alert-padding-y: 1.25rem;
|
109
114
|
$alert-border-radius: 0.1rem;
|
110
115
|
|
111
116
|
|
@@ -134,7 +139,8 @@ $badge-padding-x: 0.6em;
|
|
134
139
|
|
135
140
|
// Buttons
|
136
141
|
|
137
|
-
$btn-padding-x-sm: 0.
|
142
|
+
$btn-padding-x-sm: 0.625rem;
|
143
|
+
$btn-padding-y-sm: 0.25rem;
|
138
144
|
|
139
145
|
|
140
146
|
// Forms
|
@@ -163,7 +169,7 @@ $form-check-padding-start: $form-check-input-width + 0.6em;
|
|
163
169
|
$form-switch-width: 2.25em;
|
164
170
|
$form-switch-focus-color: #aaaaaa;
|
165
171
|
|
166
|
-
$form-select-padding-x-sm: 0.
|
172
|
+
$form-select-padding-x-sm: 0.625rem;
|
167
173
|
$form-select-padding-x-lg: 0.75rem;
|
168
174
|
|
169
175
|
|
@@ -175,7 +181,7 @@ $dropdown-box-shadow: $box-shadow-sm;
|
|
175
181
|
$dropdown-arrow-width: 7px;
|
176
182
|
$dropdown-arrow-outer-width: $dropdown-arrow-width + 1px;
|
177
183
|
$dropdown-header-color: #111111;
|
178
|
-
$dropdown-font-size: 0.
|
184
|
+
$dropdown-font-size: 0.8125rem;
|
179
185
|
|
180
186
|
$dropdown-link-active-bg: var(--primary);
|
181
187
|
|
@@ -208,24 +214,27 @@ $tooltip-color: white;
|
|
208
214
|
|
209
215
|
// Popovers
|
210
216
|
|
211
|
-
$popover-font-size: 0.
|
217
|
+
$popover-font-size: 0.75rem;
|
212
218
|
$popover-box-shadow: $dropdown-box-shadow;
|
213
219
|
|
214
220
|
$popover-header-bg: #f7f7f7;
|
215
221
|
$popover-header-border: #ebebeb;
|
216
222
|
|
223
|
+
$popover-header-padding-x: 0.625rem;
|
224
|
+
$popover-header-padding-y: 0.375rem;
|
225
|
+
|
226
|
+
$popover-body-padding-x: 0.625rem;
|
217
227
|
$popover-body-padding-y: 0.5rem;
|
218
|
-
$popover-body-padding-x: 0.75rem;
|
219
228
|
|
220
229
|
$popover-arrow-width: $dropdown-arrow-width;
|
221
230
|
|
222
231
|
|
223
232
|
// Modals
|
224
233
|
|
225
|
-
$modal-inner-padding: 1.
|
234
|
+
$modal-inner-padding: 1.25rem;
|
226
235
|
|
227
|
-
$modal-header-padding-x: 1.
|
228
|
-
$modal-header-padding-y:
|
236
|
+
$modal-header-padding-x: 1.25rem;
|
237
|
+
$modal-header-padding-y: 1rem;
|
229
238
|
|
230
239
|
$modal-content-bg: white;
|
231
240
|
$modal-content-border-radius: 0;
|
@@ -262,7 +271,7 @@ $s2bs5-clear-hover-bg-lg: $s2bs5-clear-bg-lg;
|
|
262
271
|
$s2bs5-clear-tag-icon: $btn-close-bg;
|
263
272
|
$s2bs5-clear-tag-bg: transparent escape-svg($s2bs5-clear-tag-icon) center / $s2b25-clear-height-sm auto no-repeat;
|
264
273
|
|
265
|
-
$s2bs5-padding-x: 0.
|
274
|
+
$s2bs5-padding-x: 0.625rem;
|
266
275
|
$s2bs5-padding-y: 0.375rem;
|
267
276
|
|
268
277
|
$s2bs5-multi-item-padding-x: 0.375rem;
|
@@ -21,7 +21,7 @@ $theme-bg-variations: (
|
|
21
21
|
$header-bg: white;
|
22
22
|
$header-color: #333333;
|
23
23
|
|
24
|
-
$header-height:
|
24
|
+
$header-height: 3.125rem;
|
25
25
|
|
26
26
|
|
27
27
|
// Footer
|
@@ -29,13 +29,15 @@ $header-height: 50px;
|
|
29
29
|
$footer-bg: #f9f9f9;
|
30
30
|
$footer-color: #888888;
|
31
31
|
|
32
|
+
$footer-padding: 0.375rem 1.25rem;
|
33
|
+
|
32
34
|
|
33
35
|
// Sidebar
|
34
36
|
|
35
37
|
$sidebar-bg: #222222;
|
36
38
|
$sidebar-hover-bg: #1a1a1a;
|
37
39
|
$sidebar-active-bg: #393939;
|
38
|
-
$sidebar-active-border:
|
40
|
+
$sidebar-active-border: 0.25rem;
|
39
41
|
|
40
42
|
$sidebar-link-color: #919191;
|
41
43
|
$sidebar-group-color: #595959;
|
@@ -56,10 +58,13 @@ $sidebar-mobile-toggle-active-border-width: $sidebar-mobile-toggle-border-width;
|
|
56
58
|
$sidebar-mobile-toggle-active-border-color: $sidebar-mobile-toggle-border-color;
|
57
59
|
$sidebar-mobile-toggle-active-border: $sidebar-mobile-toggle-border-width solid $sidebar-mobile-toggle-active-border-color;
|
58
60
|
|
59
|
-
$sidebar-width:
|
60
|
-
$sidebar-width-collapsed:
|
61
|
+
$sidebar-width: 15.625rem;
|
62
|
+
$sidebar-width-collapsed: 3.5rem;
|
63
|
+
|
64
|
+
$sidebar-padding: 0.5rem 0.875rem;
|
65
|
+
$sidebar-padding-collapsed: 0.5rem 0.25rem;
|
61
66
|
|
62
|
-
$sidebar-transition-duration:
|
67
|
+
$sidebar-transition-duration: 200ms;
|
63
68
|
|
64
69
|
|
65
70
|
// Content
|
@@ -67,23 +72,21 @@ $sidebar-transition-duration: 250ms;
|
|
67
72
|
$content-header-bg: #fafafa;
|
68
73
|
$content-sidebar-bg: #f9f9f9;
|
69
74
|
|
70
|
-
$content-sidebar-width:
|
75
|
+
$content-sidebar-width: 17.5rem;
|
71
76
|
|
72
|
-
$main-content-header-bg:
|
73
|
-
$main-content-header-
|
74
|
-
$main-content-header-border: 1px solid rgba(black, 0.1);
|
77
|
+
$main-content-header-bg: $content-sidebar-bg;
|
78
|
+
$main-content-header-border: 1px solid rgba(black, 0.1);
|
75
79
|
|
76
|
-
$main-content-footer-bg:
|
77
|
-
$main-content-footer-
|
78
|
-
$main-content-footer-border: 1px solid rgba(black, 0.1);
|
80
|
+
$main-content-footer-bg: $content-sidebar-bg;
|
81
|
+
$main-content-footer-border: 1px solid rgba(black, 0.1);
|
79
82
|
|
80
83
|
|
81
84
|
// Typography
|
82
85
|
|
83
86
|
$headings-border: 1px solid rgba(black, 0.1);
|
84
87
|
|
85
|
-
$header-font-size-scale: 0.
|
86
|
-
$sidebar-font-size-scale: 0.
|
88
|
+
$header-font-size-scale: 0.8125;
|
89
|
+
$sidebar-font-size-scale: 0.8125;
|
87
90
|
|
88
91
|
$badge-hover-scale: -15%;
|
89
92
|
|
@@ -96,13 +99,13 @@ $tag-border-scale: 0;
|
|
96
99
|
$tag-hover-bg-scale: -15%;
|
97
100
|
$tag-hover-border-scale: 15%;
|
98
101
|
|
99
|
-
$tag-spacing-x: 0.
|
100
|
-
$tag-spacing-y: 0.
|
102
|
+
$tag-spacing-x: 0.25rem;
|
103
|
+
$tag-spacing-y: 0.2rem;
|
101
104
|
|
102
105
|
|
103
106
|
// Scopes
|
104
107
|
|
105
|
-
$scope-padding: 0.
|
108
|
+
$scope-padding: 0.2rem 0.625rem;
|
106
109
|
|
107
110
|
$scope-color: rgba(black, 0.4);
|
108
111
|
$scope-bg: rgba(black, 0.035);
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import ApplicationController from './application_controller'
|
2
|
+
|
3
|
+
export default class extends ApplicationController {
|
4
|
+
static outlets = ['checkbox-select']
|
5
|
+
|
6
|
+
connect () {
|
7
|
+
if (!this.hasCheckboxSelectOutlet) {
|
8
|
+
// Set default outlet if none specified
|
9
|
+
this.element.setAttribute(`data-${this.identifier}-checkbox-select-outlet`, '.trestle-table')
|
10
|
+
}
|
11
|
+
|
12
|
+
this.baseHref = this.element.href
|
13
|
+
|
14
|
+
this.update()
|
15
|
+
}
|
16
|
+
|
17
|
+
update () {
|
18
|
+
this.toggleEnabled()
|
19
|
+
this.updateHref()
|
20
|
+
}
|
21
|
+
|
22
|
+
toggleEnabled () {
|
23
|
+
this.element.classList.toggle('disabled', this.checkboxes.length === 0)
|
24
|
+
}
|
25
|
+
|
26
|
+
updateHref () {
|
27
|
+
this.element.href = this.hrefWithSelectedIds
|
28
|
+
}
|
29
|
+
|
30
|
+
get checkboxes () {
|
31
|
+
if (this.hasCheckboxSelectOutlet) {
|
32
|
+
return this.checkboxSelectOutlet.checked
|
33
|
+
} else {
|
34
|
+
return []
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
get selectedIds () {
|
39
|
+
return this.checkboxes.map(c => c.value)
|
40
|
+
}
|
41
|
+
|
42
|
+
get hrefWithSelectedIds () {
|
43
|
+
const ids = this.selectedIds
|
44
|
+
|
45
|
+
if (ids.length) {
|
46
|
+
return `${this.baseHref}?ids=${ids.join(',')}`
|
47
|
+
} else {
|
48
|
+
return this.baseHref
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
checkboxSelectOutletConnected (outlet, element) {
|
53
|
+
element.addEventListener('checkbox-select:change', this.update.bind(this))
|
54
|
+
}
|
55
|
+
|
56
|
+
checkboxSelectOutletDisconnected (outlet, element) {
|
57
|
+
element.removeEventListener('checkbox-select:change', this.update.bind(this))
|
58
|
+
}
|
59
|
+
}
|
@@ -5,6 +5,7 @@ export default class extends ApplicationController {
|
|
5
5
|
|
6
6
|
toggle () {
|
7
7
|
this.updateSelectAllState()
|
8
|
+
this.dispatch('change')
|
8
9
|
}
|
9
10
|
|
10
11
|
toggleAll () {
|
@@ -13,6 +14,8 @@ export default class extends ApplicationController {
|
|
13
14
|
this.checkboxTargets.forEach((checkbox) => {
|
14
15
|
checkbox.checked = isChecked
|
15
16
|
})
|
17
|
+
|
18
|
+
this.dispatch('change')
|
16
19
|
}
|
17
20
|
|
18
21
|
updateSelectAllState () {
|
@@ -3,9 +3,9 @@ import ConfirmController from './confirm_controller'
|
|
3
3
|
import { i18n } from '../core/i18n'
|
4
4
|
|
5
5
|
export default class extends ConfirmController {
|
6
|
-
static values = {
|
7
|
-
confirmLabel: i18n['trestle.confirmation.delete'] || 'Delete'
|
8
|
-
}
|
9
|
-
|
10
6
|
static defaultConfirmClass = 'btn-danger'
|
7
|
+
|
8
|
+
get confirmLabel () {
|
9
|
+
return this.confirmLabelValue || i18n.t('trestle.confirmation.delete', { defaultValue: 'Delete' })
|
10
|
+
}
|
11
11
|
}
|
data/lib/trestle/engine.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "turbo-rails"
|
2
|
+
|
1
3
|
module Trestle
|
2
4
|
class Engine < ::Rails::Engine
|
3
5
|
isolate_namespace Trestle
|
@@ -30,22 +32,6 @@ module Trestle
|
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
initializer "turbo.mimetype" do
|
34
|
-
Mime::Type.register "text/vnd.turbo-stream.html", :turbo_stream unless Mime[:turbo_stream]
|
35
|
-
end
|
36
|
-
|
37
|
-
initializer "turbo.renderer" do
|
38
|
-
ActiveSupport.on_load(:action_controller) do
|
39
|
-
# Compatibility fix for Rails 5.2
|
40
|
-
delegate :media_type, to: "@_response" unless instance_methods.include?(:media_type)
|
41
|
-
|
42
|
-
ActionController::Renderers.add :turbo_stream do |turbo_streams_html, options|
|
43
|
-
self.content_type = Mime[:turbo_stream] if media_type.nil?
|
44
|
-
turbo_streams_html
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
35
|
config.to_prepare do
|
50
36
|
Engine.reset_helpers!
|
51
37
|
end
|
@@ -55,6 +41,22 @@ module Trestle
|
|
55
41
|
reloader.install(app) unless app.config.eager_load
|
56
42
|
end
|
57
43
|
|
44
|
+
# For compatibility with the `sassc-rails`` gem, register a custom compressor that excludes the
|
45
|
+
# Trestle admin stylesheets as a) they are already minimized and b) libsass is not compatible with
|
46
|
+
# some of the newer CSS syntax that is used.
|
47
|
+
#
|
48
|
+
# To avoid this being necessary, it is recommended that either
|
49
|
+
# 1) `sassc-rails` is removed from the Gemfile (if not required),
|
50
|
+
# 2) the `sassc-embedded` gem is added to the Gemfile, or
|
51
|
+
# 3) `sassc-rails` is replaced with `dartsass-sprockets`
|
52
|
+
config.assets.configure do |env|
|
53
|
+
if original_compressor = config.assets.css_compressor
|
54
|
+
require "trestle/sprockets_compressor"
|
55
|
+
original_compressor = Sprockets.compressors['text/css'][original_compressor] if original_compressor.is_a?(Symbol)
|
56
|
+
config.assets.css_compressor = Trestle::SprocketsCompressor.new(original_compressor)
|
57
|
+
end
|
58
|
+
end if defined?(SassC::Rails)
|
59
|
+
|
58
60
|
def reset_helpers!
|
59
61
|
@helpers = nil
|
60
62
|
end
|
@@ -14,7 +14,7 @@ module Trestle
|
|
14
14
|
include Hook::Helpers
|
15
15
|
|
16
16
|
# Whitelisted helpers will concatenate their result to the output buffer when called.
|
17
|
-
WHITELISTED_HELPERS = [:row, :col, :render, :tab, :table, :divider, :h1, :h2, :h3, :h4, :h5, :h6, :card, :panel, :well]
|
17
|
+
WHITELISTED_HELPERS = [:row, :col, :render, :tab, :table, :divider, :h1, :h2, :h3, :h4, :h5, :h6, :card, :panel, :well, :turbo_frame_tag]
|
18
18
|
|
19
19
|
# Raw block helpers will pass their block argument directly to the method without wrapping it in a new output buffer.
|
20
20
|
RAW_BLOCK_HELPERS = [:table, :toolbar]
|
@@ -5,20 +5,30 @@ module Trestle
|
|
5
5
|
delegate :admin, :instance, to: :@template
|
6
6
|
delegate :translate, :t, to: :admin
|
7
7
|
|
8
|
-
def new
|
9
|
-
|
8
|
+
def new(label: t("buttons.new", default: "New %{model_name}"), **attrs)
|
9
|
+
return unless action?(:new)
|
10
|
+
|
11
|
+
defaults = { action: :new, style: :light, icon: "fa fa-plus", class: "btn-new-resource" }
|
12
|
+
link(label, defaults.merge(attrs))
|
10
13
|
end
|
11
14
|
|
12
|
-
def save
|
13
|
-
|
15
|
+
def save(label: t("buttons.save", default: "Save %{model_name}"), **attrs)
|
16
|
+
defaults = { style: :success }
|
17
|
+
button(label, defaults.merge(attrs))
|
14
18
|
end
|
15
19
|
|
16
|
-
def delete
|
17
|
-
|
20
|
+
def delete(label: t("buttons.delete", default: "Delete %{model_name}"), **attrs)
|
21
|
+
return unless action?(:destroy)
|
22
|
+
|
23
|
+
defaults = Trestle::Options.new(action: :destroy, style: :danger, icon: "fa fa-trash", data: { turbo_method: "delete", turbo_frame: "_top", controller: "confirm-delete", confirm_delete_placement_value: "bottom" })
|
24
|
+
link(label, instance, defaults.merge(attrs))
|
18
25
|
end
|
19
26
|
|
20
|
-
def dismiss
|
21
|
-
|
27
|
+
def dismiss(label: t("buttons.ok", default: "OK"), **attrs)
|
28
|
+
return unless @template.modal_request?
|
29
|
+
|
30
|
+
defaults = Trestle::Options.new(type: :button, style: :light, data: { bs_dismiss: "modal" })
|
31
|
+
button(label, defaults.merge(attrs))
|
22
32
|
end
|
23
33
|
alias ok dismiss
|
24
34
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Trestle
|
2
|
+
class SprocketsCompressor
|
3
|
+
def initialize(original_compressor, excluded_files: ["trestle/admin"])
|
4
|
+
@original_compressor = original_compressor
|
5
|
+
@excluded_files = excluded_files
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(input)
|
9
|
+
if @excluded_files.include?(input[:name])
|
10
|
+
input[:data]
|
11
|
+
else
|
12
|
+
@original_compressor.call(input)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -21,11 +21,10 @@ module Trestle
|
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
24
|
-
def
|
25
|
-
|
26
|
-
end
|
24
|
+
def self.ruby2_keywords(*)
|
25
|
+
end unless respond_to?(:ruby2_keywords, true)
|
27
26
|
|
28
|
-
def method_missing(name, *args, &block)
|
27
|
+
ruby2_keywords def method_missing(name, *args, &block)
|
29
28
|
result = builder.send(name, *args, &block)
|
30
29
|
|
31
30
|
if builder.builder_methods.include?(name)
|
@@ -34,6 +33,10 @@ module Trestle
|
|
34
33
|
result
|
35
34
|
end
|
36
35
|
end
|
36
|
+
|
37
|
+
def respond_to_missing?(name, include_all=false)
|
38
|
+
builder.respond_to?(name) || super
|
39
|
+
end
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|