rails_accordion 0.1.11.pre.beta → 0.2.0.pre.beta

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,9 +3,13 @@
3
3
  @tailwind utilities;
4
4
 
5
5
  .accordion_content {
6
- @apply h-0 overflow-hidden w-full transition-all duration-300
6
+ @apply h-0 overflow-hidden w-full transition-all ease-in-out;
7
7
  }
8
8
 
9
9
  .accordion_toggle {
10
10
  @apply cursor-pointer;
11
11
  }
12
+
13
+ .accordion_content-container {
14
+ @apply h-max;
15
+ }
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class AccordionComponent < ViewComponent::Base
4
+
4
5
  def initialize(**args)
5
6
  super
6
7
  @args = args.presence || {}
7
- set_controller
8
+ set_data_params
8
9
  end
9
10
 
10
11
  def call
@@ -13,8 +14,10 @@ class AccordionComponent < ViewComponent::Base
13
14
 
14
15
  private
15
16
 
16
- def set_controller
17
+ def set_data_params
17
18
  @args[:data] ||= {}
18
19
  @args[:data][:controller] = [@args[:data][:controller], "accordion"].compact.join(" ")
20
+ @args[:data][:multiple_open] = @args.delete(:multiple_open) || RailsAccordion.configuration.multiple_open
21
+ @args[:data][:default_state] = @args.delete(:default_state) || RailsAccordion.configuration.default_state
19
22
  end
20
23
  end
@@ -24,7 +24,7 @@ class ItemComponent < ViewComponent::Base
24
24
 
25
25
  def body_component
26
26
  if body?
27
- content_tag :div, class: "accordion_content" do
27
+ content_tag :div, class: "accordion_content", style: content_styles do
28
28
  content_tag :div, body, class: "accordion_content-container p-2"
29
29
  end
30
30
  else
@@ -35,4 +35,12 @@ class ItemComponent < ViewComponent::Base
35
35
  def set_classes
36
36
  @args[:class] = [@args[:class], "accordion_item"].compact.join(" ")
37
37
  end
38
+
39
+ def content_styles
40
+ "transition-duration: #{parse_duration}ms;"
41
+ end
42
+
43
+ def parse_duration
44
+ RailsAccordion.configuration.animation_duration
45
+ end
38
46
  end
