shadcn-rails 0.2.0 → 0.2.1

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 (152) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -2
  3. data/README.md +21 -8
  4. data/__mocks__/@floating-ui/dom.js +67 -0
  5. data/app/assets/javascripts/shadcn/controllers/combobox_controller.js +23 -2
  6. data/app/assets/javascripts/shadcn/controllers/context_menu_controller.js +4 -31
  7. data/app/assets/javascripts/shadcn/controllers/dropdown_controller.js +32 -41
  8. data/app/assets/javascripts/shadcn/controllers/hover_card_controller.js +29 -55
  9. data/app/assets/javascripts/shadcn/controllers/popover_controller.js +29 -54
  10. data/app/assets/javascripts/shadcn/controllers/select_controller.js +26 -8
  11. data/app/assets/javascripts/shadcn/controllers/tooltip_controller.js +28 -59
  12. data/app/assets/javascripts/shadcn/index.js +7 -1
  13. data/app/assets/javascripts/shadcn/utils/floating.js +179 -0
  14. data/app/assets/stylesheets/shadcn/base.css +32 -0
  15. data/app/components/shadcn/accordion_component.html.erb +8 -0
  16. data/app/components/shadcn/accordion_component.rb +6 -15
  17. data/app/components/shadcn/alert_component.html.erb +6 -0
  18. data/app/components/shadcn/alert_component.rb +0 -18
  19. data/app/components/shadcn/alert_dialog_component.html.erb +12 -0
  20. data/app/components/shadcn/alert_dialog_component.rb +7 -27
  21. data/app/components/shadcn/aspect_ratio_component.html.erb +7 -0
  22. data/app/components/shadcn/aspect_ratio_component.rb +4 -19
  23. data/app/components/shadcn/avatar_component.html.erb +20 -0
  24. data/app/components/shadcn/avatar_component.rb +8 -36
  25. data/app/components/shadcn/badge_component.html.erb +1 -0
  26. data/app/components/shadcn/badge_component.rb +0 -11
  27. data/app/components/shadcn/base_component.rb +15 -2
  28. data/app/components/shadcn/breadcrumb_component.html.erb +5 -0
  29. data/app/components/shadcn/breadcrumb_component.rb +6 -16
  30. data/app/components/shadcn/button_component.html.erb +18 -0
  31. data/app/components/shadcn/button_component.rb +1 -41
  32. data/app/components/shadcn/card_component.html.erb +8 -0
  33. data/app/components/shadcn/card_component.rb +2 -6
  34. data/app/components/shadcn/checkbox_component.html.erb +32 -0
  35. data/app/components/shadcn/checkbox_component.rb +4 -43
  36. data/app/components/shadcn/collapsible_component.html.erb +8 -0
  37. data/app/components/shadcn/collapsible_component.rb +6 -15
  38. data/app/components/shadcn/context_menu_component.html.erb +11 -0
  39. data/app/components/shadcn/context_menu_component.rb +6 -26
  40. data/app/components/shadcn/dialog_component.html.erb +14 -0
  41. data/app/components/shadcn/dialog_component.rb +8 -29
  42. data/app/components/shadcn/drawer_component.html.erb +12 -0
  43. data/app/components/shadcn/drawer_component.rb +7 -27
  44. data/app/components/shadcn/dropdown_menu_component.html.erb +14 -0
  45. data/app/components/shadcn/dropdown_menu_component.rb +9 -29
  46. data/app/components/shadcn/field_component.rb +7 -8
  47. data/app/components/shadcn/hover_card_component.html.erb +12 -0
  48. data/app/components/shadcn/hover_card_component.rb +7 -26
  49. data/app/components/shadcn/input_component.html.erb +18 -0
  50. data/app/components/shadcn/input_component.rb +2 -27
  51. data/app/components/shadcn/input_otp_component.rb +3 -3
  52. data/app/components/shadcn/kbd_component.html.erb +1 -0
  53. data/app/components/shadcn/kbd_component.rb +3 -10
  54. data/app/components/shadcn/label_component.html.erb +3 -0
  55. data/app/components/shadcn/label_component.rb +2 -18
  56. data/app/components/shadcn/menubar_component.html.erb +6 -0
  57. data/app/components/shadcn/menubar_component.rb +4 -15
  58. data/app/components/shadcn/native_select_component.html.erb +22 -0
  59. data/app/components/shadcn/native_select_component.rb +9 -39
  60. data/app/components/shadcn/navigation_menu_component.html.erb +6 -0
  61. data/app/components/shadcn/navigation_menu_component.rb +4 -15
  62. data/app/components/shadcn/pagination_component.html.erb +5 -0
  63. data/app/components/shadcn/pagination_component.rb +11 -15
  64. data/app/components/shadcn/popover_component.html.erb +15 -0
  65. data/app/components/shadcn/popover_component.rb +10 -30
  66. data/app/components/shadcn/progress_component.html.erb +13 -0
  67. data/app/components/shadcn/progress_component.rb +6 -26
  68. data/app/components/shadcn/radio_group_component.html.erb +8 -0
  69. data/app/components/shadcn/radio_group_component.rb +12 -26
  70. data/app/components/shadcn/scroll_area_component.html.erb +7 -0
  71. data/app/components/shadcn/scroll_area_component.rb +4 -16
  72. data/app/components/shadcn/select_component.html.erb +46 -0
  73. data/app/components/shadcn/select_component.rb +6 -80
  74. data/app/components/shadcn/separator_component.html.erb +5 -0
  75. data/app/components/shadcn/separator_component.rb +6 -14
  76. data/app/components/shadcn/sheet_component.html.erb +12 -0
  77. data/app/components/shadcn/sheet_component.rb +7 -27
  78. data/app/components/shadcn/sidebar_component.rb +2 -2
  79. data/app/components/shadcn/skeleton_component.html.erb +1 -0
  80. data/app/components/shadcn/skeleton_component.rb +4 -2
  81. data/app/components/shadcn/slider_component.html.erb +12 -0
  82. data/app/components/shadcn/slider_component.rb +2 -21
  83. data/app/components/shadcn/spinner_component.html.erb +18 -0
  84. data/app/components/shadcn/spinner_component.rb +2 -30
  85. data/app/components/shadcn/switch_component.html.erb +72 -0
  86. data/app/components/shadcn/switch_component.rb +4 -82
  87. data/app/components/shadcn/table_component.html.erb +9 -0
  88. data/app/components/shadcn/table_component.rb +2 -10
  89. data/app/components/shadcn/tabs_component.html.erb +8 -0
  90. data/app/components/shadcn/tabs_component.rb +4 -17
  91. data/app/components/shadcn/textarea_component.html.erb +13 -0
  92. data/app/components/shadcn/textarea_component.rb +6 -22
  93. data/app/components/shadcn/toast_component.html.erb +36 -0
  94. data/app/components/shadcn/toast_component.rb +6 -54
  95. data/app/components/shadcn/toggle_component.html.erb +12 -0
  96. data/app/components/shadcn/toggle_component.rb +6 -21
  97. data/app/components/shadcn/toggle_group_component.html.erb +14 -0
  98. data/app/components/shadcn/toggle_group_component.rb +6 -29
  99. data/app/components/shadcn/tooltip_component.html.erb +20 -0
  100. data/app/components/shadcn/tooltip_component.rb +13 -38
  101. data/lib/generators/shadcn/add/USAGE +24 -0
  102. data/lib/generators/shadcn/add/add_generator.rb +279 -0
  103. data/lib/generators/shadcn/install/USAGE +22 -0
  104. data/lib/generators/shadcn/install/install_generator.rb +8 -3
  105. data/lib/generators/shadcn/install/templates/initializer.rb.tt +7 -27
  106. data/lib/generators/shadcn/install/templates/shadcn.yml.tt +15 -31
  107. data/lib/shadcn/rails/version.rb +1 -1
  108. metadata +47 -45
  109. data/.dockerignore +0 -40
  110. data/CLAUDE.md +0 -612
  111. data/PROGRESS.md +0 -495
  112. data/Rakefile +0 -95
  113. data/__tests__/controllers/__snapshots__/calendar_controller.test.js.snap +0 -13
  114. data/__tests__/controllers/__snapshots__/popover_controller.test.js.snap +0 -46
  115. data/__tests__/controllers/__snapshots__/sheet_controller.test.js.snap +0 -111
  116. data/__tests__/controllers/__snapshots__/tabs_controller.test.js.snap +0 -27
  117. data/__tests__/controllers/accordion_controller.test.js +0 -904
  118. data/__tests__/controllers/calendar_controller.test.js +0 -1370
  119. data/__tests__/controllers/carousel_controller.test.js +0 -912
  120. data/__tests__/controllers/checkbox_controller.test.js +0 -454
  121. data/__tests__/controllers/collapsible_controller.test.js +0 -407
  122. data/__tests__/controllers/combobox_controller.test.js +0 -971
  123. data/__tests__/controllers/context_menu_controller.test.js +0 -905
  124. data/__tests__/controllers/date_picker_controller.test.js +0 -636
  125. data/__tests__/controllers/dialog_controller.test.js +0 -878
  126. data/__tests__/controllers/drawer_controller.test.js +0 -995
  127. data/__tests__/controllers/menubar_controller.test.js +0 -737
  128. data/__tests__/controllers/navigation_menu_controller.test.js +0 -599
  129. data/__tests__/controllers/popover_controller.test.js +0 -982
  130. data/__tests__/controllers/radio_group_controller.test.js +0 -640
  131. data/__tests__/controllers/resizable_controller.test.js +0 -680
  132. data/__tests__/controllers/select_controller.test.js +0 -678
  133. data/__tests__/controllers/sheet_controller.test.js +0 -986
  134. data/__tests__/controllers/slider_controller.test.js +0 -1036
  135. data/__tests__/controllers/switch_controller.test.js +0 -424
  136. data/__tests__/controllers/tabs_controller.test.js +0 -907
  137. data/__tests__/controllers/toggle_group_controller.test.js +0 -839
  138. data/__tests__/controllers/tooltip_controller.test.js +0 -808
  139. data/__tests__/helpers/stimulus-test-helper.js +0 -203
  140. data/babel.config.cjs +0 -5
  141. data/bin/bump +0 -321
  142. data/bin/console +0 -11
  143. data/bin/release +0 -205
  144. data/bin/setup +0 -8
  145. data/bin/test +0 -75
  146. data/jest.config.js +0 -19
  147. data/jest.setup.js +0 -8
  148. data/lib/generators/shadcn/component/component_generator.rb +0 -188
  149. data/lib/generators/shadcn/theme/theme_generator.rb +0 -128
  150. data/package-lock.json +0 -7438
  151. data/package.json +0 -71
  152. data/rollup.config.js +0 -29
