shadcn_phlexcomponents 0.1.18 → 0.1.19

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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +321 -23
  3. data/app/javascript/controllers/accordion_controller.js +101 -90
  4. data/app/javascript/controllers/alert_dialog_controller.js +5 -4
  5. data/app/javascript/controllers/avatar_controller.js +12 -11
  6. data/app/javascript/controllers/checkbox_controller.js +26 -26
  7. data/app/javascript/controllers/collapsible_controller.js +35 -36
  8. data/app/javascript/controllers/combobox_controller.js +262 -231
  9. data/app/javascript/controllers/command_controller.js +205 -184
  10. data/app/javascript/controllers/date_picker_controller.js +252 -253
  11. data/app/javascript/controllers/date_range_picker_controller.js +189 -200
  12. data/app/javascript/controllers/dialog_controller.js +79 -78
  13. data/app/javascript/controllers/dropdown_menu_controller.js +229 -208
  14. data/app/javascript/controllers/dropdown_menu_sub_controller.js +111 -97
  15. data/app/javascript/controllers/form_field_controller.js +17 -16
  16. data/app/javascript/controllers/hover_card_controller.js +69 -71
  17. data/app/javascript/controllers/loading_button_controller.js +11 -10
  18. data/app/javascript/controllers/popover_controller.js +85 -78
  19. data/app/javascript/controllers/progress_controller.js +12 -11
  20. data/app/javascript/controllers/radio_group_controller.js +75 -74
  21. data/app/javascript/controllers/select_controller.js +247 -232
  22. data/app/javascript/controllers/sidebar_controller.js +26 -27
  23. data/app/javascript/controllers/sidebar_trigger_controller.js +12 -9
  24. data/app/javascript/controllers/slider_controller.js +74 -74
  25. data/app/javascript/controllers/switch_controller.js +23 -23
  26. data/app/javascript/controllers/tabs_controller.js +61 -61
  27. data/app/javascript/controllers/theme_switcher_controller.js +28 -27
  28. data/app/javascript/controllers/toast_container_controller.js +45 -31
  29. data/app/javascript/controllers/toast_controller.js +19 -18
  30. data/app/javascript/controllers/toggle_controller.js +17 -17
  31. data/app/javascript/controllers/toggle_group_controller.js +17 -17
  32. data/app/javascript/controllers/tooltip_controller.js +75 -77
  33. data/app/javascript/shadcn_phlexcomponents.js +27 -60
  34. data/app/javascript/utils/command.js +390 -334
  35. data/app/javascript/utils/floating_ui.js +139 -107
  36. data/app/javascript/utils/index.js +253 -190
  37. data/app/typescript/controllers/accordion_controller.ts +2 -0
  38. data/app/typescript/controllers/alert_dialog_controller.ts +2 -0
  39. data/app/typescript/controllers/avatar_controller.ts +2 -0
  40. data/app/typescript/controllers/checkbox_controller.ts +2 -0
  41. data/app/typescript/controllers/collapsible_controller.ts +2 -0
  42. data/app/typescript/controllers/combobox_controller.ts +2 -0
  43. data/app/typescript/controllers/command_controller.ts +2 -0
  44. data/app/typescript/controllers/date_picker_controller.ts +2 -0
  45. data/app/typescript/controllers/date_range_picker_controller.ts +2 -0
  46. data/app/typescript/controllers/dialog_controller.ts +2 -0
  47. data/app/typescript/controllers/dropdown_menu_controller.ts +2 -0
  48. data/app/typescript/controllers/dropdown_menu_sub_controller.ts +2 -0
  49. data/app/typescript/controllers/form_field_controller.ts +2 -0
  50. data/app/typescript/controllers/hover_card_controller.ts +2 -0
  51. data/app/typescript/controllers/loading_button_controller.ts +2 -0
  52. data/app/typescript/controllers/popover_controller.ts +2 -0
  53. data/app/typescript/controllers/progress_controller.ts +2 -0
  54. data/app/typescript/controllers/radio_group_controller.ts +2 -0
  55. data/app/typescript/controllers/select_controller.ts +2 -0
  56. data/app/typescript/controllers/slider_controller.ts +2 -0
  57. data/app/typescript/controllers/switch_controller.ts +2 -0
  58. data/app/typescript/controllers/tabs_controller.ts +2 -0
  59. data/app/typescript/controllers/theme_switcher_controller.ts +2 -0
  60. data/app/typescript/controllers/toast_container_controller.ts +2 -0
  61. data/app/typescript/controllers/toast_controller.ts +2 -0
  62. data/app/typescript/controllers/toggle_controller.ts +2 -0
  63. data/app/typescript/controllers/toggle_group_controller.ts +2 -0
  64. data/app/typescript/controllers/tooltip_controller.ts +2 -0
  65. data/app/typescript/shadcn_phlexcomponents.ts +27 -61
  66. data/app/typescript/utils/index.ts +7 -0
  67. data/lib/install/upgrade_shadcn_phlexcomponents.rb +28 -0
  68. data/lib/shadcn_phlexcomponents/components/accordion.rb +55 -12
  69. data/lib/shadcn_phlexcomponents/components/alert.rb +35 -16
  70. data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +52 -12
  71. data/lib/shadcn_phlexcomponents/components/aspect_ratio.rb +33 -2
  72. data/lib/shadcn_phlexcomponents/components/avatar.rb +24 -7
  73. data/lib/shadcn_phlexcomponents/components/badge.rb +23 -18
  74. data/lib/shadcn_phlexcomponents/components/breadcrumb.rb +46 -6
  75. data/lib/shadcn_phlexcomponents/components/button.rb +32 -27
  76. data/lib/shadcn_phlexcomponents/components/card.rb +59 -10
  77. data/lib/shadcn_phlexcomponents/components/checkbox.rb +51 -30
  78. data/lib/shadcn_phlexcomponents/components/checkbox_group.rb +24 -4
  79. data/lib/shadcn_phlexcomponents/components/combobox.rb +212 -69
  80. data/lib/shadcn_phlexcomponents/components/command.rb +156 -52
  81. data/lib/shadcn_phlexcomponents/components/date_picker.rb +134 -48
  82. data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +20 -42
  83. data/lib/shadcn_phlexcomponents/components/dialog.rb +80 -26
  84. data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +74 -25
  85. data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +52 -24
  86. data/lib/shadcn_phlexcomponents/components/form/form_checkbox.rb +1 -1
  87. data/lib/shadcn_phlexcomponents/components/form/form_checkbox_group.rb +1 -1
  88. data/lib/shadcn_phlexcomponents/components/form/form_combobox.rb +1 -1
  89. data/lib/shadcn_phlexcomponents/components/form/form_date_picker.rb +1 -1
  90. data/lib/shadcn_phlexcomponents/components/form/form_date_range_picker.rb +1 -1
  91. data/lib/shadcn_phlexcomponents/components/form/form_error.rb +8 -1
  92. data/lib/shadcn_phlexcomponents/components/form/form_helpers.rb +3 -2
  93. data/lib/shadcn_phlexcomponents/components/form/form_hint.rb +8 -1
  94. data/lib/shadcn_phlexcomponents/components/form/form_input.rb +1 -1
  95. data/lib/shadcn_phlexcomponents/components/form/form_radio_group.rb +1 -1
  96. data/lib/shadcn_phlexcomponents/components/form/form_select.rb +1 -1
  97. data/lib/shadcn_phlexcomponents/components/form/form_slider.rb +1 -1
  98. data/lib/shadcn_phlexcomponents/components/form/form_switch.rb +1 -1
  99. data/lib/shadcn_phlexcomponents/components/form/form_textarea.rb +1 -1
  100. data/lib/shadcn_phlexcomponents/components/form.rb +22 -6
  101. data/lib/shadcn_phlexcomponents/components/hover_card.rb +48 -18
  102. data/lib/shadcn_phlexcomponents/components/input.rb +13 -8
  103. data/lib/shadcn_phlexcomponents/components/label.rb +9 -4
  104. data/lib/shadcn_phlexcomponents/components/link.rb +8 -1
  105. data/lib/shadcn_phlexcomponents/components/pagination.rb +34 -6
  106. data/lib/shadcn_phlexcomponents/components/popover.rb +43 -13
  107. data/lib/shadcn_phlexcomponents/components/progress.rb +37 -6
  108. data/lib/shadcn_phlexcomponents/components/radio_group.rb +41 -15
  109. data/lib/shadcn_phlexcomponents/components/select.rb +99 -42
  110. data/lib/shadcn_phlexcomponents/components/separator.rb +9 -4
  111. data/lib/shadcn_phlexcomponents/components/sheet.rb +87 -21
  112. data/lib/shadcn_phlexcomponents/components/skeleton.rb +8 -1
  113. data/lib/shadcn_phlexcomponents/components/switch.rb +45 -17
  114. data/lib/shadcn_phlexcomponents/components/table.rb +84 -17
  115. data/lib/shadcn_phlexcomponents/components/tabs.rb +36 -12
  116. data/lib/shadcn_phlexcomponents/components/textarea.rb +12 -7
  117. data/lib/shadcn_phlexcomponents/components/toast.rb +46 -20
  118. data/lib/shadcn_phlexcomponents/components/toast_container.rb +19 -14
  119. data/lib/shadcn_phlexcomponents/components/toggle.rb +28 -23
  120. data/lib/shadcn_phlexcomponents/components/tooltip.rb +49 -14
  121. data/lib/shadcn_phlexcomponents/configuration.rb +46 -0
  122. data/lib/shadcn_phlexcomponents/initializers/shadcn_phlexcomponents.rb +28 -0
  123. data/lib/shadcn_phlexcomponents/version.rb +1 -1
  124. data/lib/shadcn_phlexcomponents.rb +12 -1
  125. data/lib/tasks/upgrade.rake +10 -0
  126. metadata +15 -14
  127. data/app/typescript/controllers/sidebar_controller.ts +0 -39
  128. data/app/typescript/controllers/sidebar_trigger_controller.ts +0 -21