@@ -3,6 +3,24 @@ import { Controller } from "@hotwired/stimulus";
3
3
  export default class extends Controller {
4
4
  connect() {
5
5
  this.initAccordion();
6
+
7
+ this.initDefaultState()
8
+ }
9
+
10
+ initDefaultState() {
11
+ const items = this.element.querySelectorAll('.accordion_item');
12
+
13
+ switch($(this.element).data('default-state')) {
14
+ case 'all_closed':
15
+ this.hideAll(items);
16
+ break;
17
+ case 'all_opened':
18
+ this.showAll(items);
19
+ break;
20
+ case 'first_opened':
21
+ this.hideAll(items)
22
+ this.open(items[0].querySelector('.accordion_content'))
23
+ }
6
24
  }
7
25
 
8
26
  initAccordion() {
@@ -10,34 +28,36 @@ export default class extends Controller {
10
28
 
11
29
  items.forEach((item) => {
12
30
  const toggle = item.querySelector('.accordion_toggle');
31
+ const content = item.querySelector('.accordion_content')
13
32
 
14
33
  toggle.addEventListener('click', (e) => {
15
- if (item.classList.contains('active')) {
16
- this.hide(item);
34
+ if (content.classList.contains('accordion_active')) {
35
+ this.hide(content);
17
36
  } else {
18
- this.hideAll(items);
19
- this.open(item);
37
+ if ($(this.element).data('multiple-open') != true) {
38
+ this.hideAll(items);
39
+ }
40
+ this.open(content);
20
41
  }
21
42
  });
22
43
  });
23
44
  }
24
45
 
25
46
  hideAll(items) {
26
- items.forEach((item) => this.hide(item));
47
+ items.forEach((item) => this.hide(item.querySelector('.accordion_content')));
48
+ }
49
+
50
+ showAll(items) {
51
+ items.forEach((item) => this.open(item.querySelector('.accordion_content')));
27
52
  }
28
53
 
29
54
  hide(item) {
30
- item.classList.remove("active")
31
- const content = item.querySelector('.accordion_content');
32
- content.style.height = '0px';
55
+ item.classList.remove("accordion_active")
56
+ item.style.height = 0;
33
57
  }
34
58
 
35
59
  open(item) {
36
- item.classList.add("active")
37
- const content = item.querySelector('.accordion_content');
38
- content.style.height = 'auto';
39
- const contentHeight = content.style.height
40
- // content.style.height = '0px';
41
- content.animate({ height: contentHeight + 'px' }, 50);
60
+ item.classList.add("accordion_active")
61
+ item.style.height = item.scrollHeight + 'px'
42
62
  }
43
63
  }
@@ -9,8 +9,8 @@ module RailsAccordion
9
9
  namespace "rails_accordion:install"
10
10
  desc "Copies all necessary files"
11
11
 
12
- def copy_build_files
13
- # directory File.join(__dir__, "../", "../", "../", "app", "assets", "builds"), "app/assets/builds"
12
+ def copy_config_file
13
+ template 'rails_accordion.tt', 'config/initializers/rails_accordion.rb'
14
14
  end
15
15
  end
16
16
  end
@@ -0,0 +1,5 @@
1
+ RailsAccordion.configure do |config|
2
+ config.default_state = :all_closed # :all_closed, :all_opened, :first_opened
3
+ config.animation_duration = 300 # in ms
4
+ config.multiple_open = false
5
+ end
@@ -0,0 +1,23 @@
1
+ module RailsAccordion
2
+ class Configuration
3
+ attr_accessor :default_state, :animation_duration, :multiple_open
4
+
5
+ def initialize
6
+ @default_state = :closed
7
+ @animation_duration = 300
8
+ @multiple_open = false
9
+ end
10
+ end
11
+
12
+ def self.configuration
13
+ @configuration ||= Configuration.new
14
+ end
15
+
16
+ def self.configuration=(config)
17
+ @configuration = config
18
+ end
19
+
20
+ def self.configure
21
+ yield configuration
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAccordion
4
- VERSION = "0.1.11-beta"
4
+ VERSION = "0.2.0-beta"
5
5
  end
@@ -11,6 +11,8 @@ module RailsAccordion
11
11
  class Error < StandardError; end
12
12
 
13
13
  class Engine < ::Rails::Engine
14
+ isolate_namespace RailsAccordion
15
+
14
16
  initializer "rails_accordion.importmap" do |app|
15
17
  if defined?(Importmap)
16
18
  app.config.assets.precompile << "rails_accordion.js"
@@ -514,7 +514,6 @@ video {
514
514
  }
515
515
 
516
516
  .accordion_content {
517
- height: 0px;
518
517
  width: 100%;
519
518
  overflow: hidden;
520
519
  transition-property: all;
@@ -525,3 +524,11 @@ video {
525
524
  .accordion_toggle {
526
525
  cursor: pointer;
527
526
  }
527
+
528
+ .accordion_item {
529
+ height: 0px;
530
+ }
531
+
532
+ .accordion_active {
533
+ height: max-content;
534
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_accordion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.11.pre.beta
4
+ version: 0.2.0.pre.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ahmadshoh Nasrullozoda
@@ -75,8 +75,9 @@ files:
75
75
  - bin/rails
76
76
  - bin/setup
77
77
  - lib/generators/rails_accordion/install_generator.rb
78
- - lib/generators/rails_accordion/templates/accordion_controller.js.tt
78
+ - lib/generators/rails_accordion/templates/rails_accordion.tt
79
79
  - lib/rails_accordion.rb
80
+ - lib/rails_accordion/configuration.rb
80
81
  - lib/rails_accordion/version.rb
81
82
  - lib/tasks/rails_accordion_tasks.rake
82
83
  - rails_accordion.gemspec
@@ -1,38 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- export default class extends Controller {
4
- connect() {
5
- this.initAccordion();
6
- }
7
-
8
- initAccordion() {
9
- const $toggles = $(this.element).find('.accordion_toggle');
10
-
11
- const removeAllActiveClass = () => {
12
- $toggles.each((el) => {
13
- const $parent = $(el).parent();
14
- $parent.removeClass('active');
15
- $parent.find('.accordion_content').height(0);
16
- });
17
- };
18
-
19
- $toggles.on('touch click', (e) => {
20
- const $toggle = $(e.currentTarget);
21
- const $parent = $toggle.parent();
22
- const $content = $parent.find('.accordion_content');
23
-
24
- if (!$parent.hasClass('active')) {
25
- removeAllActiveClass();
26
- $parent.addClass('active');
27
- $content.height('100%');
28
- } else {
29
- $parent.removeClass('active');
30
- $content.css({ height: '0px' });
31
- }
32
- });
33
- }
34
-
35
- afterReflex() {
36
- this.initAccordion();
37
- }
38
- }