@@ -46,50 +46,22 @@ module Shadcn
46
46
  @size = size.to_sym
47
47
  end
48
48
 
49
- def call
50
- content_tag(:span, avatar_content, avatar_attributes)
51
- end
52
-
53
49
  private
54
50
 
55
- def avatar_content
56
- if @src.present?
57
- image_with_fallback
58
- elsif fallback?
59
- fallback
60
- else
61
- fallback_element
62
- end
63
- end
64
-
65
- def image_with_fallback
66
- # Use Stimulus controller to handle image loading errors
67
- content_tag(:span, class: "contents", data: stimulus_data(controller: "shadcn--avatar")) do
68
- safe_join([
69
- tag(:img,
70
- src: @src,
71
- alt: @alt,
72
- class: IMAGE_CLASSES,
73
- data: { "shadcn--avatar-target": "image", action: "error->shadcn--avatar#handleError" }
74
- ),
75
- content_tag(:span, @fallback, class: "#{FALLBACK_CLASSES} hidden", data: { "shadcn--avatar-target": "fallback" })
76
- ])
77
- end
51
+ def avatar_classes
52
+ cn(BASE_CLASSES, SIZES[@size], class_name)
78
53
  end
79
54
 
80
- def fallback_element
81
- content_tag(:span, @fallback, class: FALLBACK_CLASSES)
55
+ def fallback_text
56
+ @fallback
82
57
  end