@@ -2,7 +2,14 @@
2
2
 
3
3
  module ShadcnPhlexcomponents
4
4
  class DatePicker < Base
5
- class_variants(base: "w-full")
5
+ class_variants(
6
+ **(
7
+ ShadcnPhlexcomponents.configuration.date_picker&.dig(:root) ||
8
+ {
9
+ base: "w-full",
10
+ }
11
+ ),
12
+ )
6
13
 
7
14
  def initialize(
8
15
  name: nil,
@@ -22,7 +29,8 @@ module ShadcnPhlexcomponents
22
29
  if value
23
30
  value = if value.is_a?(String)
24
31
  begin
25
- Time.parse(value)
32
+ # Use Time.zone.parse to ensure consistent timezone handling
33
+ Time.zone ? Time.zone.parse(value) : Time.parse(value)
26
34
  rescue
27
35
  nil
28
36
  end
@@ -70,46 +78,27 @@ module ShadcnPhlexcomponents
70
78
  # label will trigger the popover to appear
71
79
  DatePickerTrigger(
72
80
  disabled: @disabled,
73
- aria_id: @aria_id,
74
81
  select_only: @select_only,
75
82
  id: @id,
76
83
  placeholder: @placeholder,
84
+ stimulus_controller_name: "date-picker",
85
+ aria_id: @aria_id,
77
86
  )
78
87
  else
79
- div(
80
- class: <<~HEREDOC,
81
- focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]
82
- data-[focus=true]:border-ring data-[focus=true]:ring-ring/50 data-[focus=true]:ring-[3px]
83
- data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 flex shadow-xs transition-[color,box-shadow]
84
- rounded-md border bg-transparent dark:bg-input/30 border-input outline-none h-9 flex items-center
85
- aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive
86
- HEREDOC
87
- data: { date_picker_target: "inputContainer", disabled: @disabled },
88
- ) do
89
- input(
90
- id: @id,
91
- placeholder: @placeholder || @format,
92
- type: :text,
93
- class: "md:text-sm placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 text-base outline-none px-3 py-1",
94
- disabled: @disabled,
95
- data: {
96
- date_picker_target: "input",
97
- action: "input->date-picker#inputDate
98
- blur->date-picker#inputBlur
99
- focus->date-picker#setContainerFocus",
100
- },
101
- )
88
+ DatePickerInputContainer(disabled: @disabled, stimulus_controller_name: "date-picker") do
89
+ DatePickerInput(id: @id, placeholder: @placeholder, format: @format, disabled: @disabled, stimulus_controller_name: "date-picker", aria_id: @aria_id)
102
90
 
