coveragebook_components 0.7.10 → 0.8.0.beta.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/build/coco/app.css +1160 -151
  3. data/app/assets/build/coco/app.js +263 -47
  4. data/app/assets/build/coco/book.css +26 -0
  5. data/app/assets/css/app/tippy.css +4 -0
  6. data/app/components/coco/app/blocks/header/header.css +47 -0
  7. data/app/components/coco/app/blocks/header/header.html.erb +30 -0
  8. data/app/components/coco/app/blocks/header/header.js +11 -0
  9. data/app/components/coco/app/blocks/header/header.rb +35 -0
  10. data/app/components/coco/app/blocks/nav_drawer/nav_drawer.css +48 -3
  11. data/app/components/coco/app/blocks/nav_drawer/nav_drawer.html.erb +14 -6
  12. data/app/components/coco/app/blocks/nav_drawer/nav_drawer.js +18 -1
  13. data/app/components/coco/app/blocks/nav_drawer/nav_drawer.rb +26 -1
  14. data/app/components/coco/app/blocks/sidebar_nav/sidebar_nav.css +104 -0
  15. data/app/components/coco/app/blocks/sidebar_nav/sidebar_nav.html.erb +42 -0
  16. data/app/components/coco/app/blocks/sidebar_nav/sidebar_nav.js +28 -0
  17. data/app/components/coco/app/blocks/sidebar_nav/sidebar_nav.rb +28 -0
  18. data/app/components/coco/app/blocks/sidebar_nav_item/sidebar_nav_item.css +165 -0
  19. data/app/components/coco/app/blocks/sidebar_nav_item/sidebar_nav_item.html.erb +43 -0
  20. data/app/components/coco/app/blocks/sidebar_nav_item/sidebar_nav_item.js +41 -0
  21. data/app/components/coco/app/blocks/sidebar_nav_item/sidebar_nav_item.rb +98 -0
  22. data/app/components/coco/app/elements/alert/alert.css +114 -18
  23. data/app/components/coco/app/elements/alert/alert.html.erb +5 -4
  24. data/app/components/coco/app/elements/alert/alert.js +13 -3
  25. data/app/components/coco/app/elements/alert/alert.rb +10 -0
  26. data/app/components/coco/app/elements/button/button.css +59 -0
  27. data/app/components/coco/app/elements/button/button.rb +2 -1
  28. data/app/components/coco/app/elements/button_group/button_group.rb +4 -0
  29. data/app/components/coco/app/elements/color_picker/color_picker.rb +1 -1
  30. data/app/components/coco/app/elements/menu/menu.css +3 -1
  31. data/app/components/coco/app/elements/menu/menu.html.erb +1 -1
  32. data/app/components/coco/app/elements/menu/menu.rb +2 -1
  33. data/app/components/coco/app/elements/menu_items/user_profile/user_profile.css +22 -0
  34. data/app/components/coco/app/elements/menu_items/user_profile/user_profile.html.erb +17 -0
  35. data/app/components/coco/app/elements/menu_items/user_profile/user_profile.rb +20 -0
  36. data/app/components/coco/app/elements/notice/notice.css +4 -0
  37. data/app/components/coco/app/elements/snackbar/snackbar.css +8 -1
  38. data/app/components/coco/app/elements/snackbar/snackbar.rb +2 -2
  39. data/app/components/coco/app/elements/system_banner/system_banner.html.erb +2 -1
  40. data/app/components/coco/app/elements/system_banner/system_banner.js +35 -2
  41. data/app/components/coco/app/elements/system_banner/system_banner.rb +47 -3
  42. data/app/components/coco/app/layouts/application/application.css +104 -4
  43. data/app/components/coco/app/layouts/application/application.html.erb +28 -7
  44. data/app/components/coco/app/layouts/application/application.js +16 -0
  45. data/app/components/coco/app/layouts/application/application.rb +11 -3
  46. data/app/components/coco/base/avatar/avatar.css +25 -0
  47. data/app/components/coco/base/avatar/avatar.rb +20 -0
  48. data/app/components/coco/base/modal/modal.html.erb +1 -1
  49. data/app/components/coco/concerns/accepts_tag_attributes.rb +6 -2
  50. data/app/components/coco/concerns/acts_as_button_group.rb +5 -0
  51. data/app/helpers/coco/app_helper.rb +16 -0
  52. data/app/helpers/coco/base_helper.rb +4 -0
  53. data/config/tokens.cjs +4 -1
  54. data/lib/coco.rb +1 -1
  55. metadata +22 -10
  56. data/app/components/coco/app/blocks/banner/banner.css +0 -5
  57. data/app/components/coco/app/blocks/banner/banner.rb +0 -8
  58. data/app/components/coco/app/blocks/nav_bar/nav_bar.css +0 -51
  59. data/app/components/coco/app/blocks/nav_bar/nav_bar.html.erb +0 -23
  60. data/app/components/coco/app/blocks/nav_bar/nav_bar.js +0 -31
  61. data/app/components/coco/app/blocks/nav_bar/nav_bar.rb +0 -19
