coveragebook_components 0.7.9 → 0.8.0.beta.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/app/assets/build/coco/app.css +1134 -165
- data/app/assets/build/coco/app.js +307 -49
- data/app/assets/build/coco/book.css +55 -9
- data/app/assets/build/coco/book.js +24 -2
- data/app/assets/css/app/tippy.css +4 -0
- data/app/assets/css/base/base.css +12 -0
- data/app/assets/css/base/components/coco.css +0 -3
- data/app/assets/js/app/setup.js +22 -0
- data/app/assets/js/app.js +2 -0
- data/app/assets/js/helpers/location.js +9 -0
- data/app/assets/js/libs/tippy/index.js +7 -2
- data/app/components/coco/app/blocks/header/header.css +43 -0
- data/app/components/coco/app/blocks/header/header.html.erb +30 -0
- data/app/components/coco/app/blocks/header/header.js +11 -0
- data/app/components/coco/app/blocks/header/header.rb +35 -0
- data/app/components/coco/app/blocks/nav_drawer/nav_drawer.css +48 -3
- data/app/components/coco/app/blocks/nav_drawer/nav_drawer.html.erb +14 -6
- data/app/components/coco/app/blocks/nav_drawer/nav_drawer.js +18 -1
- data/app/components/coco/app/blocks/nav_drawer/nav_drawer.rb +26 -1
- data/app/components/coco/app/blocks/sidebar_nav/sidebar_nav.css +104 -0
- data/app/components/coco/app/blocks/sidebar_nav/sidebar_nav.html.erb +42 -0
- data/app/components/coco/app/blocks/sidebar_nav/sidebar_nav.js +28 -0
- data/app/components/coco/app/blocks/sidebar_nav/sidebar_nav.rb +28 -0
- data/app/components/coco/app/blocks/sidebar_nav_item/sidebar_nav_item.css +165 -0
- data/app/components/coco/app/blocks/sidebar_nav_item/sidebar_nav_item.html.erb +43 -0
- data/app/components/coco/app/blocks/sidebar_nav_item/sidebar_nav_item.js +41 -0
- data/app/components/coco/app/blocks/sidebar_nav_item/sidebar_nav_item.rb +98 -0
- data/app/components/coco/app/elements/alert/alert.css +65 -18
- data/app/components/coco/app/elements/alert/alert.html.erb +20 -5
- data/app/components/coco/app/elements/alert/alert.js +4 -3
- data/app/components/coco/app/elements/alert/alert.rb +16 -6
- data/app/components/coco/app/elements/button/button.css +87 -5
- data/app/components/coco/app/elements/button/button.rb +3 -1
- data/app/components/coco/app/elements/button_group/button_group.rb +4 -0
- data/app/components/coco/app/elements/button_to/button_to.css +5 -1
- data/app/components/coco/app/elements/button_to/button_to.rb +8 -1
- data/app/components/coco/app/elements/color_picker/color_picker.rb +1 -1
- data/app/components/coco/app/elements/menu/menu.css +5 -0
- data/app/components/coco/app/elements/menu/menu.html.erb +1 -1
- data/app/components/coco/app/elements/menu/menu.rb +2 -1
- data/app/components/coco/app/elements/menu_button/menu_button.html.erb +6 -0
- data/app/components/coco/app/elements/menu_button/menu_button.rb +8 -9
- data/app/components/coco/app/elements/menu_items/user_profile/user_profile.css +22 -0
- data/app/components/coco/app/elements/menu_items/user_profile/user_profile.html.erb +17 -0
- data/app/components/coco/app/elements/menu_items/user_profile/user_profile.rb +20 -0
- data/app/components/coco/app/elements/notice/notice.css +4 -0
- data/app/components/coco/app/elements/notice/notice.rb +2 -2
- data/app/components/coco/app/elements/snackbar/snackbar.css +8 -1
- data/app/components/coco/app/elements/snackbar/snackbar.rb +2 -2
- data/app/components/coco/app/elements/system_banner/system_banner.html.erb +2 -1
- data/app/components/coco/app/elements/system_banner/system_banner.js +35 -2
- data/app/components/coco/app/elements/system_banner/system_banner.rb +47 -3
- data/app/components/coco/app/layouts/application/application.css +104 -4
- data/app/components/coco/app/layouts/application/application.html.erb +28 -7
- data/app/components/coco/app/layouts/application/application.js +16 -0
- data/app/components/coco/app/layouts/application/application.rb +11 -3
- data/app/components/coco/base/avatar/avatar.css +25 -0
- data/app/components/coco/base/avatar/avatar.rb +20 -0
- data/app/components/coco/base/icon/icon.css +6 -2
- data/app/components/coco/base/icon/icon.rb +1 -1
- data/app/components/coco/base/modal/modal.css +2 -1
- data/app/components/coco/base/modal/modal.html.erb +1 -1
- data/app/components/coco/base/modal/modal.js +2 -0
- data/app/components/coco/base/modal_lightbox/modal_lightbox.js +2 -2
- data/app/components/coco/base/placeholder/placeholder.css +15 -1
- data/app/components/coco/base/placeholder/placeholder.rb +2 -0
- data/app/components/coco/concerns/accepts_tag_attributes.rb +6 -2
- data/app/components/coco/concerns/acts_as_button_group.rb +30 -12
- data/app/helpers/coco/app_helper.rb +26 -2
- data/app/helpers/coco/base_helper.rb +6 -0
- data/app/helpers/coco/url_helper.rb +5 -1
- data/config/tailwind.base.config.cjs +3 -0
- data/config/tokens.cjs +6 -0
- data/lib/coco.rb +1 -1
- metadata +24 -10
- data/app/components/coco/app/blocks/banner/banner.css +0 -5
- data/app/components/coco/app/blocks/banner/banner.rb +0 -8
- data/app/components/coco/app/blocks/nav_bar/nav_bar.css +0 -51
- data/app/components/coco/app/blocks/nav_bar/nav_bar.html.erb +0 -23
- data/app/components/coco/app/blocks/nav_bar/nav_bar.js +0 -31
- data/app/components/coco/app/blocks/nav_bar/nav_bar.rb +0 -19
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
&[data-theme="primary"],
|
|
15
15
|
&[data-theme="positive"] {
|
|
16
|
-
@apply bg-background-primary text-content-light-1 hover:bg-primary-600 active:bg-primary-700;
|
|
16
|
+
@apply bg-background-primary text-content-light-1 hover:bg-primary-600 active:bg-primary-700 antialiased;
|
|
17
17
|
|
|
18
18
|
&[data-state="loading"] {
|
|
19
19
|
@apply bg-background-primary;
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
&[data-theme="negative"] {
|
|
108
|
-
@apply bg-background-negative text-content-light-1 hover:bg-negative-700 active:bg-negative-800;
|
|
108
|
+
@apply bg-background-negative text-content-light-1 hover:bg-negative-700 active:bg-negative-800 antialiased;
|
|
109
109
|
|
|
110
110
|
&[data-state="loading"] {
|
|
111
111
|
@apply bg-background-negative;
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
&[data-theme="warning"] {
|
|
148
|
-
@apply bg-background-warning text-content-light-1 hover:bg-warning-700 active:bg-warning-800;
|
|
148
|
+
@apply bg-background-warning text-content-light-1 hover:bg-warning-700 active:bg-warning-800 antialiased;
|
|
149
149
|
|
|
150
150
|
&[data-state="loading"] {
|
|
151
151
|
@apply bg-background-warning;
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
&[data-theme="info"] {
|
|
188
|
-
@apply bg-background-info text-content-light-1 hover:bg-info-700 active:bg-info-800;
|
|
188
|
+
@apply bg-background-info text-content-light-1 hover:bg-info-700 active:bg-info-800 antialiased;
|
|
189
189
|
|
|
190
190
|
&[data-state="loading"] {
|
|
191
191
|
@apply bg-background-info;
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
&[data-theme="neutral-dark"] {
|
|
228
|
-
@apply bg-background-dark-1 text-content-light-1 hover:bg-gray-700 active:bg-gray-600;
|
|
228
|
+
@apply bg-background-dark-1 text-content-light-1 hover:bg-gray-700 active:bg-gray-600 antialiased;
|
|
229
229
|
|
|
230
230
|
&[data-state="loading"] {
|
|
231
231
|
@apply bg-background-dark-1;
|
|
@@ -260,8 +260,36 @@
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
&[data-theme="text-neutral-light"] {
|
|
264
|
+
@apply bg-transparent text-content-light-1 hover:bg-content-light-1/10 antialiased;
|
|
265
|
+
|
|
266
|
+
&[data-state="active"] {
|
|
267
|
+
@apply bg-content-light-1/10;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
&[data-disabled="true"] {
|
|
271
|
+
@apply opacity-30;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
&[data-theme="text-neutral-dark"] {
|
|
276
|
+
@apply bg-transparent text-content-dark-1 hover:bg-content-dark-1/10;
|
|
277
|
+
|
|
278
|
+
&[data-state="active"] {
|
|
279
|
+
@apply bg-content-dark-1/10;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
&[data-disabled="true"] {
|
|
283
|
+
@apply opacity-30;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
263
287
|
/* Responsive resizing */
|
|
264
288
|
|
|
289
|
+
&[data-size="xs"] {
|
|
290
|
+
@apply app-button-xs;
|
|
291
|
+
}
|
|
292
|
+
|
|
265
293
|
&[data-size="sm"] {
|
|
266
294
|
@apply app-button-sm;
|
|
267
295
|
}
|
|
@@ -275,6 +303,10 @@
|
|
|
275
303
|
}
|
|
276
304
|
|
|
277
305
|
@media screen(md) {
|
|
306
|
+
&[data-size-md="xs"] {
|
|
307
|
+
@apply app-button-xs;
|
|
308
|
+
}
|
|
309
|
+
|
|
278
310
|
&[data-size-md="sm"] {
|
|
279
311
|
@apply app-button-sm;
|
|
280
312
|
}
|
|
@@ -289,6 +321,10 @@
|
|
|
289
321
|
}
|
|
290
322
|
|
|
291
323
|
@media screen(lg) {
|
|
324
|
+
&[data-size-lg="xs"] {
|
|
325
|
+
@apply app-button-xs;
|
|
326
|
+
}
|
|
327
|
+
|
|
292
328
|
&[data-size-lg="sm"] {
|
|
293
329
|
@apply app-button-sm;
|
|
294
330
|
}
|
|
@@ -303,6 +339,10 @@
|
|
|
303
339
|
}
|
|
304
340
|
|
|
305
341
|
@media screen(xl) {
|
|
342
|
+
&[data-size-xl="xs"] {
|
|
343
|
+
@apply app-button-xs;
|
|
344
|
+
}
|
|
345
|
+
|
|
306
346
|
&[data-size-xl="sm"] {
|
|
307
347
|
@apply app-button-sm;
|
|
308
348
|
}
|
|
@@ -317,6 +357,11 @@
|
|
|
317
357
|
}
|
|
318
358
|
|
|
319
359
|
@media screen(2xl) {
|
|
360
|
+
&[data-size-xxl="xs"],
|
|
361
|
+
&[data-size-2xl="xs"] {
|
|
362
|
+
@apply app-button-xs;
|
|
363
|
+
}
|
|
364
|
+
|
|
320
365
|
&[data-size-xxl="sm"],
|
|
321
366
|
&[data-size-2xl="sm"] {
|
|
322
367
|
@apply app-button-sm;
|
|
@@ -334,6 +379,10 @@
|
|
|
334
379
|
}
|
|
335
380
|
|
|
336
381
|
@media screen(max) {
|
|
382
|
+
&[data-size-max="xs"] {
|
|
383
|
+
@apply app-button-xs;
|
|
384
|
+
}
|
|
385
|
+
|
|
337
386
|
&[data-size-max="sm"] {
|
|
338
387
|
@apply app-button-sm;
|
|
339
388
|
}
|
|
@@ -350,6 +399,39 @@
|
|
|
350
399
|
}
|
|
351
400
|
|
|
352
401
|
@layer utilities {
|
|
402
|
+
.app-button-xs {
|
|
403
|
+
.button-content {
|
|
404
|
+
@apply text-label-xs;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.button-icon [data-component="icon"],
|
|
408
|
+
.button-toggle {
|
|
409
|
+
@apply w-3.5 h-3.5;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
&[data-theme] {
|
|
413
|
+
.button-element {
|
|
414
|
+
@apply py-2 px-3;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
&.icon-only > .button-element .button-icon,
|
|
418
|
+
&[data-collapsed="true"] > .button-element .button-icon {
|
|
419
|
+
@apply -ml-1.5 -mr-1.5;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
&[data-theme|="text"] {
|
|
424
|
+
.button-element {
|
|
425
|
+
@apply px-1;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
&.icon-only > .button-element .button-icon,
|
|
429
|
+
&[data-collapsed="true"] > .button-element .button-icon {
|
|
430
|
+
@apply px-2;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
353
435
|
.app-button-sm {
|
|
354
436
|
.button-content {
|
|
355
437
|
@apply text-label-sm;
|
|
@@ -2,7 +2,7 @@ module Coco
|
|
|
2
2
|
module App
|
|
3
3
|
module Elements
|
|
4
4
|
class Button < Coco::Button
|
|
5
|
-
SIZES = [:sm, :md, :lg, nil]
|
|
5
|
+
SIZES = [:xs, :sm, :md, :lg, nil]
|
|
6
6
|
|
|
7
7
|
SIZE_ALIASES = {
|
|
8
8
|
default: [:sm, {xl: :md}]
|
|
@@ -26,6 +26,8 @@ module Coco
|
|
|
26
26
|
"text-toolbar",
|
|
27
27
|
"neutral-dark",
|
|
28
28
|
"neutral-light",
|
|
29
|
+
"text-neutral-light",
|
|
30
|
+
"text-neutral-dark",
|
|
29
31
|
"blank",
|
|
30
32
|
nil
|
|
31
33
|
]
|
|
@@ -3,9 +3,16 @@ module Coco
|
|
|
3
3
|
module Elements
|
|
4
4
|
class ButtonTo < Coco::Component
|
|
5
5
|
include Concerns::WrapsComponent
|
|
6
|
+
include Concerns::AcceptsOptions
|
|
7
|
+
|
|
8
|
+
accepts_option :fit, from: [:auto, :full]
|
|
6
9
|
|
|
7
10
|
wraps_component :button do |args|
|
|
8
|
-
Coco::App::Elements::Button.new(
|
|
11
|
+
Coco::App::Elements::Button.new(
|
|
12
|
+
type: :submit,
|
|
13
|
+
fit: get_option_value(:fit) || :auto,
|
|
14
|
+
**args
|
|
15
|
+
)
|
|
9
16
|
end
|
|
10
17
|
|
|
11
18
|
%i[confirmation].each do |slot_name|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
[data-coco][data-component="app-menu"] {
|
|
3
3
|
width: fit-content;
|
|
4
|
+
max-width: 240px;
|
|
4
5
|
|
|
5
6
|
.menu-item {
|
|
6
7
|
> * {
|
|
@@ -20,6 +21,10 @@
|
|
|
20
21
|
@apply !font-[400];
|
|
21
22
|
}
|
|
22
23
|
}
|
|
24
|
+
|
|
25
|
+
.divider {
|
|
26
|
+
@apply my-1.5;
|
|
27
|
+
}
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
&[data-size="sm"] {
|
|
@@ -5,9 +5,10 @@ module Coco
|
|
|
5
5
|
include Concerns::ActsAsButtonGroup
|
|
6
6
|
include Concerns::AcceptsOptions
|
|
7
7
|
|
|
8
|
-
accepts_option :size, from: [:sm, :md, nil], default: :sm
|
|
8
|
+
accepts_option :size, from: [:xs, :sm, :md, nil], default: :sm
|
|
9
9
|
|
|
10
10
|
renders_many :htmls, ->(*args, **kwargs, &block) do
|
|
11
|
+
init_button_group
|
|
11
12
|
items << block.call
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -3,11 +3,17 @@ module Coco
|
|
|
3
3
|
module Elements
|
|
4
4
|
class MenuButton < Coco::Component
|
|
5
5
|
include Concerns::AcceptsOptions
|
|
6
|
+
include Concerns::WithIcon
|
|
6
7
|
include Concerns::WrapsComponent
|
|
7
8
|
include Coco::AppHelper
|
|
8
9
|
|
|
9
|
-
wraps_component :button do |
|
|
10
|
-
|
|
10
|
+
wraps_component :button do |kwargs|
|
|
11
|
+
@size = kwargs.fetch(:size, :default)&.to_sym
|
|
12
|
+
if @size.in?(Coco::App::Elements::Button::SIZE_ALIASES.keys) && !kwargs.key?(:resize)
|
|
13
|
+
@size, @resize = Coco::App::Elements::Button::SIZE_ALIASES.fetch(@size)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Coco::App::Elements::Button.new(toggle: :vertical, fit: get_option_value(:fit) || :auto, **kwargs)
|
|
11
17
|
end
|
|
12
18
|
|
|
13
19
|
accepts_option :fit, from: [:auto, :full]
|
|
@@ -20,13 +26,6 @@ module Coco
|
|
|
20
26
|
|
|
21
27
|
attr_reader :size, :resize
|
|
22
28
|
|
|
23
|
-
def initialize(button: {}, **kwargs)
|
|
24
|
-
@size = kwargs.fetch(:size, :default)&.to_sym
|
|
25
|
-
if @size.in?(Coco::App::Elements::Button::SIZE_ALIASES.keys) && !kwargs.key?(:resize)
|
|
26
|
-
@size, @resize = Coco::App::Elements::Button::SIZE_ALIASES.fetch(@size)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
29
|
def button_text
|
|
31
30
|
text || content
|
|
32
31
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
[data-coco][data-component="app-user-profile"] {
|
|
3
|
+
@apply px-4 py-1.5 grid grid-rows-1 gap-3;
|
|
4
|
+
grid-template-columns: min-content 1fr;
|
|
5
|
+
|
|
6
|
+
.user-profile-avatar {
|
|
7
|
+
@apply flex items-center;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.user-profile-details {
|
|
11
|
+
@apply space-y-1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.user-profile-name {
|
|
15
|
+
@apply font-semibold truncate;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.user-profile-email {
|
|
19
|
+
@apply text-gray-500 text-label-sm italic truncate;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<%= render component_tag do %>
|
|
2
|
+
<div class="user-profile-avatar">
|
|
3
|
+
<%= avatar %>
|
|
4
|
+
</div>
|
|
5
|
+
<div class="user-profile-details">
|
|
6
|
+
<% if name.present? %>
|
|
7
|
+
<h5 class="user-profile-name">
|
|
8
|
+
<%= name %>
|
|
9
|
+
</h5>
|
|
10
|
+
<% end %>
|
|
11
|
+
<% if email.present? %>
|
|
12
|
+
<div class="user-profile-email">
|
|
13
|
+
<%= email %>
|
|
14
|
+
</div>
|
|
15
|
+
<% end %>
|
|
16
|
+
</div>
|
|
17
|
+
<% end %>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Coco
|
|
2
|
+
module App
|
|
3
|
+
module Elements
|
|
4
|
+
module MenuItems
|
|
5
|
+
class UserProfile < Coco::Component
|
|
6
|
+
renders_one :avatar, ->(**kwargs) do
|
|
7
|
+
Coco::Avatar.new(name: name, **kwargs, size: :lg)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
attr_reader :name, :email
|
|
11
|
+
|
|
12
|
+
def initialize(name:, email:, **)
|
|
13
|
+
@name = name
|
|
14
|
+
@email = email
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -12,8 +12,8 @@ module Coco
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
%i[title action secondary_action link].each do |slot_name|
|
|
15
|
-
renders_one slot_name, ->(**kwargs, &block) do
|
|
16
|
-
alert.send("with_#{slot_name}".to_sym, **kwargs, &block)
|
|
15
|
+
renders_one slot_name, ->(*args, **kwargs, &block) do
|
|
16
|
+
alert.send("with_#{slot_name}".to_sym, *args, **kwargs, &block)
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
@layer base {
|
|
2
|
+
:root {
|
|
3
|
+
--snackbar-bottom-offset: theme(spacing.8);
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
@layer components {
|
|
2
8
|
[data-coco][data-component="app-snackbar"] {
|
|
3
9
|
@apply bg-background-dark-2 rounded-xl overflow-hidden shadow-xl w-full;
|
|
@@ -46,7 +52,8 @@
|
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
&[data-position="fixed"] {
|
|
49
|
-
@apply fixed
|
|
55
|
+
@apply fixed left-1/2 -translate-x-1/2;
|
|
56
|
+
bottom: var(--snackbar-bottom-offset);
|
|
50
57
|
z-index: 10001;
|
|
51
58
|
}
|
|
52
59
|
|
|
@@ -14,8 +14,8 @@ module Coco
|
|
|
14
14
|
|
|
15
15
|
accepts_option :theme, from: [:positive, :warning, :negative, :pending]
|
|
16
16
|
|
|
17
|
-
renders_one :action, ->(**kwargs, &block) do
|
|
18
|
-
|
|
17
|
+
renders_one :action, ->(*args, **kwargs, &block) do
|
|
18
|
+
coco_button(*args, **kwargs, theme: :blank, size: :sm, icon: nil, &block)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
before_render do
|
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
import { CocoComponent } from "@js/coco";
|
|
2
|
+
import Cookies from "js-cookie";
|
|
2
3
|
|
|
3
|
-
export default CocoComponent("appSystemBanner", () => {
|
|
4
|
-
return {
|
|
4
|
+
export default CocoComponent("appSystemBanner", (opts = {}) => {
|
|
5
|
+
return {
|
|
6
|
+
cookieName: null,
|
|
7
|
+
cookieValue: null,
|
|
8
|
+
cookieExpiry: null,
|
|
9
|
+
|
|
10
|
+
init() {
|
|
11
|
+
this.cookieName = opts.cookieName;
|
|
12
|
+
this.cookieValue = opts.cookieValue;
|
|
13
|
+
this.cookieExpiry = opts.cookieExpiry;
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
onDismiss() {
|
|
17
|
+
this.$dispatch("banner:dismiss", { banner: this });
|
|
18
|
+
if (this.shouldSetCookie) {
|
|
19
|
+
Cookies.set(this.cookieName, this.cookieValue, {
|
|
20
|
+
expires: this.cookieExpiry,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
remove() {
|
|
26
|
+
this.$root.remove();
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
get shouldSetCookie() {
|
|
30
|
+
return Number.isInteger(this.cookieExpiry);
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
root: {
|
|
34
|
+
"@alert:dismiss": "onDismiss",
|
|
35
|
+
"@alert:removed": "remove",
|
|
36
|
+
},
|
|
37
|
+
};
|
|
5
38
|
});
|
|
@@ -5,17 +5,61 @@ module Coco
|
|
|
5
5
|
include Concerns::AcceptsOptions
|
|
6
6
|
include Concerns::WrapsComponent
|
|
7
7
|
|
|
8
|
+
accepts_option :dismissable, from: [true, false], default: false
|
|
9
|
+
|
|
8
10
|
wraps_component :alert do |args|
|
|
9
11
|
theme = vivid_theme_name(args.fetch(:theme, nil)) || :info_vivid
|
|
10
|
-
Coco::App::Elements::Alert.new(
|
|
12
|
+
Coco::App::Elements::Alert.new(
|
|
13
|
+
**args,
|
|
14
|
+
theme: theme,
|
|
15
|
+
banner: true,
|
|
16
|
+
cloak: false,
|
|
17
|
+
single_line: true,
|
|
18
|
+
dismissable: dismissable?,
|
|
19
|
+
condensed: true
|
|
20
|
+
)
|
|
11
21
|
end
|
|
12
22
|
|
|
13
23
|
%i[title action secondary_action link].each do |slot_name|
|
|
14
|
-
renders_one slot_name, ->(**kwargs, &block) do
|
|
15
|
-
alert.send("with_#{slot_name}".to_sym, **kwargs, &block)
|
|
24
|
+
renders_one slot_name, ->(*args, **kwargs, &block) do
|
|
25
|
+
alert.send("with_#{slot_name}".to_sym, *args, **kwargs, &block)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
before_render do
|
|
30
|
+
if dismissable? && id.blank?
|
|
31
|
+
raise ArgumentError, "Dismissable banners must be given an ID"
|
|
16
32
|
end
|
|
17
33
|
end
|
|
18
34
|
|
|
35
|
+
attr_reader :dismiss_for, :id
|
|
36
|
+
|
|
37
|
+
def initialize(id: nil, dismiss_for: nil, **)
|
|
38
|
+
@id = id
|
|
39
|
+
@dismiss_for = dismiss_for
|
|
40
|
+
set_tag_attr(:id, id)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def dismissable?
|
|
44
|
+
get_option_value(:dismissable) == true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def render?
|
|
48
|
+
helpers.cookies[dismiss_cookie_name] != "true"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def dismiss_cookie_name
|
|
52
|
+
"cb_system_banner_#{tag_attr(:id)&.underscore}_dismissed".to_sym
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def alpine_data
|
|
56
|
+
dismissable? ? {
|
|
57
|
+
cookie_name: dismiss_cookie_name,
|
|
58
|
+
cookie_expiry: dismiss_for&.in_days&.to_i,
|
|
59
|
+
cookie_value: "true"
|
|
60
|
+
} : {}
|
|
61
|
+
end
|
|
62
|
+
|
|
19
63
|
private
|
|
20
64
|
|
|
21
65
|
def vivid_theme_name(theme)
|
|
@@ -1,9 +1,109 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
[data-coco][data-component="
|
|
3
|
-
@apply grid
|
|
2
|
+
[data-coco][data-component="application-layout"] {
|
|
3
|
+
@apply grid overflow-hidden absolute inset-0 w-screen;
|
|
4
|
+
height: var(--app-height);
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
grid-template-areas: "body";
|
|
7
|
+
grid-template-rows: 1fr;
|
|
8
|
+
grid-template-columns: 1fr;
|
|
9
|
+
|
|
10
|
+
&.with-header {
|
|
11
|
+
grid-template-areas: "header" "body";
|
|
12
|
+
grid-template-rows: min-content 1fr;
|
|
13
|
+
|
|
14
|
+
&.with-banner {
|
|
15
|
+
grid-template-areas: "header" "body" "banner";
|
|
16
|
+
grid-template-rows: min-content 1fr min-content;
|
|
17
|
+
|
|
18
|
+
&.with-sidebar-nav {
|
|
19
|
+
grid-template-areas: "header" "body" "banner" "sidebar";
|
|
20
|
+
grid-template-rows: min-content 1fr min-content min-content;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&:not(.with-banner) {
|
|
25
|
+
&.with-sidebar-nav {
|
|
26
|
+
grid-template-areas: "header" "body" "sidebar";
|
|
27
|
+
grid-template-rows: min-content 1fr min-content;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&.with-sidebar-nav {
|
|
33
|
+
--snackbar-bottom-offset: theme(spacing.16);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&:not(.with-header).with-banner {
|
|
37
|
+
grid-template-areas: "body" "banner";
|
|
38
|
+
grid-template-rows: 1fr min-content;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.layout-banner {
|
|
42
|
+
@apply w-screen z-10;
|
|
43
|
+
grid-area: banner;
|
|
44
|
+
height: min-content;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.layout-header {
|
|
48
|
+
@apply w-screen z-10;
|
|
49
|
+
grid-area: header;
|
|
50
|
+
height: min-content;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.layout-body {
|
|
54
|
+
@apply relative z-0 h-full overflow-y-auto scroll-smooth;
|
|
55
|
+
grid-area: body;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.layout-sidebar-nav {
|
|
59
|
+
@apply scroll-smooth;
|
|
60
|
+
scrollbar-width: none;
|
|
61
|
+
grid-area: sidebar;
|
|
62
|
+
height: min-content;
|
|
63
|
+
|
|
64
|
+
&::-webkit-scrollbar {
|
|
65
|
+
display: none;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@media screen(sm) {
|
|
70
|
+
.layout-sidebar-nav {
|
|
71
|
+
@apply h-full overflow-auto;
|
|
72
|
+
width: min-content;
|
|
73
|
+
|
|
74
|
+
> * {
|
|
75
|
+
@apply h-full;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
grid-template-areas: "body";
|
|
80
|
+
grid-template-rows: 1fr;
|
|
81
|
+
|
|
82
|
+
&.with-sidebar-nav {
|
|
83
|
+
--snackbar-bottom-offset: theme(spacing.10);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
&.with-header {
|
|
87
|
+
&.with-banner {
|
|
88
|
+
grid-template-areas: "banner" "header" "body";
|
|
89
|
+
grid-template-rows: min-content min-content 1fr;
|
|
90
|
+
grid-template-columns: 1fr;
|
|
91
|
+
|
|
92
|
+
&.with-sidebar-nav {
|
|
93
|
+
grid-template-areas: "banner banner" "header header" "sidebar body";
|
|
94
|
+
grid-template-rows: min-content min-content 1fr;
|
|
95
|
+
grid-template-columns: min-content 1fr;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&:not(.with-banner) {
|
|
100
|
+
&.with-sidebar-nav {
|
|
101
|
+
grid-template-areas: "header header" "sidebar body";
|
|
102
|
+
grid-template-rows: min-content 1fr;
|
|
103
|
+
grid-template-columns: min-content 1fr;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
7
107
|
}
|
|
8
108
|
}
|
|
9
109
|
}
|