103
91
  DatePickerTrigger(
104
92
  disabled: @disabled,
105
- aria_id: @aria_id,
106
93
  select_only: @select_only,
107
94
  placeholder: @placeholder,
95
+ stimulus_controller_name: "date-picker",
96
+ aria_id: @aria_id,
108
97
  )
109
98
  end
110
99
  end
111
100
 
112
- DatePickerContent(aria_id: @aria_id)
101
+ DatePickerContent(stimulus_controller_name: "date-picker", aria_id: @aria_id)
113
102
  end
114
103
  end
115
104
  end
@@ -118,12 +107,14 @@ module ShadcnPhlexcomponents
118
107
  def initialize(
119
108
  select_only: true,
120
109
  placeholder: nil,
110
+ stimulus_controller_name: nil,
121
111
  aria_id: nil,
122
112
  **attributes
123
113
  )
124
114
  @select_only = select_only
125
115
  @placeholder = placeholder
126
116
  @aria_id = aria_id
117
+ @stimulus_controller_name = stimulus_controller_name
127
118
  super(**attributes)
128
119
  end
129
120
 
@@ -138,7 +129,7 @@ module ShadcnPhlexcomponents
138
129
  def view_template
139
130
  if @select_only
140
131
  button(type: :button, disabled: @disabled, **@attributes) do