@@ -3,7 +3,7 @@
3
3
  @apply rounded-xl overflow-hidden border border-transparent @container;
4
4
 
5
5
  .alert-container {
6
- @apply flex items-start p-4 relative;
6
+ @apply flex items-start px-4 py-2 relative;
7
7
  }
8
8
 
9
9
  .alert-icon {
@@ -23,7 +23,7 @@
23
23
  }
24
24
 
25
25
  .alert-title {
26
- @apply text-para-md font-bold;
26
+ @apply text-heading-6 font-bold;
27
27
  }
28
28
 
29
29
  .alert-message {
@@ -34,10 +34,6 @@
34
34
  }
35
35
  }
36
36
 
37
- &.with-title .alert-message {
38
- @apply mt-1;
39
- }
40
-
41
37
  .alert-actions {
42
38
  @apply space-x-1 flex items-center;
43
39
  }
@@ -56,7 +52,7 @@
56
52
  @apply rounded-none;
57
53
 
58
54
  .alert-container {
59
- @apply @[1000px]:justify-center;
55
+ @apply @[1000px]:justify-center px-app;
60
56
  }
61
57
 
62
58
  .alert-body {
@@ -71,14 +67,39 @@
71
67
  @apply flex-none;
72
68
 
73
69
  .coco-button .button-element {
74
- @apply text-content-dark-2 hover:text-content-dark-1;
70
+ @apply text-content-dark-2 hover:text-content-dark-1 bg-transparent hover:bg-white/10 transition;
75
71
  }
76
72
  }
77
73
  }
78
74
 
75
+ /* Condensed */
76
+
77
+ &[data-condensed="true"] {
78
+ .alert-container {
79
+ min-height: theme(spacing.12);
80
+ @apply py-1.5;
81
+ }
82
+
83
+ .alert-icon {
84
+ @apply p-0 !bg-transparent;
85
+ }
86
+
87
+ .alert-body {
88
+ @apply pl-3;
89
+ }
90
+
91
+ .alert-title {
92
+ @apply text-para-md sm:text-para-sm xl:text-para-md;
93
+ }
94
+
95
+ .alert-message {
96
+ @apply text-para-md sm:text-para-sm xl:text-para-md;
97
+ }
98
+ }
99
+
79
100
  /* Layout */
80
101
 
81
- @apply app-alert-stacked @[500px]:app-alert-multi-line;
102
+ @apply app-alert-stacked @[576px]:app-alert-multi-line;
82
103
 
83
104
  &[data-single-line="true"]:not(.force-multi-line) {
84
105
  @apply @[1000px]:app-alert-single-line;
@@ -95,7 +116,7 @@
95
116
  }
96
117
 