83
58
 
84
- def avatar_classes
85
- cn(BASE_CLASSES, SIZES[@size], class_name)
59
+ def has_image?
60
+ @src.present?
86
61
  end
87
62
 
88
- def avatar_attributes
89
- attrs = { class: avatar_classes }
90
- attrs.merge!(html_options)
91
- attrs.merge!(build_data)
92
- attrs.compact
63
+ def has_fallback_slot?
64
+ fallback?
93
65
  end
94
66
 
95
67
  def generate_fallback(alt)
@@ -0,0 +1 @@
1
+ <span class="<%= badge_classes %>" <%= tag_attributes %>><%= content %></span>
@@ -29,21 +29,10 @@ module Shadcn
29
29
  @variant = variant.to_sym
30
30
  end
31
31
 
32
- def call
33
- content_tag(:span, content, badge_attributes)
34
- end
35
-
36
32
  private
37
33
 
38
34
  def badge_classes
39
35
  cn(BASE_CLASSES, VARIANTS[@variant], class_name)
40
36
  end
41
-
42
- def badge_attributes
43
- attrs = { class: badge_classes }
44
- attrs.merge!(html_options)
45
- attrs.merge!(build_data)
46
- attrs.compact
47
- end
48
37
  end
49
38
  end
@@ -10,11 +10,15 @@ module Shadcn
10
10
  # Common attributes shared by all components
