diff --git a/Gemfile.lock b/Gemfile.lock index 8b4928b..2817ad1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,7 +6,7 @@ PATH gretel (~> 5.0) importmap-rails (~> 2.0) inline_svg (~> 1.10) - rails (>= 7.1.4) + rails (>= 7.1.4, < 8.0) sassc-rails (~> 2.1) simple_form (~> 5.3) stimulus-rails (~> 1.3) @@ -15,29 +15,29 @@ PATH GEM remote: https://rubygems.org/ specs: - actioncable (7.2.1.1) - actionpack (= 7.2.1.1) - activesupport (= 7.2.1.1) + actioncable (7.2.2.1) + actionpack (= 7.2.2.1) + activesupport (= 7.2.2.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.2.1.1) - actionpack (= 7.2.1.1) - activejob (= 7.2.1.1) - activerecord (= 7.2.1.1) - activestorage (= 7.2.1.1) - activesupport (= 7.2.1.1) + actionmailbox (7.2.2.1) + actionpack (= 7.2.2.1) + activejob (= 7.2.2.1) + activerecord (= 7.2.2.1) + activestorage (= 7.2.2.1) + activesupport (= 7.2.2.1) mail (>= 2.8.0) - actionmailer (7.2.1.1) - actionpack (= 7.2.1.1) - actionview (= 7.2.1.1) - activejob (= 7.2.1.1) - activesupport (= 7.2.1.1) + actionmailer (7.2.2.1) + actionpack (= 7.2.2.1) + actionview (= 7.2.2.1) + activejob (= 7.2.2.1) + activesupport (= 7.2.2.1) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.2.1.1) - actionview (= 7.2.1.1) - activesupport (= 7.2.1.1) + actionpack (7.2.2.1) + actionview (= 7.2.2.1) + activesupport (= 7.2.2.1) nokogiri (>= 1.8.5) racc rack (>= 2.2.4, < 3.2) @@ -46,36 +46,37 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (7.2.1.1) - actionpack (= 7.2.1.1) - activerecord (= 7.2.1.1) - activestorage (= 7.2.1.1) - activesupport (= 7.2.1.1) + actiontext (7.2.2.1) + actionpack (= 7.2.2.1) + activerecord (= 7.2.2.1) + activestorage (= 7.2.2.1) + activesupport (= 7.2.2.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.2.1.1) - activesupport (= 7.2.1.1) + actionview (7.2.2.1) + activesupport (= 7.2.2.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.2.1.1) - activesupport (= 7.2.1.1) + activejob (7.2.2.1) + activesupport (= 7.2.2.1) globalid (>= 0.3.6) - activemodel (7.2.1.1) - activesupport (= 7.2.1.1) - activerecord (7.2.1.1) - activemodel (= 7.2.1.1) - activesupport (= 7.2.1.1) + activemodel (7.2.2.1) + activesupport (= 7.2.2.1) + activerecord (7.2.2.1) + activemodel (= 7.2.2.1) + activesupport (= 7.2.2.1) timeout (>= 0.4.0) - activestorage (7.2.1.1) - actionpack (= 7.2.1.1) - activejob (= 7.2.1.1) - activerecord (= 7.2.1.1) - activesupport (= 7.2.1.1) + activestorage (7.2.2.1) + actionpack (= 7.2.2.1) + activejob (= 7.2.2.1) + activerecord (= 7.2.2.1) + activesupport (= 7.2.2.1) marcel (~> 1.0) - activesupport (7.2.1.1) + activesupport (7.2.2.1) base64 + benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) @@ -89,8 +90,9 @@ GEM public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) base64 (0.2.0) + benchmark (0.4.0) bigdecimal (3.1.8) - brakeman (6.2.1) + brakeman (6.2.2) racc builder (3.3.0) capybara (3.40.0) @@ -111,7 +113,7 @@ GEM crass (1.0.6) css_parser (1.19.1) addressable - date (3.3.4) + date (3.4.1) diff-lcs (1.5.1) drb (2.2.1) erubi (1.13.0) @@ -141,17 +143,17 @@ GEM inline_svg (1.10.0) activesupport (>= 3.0) nokogiri (>= 1.6) - io-console (0.7.2) + io-console (0.8.0) irb (1.14.1) rdoc (>= 4.0.0) reline (>= 0.4.2) - json (2.7.2) + json (2.9.0) language_server-protocol (3.17.0.3) - logger (1.6.1) - loofah (2.22.0) + logger (1.6.2) + loofah (2.23.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) - lookbook (2.3.2) + lookbook (2.3.4) activemodel css_parser htmlbeautifier (~> 1.3) @@ -172,8 +174,8 @@ GEM matrix (0.4.2) method_source (1.1.0) mini_mime (1.1.5) - minitest (5.25.1) - net-imap (0.4.17) + minitest (5.25.4) + net-imap (0.5.1) date net-protocol net-pop (0.1.2) @@ -182,27 +184,28 @@ GEM timeout net-smtp (0.5.0) net-protocol - nio4r (2.7.3) - nokogiri (1.16.7-aarch64-linux) + nio4r (2.7.4) + nokogiri (1.17.1-aarch64-linux) racc (~> 1.4) - nokogiri (1.16.7-arm-linux) + nokogiri (1.17.1-arm-linux) racc (~> 1.4) - nokogiri (1.16.7-arm64-darwin) + nokogiri (1.17.1-arm64-darwin) racc (~> 1.4) - nokogiri (1.16.7-x86-linux) + nokogiri (1.17.1-x86-linux) racc (~> 1.4) - nokogiri (1.16.7-x86_64-darwin) + nokogiri (1.17.1-x86_64-darwin) racc (~> 1.4) - nokogiri (1.16.7-x86_64-linux) + nokogiri (1.17.1-x86_64-linux) racc (~> 1.4) parallel (1.26.3) - parser (3.3.5.0) + parser (3.3.6.0) ast (~> 2.4.1) racc - psych (5.1.2) + psych (5.2.1) + date stringio public_suffix (6.0.1) - puma (6.4.3) + puma (6.5.0) nio4r (~> 2.0) racc (1.8.1) rack (3.1.8) @@ -210,33 +213,32 @@ GEM rack (>= 3.0.0) rack-test (2.1.0) rack (>= 1.3) - rackup (2.1.0) + rackup (2.2.1) rack (>= 3) - webrick (~> 1.8) - rails (7.2.1.1) - actioncable (= 7.2.1.1) - actionmailbox (= 7.2.1.1) - actionmailer (= 7.2.1.1) - actionpack (= 7.2.1.1) - actiontext (= 7.2.1.1) - actionview (= 7.2.1.1) - activejob (= 7.2.1.1) - activemodel (= 7.2.1.1) - activerecord (= 7.2.1.1) - activestorage (= 7.2.1.1) - activesupport (= 7.2.1.1) + rails (7.2.2.1) + actioncable (= 7.2.2.1) + actionmailbox (= 7.2.2.1) + actionmailer (= 7.2.2.1) + actionpack (= 7.2.2.1) + actiontext (= 7.2.2.1) + actionview (= 7.2.2.1) + activejob (= 7.2.2.1) + activemodel (= 7.2.2.1) + activerecord (= 7.2.2.1) + activestorage (= 7.2.2.1) + activesupport (= 7.2.2.1) bundler (>= 1.15.0) - railties (= 7.2.1.1) + railties (= 7.2.2.1) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.0) + rails-html-sanitizer (1.6.1) loofah (~> 2.21) - nokogiri (~> 1.14) - railties (7.2.1.1) - actionpack (= 7.2.1.1) - activesupport (= 7.2.1.1) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (7.2.2.1) + actionpack (= 7.2.2.1) + activesupport (= 7.2.2.1) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -244,15 +246,15 @@ GEM zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.2.1) - rdoc (6.7.0) + rdoc (6.8.1) psych (>= 4.0.0) redcarpet (3.6.0) - regexp_parser (2.9.2) - reline (0.5.10) + regexp_parser (2.9.3) + reline (0.5.12) io-console (~> 0.5) - rexml (3.3.8) - rouge (4.4.0) - rspec-core (3.13.1) + rexml (3.3.9) + rouge (4.5.1) + rspec-core (3.13.2) rspec-support (~> 3.13.0) rspec-expectations (3.13.3) diff-lcs (>= 1.2.0, < 2.0) @@ -262,7 +264,7 @@ GEM rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (7.0.1) + rspec-rails (7.1.0) actionpack (>= 7.0) activesupport (>= 7.0) railties (>= 7.0) @@ -270,20 +272,20 @@ GEM rspec-expectations (~> 3.13) rspec-mocks (~> 3.13) rspec-support (~> 3.13) - rspec-support (3.13.1) - rubocop (1.67.0) + rspec-support (3.13.2) + rubocop (1.69.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 2.4, < 3.0) - rubocop-ast (>= 1.32.2, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.36.2, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.32.3) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.36.2) parser (>= 3.3.1.0) - rubocop-rails (2.26.2) + rubocop-rails (2.27.0) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.52.0, < 2.0) @@ -298,8 +300,8 @@ GEM sprockets (> 3.0) sprockets-rails tilt - securerandom (0.3.1) - selenium-webdriver (4.25.0) + securerandom (0.4.0) + selenium-webdriver (4.27.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) @@ -315,32 +317,33 @@ GEM actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) - sqlite3 (2.1.0-aarch64-linux-gnu) - sqlite3 (2.1.0-aarch64-linux-musl) - sqlite3 (2.1.0-arm-linux-gnu) - sqlite3 (2.1.0-arm-linux-musl) - sqlite3 (2.1.0-arm64-darwin) - sqlite3 (2.1.0-x86-linux-gnu) - sqlite3 (2.1.0-x86-linux-musl) - sqlite3 (2.1.0-x86_64-darwin) - sqlite3 (2.1.0-x86_64-linux-gnu) - sqlite3 (2.1.0-x86_64-linux-musl) + sqlite3 (2.4.1-aarch64-linux-gnu) + sqlite3 (2.4.1-aarch64-linux-musl) + sqlite3 (2.4.1-arm-linux-gnu) + sqlite3 (2.4.1-arm-linux-musl) + sqlite3 (2.4.1-arm64-darwin) + sqlite3 (2.4.1-x86-linux-gnu) + sqlite3 (2.4.1-x86-linux-musl) + sqlite3 (2.4.1-x86_64-darwin) + sqlite3 (2.4.1-x86_64-linux-gnu) + sqlite3 (2.4.1-x86_64-linux-musl) stimulus-rails (1.3.4) railties (>= 6.0.0) - stringio (3.1.1) + stringio (3.1.2) thor (1.3.2) tilt (2.4.0) - timeout (0.4.1) + timeout (0.4.2) tzinfo (2.0.6) concurrent-ruby (~> 1.0) unaccent (0.4.0) - unicode-display_width (2.6.0) - useragent (0.16.10) - view_component (3.17.0) - activesupport (>= 5.2.0, < 8.0) + unicode-display_width (3.1.2) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) + useragent (0.16.11) + view_component (3.20.0) + activesupport (>= 5.2.0, < 8.1) concurrent-ruby (~> 1.0) method_source (~> 1.0) - webrick (1.8.2) websocket (1.2.11) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) @@ -348,7 +351,7 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) yard (0.9.37) - zeitwerk (2.7.0) + zeitwerk (2.7.1) PLATFORMS aarch64-linux diff --git a/app/assets/images/essence/icon_component/arrow_right.svg b/app/assets/images/essence/icon_component/arrow_right.svg new file mode 100644 index 0000000..8cb5e86 --- /dev/null +++ b/app/assets/images/essence/icon_component/arrow_right.svg @@ -0,0 +1 @@ + diff --git a/app/assets/images/essence/icon_component/chevron_up_down.svg b/app/assets/images/essence/icon_component/chevron_up_down.svg new file mode 100644 index 0000000..d3e7a14 --- /dev/null +++ b/app/assets/images/essence/icon_component/chevron_up_down.svg @@ -0,0 +1,3 @@ + diff --git a/app/assets/stylesheets/essence/beyond/components/_index.scss b/app/assets/stylesheets/essence/beyond/components/_index.scss index 3b37374..5f07140 100644 --- a/app/assets/stylesheets/essence/beyond/components/_index.scss +++ b/app/assets/stylesheets/essence/beyond/components/_index.scss @@ -5,6 +5,8 @@ @import '../../../../../components/essence/card_component/card_component'; @import '../../../../../components/essence/clipboard_copy_component/clipboard_copy_component'; @import '../../../../../components/essence/empty_state_component/empty_state_component'; +@import '../../../../../components/essence/expand_all_button_component/expand_all_button_component'; +@import '../../../../../components/essence/expandable_component/expandable_component'; @import '../../../../../components/essence/link_component/link_component'; @import '../../../../../components/essence/notification_component/notification_component'; @import '../../../../../components/essence/paragraph_component/paragraph_component'; diff --git a/app/components/essence/expand_all_button_component.rb b/app/components/essence/expand_all_button_component.rb new file mode 100644 index 0000000..12db382 --- /dev/null +++ b/app/components/essence/expand_all_button_component.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Essence + class ExpandAllButtonComponent < ApplicationComponent + attr_reader :expand_all_text, :html_options + + DEFAULT_TARGET = '.expandable' + + def initialize(target: DEFAULT_TARGET, + expand_all_text: nil, + collapse_all_text: nil, + **html_options) + @target = target + @expand_all_text = expand_all_text + @collapse_all_text = collapse_all_text + @html_options = html_options + end + + private + + def before_render + @expand_all_text ||= t('.expand_all_text') + @collapse_all_text ||= t('.collapse_all_text') + + set_base_html_options( + 'expand-all-button', + data: { + controller: 'expand-all-button', + action: 'expand-all-button#toggleAll', + expand_all_button_expandable_outlet: @target, + expand_all_button_expand_all_text_value: @expand_all_text, + expand_all_button_collapse_all_text_value: @collapse_all_text, + expand_all_button_all_expanded_value: false + } + ) + end + end +end diff --git a/app/components/essence/expand_all_button_component/expand_all_button_component.html.erb b/app/components/essence/expand_all_button_component/expand_all_button_component.html.erb new file mode 100644 index 0000000..e6e8523 --- /dev/null +++ b/app/components/essence/expand_all_button_component/expand_all_button_component.html.erb @@ -0,0 +1,3 @@ +<%= render Essence::ButtonComponent.new(name: expand_all_text, display_as: :link, type: :button, **html_options) do |button| %> + <% button.with_left_icon 'chevron_up_down' %> +<% end %> diff --git a/app/components/essence/expand_all_button_component/expand_all_button_component.scss b/app/components/essence/expand_all_button_component/expand_all_button_component.scss new file mode 100644 index 0000000..597c64e --- /dev/null +++ b/app/components/essence/expand_all_button_component/expand_all_button_component.scss @@ -0,0 +1,13 @@ +:root { + --primaryLink-color: deepskyblue; + --primaryLink-hover-color: #0099cc; +} + +$expand-all-button-icon-size: 15px; + +.expand-all-button { + .button-icon { + height: $expand-all-button-icon-size; + width: $expand-all-button-icon-size; + } +} diff --git a/app/components/essence/expand_all_button_component/expand_all_button_component.yml b/app/components/essence/expand_all_button_component/expand_all_button_component.yml new file mode 100644 index 0000000..bbeb5c1 --- /dev/null +++ b/app/components/essence/expand_all_button_component/expand_all_button_component.yml @@ -0,0 +1,4 @@ +--- +en: + expand_all_text: Expand all + collapse_all_text: Collapse all diff --git a/app/components/essence/expand_all_button_component/expand_all_button_component_controller.js b/app/components/essence/expand_all_button_component/expand_all_button_component_controller.js new file mode 100644 index 0000000..b04351a --- /dev/null +++ b/app/components/essence/expand_all_button_component/expand_all_button_component_controller.js @@ -0,0 +1,52 @@ +import { Controller } from "@hotwired/stimulus"; + +export default class extends Controller { + static outlets = [ + "expandable" + ] + + static values = { + expandAllText: String, + collapseAllText: String, + allExpanded: Boolean + } + + connect() { + this.checkExpandables() + } + + toggleAll() { + this.#updateExpandablesState(!this.allExpandedValue) + } + + collapseAll() { + this.#updateExpandablesState(false) + } + + expandAll() { + this.#updateExpandablesState(true) + } + + checkExpandables() { + if (this.expandableOutlets.length === 0) return + + const allExpanded = this.expandableOutlets.every(expandable => expandable.expandedValue) + const allCollapsed = this.expandableOutlets.every(expandable => !expandable.expandedValue) + + if (allExpanded) { + this.#updateExpandedState(true) + } else if (allCollapsed) { + this.#updateExpandedState(false) + } + } + + #updateExpandablesState(expandedState) { + this.#updateExpandedState(expandedState) + this.expandableOutlets.forEach(expandable => expandedState ? expandable.expand() : expandable.collapse()) + } + + #updateExpandedState(expandedState) { + this.allExpandedValue = expandedState + this.element.querySelector("span").textContent = expandedState ? this.collapseAllTextValue : this.expandAllTextValue + } +} diff --git a/app/components/essence/expandable_component.rb b/app/components/essence/expandable_component.rb new file mode 100644 index 0000000..e203491 --- /dev/null +++ b/app/components/essence/expandable_component.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Essence + class ExpandableComponent < ApplicationComponent + attr_reader :name, :html_options + + DEFAULT_EXPANDED = false + + def initialize(name:, + expanded: DEFAULT_EXPANDED, + **html_options) + @name = name + @expanded = fetch_or_fallback_boolean(expanded, fallback: DEFAULT_EXPANDED) + @html_options = html_options + end + + private + + def before_render + set_base_html_options( + 'expandable', + data: { + controller: 'expandable', + expandable_expanded_value: @expanded, + expandable_expand_all_button_outlet: '.expand-all-button' + } + ) + end + end +end diff --git a/app/components/essence/expandable_component/expandable_component.html.erb b/app/components/essence/expandable_component/expandable_component.html.erb new file mode 100644 index 0000000..6968432 --- /dev/null +++ b/app/components/essence/expandable_component/expandable_component.html.erb @@ -0,0 +1,8 @@ +