97
118
  &[data-theme*="vivid"] {
98
- @apply border-none;
119
+ @apply border-none antialiased;
99
120
 
100
121
  .alert-content {
101
122
  @apply text-content-light-1;
@@ -186,13 +207,30 @@
186
207
 
187
208
  @layer utilities {
188
209
  .app-alert-stacked {
189
- .alert-title {
190
- matgin-top: -1px;
191
- margin-bottom: 2px;
210
+ .alert-container {
211
+ @apply py-4;
192
212
  }
193
213
 
194
214
  .alert-actions {
195
- @apply mt-2;
215
+ @apply mt-3;
216
+ }
217
+
218
+ &.with-title .alert-message {
219
+ @apply mt-1;
220
+ }
221
+
222
+ &[data-condensed="true"] {
223
+ .alert-container {
224
+ @apply py-3;
225
+ }
226
+
227
+ .coco-icon {
228
+ @apply mt-1.5;
229
+ }
230
+
231
+ &.with-title .alert-message {
232
+ @apply mt-0;
233
+ }
196
234
  }
197
235
 
198
236
  &[data-dismissable="true"] {
@@ -204,11 +242,29 @@
204
242
  @apply ml-auto absolute top-2 right-2;
205
243
  }
206
244
  }
245
+
246
+ &:not(.with-title) {
247
+ &:not(.with-action) {
248
+ .alert-container {
249
+ @apply items-center;
250
+ }
251
+
252
+ .alert-icon {
253
+ @apply self-center;
254
+ }
255
+
256
+ &[data-dismissable="true"] {
257
+ .alert-dismiss {
258
+ @apply absolute right-3 top-1/2 -translate-y-1/2;
259
+ }
260
+ }
261
+ }
262
+ }
207
263
  }
208
264
 
209
265
  .app-alert-multi-line {
210
266
  .alert-container {
211
- @apply items-center;
267
+ @apply items-center py-2.5;
212
268
  }
213
269
 
214
270
  .alert-icon {
@@ -227,22 +283,44 @@
227
283
  margin-bottom: 0;
228
284
  }
229
285
 
286
+ &.with-title .alert-message {
287
+ @apply mt-1;
288
+ }
289
+
290
+ &[data-condensed="true"] {
291
+ .alert-container {
292
+ @apply py-2;
293
+ }
294
+
295
+ .coco-icon {
296
+ @apply mt-0;
297
+ }
298
+
299
+ &.with-title .alert-message {
300
+ @apply mt-0;
301
+ }
302
+ }
303
+
230
304
  .alert-actions {
231
305
  @apply mt-0 ml-auto;
232
306
  }
233
307
 
234
308
  &[data-dismissable="true"] {
235
- .alert-container {
236
- @apply pr-3;
309
+ .alert-body {
310
+ @apply pr-2;
237
311
  }
238
312
 
239
313
  .alert-dismiss {
240
- @apply relative top-auto right-auto flex flex-col;
314
+ @apply absolute right-3 top-1/2 -translate-y-1/2;
241
315
  }
242
316
  }
243
317
  }
244
318
 
245
319
  .app-alert-single-line {
320
+ .alert-container {
321
+ @apply py-2;
322
+ }
323
+
246
324
  .alert-content {
247
325
  @apply flex items-center w-full space-x-2;
248
326
  }
@@ -251,8 +329,26 @@
251
329
  @apply whitespace-nowrap;
252
330
  }
253
331
 
332
+ &.with-title .alert-message {
333
+ @apply mt-0;
334
+ }
335
+
254
336
  .alert-link {
255
337
  @apply hidden;
256
338
  }
339
+
340
+ &[data-dismissable="true"] {
341
+ .alert-body {
342
+ @apply pr-2;
343
+ }
344
+
345
+ .alert-container {
346
+ @apply px-12;
347
+ }
348
+
349
+ .alert-dismiss {
350
+ @apply absolute right-3 top-1/2 -translate-y-1/2;
351
+ }
352
+ }
257
353
  }
258
354
  }
@@ -1,10 +1,11 @@
1
1
  <%= render component_tag(x: {
2
2
  data: "appAlert",
3
- show: "!dismissed",
4
3
  bind: "root",
5
- cloak: true
4
+ show: "!dismissed",
5
+ cloak: (true if cloak?)
6
6
  }, class: {
7
7
  "with-title": title?,
8
+ "with-action": action? || secondary_action?,
8
9
  "vivid": vivid?
9
10
  }) do %>
10
11
  <div class="alert-container">
@@ -44,7 +45,7 @@
44
45
  <%= coco_button(
45
46
  *@action_data[:args],
46
47
  **@action_data[:kwargs],
47
- size: :sm,
48
+ size: button_size,
48
49
  &@action_data[:block]
49
50
  ) %>
50
51
  </div>
@@ -58,7 +59,7 @@
58
59
  <%= coco_button(
59
60
  *@secondary_action_data[:args],
60
61
  **@secondary_action_data[:kwargs],
61
- size: :sm,
62
+ size: button_size,
62
63
  &@secondary_action_data[:block]
63
64
  ) %>
64
65
  </div>
@@ -7,6 +7,13 @@ export default CocoComponent("appAlert", () => {
7
7
  forceMultiLine: false,
8
8
  dismissDuration: 300,
9
9
 
10
+ init() {
11
+ this.checkSingleLineWrap = Alpine.throttle(
12
+ this.checkSingleLineWrap.bind(this),
13
+ 200
14
+ );
15
+ },
16
+
10
17
  dismiss() {
11
18
  if (this.$options.dismissable) {
12
19
  this.$dispatch("alert:dismiss", {
@@ -21,18 +28,21 @@ export default CocoComponent("appAlert", () => {
21
28
  },
22
29
 
23
30
  remove() {
31
+ this.$nextTick(() => this.$dispatch("alert:removed", { alert: this }));
24
32
  this.$root.remove();
25
33
  },
26
34
 
27
35
  checkSingleLineWrap({ height }) {
28
- if (!this.forceMultiLine) {
29
- this.forceMultiLine = height > 24 && this.$options.singleLine;
36
+ this.forceMultiLine = false;
37
+ if (height > 24 && this.$options.singleLine) {
38
+ this.$nextTick(() => {
39
+ this.forceMultiLine = true;
40
+ });
30
41
  }
31
42
  },
32
43
 
33
44
  root: {
34
45
  "x-options": '["dismissable", "singleLine"]',
35
- "x-show": "!dismissed",
36
46
  ":class": "{'force-multi-line': forceMultiLine}",
37
47
  },
38
48
  };
@@ -22,6 +22,8 @@ module Coco
22
22
  accepts_option :banner, from: [true, false], default: false
23
23
  accepts_option :theme, from: THEMES, default: "info"
24
24
  accepts_option :single_line, from: [true, false]
25
+ accepts_option :cloak, from: [true, false], default: true, private: true
26
+ accepts_option :condensed, from: [true, false], default: false
25
27
 
26
28
  renders_one :title
27
29
 
@@ -58,6 +60,10 @@ module Coco
58
60
  get_option_value(:single_line)
59
61
  end
60
62
 
63
+ def cloak?
64
+ get_option_value(:cloak)
65
+ end
66
+
61
67
  def vivid?
62
68
  theme = get_option_value(:theme)
63
69
  theme.to_s.match?(/vivid$/)
@@ -66,6 +72,10 @@ module Coco
66
72
  def unvividify(theme)
67
73
  theme.to_s.match?(/vivid$/) ? theme.to_s.underscore.gsub("_vivid", "").to_sym : theme
68
74
  end
75
+
76
+ def button_size
77
+ get_option_value(:condensed) ? :xs : :sm
78
+ end
69
79
  end
70
80
  end
71
81
  end
@@ -286,6 +286,10 @@
286
286
 
287
287
  /* Responsive resizing */
288
288
 
289
+ &[data-size="xs"] {
290
+ @apply app-button-xs;
291
+ }
292
+
289
293
  &[data-size="sm"] {
290
294
  @apply app-button-sm;
291
295
  }
@@ -299,6 +303,10 @@
299
303
  }
300
304
 
301
305
  @media screen(md) {
306
+ &[data-size-md="xs"] {
307
+ @apply app-button-xs;
308
+ }
309
+
302
310
  &[data-size-md="sm"] {
303
311
  @apply app-button-sm;
304
312
  }
@@ -313,6 +321,10 @@
313
321
  }
314
322
 
315
323
  @media screen(lg) {
324
+ &[data-size-lg="xs"] {
325
+ @apply app-button-xs;
326
+ }
327
+
316
328
  &[data-size-lg="sm"] {
317
329
  @apply app-button-sm;
318
330
  }
@@ -327,6 +339,10 @@
327
339
  }
328
340
 
329
341
  @media screen(xl) {
342
+ &[data-size-xl="xs"] {
343
+ @apply app-button-xs;
344
+ }
345
+
330
346
  &[data-size-xl="sm"] {
331
347
  @apply app-button-sm;
332
348
  }
@@ -341,6 +357,11 @@
341
357
  }
342
358
 
343
359
  @media screen(2xl) {
360
+ &[data-size-xxl="xs"],
361
+ &[data-size-2xl="xs"] {
362
+ @apply app-button-xs;
363
+ }
364
+
344
365
  &[data-size-xxl="sm"],
345
366
  &[data-size-2xl="sm"] {
346
367
  @apply app-button-sm;
@@ -358,6 +379,10 @@
358
379
  }
359
380
 
360
381
  @media screen(max) {
382
+ &[data-size-max="xs"] {
383
+ @apply app-button-xs;
384
+ }
385
+
361
386
  &[data-size-max="sm"] {
362
387
  @apply app-button-sm;
363
388
  }
@@ -374,6 +399,40 @@
374
399
  }
375
400
 
376
401
  @layer utilities {
402
+ .app-button-xs {
403
+ .button-content {
404
+ font-size: 14px;
405
+ line-height: 14px;
406
+ }
407
+
408
+ .button-icon [data-component="icon"],
409
+ .button-toggle {
410
+ @apply w-3.5 h-3.5;
411
+ }
412
+
413
+ &[data-theme] {
414
+ .button-element {
415
+ @apply py-2 px-3;
416
+ }
417
+ }
418
+
419
+ &.icon-only > .button-element .button-icon,
420
+ &[data-collapsed="true"] > .button-element .button-icon {
421
+ @apply -ml-1 -mr-1;
422
+ }
423
+
424
+ &[data-theme|="text"] {
425
+ .button-element {
426
+ @apply px-2;
427
+ }
428
+
429
+ &.icon-only > .button-element .button-icon,
430
+ &[data-collapsed="true"] > .button-element .button-icon {
431
+ @apply px-2;
432
+ }
433
+ }
434
+ }
435
+
377
436
  .app-button-sm {
378
437
  .button-content {
379
438
  @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}]
@@ -36,6 +36,7 @@ module Coco
36
36
 
37
37
  accepts_option :size, from: SIZES, default: :md
38
38
  accepts_option :theme, from: THEMES, default: DEFAULT_THEME
39
+ accepts_option :variant
39
40
 
40
41
  renders_one :dropdown, types: {
41
42
  content: ->(&block) { block.call },
@@ -26,6 +26,10 @@ module Coco
26
26
  **kwargs
27
27
  }
28
28
 
29
+ if component_args.key?(:resize)
30
+ args[:resize] = component_args[:resize]
31
+ end
32
+
29
33
  if get_option_value(:collapsible) == false
30
34
  args[:collapsible] = false
31
35
  end
@@ -20,7 +20,7 @@ module Coco
20
20
  {color: "#3A2D86"}
21
21
  ]
22
22
 
23
- accepts_option :size, from: [:sm, :md, nil], default: :sm
23
+ accepts_option :size, from: [:xs, :sm, :md, nil], default: :sm
24
24
 
25
25
  before_render do
26
26
  content unless content_evaluated?
@@ -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
  > * {
@@ -26,7 +27,8 @@
26
27
  }
27
28
  }
28
29
 
29
- &[data-size="sm"] {
30
+ &[data-size="sm"],
31
+ &[data-size="xs"] {
30
32
  @apply py-1.5;
31
33
 
32
34
  .menu-item {
@@ -1,6 +1,6 @@
1
1
  <%= render component_tag do %>
2
2
  <ol class="menu-items">
3
- <% items.each do |item| %>
3
+ <% items.compact.each do |item| %>
4
4
  <li class="menu-item">
5
5
  <%= item %>
6
6
  </li>
@@ -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
 
@@ -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
@@ -1,5 +1,9 @@
1
1
  @layer components {
2
2
  [data-coco][data-component="app-notice"] {
3
3
  @apply rounded-xl overflow-hidden;
4
+
5
+ div[class="alert-container"] {
6
+ @apply py-4;
7
+ }
4
8
  }
5
9
  }
@@ -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 bottom-8 left-1/2 -translate-x-1/2;
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
- Coco::App::Elements::Button.new(**kwargs, theme: :blank, size: :sm, icon: nil)
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,4 +1,5 @@
1
- <%= render component_tag(x: { data: "appSystemBanner" }) do %>
1
+ <%= render component_tag(
2
+ x: { data: x_data("appSystemBanner", alpine_data), bind: "root"}) do %>
2
3
  <%= render alert do %>
3
4
  <%= content %>
4
5
  <% end %>
@@ -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
  });