11
11
  attr_reader :class_name, :data, :html_options
12
12
 
13
- # @param class_name [String, nil] Additional CSS classes
13
+ # @param class_name [String, nil] Additional CSS classes (preferred)
14
+ # @param class [String, nil] Alias for class_name (for Rails-like API)
14
15
  # @param data [Hash] Data attributes (will be prefixed with data-)
15
16
  # @param html_options [Hash] Additional HTML attributes
16
17
  def initialize(class_name: nil, data: {}, **html_options, &block)
17
- @class_name = class_name
18
+ # Support both class: and class_name: for better Rails compatibility
19
+ # class_name takes precedence if both are provided
20
+ html_class = html_options.delete(:class)
21
+ @class_name = class_name || html_class
18
22
  @data = data
19
23
  @html_options = html_options
20
24
  @constructor_block = block
@@ -96,5 +100,14 @@ module Shadcn
96
100
 
97
101
  classes.split.map { |c| "#{config.tailwind_prefix}#{c}" }.join(" ")
98
102
  end
103
+
104
+ # Build HTML attributes string for use in templates
105
+ # Combines html_options and data attributes
106
+ # Uses html_escape_once to avoid double-escaping already-escaped content
107
+ # @return [String] HTML-safe attribute string
108
+ def tag_attributes
109
+ attrs = html_options.merge(build_data)
110
+ attrs.map { |k, v| "#{k}=\"#{ERB::Util.html_escape_once(v)}\"" if v }.compact.join(" ").html_safe
111
+ end
99
112
  end
100
113
  end
@@ -0,0 +1,5 @@
1
+ <nav aria-label="Breadcrumb" class="<%= breadcrumb_classes %>" <%= tag_attributes %>>
2
+ <ol class="flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5">
3
+ <%= breadcrumb_list_content %>
4
+ </ol>
5
+ </nav>
@@ -21,24 +21,14 @@ module Shadcn
21
21
  )
22
22
  end
23
23
 
24
- def call
25
- content_tag(:nav, breadcrumb_attributes) do
26
- content_tag(:ol, class: "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5") do
27
- safe_join(items_with_separators)
28
- end
29
- end
30
- end
31
-
32
24
  private
33
25
 
34
- def breadcrumb_attributes
35
- attrs = {
36
- "aria-label": "Breadcrumb",
37
- class: merge_classes("")
38
- }
39
- attrs.merge!(html_options)
40
- attrs.merge!(build_data)
41
- attrs.compact
26
+ def breadcrumb_classes
27
+ merge_classes("")
28
+ end
29
+
30
+ def breadcrumb_list_content
31
+ safe_join(items_with_separators)
42
32
  end
43
33
 
44
34
  def items_with_separators
@@ -0,0 +1,18 @@
1
+ <% if @href %>
2
+ <a href="<%= @href %>"
3
+ class="<%= button_classes %>"
4
+ role="button"
5
+ <%= "aria-disabled=true tabindex=-1" if @disabled %>
6
+ <%= tag_attributes %>>
7
+ <%= button_content %>
8
+ </a>
9
+ <% else %>
10
+ <button type="<%= @type %>"
11
+ class="<%= button_classes %>"
12
+ <%= "disabled" if @disabled || @loading %>
13
+ <%= "aria-disabled=true" if @disabled || @loading %>
14
+ <%= "aria-busy=true" if @loading %>
15
+ <%= tag_attributes %>>
16
+ <%= button_content %>
17
+ </button>
18
+ <% end %>
@@ -75,24 +75,8 @@ module Shadcn
75
75
  @loading = loading