141
- span(class: "pointer-events-none", data: { "#{stimulus_controller_name}-target" => "triggerText" })
132
+ span(class: "pointer-events-none", data: { "#{@stimulus_controller_name}-target" => "triggerText" })
142
133
 
143
134
  icon("calendar", class: "size-5")
144
135
  end
@@ -158,21 +149,18 @@ module ShadcnPhlexcomponents
158
149
  },
159
150
  data: {
160
151
  placeholder: @placeholder,
161
- action: "click->#{stimulus_controller_name}#toggle",
162
- "#{stimulus_controller_name}-target" => "trigger",
152
+ action: "click->#{@stimulus_controller_name}#toggle",
153
+ "#{@stimulus_controller_name}-target" => "trigger",
163
154
  },
164
155
  }
165
156
  end
166
-
167
- def stimulus_controller_name
168
- "date-picker"
169
- end
170
157
  end
171
158
 
172
159
  class DatePickerContent < Base
173
- def initialize(side: :bottom, align: :start, aria_id: nil, **attributes)
160
+ def initialize(side: :bottom, align: :start, stimulus_controller_name: nil, aria_id: nil, **attributes)
174
161
  @side = side
175
162
  @align = align
163
+ @stimulus_controller_name = stimulus_controller_name
176
164
  @aria_id = aria_id
177
165
  super(**attributes)
178
166
  end
@@ -189,26 +177,124 @@ module ShadcnPhlexcomponents
189
177
  data: {
190
178
  side: @side,
191
179
  align: @align,
192
- "#{stimulus_controller_name}-target" => "content",
193
- action: "#{stimulus_controller_name}:click:outside->#{stimulus_controller_name}#clickOutside",
180
+ "#{@stimulus_controller_name}-target" => "content",
181
+ action: "#{@stimulus_controller_name}:click:outside->#{@stimulus_controller_name}#clickOutside",
194
182
  },
195
183
  }
196
184
  end
197
185
 
198
- def stimulus_controller_name
199
- "date-picker"
200
- end
201
-
202
186
  def view_template(&)
203
- div(
204
- style: { display: "none" },
205
- class: "fixed top-0 left-0 w-max z-50",
206
- data: { "#{stimulus_controller_name}-target" => "contentContainer" },
207
- ) do
187
+ DatePickerContentContainer(stimulus_controller_name: @stimulus_controller_name) do
208
188
  div(**@attributes) do
209
- div(data: { "#{stimulus_controller_name}-target" => "calendar" })
189
+ div(data: { "#{@stimulus_controller_name}-target" => "calendar" })
210
190
  end
211
191
  end
212
192
  end
213
193
  end
