daisyui 1.1.1 → 1.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.
@@ -1,15 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "securerandom"
4
+
3
5
  module DaisyUI
4
6
  class Dropdown < Base
5
7
  self.component_class = :dropdown
6
8
 
7
- def initialize(*modifiers, as: :div, id: nil, **options)
8
- super
9
+ # Placement modifiers that, in :popover mode, must live on the popover
10
+ # element itself (DaisyUI's `position-area` rule is on `.dropdown`).
11
+ PLACEMENT_MODIFIERS = %i[start center end top bottom left right].freeze
12
+
13
+ # Default Stimulus identifier for the opt-in popover controller. Namespaced
14
+ # so it never collides with a consumer app's own `dropdown` controller.
15
+ DEFAULT_STIMULUS_IDENTIFIER = "daisy-dropdown"
16
+
17
+ def initialize(*modifiers, as: :div, id: nil, popover_id: nil, stimulus: false, **)
18
+ @popover = modifiers.include?(:popover)
19
+ @popover_id = popover_id if @popover
20
+ # stimulus: true enables the controller; a String/Symbol enables AND
21
+ # overrides the identifier. Only meaningful in :popover mode.
22
+ @stimulus = stimulus
23
+ super(*modifiers, as:, id:, **)
9
24
  end
10
25
 
11
26
  def view_template
12
- if tap_to_close?
27
+ if popover?
28
+ # DaisyUI's popover variant is a FLAT structure: the trigger button and
29
+ # the popover menu are siblings, and `dropdown` + the placement class
30
+ # ride the popover element (that is what carries `position-area`). The
31
+ # wrapper here is a plain, non-positioning container.
32
+ public_send(as, **popover_root_attributes) do
33
+ yield self if block_given?
34
+ end
35
+ elsif tap_to_close?
13
36
  details(class: classes, **attributes) do
14
37
  yield self if block_given?
15
38
  end
@@ -20,38 +43,132 @@ module DaisyUI
20
43
  end
21
44
  end
22
45
 
23
- def button(*, **, &)
24
- if tap_to_close?
25
- render Button.new(*, as: :summary, **, &)
46
+ def button(*modifiers, **options, &)
47
+ if popover?
48
+ render Button.new(*modifiers, as: :button, **popover_button_options(options), &)
49
+ elsif tap_to_close?
50
+ render Button.new(*modifiers, as: :summary, **options, &)
26
51
  else
27
- render Button.new(*, as: :div, role: :button, tabindex: 0, **, &)
52
+ render Button.new(*modifiers, as: :div, role: :button, tabindex: 0, **options, &)
28
53
  end
29
54
  end
30
55
 
31
- def content(*, as: :div, **options, &)
56
+ def content(*modifiers, as: :div, **options, &)
57
+ return render_as(*modifiers, as:, **popover_menu_options(options), &) if popover?
58
+
32
59
  content_classes = component_classes("dropdown-content", options:)
33
60
 
34
61
  if tap_to_close?
35
- render_as(*, as:, class: content_classes, **options, &)
62
+ render_as(*modifiers, as:, class: content_classes, **options, &)
36
63
  else
37
- render_as(*, as:, tabindex: 0, class: content_classes, **options, &)
64
+ render_as(*modifiers, as:, tabindex: 0, class: content_classes, **options, &)
38
65
  end
39
66
  end
40
67
 
41
- def menu(*, **options, &)
68
+ def menu(*modifiers, **options, &)
69
+ if popover?
70
+ options[:role] ||= "menu"
71
+ return render Menu.new(*modifiers, **popover_menu_options(options), &)
72
+ end
73
+
42
74
  menu_classes = component_classes("dropdown-content", options:)
43
75
 
44
76
  if tap_to_close?
45
- render Menu.new(*, class: menu_classes, **options, &)
77
+ render Menu.new(*modifiers, class: menu_classes, **options, &)
46
78
  else