76
76
  end
77
77
 
78
- def call
79
- if @href
80
- link_tag
81
- else
82
- button_tag
83
- end
84
- end
85
-
86
78
  private
87
79
 
88
- def button_tag
89
- content_tag(:button, button_content, button_attributes)
90
- end
91
-
92
- def link_tag
93
- content_tag(:a, button_content, link_attributes)
94
- end
95
-
96
80
  def button_content
97
81
  if @loading
98
82
  safe_join([loading_spinner, content])
@@ -102,7 +86,7 @@ module Shadcn
102
86
  end
103
87
 
104
88
  def loading_spinner
105
- content_tag(:span, "", class: "animate-spin h-4 w-4 border-2 border-current border-t-transparent rounded-full", "aria-hidden": true)
89
+ tag.span("", class: "animate-spin h-4 w-4 border-2 border-current border-t-transparent rounded-full", "aria-hidden": true)
106
90
  end
107
91
 
108
92
  def button_classes
@@ -113,29 +97,5 @@ module Shadcn
113
97
  class_name
114
98
  )
115
99
  end
116
-
117
- def button_attributes
118
- attrs = html_options.merge(
119
- type: @type,
120
- class: button_classes,
121
- disabled: @disabled || @loading || nil,
122
- "aria-disabled": (@disabled || @loading) ? "true" : nil,
123
- "aria-busy": @loading ? "true" : nil
124
- )
125
- attrs.merge!(build_data)
126
- attrs.compact
127
- end
128
-
129
- def link_attributes
130
- attrs = html_options.merge(
131
- href: @href,
132
- class: button_classes,
133
- role: "button",
134
- "aria-disabled": @disabled ? "true" : nil,
135
- tabindex: @disabled ? "-1" : nil
136
- )
137
- attrs.merge!(build_data)
138
- attrs.compact
139
- end
140
100
  end
141
101
  end
@@ -0,0 +1,8 @@
1
+ <div class="<%= card_classes %>" <%= tag_attributes %>>
2
+ <%= header %>
3
+ <%= title %>
4
+ <%= description %>
5
+ <%= content_slot %>
6
+ <%= content %>
7
+ <%= footer %>
8
+ </div>
@@ -50,14 +50,10 @@ module Shadcn
50
50
 
51
51
  BASE_CLASSES = "rounded-xl border bg-card text-card-foreground shadow"
52
52
 
53
- def call
54
- content_tag(:div, card_content, class: merge_classes(BASE_CLASSES), **html_options.merge(build_data))
55
- end
56
-
57
53
  private
58
54
 
59
- def card_content
60
- safe_join([header, title, description, content_slot, content, footer].compact)
55
+ def card_classes
56
+ merge_classes(BASE_CLASSES)
61
57
  end
62
58
  end
63
59
  end
@@ -0,0 +1,32 @@
1
+ <% if has_label? %>
2
+ <label class="flex items-center space-x-2 cursor-pointer">
3
+ <% if @name %>
4
+ <input type="hidden" name="<%= ERB::Util.html_escape_once(@name) %>" value="0" autocomplete="off">
5
+ <% end %>
6
+ <input type="checkbox"
7
+ class="<%= checkbox_classes %>"<% if @name %>
8
+ name="<%= ERB::Util.html_escape_once(@name) %>"<% end %><% if @id %>
9
+ id="<%= ERB::Util.html_escape_once(@id) %>"<% end %><% if @value %>
10
+ value="<%= ERB::Util.html_escape_once(@value) %>"<% end %><% if @checked %>
11
+ checked<% end %><% if @disabled %>
12
+ disabled<% end %><% if @required %>
13
+ required<% end %>
14
+ <%= tag_attributes %>>
15
+ <span class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
16
+ <%= content %>
17
+ </span>
18
+ </label>
19
+ <% else %>
20
+ <% if @name %>
21
+ <input type="hidden" name="<%= ERB::Util.html_escape_once(@name) %>" value="0" autocomplete="off">
22
+ <% end %>
23
+ <input type="checkbox"
24
+ class="<%= checkbox_classes %>"<% if @name %>
25
+ name="<%= ERB::Util.html_escape_once(@name) %>"<% end %><% if @id %>
26
+ id="<%= ERB::Util.html_escape_once(@id) %>"<% end %><% if @value %>
27
+ value="<%= ERB::Util.html_escape_once(@value) %>"<% end %><% if @checked %>
28
+ checked<% end %><% if @disabled %>
29
+ disabled<% end %><% if @required %>
30
+ required<% end %>
31
+ <%= tag_attributes %>>
32
+ <% end %>
@@ -51,53 +51,14 @@ module Shadcn
51
51
  @required = required