194
+
195
+ class DatePickerContentContainer < Base
196
+ class_variants(
197
+ **(
198
+ ShadcnPhlexcomponents.configuration.date_picker&.dig(:content_container) ||
199
+ {
200
+ base: "fixed top-0 left-0 w-max z-50",
201
+ }
202
+ ),
203
+ )
204
+
205
+ def initialize(stimulus_controller_name: nil, **attributes)
206
+ @stimulus_controller_name = stimulus_controller_name
207
+ super(**attributes)
208
+ end
209
+
210
+ def default_attributes
211
+ {
212
+ style: { display: "none" },
213
+ data: { "#{@stimulus_controller_name}-target" => "contentContainer" },
214
+ }
215
+ end
216
+
217
+ def view_template(&)
218
+ div(**@attributes, &)
219
+ end
220
+ end
221
+
222
+ class DatePickerInputContainer < Base
223
+ class_variants(
224
+ **(
225
+ ShadcnPhlexcomponents.configuration.date_picker&.dig(:input_container) ||
226
+ {
227
+ base: <<~HEREDOC,
228
+ focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]
229
+ data-[focus=true]:border-ring data-[focus=true]:ring-ring/50 data-[focus=true]:ring-[3px]
230
+ data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 flex shadow-xs transition-[color,box-shadow]
231
+ rounded-md border bg-transparent dark:bg-input/30 border-input outline-none h-9 flex items-center
232
+ aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive
233
+ HEREDOC
234
+ }
235
+ ),
236
+ )
237
+
238
+ def initialize(disabled: false, stimulus_controller_name: nil, **attributes)
239
+ @disabled = disabled
240
+ @stimulus_controller_name = stimulus_controller_name
241
+ super(**attributes)
242
+ end
243
+
244
+ def default_attributes
245
+ {
246
+ data: {
247
+ "#{@stimulus_controller_name}-target" => "inputContainer",
248
+ disabled: @disabled,
249
+ },
250
+ }
251
+ end
252
+
253
+ def view_template(&)
254
+ div(**@attributes, &)
255
+ end
256
+ end
257
+
258
+ class DatePickerInput < Base
259
+ class_variants(
260
+ **(
261
+ ShadcnPhlexcomponents.configuration.date_picker&.dig(:input) ||
262
+ {
263
+ base: <<~HEREDOC,
264
+ md:text-sm placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground
265
+ flex h-9 w-full min-w-0 text-base outline-none px-3 py-1
266
+ HEREDOC
267
+ }
268
+ ),
269
+ )
270
+
271
+ def initialize(id: nil, placeholder: nil, format: nil, disabled: false, stimulus_controller_name: nil, aria_id: nil, **attributes)
272
+ @id = id
273
+ @placeholder = placeholder
274
+ @format = format
275
+ @disabled = disabled
276
+ @stimulus_controller_name = stimulus_controller_name
277
+ @aria_id = aria_id
278
+ super(**attributes)
279
+ end
280
+
281
+ def default_attributes
282
+ {
283
+ id: @id || "#{@aria_id}-input",
284
+ placeholder: @placeholder || @format,
285
+ type: :text,
286
+ disabled: @disabled,
287
+ data: {
288
+ "#{@stimulus_controller_name}-target" => "input",
289
+ action: "input->#{@stimulus_controller_name}#inputDate
290
+ blur->#{@stimulus_controller_name}#inputBlur
291
+ focus->#{@stimulus_controller_name}#setContainerFocus",
292
+ },
293
+ }
294
+ end
295
+
296
+ def view_template
297
+ input(**@attributes)
298
+ end
299
+ end
214
300
  end
@@ -2,7 +2,14 @@
2
2
 
3
3
  module ShadcnPhlexcomponents
4
4
  class DateRangePicker < Base
5
- class_variants(base: "w-full")
5
+ class_variants(
6
+ **(
7
+ ShadcnPhlexcomponents.configuration.date_picker&.dig(:root) ||
8
+ {
9
+ base: "w-full",
10
+ }
11
+ ),
12
+ )
6
13
 