47
- render Menu.new(*, tabindex: 0, class: menu_classes, **options, &)
79
+ render Menu.new(*modifiers, tabindex: 0, class: menu_classes, **options, &)
48
80
  end
49
81
  end
50
82
 
83
+ def popover?
84
+ modifiers.include?(:popover)
85
+ end
86
+
51
87
  def tap_to_close?
52
88
  modifiers.include?(:tap_to_close)
53
89
  end
54
90
 
91
+ private
92
+
93
+ # Stable id shared by the trigger (`popovertarget`) and the popover element
94
+ # (`id`); the matching CSS anchor pairs `anchor-name` with `position-anchor`.
95
+ def popover_id
96
+ @popover_id ||= "dropdown_#{SecureRandom.hex(8)}"
97
+ end
98
+
99
+ def anchor_name
100
+ "#{popover_id}_anchor"
101
+ end
102
+
103
+ # Whether the opt-in Stimulus controller is enabled (popover mode only).
104
+ def stimulus?
105
+ @popover && @stimulus
106
+ end
107
+
108
+ # Resolved Stimulus identifier: the default, or a caller-supplied override.
109
+ def stimulus_identifier
110
+ return DEFAULT_STIMULUS_IDENTIFIER if @stimulus == true
111
+
112
+ @stimulus.to_s
113
+ end
114
+
115
+ # Wrapper attributes; in opt-in Stimulus mode add `data-controller`, merged
116
+ # with any caller-supplied controller token (space-joined, not clobbered).
117
+ def popover_root_attributes
118
+ attrs = attributes
119
+ return attrs unless stimulus?
120
+
121
+ data = (attrs[:data] || {}).dup
122
+ data[:controller] = [data[:controller], stimulus_identifier].compact.join(" ")
123
+ attrs.merge(data:)
124
+ end
125
+
126
+ # Trigger wiring: a real <button> (required for the Popover API invoker),
127
+ # `popovertarget` pointing at the menu, an `anchor-name` for CSS anchor
128
+ # positioning, and ARIA wiring. `aria-controls`/`aria-expanded` give assistive
129
+ # tech the trigger<->menu relationship and open state (the native Popover API
130
+ # does not mirror open state onto the invoker; the Stimulus controller keeps
131
+ # `aria-expanded` in sync when enabled). Caller `style`/`aria` are merged.
132
+ def popover_button_options(options)
133
+ options[:popovertarget] = popover_id
134
+ options[:style] = merge_style(options[:style], "anchor-name:--#{anchor_name}")
135
+ options[:aria] = { haspopup: "menu", controls: popover_id, expanded: "false" }.merge(options[:aria] || {})
136
+ merge_stimulus_data(options, target: "trigger") if stimulus?
137
+ options
138
+ end
139
+
140
+ # Popover element wiring: `dropdown` + placement classes (so `position-area`
141
+ # applies), `popover="auto"`, the shared id, and `position-anchor`. We strip
142
+ # any `dropdown-content` — that descendant rule forces `position: absolute`,
143
+ # which conflicts with the top-layer popover. (`role="menu"` is added by
144
+ # `menu`, not here, so a non-menu `content` panel is not mislabeled.)
145
+ def popover_menu_options(options)
146
+ caller_classes = Array(options.delete(:class)).flat_map { |v| v.to_s.split }.reject { |c| c.empty? || c == "dropdown-content" }
147
+ placement = PLACEMENT_MODIFIERS.select { |m| modifiers.include?(m) }.map { |m| apply_prefix("dropdown-#{m}") }
148
+
149
+ options[:class] = merge_classes(apply_prefix("dropdown"), *placement, *caller_classes)
150
+ options[:id] = popover_id
151
+ options[:popover] = "auto"
152
+ options[:style] = merge_style(options[:style], "position-anchor:--#{anchor_name}")
153
+ merge_stimulus_data(options, target: "menu") if stimulus?
154
+ options
155
+ end
156
+
157
+ # Add a `data-<identifier>-target` to a child element's options without
158
+ # clobbering caller-supplied data.
159
+ def merge_stimulus_data(options, target:)
160
+ data = (options[:data] || {}).dup
161
+ key = :"#{stimulus_identifier}_target"
162
+ existing = data[key].to_s.split
163
+ data[key] = (existing + [target]).uniq.join(" ")
164
+ options[:data] = data
165
+ options
166
+ end
167
+
168
+ def merge_style(existing, added)
169
+ [existing&.chomp(";"), added].compact.join(";")
170
+ end
171
+
55
172
  register_modifiers(
56
173
  # Placement
57
174
  # "sm:dropdown-start"
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DaisyUI
4
+ # Optional Rails integration. Loaded only when Rails::Engine is defined (see
5
+ # lib/daisy_ui.rb), so the gem stays a plain Phlex library outside Rails.
6
+ #
7
+ # It exposes the gem's bundled JavaScript (the opt-in `daisy-dropdown`
8
+ # Stimulus controller) to the host app:
9
+ # * appends the JS dir to importmap-rails' paths and auto-pins it, so
10
+ # consumers get `daisy_ui/controllers/daisy_dropdown_controller` with no
11
+ # manual pin;
12
+ # * appends the JS dir to the asset load path so Propshaft/Sprockets serve
13
+ # the file.
14
+ #
15
+ # The controller is opt-in at the markup level (`Dropdown(:popover, stimulus:
16
+ # true)`), so apps that never opt in ship no extra behavior.
17
+ # Asset-only engine: no isolate_namespace, since it exposes no routes, models,
18
+ # or helpers — only static JavaScript — and namespacing would risk surprises in
19
+ # the host app for no benefit.
20
+ class Engine < ::Rails::Engine
21
+ JAVASCRIPT_PATH = root.join("app/javascript")
22
+
23
+ initializer "daisy_ui.assets" do |app|
24
+ app.config.assets.paths << JAVASCRIPT_PATH.to_s if app.config.respond_to?(:assets)
25
+ end
26
+
27
+ initializer "daisy_ui.importmap", before: "importmap" do |app|
28
+ next unless app.config.respond_to?(:importmap)
29
+
30
+ importmap = app.config.importmap
31
+ importmap.paths << root.join("config/importmap.rb") if importmap.respond_to?(:paths)
32
+ # Reload the gem's controller in development when it changes.
33
+ importmap.cache_sweepers << JAVASCRIPT_PATH if importmap.respond_to?(:cache_sweepers)
34
+ end
35
+ end
36
+ end
@@ -30,16 +30,25 @@ module DaisyUI
30
30
 
31
31
  register_modifiers(
32
32
  # "sm:floating-label"
33
+ # "@sm:floating-label"
33
34
  # "md:floating-label"
35
+ # "@md:floating-label"
34
36
  # "lg:floating-label"
37
+ # "@lg:floating-label"
35
38
  floating: "floating-label",
36
39
  # "sm:input"
40
+ # "@sm:input"
37
41
  # "md:input"
42
+ # "@md:input"
38
43
  # "lg:input"
44
+ # "@lg:input"
39
45
  input: "input",
40
46
  # "sm:select"
47
+ # "@sm:select"
41
48
  # "md:select"
49
+ # "@md:select"
42
50
  # "lg:select"
51
+ # "@lg:select"
43
52
  select: "select"
44
53
  )
45
54
 
data/lib/daisy_ui/link.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module DaisyUI
4
4
  class Link < Base
5
- self.component_class = "link"
5
+ self.component_class = :link
6
6
 
7
7
  def view_template(&)
8
8
  a(class: classes, **attributes, &)
@@ -10,24 +10,69 @@ module DaisyUI
10
10
 
11
11
  register_modifiers(
12
12
  # Style
13
- # "sm:link-hover" "md:link-hover" "lg:link-hover"
13
+ # "sm:link-hover"
14
+ # "@sm:link-hover"
15
+ # "md:link-hover"
16
+ # "@md:link-hover"
17
+ # "lg:link-hover"
18
+ # "@lg:link-hover"
14
19
  hover: "link-hover",
15
20
  # Colors
16
- # "sm:link-neutral" "md:link-neutral" "lg:link-neutral"
21
+ # "sm:link-neutral"
22
+ # "@sm:link-neutral"
23
+ # "md:link-neutral"
24
+ # "@md:link-neutral"
25
+ # "lg:link-neutral"
26
+ # "@lg:link-neutral"
17
27
  neutral: "link-neutral",
18
- # "sm:link-primary" "md:link-primary" "lg:link-primary"
28
+ # "sm:link-primary"
29
+ # "@sm:link-primary"
30
+ # "md:link-primary"
31
+ # "@md:link-primary"
32
+ # "lg:link-primary"
33
+ # "@lg:link-primary"
19
34
  primary: "link-primary",
20
- # "sm:link-secondary" "md:link-secondary" "lg:link-secondary"
35
+ # "sm:link-secondary"
36
+ # "@sm:link-secondary"
37
+ # "md:link-secondary"
38
+ # "@md:link-secondary"
39
+ # "lg:link-secondary"
40
+ # "@lg:link-secondary"
21
41
  secondary: "link-secondary",
22
- # "sm:link-accent" "md:link-accent" "lg:link-accent"
42
+ # "sm:link-accent"
43
+ # "@sm:link-accent"
44
+ # "md:link-accent"
45
+ # "@md:link-accent"
46
+ # "lg:link-accent"
47
+ # "@lg:link-accent"
23
48
  accent: "link-accent",
24
- # "sm:link-info" "md:link-info" "lg:link-info"
49
+ # "sm:link-info"
50
+ # "@sm:link-info"
51
+ # "md:link-info"
52
+ # "@md:link-info"
53
+ # "lg:link-info"
54
+ # "@lg:link-info"
25
55
  info: "link-info",
26
- # "sm:link-success" "md:link-success" "lg:link-success"
56
+ # "sm:link-success"
57
+ # "@sm:link-success"
58
+ # "md:link-success"
59
+ # "@md:link-success"
60
+ # "lg:link-success"
61
+ # "@lg:link-success"
27
62
  success: "link-success",
28
- # "sm:link-warning" "md:link-warning" "lg:link-warning"
63
+ # "sm:link-warning"
64
+ # "@sm:link-warning"
65
+ # "md:link-warning"
66
+ # "@md:link-warning"
67
+ # "lg:link-warning"
68
+ # "@lg:link-warning"
29
69
  warning: "link-warning",
30
- # "sm:link-error" "md:link-error" "lg:link-error"
70
+ # "sm:link-error"
71
+ # "@sm:link-error"
72
+ # "md:link-error"
73
+ # "@md:link-error"
74
+ # "lg:link-error"
75
+ # "@lg:link-error"
31
76
  error: "link-error"
32
77
  ).freeze
33
78
  end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DaisyUI
4
+ class Megamenu < Base
5
+ self.component_class = :megamenu
6
+
7
+ def initialize(*, as: :div, **)
8
+ super
9
+ end
10
+
11
+ def view_template(&)
12
+ public_send(as, class: classes, **attributes, &)
13
+ end
14
+
15
+ def active_indicator(**options, &)
16
+ span(class: component_classes("megamenu-active", options:), **options, &)
17
+ end
18
+
19
+ register_modifiers(
20
+ # "sm:megamenu-wide"
21
+ # "@sm:megamenu-wide"
22
+ # "md:megamenu-wide"
23
+ # "@md:megamenu-wide"
24
+ # "lg:megamenu-wide"
25
+ # "@lg:megamenu-wide"
26
+ wide: "megamenu-wide",
27
+ # "sm:megamenu-full"
28
+ # "@sm:megamenu-full"
29
+ # "md:megamenu-full"
30
+ # "@md:megamenu-full"
31
+ # "lg:megamenu-full"
32
+ # "@lg:megamenu-full"
33
+ full: "megamenu-full",
34
+ # "sm:megamenu-vertical"
35
+ # "@sm:megamenu-vertical"
36
+ # "md:megamenu-vertical"
37
+ # "@md:megamenu-vertical"
38
+ # "lg:megamenu-vertical"
39
+ # "@lg:megamenu-vertical"
40
+ vertical: "megamenu-vertical",
41
+ # Sizes
42
+ # "sm:megamenu-xs"
43
+ # "@sm:megamenu-xs"
44
+ # "md:megamenu-xs"
45
+ # "@md:megamenu-xs"
46
+ # "lg:megamenu-xs"
47
+ # "@lg:megamenu-xs"
48
+ xs: "megamenu-xs",
49
+ # "sm:megamenu-sm"
50
+ # "@sm:megamenu-sm"
51
+ # "md:megamenu-sm"
52
+ # "@md:megamenu-sm"
53
+ # "lg:megamenu-sm"
54
+ # "@lg:megamenu-sm"
55
+ sm: "megamenu-sm",
56
+ # "sm:megamenu-md"
57
+ # "@sm:megamenu-md"
58
+ # "md:megamenu-md"
59
+ # "@md:megamenu-md"
60
+ # "lg:megamenu-md"
61
+ # "@lg:megamenu-md"
62
+ md: "megamenu-md",
63
+ # "sm:megamenu-lg"
64
+ # "@sm:megamenu-lg"
65
+ # "md:megamenu-lg"
66
+ # "@md:megamenu-lg"
67
+ # "lg:megamenu-lg"
68
+ # "@lg:megamenu-lg"
69
+ lg: "megamenu-lg",
70
+ # "sm:megamenu-xl"
71
+ # "@sm:megamenu-xl"
72
+ # "md:megamenu-xl"
73
+ # "@md:megamenu-xl"
74
+ # "lg:megamenu-xl"
75
+ # "@lg:megamenu-xl"
76
+ xl: "megamenu-xl"
77
+ )
78
+ end
79
+ end
@@ -22,11 +22,26 @@ module DaisyUI
22
22
  end
23
23
 
24
24
  register_modifiers(
25
- # "sm:menu-disabled" "md:menu-disabled" "lg:menu-disabled"
25
+ # "sm:menu-disabled"
26
+ # "@sm:menu-disabled"
27
+ # "md:menu-disabled"
28
+ # "@md:menu-disabled"
29
+ # "lg:menu-disabled"
30
+ # "@lg:menu-disabled"
26
31
  disabled: "menu-disabled",
27
- # "sm:menu-active" "md:menu-active" "lg:menu-active"
32
+ # "sm:menu-active"
33
+ # "@sm:menu-active"
34
+ # "md:menu-active"
35
+ # "@md:menu-active"
36
+ # "lg:menu-active"
37
+ # "@lg:menu-active"
28
38
  active: "menu-active",
29
- # "sm:menu-focus" "md:menu-focus" "lg:menu-focus"
39
+ # "sm:menu-focus"
40
+ # "@sm:menu-focus"
41
+ # "md:menu-focus"
42
+ # "@md:menu-focus"
43
+ # "lg:menu-focus"
44
+ # "@lg:menu-focus"
30
45
  focus: "menu-focus"
31
46
  )
32
47
  end
@@ -5,8 +5,7 @@ module DaisyUI
5
5
  self.component_class = :modal
6
6
 
7
7
  def initialize(*, id:, **)
8
- super(*, **)
9
- @id = id
8
+ super
10
9
  end
11
10
 
12
11
  def view_template(&block)
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DaisyUI
4
+ class Otp < Base
5
+ self.component_class = :otp
6
+
7
+ def initialize(*, digits: 4, as: :label, input_attributes: {}, **)
8
+ super(*, as:, **)
9
+ @digits = digits
10
+ @input_attributes = input_attributes
11
+ end
12
+
13
+ def view_template(&)
14
+ public_send(as, class: classes, **attributes) do
15
+ digits.times { span }
16
+ input(
17
+ type: :text,
18
+ autocomplete: "one-time-code",
19
+ inputmode: :numeric,
20
+ maxlength: digits,
21
+ pattern: "[0-9]{#{digits}}",
22
+ required: true,
23
+ **input_attributes
24
+ )
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :digits, :input_attributes
31
+
32
+ register_modifiers(
33
+ # "sm:otp-joined"
34
+ # "@sm:otp-joined"
35
+ # "md:otp-joined"
36
+ # "@md:otp-joined"
37
+ # "lg:otp-joined"
38
+ # "@lg:otp-joined"
39
+ joined: "otp-joined",
40
+ # Sizes
41
+ # "sm:otp-xs"
42
+ # "@sm:otp-xs"
43
+ # "md:otp-xs"
44
+ # "@md:otp-xs"
45
+ # "lg:otp-xs"
46
+ # "@lg:otp-xs"
47
+ xs: "otp-xs",
48
+ # "sm:otp-sm"
49
+ # "@sm:otp-sm"
50
+ # "md:otp-sm"
51
+ # "@md:otp-sm"
52
+ # "lg:otp-sm"
53
+ # "@lg:otp-sm"
54
+ sm: "otp-sm",
55
+ # "sm:otp-md"
56
+ # "@sm:otp-md"
57
+ # "md:otp-md"
58
+ # "@md:otp-md"
59
+ # "lg:otp-md"
60
+ # "@lg:otp-md"
61
+ md: "otp-md",
62
+ # "sm:otp-lg"
63
+ # "@sm:otp-lg"
64
+ # "md:otp-lg"
65
+ # "@md:otp-lg"
66
+ # "lg:otp-lg"
67
+ # "@lg:otp-lg"
68
+ lg: "otp-lg",
69
+ # "sm:otp-xl"
70
+ # "@sm:otp-xl"
71
+ # "md:otp-xl"
72
+ # "@md:otp-xl"
73
+ # "lg:otp-xl"
74
+ # "@lg:otp-xl"
75
+ xl: "otp-xl",
76
+ # Colors
77
+ # "sm:otp-neutral"
78
+ # "@sm:otp-neutral"
79
+ # "md:otp-neutral"
80
+ # "@md:otp-neutral"
81
+ # "lg:otp-neutral"
82
+ # "@lg:otp-neutral"
83
+ neutral: "otp-neutral",
84
+ # "sm:otp-primary"
85
+ # "@sm:otp-primary"
86
+ # "md:otp-primary"
87
+ # "@md:otp-primary"
88
+ # "lg:otp-primary"
89
+ # "@lg:otp-primary"
90
+ primary: "otp-primary",
91
+ # "sm:otp-secondary"
92
+ # "@sm:otp-secondary"
93
+ # "md:otp-secondary"
94
+ # "@md:otp-secondary"
95
+ # "lg:otp-secondary"
96
+ # "@lg:otp-secondary"
97
+ secondary: "otp-secondary",
98
+ # "sm:otp-accent"
99
+ # "@sm:otp-accent"
100
+ # "md:otp-accent"
101
+ # "@md:otp-accent"
102
+ # "lg:otp-accent"
103
+ # "@lg:otp-accent"
104
+ accent: "otp-accent",
105
+ # "sm:otp-success"
106
+ # "@sm:otp-success"
107
+ # "md:otp-success"
108
+ # "@md:otp-success"
109
+ # "lg:otp-success"
110
+ # "@lg:otp-success"
111
+ success: "otp-success",
112
+ # "sm:otp-info"
113
+ # "@sm:otp-info"
114
+ # "md:otp-info"
115
+ # "@md:otp-info"
116
+ # "lg:otp-info"
117
+ # "@lg:otp-info"
118
+ info: "otp-info",
119
+ # "sm:otp-warning"
120
+ # "@sm:otp-warning"
121
+ # "md:otp-warning"
122
+ # "@md:otp-warning"
123
+ # "lg:otp-warning"
124
+ # "@lg:otp-warning"
125
+ warning: "otp-warning",
126
+ # "sm:otp-error"
127
+ # "@sm:otp-error"
128
+ # "md:otp-error"
129
+ # "@md:otp-error"
130
+ # "lg:otp-error"
131
+ # "@lg:otp-error"
132
+ error: "otp-error"
133
+ )
134
+ end
135
+ end
@@ -3,7 +3,7 @@
3
3
  module DaisyUI
4
4
  # @component html class="join"
5
5
  class Pagination < Base
6
- self.component_class = "join"
6
+ self.component_class = :join
7
7
 
8
8
  def view_template(&)
9
9
  public_send(as, class: classes, **attributes, &)
@@ -18,8 +18,8 @@ module DaisyUI
18
18
  style_parts = []
19
19
  style_parts << style if style && !style.empty?
20
20
  style_parts << "--value: #{value};"
21
- style_parts << "--size: #{size};" if size && !size.empty?
22
- style_parts << "--thickness: #{thickness};" if thickness && !thickness.empty?
21
+ style_parts << "--size: #{size};" if size && !size.to_s.empty?
22
+ style_parts << "--thickness: #{thickness};" if thickness && !thickness.to_s.empty?
23
23
 
24
24
  public_send(as, role: :progressbar, class: classes, style: style_parts.join(" "), **attributes, &)
25
25
  end
@@ -104,7 +104,14 @@ module DaisyUI
104
104
  # "@md:range-error"
105
105
  # "lg:range-error"
106
106
  # "@lg:range-error"
107
- error: "range-error"
107
+ error: "range-error",
108
+ # "sm:range-vertical"
109
+ # "@sm:range-vertical"
110
+ # "md:range-vertical"
111
+ # "@md:range-vertical"
112
+ # "lg:range-vertical"
113
+ # "@lg:range-vertical"
114
+ vertical: "range-vertical"
108
115
  )
