epages-essence 0.1.0 → 0.2.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/LICENSE +1 -1
- data/README.md +4 -3
- data/app/assets/images/essence/icon_component/arrow_right.svg +1 -0
- data/app/assets/images/essence/icon_component/chevron_up_down.svg +3 -0
- data/app/assets/images/essence/icon_component/power_off.svg +1 -0
- data/app/assets/images/essence/icon_component/sparkles.svg +1 -0
- data/app/assets/images/essence/icon_component/x_mark.svg +3 -0
- data/app/assets/stylesheets/essence/beyond/{_base.scss → layout/base.css} +0 -5
- data/app/assets/stylesheets/essence/beyond/layout/{_content.scss → content.css} +1 -1
- data/app/assets/stylesheets/essence/beyond/simple_form/control.css +249 -0
- data/app/assets/stylesheets/essence/beyond/simple_form/error.css +29 -0
- data/app/assets/stylesheets/essence/beyond/simple_form/fieldset.css +32 -0
- data/app/assets/stylesheets/essence/beyond/simple_form/group.css +21 -0
- data/app/assets/stylesheets/essence/beyond/simple_form/hint.css +6 -0
- data/app/assets/stylesheets/essence/beyond/simple_form/label.css +38 -0
- data/app/assets/stylesheets/essence/beyond/simple_form/row.css +5 -0
- data/app/assets/stylesheets/essence/beyond/simple_form/wrapper.css +3 -0
- data/app/assets/stylesheets/essence/beyond/utils/margin.css +15 -0
- data/app/assets/stylesheets/essence/beyond/variables.css +281 -0
- data/app/assets/stylesheets/essence/beyond.css +39 -0
- data/app/components/essence/action_bar_component/action_bar_component.css +23 -0
- data/app/components/essence/action_bar_component.rb +2 -1
- data/app/components/essence/app_info_component/app_info_component.css +45 -0
- data/app/components/essence/application_component.rb +1 -3
- data/app/components/essence/breadcrumb_component/breadcrumb_component.css +35 -0
- data/app/components/essence/button_component/button_component.css +140 -0
- data/app/components/essence/button_component/button_component.html.erb +2 -0
- data/app/components/essence/button_component/button_component_controller.js +27 -0
- data/app/components/essence/button_component.rb +27 -2
- data/app/components/essence/button_group_component/button_group_component.css +21 -0
- data/app/components/essence/button_group_component/button_group_component.html.erb +5 -0
- data/app/components/essence/button_group_component.rb +28 -0
- data/app/components/essence/card_component/card_component.css +66 -0
- data/app/components/essence/card_component/card_component.html.erb +6 -0
- data/app/components/essence/card_component/ribbon_component.html.erb +3 -0
- data/app/components/essence/card_component.rb +38 -4
- data/app/components/essence/clipboard_copy_component/{clipboard_copy_component.scss → clipboard_copy_component.css} +4 -4
- data/app/components/essence/empty_state_component/empty_state_component.css +42 -0
- data/app/components/essence/expandable_component/expandable_component.css +36 -0
- data/app/components/essence/expandable_component/expandable_component.html.erb +8 -0
- data/app/components/essence/expandable_component/expandable_component_controller.js +32 -0
- data/app/components/essence/expandable_component.rb +30 -0
- data/app/components/essence/expandable_toggle_component/expandable_toggle_component.css +7 -0
- data/app/components/essence/expandable_toggle_component/expandable_toggle_component.html.erb +3 -0
- data/app/components/essence/expandable_toggle_component/expandable_toggle_component.yml +4 -0
- data/app/components/essence/expandable_toggle_component/expandable_toggle_component_controller.js +52 -0
- data/app/components/essence/expandable_toggle_component.rb +38 -0
- data/app/components/essence/flash_component/container_component.html.erb +7 -0
- data/app/components/essence/flash_component/flash_component.css +101 -0
- data/app/components/essence/flash_component/flash_component.html.erb +11 -0
- data/app/components/essence/flash_component/flash_component_controller.js +24 -0
- data/app/components/essence/flash_component.rb +29 -0
- data/app/components/essence/link_component/link_component.css +49 -0
- data/app/components/essence/notification_component/notification_component.css +55 -0
- data/app/components/essence/notification_component.rb +6 -2
- data/app/components/essence/paragraph_component/{paragraph_component.scss → paragraph_component.css} +0 -5
- data/app/components/essence/scroll_shadow_component/{scroll_shadow_component.scss → scroll_shadow_component.css} +4 -0
- data/app/components/essence/spinner_component/{spinner_component.scss → spinner_component.css} +5 -12
- data/app/components/essence/spinner_component/spinner_component.html.erb +1 -1
- data/app/components/essence/spinner_component.rb +4 -2
- data/app/components/essence/status_component/status_component.css +64 -0
- data/app/components/essence/status_component.rb +1 -1
- data/app/components/essence/step_list_component/step_list_component.css +72 -0
- data/app/components/essence/step_list_component/step_list_component.html.erb +3 -1
- data/app/components/essence/step_list_component.rb +7 -1
- data/app/components/essence/table_component/{table_component.scss → table_component.css} +5 -8
- data/app/components/essence/title_component/{title_component.scss → title_component.css} +0 -4
- data/app/components/essence/tooltip_component/tooltip_component.css +55 -0
- data/app/inputs/file_input.rb +73 -0
- data/app/javascript/essence/application.js +2 -2
- data/app/javascript/essence/controllers/file_input_controller.js +41 -0
- data/app/javascript/essence/controllers/index.js +18 -3
- data/app/views/essence/beyond/body.html.erb +1 -0
- data/config/importmap.rb +3 -0
- data/config/initializers/essence/inline_svg.rb +5 -0
- data/config/initializers/essence/simple_form.rb +29 -8
- data/config/locales/essence.en.yml +3 -0
- data/lib/components/input_group.rb +19 -0
- data/lib/essence/engine.rb +20 -5
- data/lib/essence/version.rb +1 -1
- data/lib/essence.rb +1 -1
- data/vendor/assets/stylesheets/essence/flexboxgrid.css +824 -0
- metadata +78 -53
- data/app/assets/config/essence_manifest.js +0 -5
- data/app/assets/stylesheets/essence/beyond/components/_index.scss +0 -17
- data/app/assets/stylesheets/essence/beyond/layout/_index.scss +0 -1
- data/app/assets/stylesheets/essence/beyond/simple_form/_control.scss +0 -172
- data/app/assets/stylesheets/essence/beyond/simple_form/_error.scss +0 -27
- data/app/assets/stylesheets/essence/beyond/simple_form/_fieldset.scss +0 -34
- data/app/assets/stylesheets/essence/beyond/simple_form/_group.scss +0 -6
- data/app/assets/stylesheets/essence/beyond/simple_form/_hint.scss +0 -8
- data/app/assets/stylesheets/essence/beyond/simple_form/_index.scss +0 -43
- data/app/assets/stylesheets/essence/beyond/simple_form/_label.scss +0 -26
- data/app/assets/stylesheets/essence/beyond/simple_form/_wrapper.scss +0 -5
- data/app/assets/stylesheets/essence/beyond.scss +0 -4
- data/app/components/essence/action_bar_component/action_bar_component.scss +0 -29
- data/app/components/essence/app_info_component/app_info_component.scss +0 -45
- data/app/components/essence/breadcrumb_component/breadcrumb_component.scss +0 -39
- data/app/components/essence/button_component/button_component.scss +0 -105
- data/app/components/essence/card_component/card_component.scss +0 -21
- data/app/components/essence/empty_state_component/empty_state_component.scss +0 -50
- data/app/components/essence/link_component/link_component.scss +0 -58
- data/app/components/essence/notification_component/notification_component.scss +0 -63
- data/app/components/essence/status_component/status_component.scss +0 -80
- data/app/components/essence/step_list_component/step_list_component.scss +0 -79
- data/app/components/essence/tooltip_component/tooltip_component.scss +0 -63
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.button-group {
|
|
2
|
+
display: flex;
|
|
3
|
+
|
|
4
|
+
& > .button {
|
|
5
|
+
border-radius: 0;
|
|
6
|
+
|
|
7
|
+
&:not(:first-child) {
|
|
8
|
+
border-left: 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
&:first-child {
|
|
12
|
+
border-top-left-radius: var(--button-borderRadius);
|
|
13
|
+
border-bottom-left-radius: var(--button-borderRadius);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&:last-child {
|
|
17
|
+
border-top-right-radius: var(--button-borderRadius);
|
|
18
|
+
border-bottom-right-radius: var(--button-borderRadius);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Essence
|
|
4
|
+
class ButtonGroupComponent < ApplicationComponent
|
|
5
|
+
attr_reader :html_options
|
|
6
|
+
|
|
7
|
+
renders_many :group, types: {
|
|
8
|
+
button: lambda { |**args|
|
|
9
|
+
ButtonComponent.new(size: 16, **args.merge(display_as: :button))
|
|
10
|
+
},
|
|
11
|
+
link: lambda { |**args|
|
|
12
|
+
LinkComponent.new(size: 16, **args.merge(display_as: :button))
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
def initialize(**html_options)
|
|
17
|
+
@html_options = html_options
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
alias button_group_elements group
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def before_render
|
|
25
|
+
set_base_html_options('button-group')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--ribbon-text: #ffffff;
|
|
3
|
+
--ribbon-light-background: #a6a6a6;
|
|
4
|
+
--ribbon-light-shadow: #808080;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.card {
|
|
8
|
+
background-color: var(--card-background);
|
|
9
|
+
border-radius: var(--card-borderRadius);
|
|
10
|
+
box-shadow: var(--card-shadow);
|
|
11
|
+
padding: var(--card-padding);
|
|
12
|
+
position: relative;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.card-ribbon {
|
|
16
|
+
position: absolute;
|
|
17
|
+
top: -8px;
|
|
18
|
+
right: 40px;
|
|
19
|
+
display: inline-block;
|
|
20
|
+
padding: 6px 10px;
|
|
21
|
+
font-size: 12px;
|
|
22
|
+
font-weight: 700;
|
|
23
|
+
border-bottom-left-radius: 3px;
|
|
24
|
+
border-bottom-right-radius: 3px;
|
|
25
|
+
color: var(--ribbon-text);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.card-ribbon-light {
|
|
29
|
+
background-color: var(--ribbon-light-background);
|
|
30
|
+
|
|
31
|
+
.card-ribbon-text::after {
|
|
32
|
+
border-bottom: 8px solid var(--ribbon-light-shadow);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.card-ribbon-dark {
|
|
37
|
+
background-color: var(--ribbon-dark-background);
|
|
38
|
+
|
|
39
|
+
.card-ribbon-text::after {
|
|
40
|
+
border-bottom: 8px solid var(--ribbon-dark-shadow);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.card-ribbon-text {
|
|
45
|
+
position: relative;
|
|
46
|
+
|
|
47
|
+
&::after {
|
|
48
|
+
content: "";
|
|
49
|
+
border-right: 7px solid transparent;
|
|
50
|
+
position: absolute;
|
|
51
|
+
top: -7px;
|
|
52
|
+
right: -17px;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.card-headline {
|
|
57
|
+
color: var(--card-headline);
|
|
58
|
+
font-size: 140%;
|
|
59
|
+
margin: -10px 0 0.83em;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.card-sub-headline {
|
|
63
|
+
color: var(--formGroup-label);
|
|
64
|
+
font-size: 13px;
|
|
65
|
+
margin: 0 0 20px;
|
|
66
|
+
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
<div <%= tag.attributes **html_options %>>
|
|
2
|
+
<% if ribbon? %>
|
|
3
|
+
<%= ribbon %>
|
|
4
|
+
<% end %>
|
|
2
5
|
<% if headline? %>
|
|
3
6
|
<h2 class="card-headline"><%= headline %></h2>
|
|
4
7
|
<% end %>
|
|
8
|
+
<% if sub_headline? %>
|
|
9
|
+
<p class="card-sub-headline"><%= sub_headline %></p>
|
|
10
|
+
<% end %>
|
|
5
11
|
<div class="card-content">
|
|
6
12
|
<%= content %>
|
|
7
13
|
</div>
|
|
@@ -2,12 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
module Essence
|
|
4
4
|
class CardComponent < ApplicationComponent
|
|
5
|
-
attr_reader :headline, :html_options
|
|
5
|
+
attr_reader :headline, :sub_headline, :html_options
|
|
6
|
+
|
|
7
|
+
renders_one :ribbon, 'RibbonComponent'
|
|
6
8
|
|
|
7
9
|
def initialize(headline: nil,
|
|
10
|
+
sub_headline: nil,
|
|
8
11
|
**html_options)
|
|
9
|
-
@headline
|
|
10
|
-
@
|
|
12
|
+
@headline = headline
|
|
13
|
+
@sub_headline = sub_headline
|
|
14
|
+
@html_options = html_options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class RibbonComponent < ApplicationComponent
|
|
18
|
+
attr_reader :text, :html_options
|
|
19
|
+
|
|
20
|
+
DEFAULT_VARIANT = :light
|
|
21
|
+
|
|
22
|
+
VARIANT_MAPPINGS = {
|
|
23
|
+
DEFAULT_VARIANT => 'card-ribbon-light',
|
|
24
|
+
:dark => 'card-ribbon-dark'
|
|
25
|
+
}.freeze
|
|
26
|
+
|
|
27
|
+
VARIANT_OPTIONS = VARIANT_MAPPINGS.keys.freeze
|
|
28
|
+
|
|
29
|
+
def initialize(text:,
|
|
30
|
+
variant: DEFAULT_VARIANT,
|
|
31
|
+
**html_options)
|
|
32
|
+
@text = text
|
|
33
|
+
@variant = fetch_or_fallback(VARIANT_OPTIONS, variant.to_sym, DEFAULT_VARIANT)
|
|
34
|
+
@html_options = html_options
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def before_render
|
|
40
|
+
set_base_html_options(
|
|
41
|
+
'card-ribbon',
|
|
42
|
+
VARIANT_MAPPINGS[@variant]
|
|
43
|
+
)
|
|
44
|
+
end
|
|
11
45
|
end
|
|
12
46
|
|
|
13
47
|
private
|
|
@@ -20,7 +54,7 @@ module Essence
|
|
|
20
54
|
content?
|
|
21
55
|
end
|
|
22
56
|
|
|
23
|
-
[:headline].each do |method_name|
|
|
57
|
+
[:headline, :sub_headline].each do |method_name|
|
|
24
58
|
define_method(:"#{method_name}?") do
|
|
25
59
|
instance_variable_get(:"@#{method_name}").present?
|
|
26
60
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
.empty-state {
|
|
2
|
+
align-items: center;
|
|
3
|
+
display: flex;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.empty-state-image {
|
|
8
|
+
flex-shrink: 0;
|
|
9
|
+
margin: 0 60px 0 0;
|
|
10
|
+
max-width: 200px;
|
|
11
|
+
|
|
12
|
+
.bubbles {
|
|
13
|
+
fill: var(--emptyState-bubbles);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.outline {
|
|
17
|
+
fill: var(--emptyState-outline);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.surface {
|
|
21
|
+
fill: var(--emptyState-surface);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.empty-state-text {
|
|
26
|
+
display: grid;
|
|
27
|
+
gap: 20px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.empty-state-headline {
|
|
31
|
+
color: var(--emptyState-headline);
|
|
32
|
+
font-size: 300%;
|
|
33
|
+
font-weight: lighter;
|
|
34
|
+
line-height: 1;
|
|
35
|
+
margin-bottom: 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.empty-state-body {
|
|
39
|
+
color: var(--emptyState-help-text);
|
|
40
|
+
font-size: 125%;
|
|
41
|
+
margin: 0;
|
|
42
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.expandable {
|
|
2
|
+
&[data-expandable-expanded-value="false"] {
|
|
3
|
+
.expandable-content {
|
|
4
|
+
height: 0;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
&[data-expandable-expanded-value="true"] {
|
|
9
|
+
.button-icon {
|
|
10
|
+
transform: rotate(90deg);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.expandable-content {
|
|
14
|
+
margin-top: 10px;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.expandable-button {
|
|
19
|
+
font-weight: bold;
|
|
20
|
+
|
|
21
|
+
.button-icon {
|
|
22
|
+
fill: currentColor;
|
|
23
|
+
height: 10px;
|
|
24
|
+
width: 10px;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.expandable-content {
|
|
29
|
+
interpolate-size: allow-keywords;
|
|
30
|
+
height: auto;
|
|
31
|
+
margin-top: 0;
|
|
32
|
+
overflow: hidden;
|
|
33
|
+
padding-left: 20px;
|
|
34
|
+
transition: height 250ms, margin-top 250ms;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<div <%= tag.attributes **html_options %>>
|
|
2
|
+
<%= render Essence::ButtonComponent.new(name:, display_as: :link, type: :button, class: 'expandable-button', data: { action: 'expandable#toggle' }) do |button| %>
|
|
3
|
+
<% button.with_left_icon 'arrow_right' %>
|
|
4
|
+
<% end %>
|
|
5
|
+
<div class="expandable-content">
|
|
6
|
+
<%= content %>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
|
2
|
+
|
|
3
|
+
export default class extends Controller {
|
|
4
|
+
static outlets = [
|
|
5
|
+
"expandable-toggle"
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
static values = {
|
|
9
|
+
expanded: Boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
toggle() {
|
|
13
|
+
this.#updateExpandedState(!this.expandedValue)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
expand() {
|
|
17
|
+
this.#updateExpandedState(true)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
collapse() {
|
|
21
|
+
this.#updateExpandedState(false)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#updateExpandedState(expandedState) {
|
|
25
|
+
this.expandedValue = expandedState
|
|
26
|
+
this.#triggerOutletsCheckExpandables()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#triggerOutletsCheckExpandables() {
|
|
30
|
+
this.expandableToggleOutlets.forEach(expandable => expandable.checkExpandables())
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Essence
|
|
4
|
+
class ExpandableComponent < ApplicationComponent
|
|
5
|
+
attr_reader :name, :html_options
|
|
6
|
+
|
|
7
|
+
DEFAULT_EXPANDED = false
|
|
8
|
+
|
|
9
|
+
def initialize(name:,
|
|
10
|
+
expanded: DEFAULT_EXPANDED,
|
|
11
|
+
**html_options)
|
|
12
|
+
@name = name
|
|
13
|
+
@expanded = fetch_or_fallback_boolean(expanded, fallback: DEFAULT_EXPANDED)
|
|
14
|
+
@html_options = html_options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def before_render
|
|
20
|
+
set_base_html_options(
|
|
21
|
+
'expandable',
|
|
22
|
+
data: {
|
|
23
|
+
controller: 'expandable',
|
|
24
|
+
expandable_expanded_value: @expanded,
|
|
25
|
+
expandable_expand_all_button_outlet: '.expandable-toggle'
|
|
26
|
+
}
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/app/components/essence/expandable_toggle_component/expandable_toggle_component_controller.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
|
2
|
+
|
|
3
|
+
export default class extends Controller {
|
|
4
|
+
static outlets = [
|
|
5
|
+
"expandable"
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
static values = {
|
|
9
|
+
expandAllText: String,
|
|
10
|
+
collapseAllText: String,
|
|
11
|
+
allExpanded: Boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
connect() {
|
|
15
|
+
this.checkExpandables()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
toggleAll() {
|
|
19
|
+
this.#updateExpandablesState(!this.allExpandedValue)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
collapseAll() {
|
|
23
|
+
this.#updateExpandablesState(false)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
expandAll() {
|
|
27
|
+
this.#updateExpandablesState(true)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
checkExpandables() {
|
|
31
|
+
if (this.expandableOutlets.length === 0) return
|
|
32
|
+
|
|
33
|
+
const allExpanded = this.expandableOutlets.every(expandable => expandable.expandedValue)
|
|
34
|
+
const allCollapsed = this.expandableOutlets.every(expandable => !expandable.expandedValue)
|
|
35
|
+
|
|
36
|
+
if (allExpanded) {
|
|
37
|
+
this.#updateExpandedState(true)
|
|
38
|
+
} else if (allCollapsed) {
|
|
39
|
+
this.#updateExpandedState(false)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#updateExpandablesState(expandedState) {
|
|
44
|
+
this.#updateExpandedState(expandedState)
|
|
45
|
+
this.expandableOutlets.forEach(expandable => expandedState ? expandable.expand() : expandable.collapse())
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
#updateExpandedState(expandedState) {
|
|
49
|
+
this.allExpandedValue = expandedState
|
|
50
|
+
this.element.querySelector("span").textContent = expandedState ? this.collapseAllTextValue : this.expandAllTextValue
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Essence
|
|
4
|
+
class ExpandableToggleComponent < ApplicationComponent
|
|
5
|
+
attr_reader :expand_all_text, :html_options
|
|
6
|
+
|
|
7
|
+
DEFAULT_TARGET = '.expandable'
|
|
8
|
+
|
|
9
|
+
def initialize(target: DEFAULT_TARGET,
|
|
10
|
+
expand_all_text: nil,
|
|
11
|
+
collapse_all_text: nil,
|
|
12
|
+
**html_options)
|
|
13
|
+
@target = target
|
|
14
|
+
@expand_all_text = expand_all_text
|
|
15
|
+
@collapse_all_text = collapse_all_text
|
|
16
|
+
@html_options = html_options
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def before_render
|
|
22
|
+
@expand_all_text ||= t('.expand_all_text')
|
|
23
|
+
@collapse_all_text ||= t('.collapse_all_text')
|
|
24
|
+
|
|
25
|
+
set_base_html_options(
|
|
26
|
+
'expandable-toggle',
|
|
27
|
+
data: {
|
|
28
|
+
controller: 'expandable-toggle',
|
|
29
|
+
action: 'expandable-toggle#toggleAll',
|
|
30
|
+
expandable_toggle_expandable_outlet: @target,
|
|
31
|
+
expandable_toggle_expand_all_text_value: @expand_all_text,
|
|
32
|
+
expandable_toggle_collapse_all_text_value: @collapse_all_text,
|
|
33
|
+
expandable_toggle_all_expanded_value: false
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
.flash {
|
|
2
|
+
background-color: var(--notification-background);
|
|
3
|
+
border-radius: var(--notification-borderRadius);
|
|
4
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
position: relative;
|
|
8
|
+
right: 25px;
|
|
9
|
+
top: 97px;
|
|
10
|
+
pointer-events: auto;
|
|
11
|
+
opacity: 1;
|
|
12
|
+
animation: show 700ms ease-out;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.flash-hide {
|
|
16
|
+
opacity: 0;
|
|
17
|
+
right: -250px;
|
|
18
|
+
transition: all 1.3s ease-out;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.flash-container {
|
|
22
|
+
position: fixed;
|
|
23
|
+
right: 0;
|
|
24
|
+
top: 0;
|
|
25
|
+
z-index: 1;
|
|
26
|
+
pointer-events: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.flash-body {
|
|
30
|
+
color: var(--notification-text);
|
|
31
|
+
padding: 8px 14px;
|
|
32
|
+
|
|
33
|
+
&::first-letter {
|
|
34
|
+
text-transform: uppercase;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.flash-close {
|
|
39
|
+
width: 40px;
|
|
40
|
+
text-align: center;
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.flash-close-icon {
|
|
48
|
+
width: 8px;
|
|
49
|
+
height: 8px;
|
|
50
|
+
position: relative;
|
|
51
|
+
fill: gray;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.flash-danger,
|
|
55
|
+
.flash-alert {
|
|
56
|
+
.flash-indicator {
|
|
57
|
+
background-color: var(--notification-danger);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.flash-icon {
|
|
62
|
+
display: block;
|
|
63
|
+
fill: var(--notification-background);
|
|
64
|
+
height: 18px;
|
|
65
|
+
width: 18px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.flash-indicator {
|
|
69
|
+
padding: 10px 8px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.flash-info {
|
|
73
|
+
.flash-indicator {
|
|
74
|
+
background-color: var(--notification-info);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.flash-success,
|
|
79
|
+
.flash-notice {
|
|
80
|
+
.flash-indicator {
|
|
81
|
+
background-color: var(--notification-success);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.flash-warning {
|
|
86
|
+
.flash-indicator {
|
|
87
|
+
background-color: var(--notification-warning);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@keyframes show {
|
|
92
|
+
from {
|
|
93
|
+
opacity: 0;
|
|
94
|
+
right: -250px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
to {
|
|
98
|
+
opacity: 1;
|
|
99
|
+
right: 25px;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div <%= tag.attributes **html_options %>>
|
|
2
|
+
<div class="flash-indicator">
|
|
3
|
+
<%= render Essence::IconComponent.new(name: icon, class: 'flash-icon') %>
|
|
4
|
+
</div>
|
|
5
|
+
<div class="flash-body">
|
|
6
|
+
<%= content %>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="flash-close" data-action="click->flash#dismiss">
|
|
9
|
+
<%= render Essence::IconComponent.new(name: 'x_mark', class: 'flash-close-icon') %>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
|
2
|
+
|
|
3
|
+
export default class extends Controller {
|
|
4
|
+
connect() {
|
|
5
|
+
const flash = this.element
|
|
6
|
+
|
|
7
|
+
if (flash.classList.contains("flash-success") ||
|
|
8
|
+
flash.classList.contains("flash-notice") ||
|
|
9
|
+
flash.classList.contains("flash-info")) {
|
|
10
|
+
setTimeout(() => {
|
|
11
|
+
this.dismiss()
|
|
12
|
+
}, 3300);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
dismiss() {
|
|
17
|
+
const flash = this.element
|
|
18
|
+
|
|
19
|
+
flash.classList.add("flash-hide")
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
flash.remove()
|
|
22
|
+
}, 1300)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Essence
|
|
4
|
+
class FlashComponent < NotificationComponent
|
|
5
|
+
class ContainerComponent < ApplicationComponent; end
|
|
6
|
+
|
|
7
|
+
VARIANT_MAPPINGS = {
|
|
8
|
+
:success => 'flash-success',
|
|
9
|
+
:notice => 'flash-notice',
|
|
10
|
+
DEFAULT_VARIANT => 'flash-info',
|
|
11
|
+
:warning => 'flash-warning',
|
|
12
|
+
:danger => 'flash-danger',
|
|
13
|
+
:alert => 'flash-danger'
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def before_render
|
|
19
|
+
set_base_html_options(
|
|
20
|
+
'flash',
|
|
21
|
+
VARIANT_MAPPINGS[@variant],
|
|
22
|
+
data: {
|
|
23
|
+
controller: 'flash'
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
set_icon
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|