7
14
  def initialize(
8
15
  name: nil,
@@ -28,7 +35,8 @@ module ShadcnPhlexcomponents
28
35
  value = value.map do |v|
29
36
  if v.is_a?(String)
30
37
  begin
31
- Time.parse(v)
38
+ # Use Time.zone.parse to ensure consistent timezone handling
39
+ Time.zone ? Time.zone.parse(v) : Time.parse(v)
32
40
  rescue
33
41
  nil
34
42
  end
@@ -87,61 +95,31 @@ module ShadcnPhlexcomponents
87
95
  if @select_only
88
96
  # For select_only date picker, id is passed to button so that clicking on its
89
97
  # label will trigger the popover to appear
90
- DateRangePickerTrigger(
98
+ DatePickerTrigger(
91
99
  disabled: @disabled,
92
- aria_id: @aria_id,
93
100
  select_only: @select_only,
94
101
  id: @id,
95
102
  placeholder: @placeholder,
103
+ stimulus_controller_name: "date-range-picker",
104
+ aria_id: @aria_id,
96
105
  )
97
106
  else
98
- div(
99
- class: <<~HEREDOC,
100
- focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]
101
- data-[focus=true]:border-ring data-[focus=true]:ring-ring/50 data-[focus=true]:ring-[3px]
102
- data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 flex shadow-xs transition-[color,box-shadow]
103
- rounded-md border bg-transparent dark:bg-input/30 border-input outline-none h-9 flex items-center
104
- aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive
105
- HEREDOC
106
- data: { date_range_picker_target: "inputContainer", disabled: @disabled },
107
- ) do
108
- input(
109
- id: @id,
110
- placeholder: @placeholder || "#{@format} - #{@format}",
111
- type: :text,
112
- class: "md:text-sm placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 text-base outline-none px-3 py-1",
113
- disabled: @disabled,
114
- data: {
115
- date_range_picker_target: "input",
116
- action: "input->date-range-picker#inputDate
117
- blur->date-range-picker#inputBlur
118
- focus->date-range-picker#setContainerFocus",
119
- },
120
- )
121
107
 
122
- DateRangePickerTrigger(
108
+ DatePickerInputContainer(disabled: @disabled, stimulus_controller_name: "date-range-picker") do
109
+ DatePickerInput(id: @id, placeholder: @placeholder, format: "#{@format} - #{@format}", disabled: @disabled, stimulus_controller_name: "date-range-picker", aria_id: @aria_id)
110
+
111
+ DatePickerTrigger(
123
112
  disabled: @disabled,
124
- aria_id: @aria_id,
125
113
  select_only: @select_only,
126
114
  placeholder: @placeholder,
115
+ stimulus_controller_name: "date-range-picker",
116
+ aria_id: @aria_id,
127
117
  )
128
118
  end
129
119
  end
130
120
 
131
- DateRangePickerContent(aria_id: @aria_id)
121
+ DatePickerContent(stimulus_controller_name: "date-range-picker", aria_id: @aria_id)
132
122
  end
133
123
  end
134
124
  end
135
-
136
- class DateRangePickerTrigger < DatePickerTrigger
137
- def stimulus_controller_name
138
- "date-range-picker"
139
- end
140
- end
141
-
142
- class DateRangePickerContent < DatePickerContent
143
- def stimulus_controller_name
144
- "date-range-picker"
145
- end
146
- end
147
125
  end
@@ -2,7 +2,14 @@
2
2
 
3
3
  module ShadcnPhlexcomponents
4
4
  class Dialog < Base
5
- class_variants(base: "inline-flex max-w-fit")
5
+ class_variants(
6
+ **(
7
+ ShadcnPhlexcomponents.configuration.dialog&.dig(:root) ||
8
+ {
9
+ base: "inline-flex max-w-fit",
10
+ }
11
+ ),
12
+ )
6
13
 
7
14
  def initialize(open: false, **attributes)
8
15
  @open = open
@@ -97,13 +104,18 @@ module ShadcnPhlexcomponents
97
104
 
98
105
  class DialogContent < Base
99
106
  class_variants(
100
- base: <<~HEREDOC,
101
- bg-background data-[state=open]:animate-in data-[state=closed]:animate-out
102
- data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
103
- data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)]
104
- translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg
105
- pointer-events-auto outline-none
106
- HEREDOC
107
+ **(
108
+ ShadcnPhlexcomponents.configuration.dialog&.dig(:content) ||
109
+ {
110
+ base: <<~HEREDOC,
111
+ bg-background data-[state=open]:animate-in data-[state=closed]:animate-out
112
+ data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
113
+ data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)]
114
+ translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg
115
+ pointer-events-auto outline-none
116
+ HEREDOC
117
+ }
118
+ ),
107
119
  )
108
120
 
109
121
  def initialize(aria_id: nil, **attributes)
@@ -131,26 +143,20 @@ module ShadcnPhlexcomponents
131
143
  div(style: { display: "none" }, **@attributes) do