109
116
  end
110
117
  end
@@ -20,6 +20,10 @@ module DaisyUI
20
20
  li(class: step_classes, **options, &)
21
21
  end
22
22
 
23
+ def icon(**options, &)
24
+ div(class: component_classes("step-icon", options:), **options, &)
25
+ end
26
+
23
27
  private
24
28
 
25
29
  def build_step_classes(step_modifiers, options)
@@ -42,12 +46,6 @@ module DaisyUI
42
46
  }
43
47
  end
44
48
 
45
- public
46
-
47
- def icon(**options, &)
48
- div(class: component_classes("step-icon", options:), **options, &)
49
- end
50
-
51
49
  register_modifiers(
52
50
  # "sm:steps-vertical"
53
51
  # "@sm:steps-vertical"
@@ -5,7 +5,7 @@ module DaisyUI
5
5
  class SubMenu < Base
6
6
  def initialize(*, **)
7
7
  super
8
- @items ||= []
8
+ @items = []
9
9
  end
10
10
 
11
11
  def view_template(&)
@@ -3,7 +3,7 @@
3
3
  module DaisyUI
4
4
  # @private
5
5
  class TabWithContent < Base
6
- self.component_class = "tab"
6
+ self.component_class = :tab
7
7
 
8
8
  def initialize(*, content:, label: nil, id: nil, **)
9
9
  super(*, **)
@@ -3,7 +3,7 @@
3
3
  module DaisyUI
4
4
  # @private
5
5
  class TabWithoutContent < Base
6
- self.component_class = "tab"
6
+ self.component_class = :tab
7
7
 
8
8
  def initialize(*, label: nil, **)
9
9
  super(*, **)