52
52
  end
53
53
 
54
- def call
55
- if content.present?
56
- # Render with integrated label
57
- content_tag(:label, class: "flex items-center space-x-2 cursor-pointer") do
58
- safe_join([
59
- hidden_input,
60
- checkbox_input,
61
- content_tag(:span, content, class: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70")
62
- ])
63
- end
64
- else
65
- # Render just the checkbox (for use with external labels)
66
- safe_join([hidden_input, checkbox_input].compact)
67
- end
68
- end
69
-
70
54
  private
71
55
 
72
- def hidden_input
73
- # Include hidden input with "0" value for unchecked state (Rails convention)
74
- return unless @name
75
-
76
- tag(:input,
77
- type: "hidden",
78
- name: @name,
79
- value: "0",
80
- autocomplete: "off"
81
- )
82
- end
83
-
84
- def checkbox_input
85
- tag(:input, input_attributes)
56
+ def checkbox_classes
57
+ cn(BASE_CLASSES, class_name)
86
58
  end
87
59
 
88
- def input_attributes
89
- attrs = {
90
- type: "checkbox",
91
- name: @name,
92
- id: @id,
93
- value: @value,
94
- class: cn(BASE_CLASSES, class_name),
95
- disabled: @disabled || nil,
96
- checked: @checked || nil,
97
- required: @required || nil
98
- }
99
- attrs.merge!(html_options.except(:class))
100
- attrs.compact
60
+ def has_label?
61
+ content.present?
101
62
  end
102
63
  end
103
64
  end
@@ -0,0 +1,8 @@
1
+ <div class="<%= collapsible_classes %>"
2
+ data-controller="shadcn--collapsible"
3
+ data-shadcn--collapsible-open-value="<%= @open %>"
4
+ data-shadcn--collapsible-disabled-value="<%= @disabled %>"
5
+ data-state="<%= state %>"
6
+ <%= tag_attributes %>>
7
+ <%= collapsible_content %>
8
+ </div>
@@ -31,12 +31,12 @@ module Shadcn
31
31
  @disabled = disabled
32
32
  end
33
33
 
34
- def call
35
- content_tag(:div, collapsible_content, collapsible_attributes)
36
- end
37
-
38
34
  private
39
35
 
36
+ def collapsible_classes
37
+ class_name
38
+ end
39
+
40
40
  def collapsible_content
41
41
  safe_join([trigger_wrapper, body].compact)
42
42
  end
@@ -50,17 +50,8 @@ module Shadcn
50
50
  })
51
51
  end
52
52
 
53
- def collapsible_attributes
54
- attrs = {
55
- class: class_name,
56
- "data-controller": "shadcn--collapsible",
57
- "data-shadcn--collapsible-open-value": @open.to_s,
58
- "data-shadcn--collapsible-disabled-value": @disabled.to_s,
59
- "data-state": @open ? "open" : "closed"
60
- }
61
- attrs.merge!(html_options)
62
- attrs.merge!(build_data)
63
- attrs.compact
53
+ def state
54
+ @open ? "open" : "closed"
64
55
  end
65
56
  end
66
57
  end
@@ -0,0 +1,11 @@
1
+ <div class="<%= context_menu_classes %>"
2
+ data-controller="<%= context_menu_data_attrs[:controller] %>"
3
+ data-action="<%= context_menu_data_attrs[:action] %>"
4
+ <%= tag_attributes %>>
5
+ <% if trigger? %>
6
+ <div data-shadcn--context-menu-target="trigger" data-action="contextmenu->shadcn--context-menu#show:prevent">
7
+ <%= trigger %>
8
+ </div>
9
+ <% end %>
10
+ <%= menu if menu? %>
11
+ </div>
@@ -28,37 +28,17 @@ module Shadcn
28
28
  ContextMenuContentComponent.new(**options)
29
29
  }
30
30
 