132
144
  yield
133
145
 
134
- button(
135
- class: <<~HEREDOC,
136
- ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground
137
- absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2
138
- focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none
139
- [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4
140
- HEREDOC
141
- data: {
142
- action: "click->dialog#close",
143
- },
144
- ) do
145
- icon("x", class: "size-4")
146
- span(class: "sr-only") { "close" }
147
- end
146
+ DialogCloseIcon()
148
147
  end
149
148
  end
150
149
  end
151
150
 
152
151
  class DialogHeader < Base
153
- class_variants(base: "flex flex-col gap-2 text-center sm:text-left")
152
+ class_variants(
153
+ **(
154
+ ShadcnPhlexcomponents.configuration.dialog&.dig(:header) ||
155
+ {
156
+ base: "flex flex-col gap-2 text-center sm:text-left",
157
+ }
158
+ ),
159
+ )
154
160
 
155
161
  def view_template(&)
156
162
  div(**@attributes, &)
@@ -158,7 +164,14 @@ module ShadcnPhlexcomponents
158
164
  end
159
165
 
160
166
  class DialogTitle < Base
161
- class_variants(base: "text-lg leading-none font-semibold")
167
+ class_variants(
168
+ **(
169
+ ShadcnPhlexcomponents.configuration.dialog&.dig(:title) ||
170
+ {
171
+ base: "text-lg leading-none font-semibold",
172
+ }
173
+ ),
174
+ )
162
175
 
163
176
  def initialize(aria_id: nil, **attributes)
164
177
  @aria_id = aria_id
@@ -177,7 +190,14 @@ module ShadcnPhlexcomponents
177
190
  end
178
191
 
179
192
  class DialogDescription < Base
180
- class_variants(base: "text-muted-foreground text-sm")
193
+ class_variants(
194
+ **(
195
+ ShadcnPhlexcomponents.configuration.dialog&.dig(:description) ||
196
+ {
197
+ base: "text-muted-foreground text-sm",
198
+ }
199
+ ),
200
+ )
181
201
 
182
202
  def initialize(aria_id: nil, **attributes)
183
203
  @aria_id = aria_id
@@ -196,7 +216,14 @@ module ShadcnPhlexcomponents
196
216
  end
197
217
 
198
218
  class DialogFooter < Base
199
- class_variants(base: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end")
219
+ class_variants(
220
+ **(
221
+ ShadcnPhlexcomponents.configuration.dialog&.dig(:footer) ||
222
+ {
223
+ base: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
224
+ }
225
+ ),
226
+ )
200
227
 
201
228
  def view_template(&)
202
229
  div(**@attributes, &)
@@ -233,4 +260,31 @@ module ShadcnPhlexcomponents
233
260
  end
234
261
  end
235
262
  end
263
+
264
+ class DialogCloseIcon < Base
265
+ class_variants(
266
+ **(
267
+ ShadcnPhlexcomponents.configuration.dialog&.dig(:close_icon) ||
268
+ {
269
+ base: <<~HEREDOC,
270
+ ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground
271
+ absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2
272
+ focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none
273
+ [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4
274
+ HEREDOC
275
+ }
276
+ ),
277
+ )
278
+
279
+ def default_attributes
280
+ { data: { action: "click->dialog#close" } }
281
+ end
282
+
283
+ def view_template
284
+ button(**@attributes) do
285
+ icon("x", class: "size-4")
286
+ span(class: "sr-only") { "close" }
287
+ end
288
+ end
289
+ end
236
290
  end
@@ -2,7 +2,14 @@
2
2
 
3
3
  module ShadcnPhlexcomponents
4
4
  class DropdownMenu < Base
5
- class_variants(base: "inline-flex max-w-fit")
5
+ class_variants(
6
+ **(
7
+ ShadcnPhlexcomponents.configuration.dropdown_menu&.dig(:root) ||
8
+ {
9
+ base: "inline-flex max-w-fit",
10
+ }
11
+ ),
12
+ )
6
13
 
7
14
  def initialize(open: false, **attributes)
8
15
  @aria_id = "dropdown-menu-#{SecureRandom.hex(5)}"
@@ -104,14 +111,19 @@ module ShadcnPhlexcomponents
104
111
 
105
112
  class DropdownMenuContent < Base
106
113
  class_variants(
107
- base: <<~HEREDOC,
108
- bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out
109
- data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
110
- data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2
111
- data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50
112
- max-h-(--radix-popper-available-height) min-w-[8rem] origin-(--radix-popper-transform-origin)
113
- overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md pointer-events-auto outline-none
114
- HEREDOC
114
+ **(
115
+ ShadcnPhlexcomponents.configuration.dropdown_menu&.dig(:content) ||
116
+ {
117
+ base: <<~HEREDOC,
118
+ bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out
119
+ data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
120
+ data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2
121
+ data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50
122
+ max-h-(--radix-popper-available-height) min-w-[8rem] origin-(--radix-popper-transform-origin)
123
+ overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md pointer-events-auto outline-none
124
+ HEREDOC
125
+ }
126
+ ),
115
127
  )
116
128
 
117
129
  def initialize(side: :bottom, align: :center, aria_id: nil, **attributes)
@@ -122,11 +134,7 @@ module ShadcnPhlexcomponents
122
134
  end
123
135
 
124
136
  def view_template(&)
125
- div(
126
- style: { display: "none" },
127
- class: "fixed top-0 left-0 w-max z-50",
128
- data: { dropdown_menu_target: "contentContainer" },
129
- ) do
137
+ DropdownMenuContentContainer do
130
138
  div(**@attributes, &)
131
139
  end
132
140
  end
@@ -156,7 +164,14 @@ module ShadcnPhlexcomponents
156
164
  end
157
165
 
158
166
  class DropdownMenuLabel < Base
159
- class_variants(base: "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8")
167
+ class_variants(
168
+ **(
169
+ ShadcnPhlexcomponents.configuration.dropdown_menu&.dig(:label) ||
170
+ {
171
+ base: "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
172
+ }
173
+ ),
174
+ )
160
175
 
161
176
  def view_template(&)
162
177
  div(**@attributes, &)
@@ -165,15 +180,20 @@ module ShadcnPhlexcomponents
165
180
 
166
181
  class DropdownMenuItem < Base
167
182
  class_variants(
168
- base: <<~HEREDOC,
169
- focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive
170
- data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20
171
- data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive
172
- [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2
173
- rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none
174
- data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0
175
- [&_svg:not([class*='size-'])]:size-4
176
- HEREDOC
183
+ **(
184
+ ShadcnPhlexcomponents.configuration.dropdown_menu&.dig(:item) ||
185
+ {
186
+ base: <<~HEREDOC,
187
+ focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive
188
+ data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20
189
+ data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive
190
+ [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2
191
+ rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none
192
+ data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0
193
+ [&_svg:not([class*='size-'])]:size-4
194
+ HEREDOC
195
+ }
196
+ ),
177
197
  )
178
198
 
179
199
  def initialize(as_child: false, variant: :default, disabled: false, **attributes)
@@ -255,7 +275,14 @@ module ShadcnPhlexcomponents
255
275
  end
256
276
 
257
277
  class DropdownMenuSeparator < Base
258
- class_variants(base: "bg-border -mx-1 my-1 h-px")
278
+ class_variants(
279
+ **(
280
+ ShadcnPhlexcomponents.configuration.dropdown_menu&.dig(:separator) ||
281
+ {
282
+ base: "bg-border -mx-1 my-1 h-px",
283
+ }
284
+ ),
285
+ )
259
286
 
260
287
  def view_template(&)
261
288
  div(**@attributes, &)
@@ -280,4 +307,26 @@ module ShadcnPhlexcomponents
280
307
  div(**@attributes, &)
281
308
  end
282
309
  end
310
+
311
+ class DropdownMenuContentContainer < Base
312
+ class_variants(
313
+ **(
314
+ ShadcnPhlexcomponents.configuration.dropdown_menu&.dig(:content_container) ||
315
+ {
316
+ base: "fixed top-0 left-0 w-max z-50",
317
+ }
318
+ ),
319
+ )
320
+
321
+ def default_attributes
322
+ {
323
+ style: { display: "none" },
324
+ data: { dropdown_menu_target: "contentContainer" },
325
+ }
326
+ end
327
+
328
+ def view_template(&)
329
+ div(**@attributes, &)
330
+ end
331
+ end
283
332
  end