31
- def call
32
- content_tag(:div, context_menu_content, context_menu_attributes)
33
- end
34
-
35
31
  private
36
32
 
37
- def context_menu_content
38
- safe_join([
39
- trigger_wrapper,
40
- menu
41
- ].compact)
42
- end
43
-
44
- def trigger_wrapper
45
- return unless trigger
46
-
47
- content_tag(:div, trigger, {
48
- "data-shadcn--context-menu-target": "trigger",
49
- "data-action": "contextmenu->shadcn--context-menu#show:prevent"
50
- })
33
+ def context_menu_classes
34
+ cn("relative inline-block", class_name)
51
35
  end
52
36
 
53
- def context_menu_attributes
54
- attrs = {
55
- class: cn("relative inline-block", class_name),
56
- "data-controller": "shadcn--context-menu",
57
- "data-action": "keydown.escape->shadcn--context-menu#close"
37
+ def context_menu_data_attrs
38
+ {
39
+ controller: "shadcn--context-menu",
40
+ action: "keydown.escape->shadcn--context-menu#close"
58
41
  }
59
- attrs.merge!(html_options)
60
- attrs.merge!(build_data)
61
- attrs.compact
62
42
  end
63
43
  end
64
44
  end
@@ -0,0 +1,14 @@
1
+ <div id="<%= @id %>"
2
+ class="<%= dialog_classes %>"
3
+ data-controller="<%= dialog_data_attrs[:controller] %>"
4
+ data-shadcn--dialog-open-value="<%= dialog_data_attrs[:"shadcn--dialog-open-value"] %>"
5
+ data-shadcn--dialog-modal-value="<%= dialog_data_attrs[:"shadcn--dialog-modal-value"] %>"
6
+ data-dialog-id="<%= dialog_data_attrs[:"dialog-id"] %>"
7
+ <%= tag_attributes %>>
8
+ <% if trigger? %>
9
+ <div data-shadcn--dialog-target="trigger" data-action="click->shadcn--dialog#open">
10
+ <%= trigger %>
11
+ </div>
12
+ <% end %>
13
+ <%= body if body? %>
14
+ </div>
@@ -38,40 +38,19 @@ module Shadcn
38
38
  @modal = modal
39
39
  end
40
40
 
41
- def call
42
- content_tag(:div, dialog_content, dialog_attributes)
43
- end
44
-
45
41
  private
46
42
 
47
- def dialog_content
48
- safe_join([
49
- trigger_wrapper,
50
- body
51
- ].compact)
52
- end
53
-
54
- def trigger_wrapper
55
- return unless trigger
56
-
57
- content_tag(:div, trigger, {
58
- "data-shadcn--dialog-target": "trigger",
59
- "data-action": "click->shadcn--dialog#open"
60
- })
43
+ def dialog_classes
44
+ class_name
61
45
  end
62
46
 
63
- def dialog_attributes
64
- attrs = {
65
- id: @id,
66
- class: class_name,
67
- "data-controller": "shadcn--dialog",
68
- "data-shadcn--dialog-open-value": @open.to_s,
69
- "data-shadcn--dialog-modal-value": @modal.to_s,
70
- "data-dialog-id": @id
47
+ def dialog_data_attrs
48
+ {
49
+ controller: "shadcn--dialog",
50
+ "shadcn--dialog-open-value": @open.to_s,
51
+ "shadcn--dialog-modal-value": @modal.to_s,
52
+ "dialog-id": @id
71
53
  }
72
- attrs.merge!(html_options)
73
- attrs.merge!(build_data)
74
- attrs.compact
75
54
  end
76
55
  end
77
56
  end
@@ -0,0 +1,12 @@
1
+ <div class="<%= drawer_classes %>"
2
+ data-controller="<%= drawer_data_attrs[:controller] %>"
3
+ data-shadcn--drawer-open-value="<%= drawer_data_attrs[:"shadcn--drawer-open-value"] %>"
4
+ data-shadcn--drawer-direction-value="<%= drawer_data_attrs[:"shadcn--drawer-direction-value"] %>"
5
+ <%= tag_attributes %>>
6
+ <% if trigger? %>
7
+ <div data-shadcn--drawer-target="trigger" data-action="click->shadcn--drawer#open">
8
+ <%= trigger %>
9
+ </div>
10
+ <% end %>
11
+ <%= body if body? %>
12
+ </div>
@@ -35,38 +35,18 @@ module Shadcn
35
35
  @direction = direction
36
36
  end
37
37
 
38
- def call
39
- content_tag(:div, drawer_content, drawer_attributes)
40
- end
41
-
42
38
  private
43
39
 
44
- def drawer_content
45
- safe_join([
46
- trigger_wrapper,
47
- body
48
- ].compact)
49
- end
50
-
51
- def trigger_wrapper
52
- return unless trigger
53
-
54
- content_tag(:div, trigger, {
55
- "data-shadcn--drawer-target": "trigger",
56
- "data-action": "click->shadcn--drawer#open"
57
- })
40
+ def drawer_classes
41
+ class_name
58
42
  end
59
43
 
60
- def drawer_attributes
61
- attrs = {
62
- class: class_name,
63
- "data-controller": "shadcn--drawer",
64
- "data-shadcn--drawer-open-value": @open.to_s,
65
- "data-shadcn--drawer-direction-value": @direction.to_s
44
+ def drawer_data_attrs
45
+ {
46
+ controller: "shadcn--drawer",
47
+ "shadcn--drawer-open-value": @open.to_s,
48
+ "shadcn--drawer-direction-value": @direction.to_s
66
49
  }
67
- attrs.merge!(html_options)
68
- attrs.merge!(build_data)
69
- attrs.compact
70
50
  end
71
51
  end
72
52
  end
@@ -0,0 +1,14 @@
1
+ <div class="<%= dropdown_classes %>"
2
+ data-controller="<%= dropdown_data_attrs[:controller] %>"
3
+ data-shadcn--dropdown-open-value="<%= dropdown_data_attrs[:"shadcn--dropdown-open-value"] %>"
4
+ data-shadcn--dropdown-align-value="<%= dropdown_data_attrs[:"shadcn--dropdown-align-value"] %>"
5
+ data-shadcn--dropdown-side-value="<%= dropdown_data_attrs[:"shadcn--dropdown-side-value"] %>"
6
+ data-action="<%= dropdown_data_attrs[:action] %>"
7
+ <%= tag_attributes %>>
8
+ <% if trigger? %>
9
+ <div data-shadcn--dropdown-target="trigger" data-action="click->shadcn--dropdown#toggle">
10
+ <%= trigger %>
11
+ </div>
12
+ <% end %>
13
+ <%= menu if menu? %>
14
+ </div>
@@ -36,40 +36,20 @@ module Shadcn
36
36
  @side = side
37
37
  end
38
38
 
39
- def call
40
- content_tag(:div, dropdown_content, dropdown_attributes)
41
- end
42
-
43
39
  private
44
40
 
45
- def dropdown_content
46
- safe_join([
47
- trigger_wrapper,
48
- menu
49
- ].compact)
50
- end
51
-
52
- def trigger_wrapper
53
- return unless trigger
54
-
55
- content_tag(:div, trigger, {
56
- "data-shadcn--dropdown-target": "trigger",
57
- "data-action": "click->shadcn--dropdown#toggle"
58
- })
41
+ def dropdown_classes
42
+ cn("relative inline-block", class_name)
59
43
  end
60
44
 
61
- def dropdown_attributes
62
- attrs = {
63
- class: cn("relative inline-block", class_name),
64
- "data-controller": "shadcn--dropdown",
65
- "data-shadcn--dropdown-open-value": @open.to_s,
66
- "data-shadcn--dropdown-align-value": @align.to_s,
67
- "data-shadcn--dropdown-side-value": @side.to_s,
68
- "data-action": "keydown.escape->shadcn--dropdown#close clickOutside->shadcn--dropdown#close"
45
+ def dropdown_data_attrs
46
+ {
47
+ controller: "shadcn--dropdown",
48
+ "shadcn--dropdown-open-value": @open.to_s,
49
+ "shadcn--dropdown-align-value": @align.to_s,
50
+ "shadcn--dropdown-side-value": @side.to_s,
51
+ action: "keydown.escape->shadcn--dropdown#close clickOutside->shadcn--dropdown#close"
69
52
  }
70
- attrs.merge!(html_options)
71
- attrs.merge!(build_data)
72
- attrs.compact
73
53
  end
74
54
  end
75
55
  end