shadcn_phlexcomponents 0.1.11 → 0.1.16
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.
- checksums.yaml +4 -4
- data/app/javascript/controllers/accordion_controller.js +107 -0
- data/app/javascript/controllers/alert_dialog_controller.js +7 -0
- data/app/javascript/controllers/avatar_controller.js +14 -0
- data/app/javascript/controllers/checkbox_controller.js +29 -0
- data/app/javascript/controllers/collapsible_controller.js +39 -0
- data/app/javascript/controllers/combobox_controller.js +278 -0
- data/app/javascript/controllers/command_controller.js +207 -0
- data/app/javascript/controllers/date_picker_controller.js +258 -0
- data/app/javascript/controllers/date_range_picker_controller.js +200 -0
- data/app/javascript/controllers/dialog_controller.js +83 -0
- data/app/javascript/controllers/dropdown_menu_controller.js +238 -0
- data/app/javascript/controllers/dropdown_menu_sub_controller.js +118 -0
- data/app/javascript/controllers/form_field_controller.js +20 -0
- data/app/javascript/controllers/hover_card_controller.js +73 -0
- data/app/javascript/controllers/loading_button_controller.js +14 -0
- data/app/javascript/controllers/popover_controller.js +90 -0
- data/app/javascript/controllers/progress_controller.js +14 -0
- data/app/javascript/controllers/radio_group_controller.js +80 -0
- data/app/javascript/controllers/select_controller.js +265 -0
- data/app/javascript/controllers/sidebar_controller.js +29 -0
- data/app/javascript/controllers/sidebar_trigger_controller.js +15 -0
- data/app/javascript/controllers/slider_controller.js +82 -0
- data/app/javascript/controllers/switch_controller.js +26 -0
- data/app/javascript/controllers/tabs_controller.js +66 -0
- data/app/javascript/controllers/theme_switcher_controller.js +32 -0
- data/app/javascript/controllers/toast_container_controller.js +48 -0
- data/app/javascript/controllers/toast_controller.js +22 -0
- data/app/javascript/controllers/toggle_controller.js +20 -0
- data/app/javascript/controllers/toggle_group_controller.js +20 -0
- data/app/javascript/controllers/tooltip_controller.js +79 -0
- data/app/javascript/shadcn_phlexcomponents.js +60 -0
- data/app/javascript/utils/command.js +448 -0
- data/app/javascript/utils/floating_ui.js +160 -0
- data/app/javascript/utils/index.js +288 -0
- data/app/stylesheets/date_picker.css +118 -0
- data/app/typescript/controllers/accordion_controller.ts +136 -0
- data/app/typescript/controllers/alert_dialog_controller.ts +12 -0
- data/app/{javascript → typescript}/controllers/avatar_controller.ts +7 -2
- data/app/{javascript → typescript}/controllers/checkbox_controller.ts +11 -4
- data/app/{javascript → typescript}/controllers/collapsible_controller.ts +12 -5
- data/app/typescript/controllers/combobox_controller.ts +376 -0
- data/app/typescript/controllers/command_controller.ts +301 -0
- data/app/{javascript → typescript}/controllers/date_picker_controller.ts +185 -125
- data/app/{javascript → typescript}/controllers/date_range_picker_controller.ts +89 -79
- data/app/{javascript → typescript}/controllers/dialog_controller.ts +59 -57
- data/app/typescript/controllers/dropdown_menu_controller.ts +309 -0
- data/app/{javascript → typescript}/controllers/dropdown_menu_sub_controller.ts +31 -29
- data/app/{javascript → typescript}/controllers/form_field_controller.ts +6 -1
- data/app/{javascript → typescript}/controllers/hover_card_controller.ts +36 -26
- data/app/{javascript → typescript}/controllers/loading_button_controller.ts +6 -1
- data/app/{javascript → typescript}/controllers/popover_controller.ts +42 -65
- data/app/{javascript → typescript}/controllers/progress_controller.ts +9 -3
- data/app/{javascript → typescript}/controllers/radio_group_controller.ts +16 -9
- data/app/typescript/controllers/select_controller.ts +341 -0
- data/app/{javascript → typescript}/controllers/slider_controller.ts +23 -16
- data/app/{javascript → typescript}/controllers/switch_controller.ts +11 -4
- data/app/{javascript → typescript}/controllers/tabs_controller.ts +26 -18
- data/app/{javascript → typescript}/controllers/theme_switcher_controller.ts +6 -1
- data/app/{javascript → typescript}/controllers/toast_container_controller.ts +6 -1
- data/app/{javascript → typescript}/controllers/toast_controller.ts +7 -1
- data/app/typescript/controllers/toggle_controller.ts +28 -0
- data/app/typescript/controllers/toggle_group_controller.ts +28 -0
- data/app/{javascript → typescript}/controllers/tooltip_controller.ts +43 -31
- data/app/typescript/shadcn_phlexcomponents.ts +61 -0
- data/app/typescript/utils/command.ts +544 -0
- data/app/typescript/utils/floating_ui.ts +196 -0
- data/app/typescript/utils/index.ts +424 -0
- data/lib/install/install_shadcn_phlexcomponents.rb +10 -3
- data/lib/shadcn_phlexcomponents/alias.rb +3 -0
- data/lib/shadcn_phlexcomponents/components/accordion.rb +2 -1
- data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +18 -15
- data/lib/shadcn_phlexcomponents/components/base.rb +14 -0
- data/lib/shadcn_phlexcomponents/components/collapsible.rb +1 -2
- data/lib/shadcn_phlexcomponents/components/combobox.rb +87 -57
- data/lib/shadcn_phlexcomponents/components/command.rb +77 -47
- data/lib/shadcn_phlexcomponents/components/date_picker.rb +25 -81
- data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +21 -4
- data/lib/shadcn_phlexcomponents/components/dialog.rb +14 -12
- data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +5 -4
- data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +2 -1
- data/lib/shadcn_phlexcomponents/components/form/form_combobox.rb +64 -0
- data/lib/shadcn_phlexcomponents/components/form.rb +14 -0
- data/lib/shadcn_phlexcomponents/components/hover_card.rb +3 -2
- data/lib/shadcn_phlexcomponents/components/popover.rb +3 -3
- data/lib/shadcn_phlexcomponents/components/select.rb +10 -25
- data/lib/shadcn_phlexcomponents/components/sheet.rb +15 -11
- data/lib/shadcn_phlexcomponents/components/table.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/tabs.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/toast_container.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/toggle.rb +54 -0
- data/lib/shadcn_phlexcomponents/components/tooltip.rb +3 -2
- data/lib/shadcn_phlexcomponents/engine.rb +1 -5
- data/lib/shadcn_phlexcomponents/version.rb +1 -1
- metadata +71 -32
- data/app/javascript/controllers/accordion_controller.ts +0 -133
- data/app/javascript/controllers/combobox_controller.ts +0 -145
- data/app/javascript/controllers/command_controller.ts +0 -129
- data/app/javascript/controllers/command_root_controller.ts +0 -355
- data/app/javascript/controllers/dropdown_menu_controller.ts +0 -133
- data/app/javascript/controllers/dropdown_menu_root_controller.ts +0 -234
- data/app/javascript/controllers/select_controller.ts +0 -200
- data/app/javascript/shadcn_phlexcomponents.ts +0 -57
- data/app/javascript/utils.ts +0 -437
- /data/app/{javascript → typescript}/controllers/sidebar_controller.ts +0 -0
- /data/app/{javascript → typescript}/controllers/sidebar_trigger_controller.ts +0 -0
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ShadcnPhlexcomponents
|
4
4
|
class AlertDialog < Base
|
5
|
-
class_variants(base: "inline-
|
5
|
+
class_variants(base: "inline-flex max-w-fit")
|
6
6
|
|
7
7
|
def initialize(open: false, **attributes)
|
8
8
|
@open = open
|
@@ -49,14 +49,18 @@ module ShadcnPhlexcomponents
|
|
49
49
|
def default_attributes
|
50
50
|
{
|
51
51
|
data: {
|
52
|
-
controller: "dialog",
|
53
|
-
|
54
|
-
}
|
55
|
-
}
|
52
|
+
controller: "alert-dialog",
|
53
|
+
alert_dialog_is_open_value: @open.to_s
|
54
|
+
}
|
55
|
+
}
|
56
56
|
end
|
57
57
|
|
58
58
|
def view_template(&)
|
59
|
-
div(**@attributes
|
59
|
+
div(**@attributes) do
|
60
|
+
overlay("alert-dialog")
|
61
|
+
|
62
|
+
yield
|
63
|
+
end
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
@@ -75,10 +79,10 @@ module ShadcnPhlexcomponents
|
|
75
79
|
expanded: "false",
|
76
80
|
controls: "#{@aria_id}-content",
|
77
81
|
},
|
78
|
-
data: {
|
79
|
-
action: "click->dialog#open",
|
80
|
-
dialog_target: "trigger",
|
82
|
+
data: {
|
81
83
|
as_child: @as_child.to_s,
|
84
|
+
alert_dialog_target: "trigger",
|
85
|
+
action: "click->alert-dialog#open"
|
82
86
|
},
|
83
87
|
}
|
84
88
|
end
|
@@ -106,7 +110,7 @@ module ShadcnPhlexcomponents
|
|
106
110
|
data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
|
107
111
|
data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)]
|
108
112
|
translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg
|
109
|
-
pointer-events-auto
|
113
|
+
pointer-events-auto outline-none
|
110
114
|
HEREDOC
|
111
115
|
)
|
112
116
|
|
@@ -126,14 +130,13 @@ module ShadcnPhlexcomponents
|
|
126
130
|
},
|
127
131
|
data: {
|
128
132
|
state: "closed",
|
129
|
-
|
133
|
+
alert_dialog_target: "content"
|
130
134
|
},
|
131
135
|
}
|
132
136
|
end
|
133
137
|
|
134
138
|
def view_template(&)
|
135
|
-
|
136
|
-
div(class: "#{@class} hidden", **@attributes, &)
|
139
|
+
div(style: { display: "none" }, **@attributes, &)
|
137
140
|
end
|
138
141
|
end
|
139
142
|
|
@@ -201,7 +204,7 @@ module ShadcnPhlexcomponents
|
|
201
204
|
def default_attributes
|
202
205
|
{
|
203
206
|
data: {
|
204
|
-
action: "click->dialog#close",
|
207
|
+
action: "click->alert-dialog#close",
|
205
208
|
},
|
206
209
|
}
|
207
210
|
end
|
@@ -222,7 +225,7 @@ module ShadcnPhlexcomponents
|
|
222
225
|
def default_attributes
|
223
226
|
{
|
224
227
|
data: {
|
225
|
-
action: "click->dialog#close",
|
228
|
+
action: "click->alert-dialog#close",
|
226
229
|
},
|
227
230
|
}
|
228
231
|
end
|
@@ -141,5 +141,19 @@ module ShadcnPhlexcomponents
|
|
141
141
|
disabled
|
142
142
|
end
|
143
143
|
end
|
144
|
+
|
145
|
+
def overlay(component)
|
146
|
+
div(
|
147
|
+
style: { display: "none" },
|
148
|
+
class: "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50 pointer-events-auto",
|
149
|
+
aria: {
|
150
|
+
hidden: true,
|
151
|
+
},
|
152
|
+
data: {
|
153
|
+
state: "closed",
|
154
|
+
"#{component}-target" => "overlay"
|
155
|
+
}
|
156
|
+
)
|
157
|
+
end
|
144
158
|
end
|
145
159
|
end
|
@@ -9,18 +9,24 @@ module ShadcnPhlexcomponents
|
|
9
9
|
name: nil,
|
10
10
|
value: nil,
|
11
11
|
placeholder: nil,
|
12
|
-
dir: "ltr",
|
13
12
|
include_blank: false,
|
14
13
|
disabled: false,
|
14
|
+
search_path: nil,
|
15
|
+
search_error_text: "Something went wrong, please try again.",
|
16
|
+
search_empty_text: "No results found",
|
17
|
+
search_placeholder_text: "Search...",
|
15
18
|
**attributes
|
16
19
|
)
|
17
20
|
@id = id
|
18
21
|
@name = name
|
19
22
|
@value = value
|
20
23
|
@placeholder = placeholder
|
21
|
-
@dir = dir
|
22
24
|
@include_blank = include_blank
|
23
25
|
@disabled = disabled
|
26
|
+
@search_path = search_path
|
27
|
+
@search_error_text = search_error_text
|
28
|
+
@search_empty_text = search_empty_text
|
29
|
+
@search_placeholder_text = search_placeholder_text
|
24
30
|
@aria_id = "combobox-#{SecureRandom.hex(5)}"
|
25
31
|
super(**attributes)
|
26
32
|
end
|
@@ -29,7 +35,6 @@ module ShadcnPhlexcomponents
|
|
29
35
|
ComboboxTrigger(
|
30
36
|
id: @id,
|
31
37
|
aria_id: @aria_id,
|
32
|
-
dir: @dir,
|
33
38
|
value: @value,
|
34
39
|
placeholder: @placeholder,
|
35
40
|
disabled: @disabled,
|
@@ -39,7 +44,13 @@ module ShadcnPhlexcomponents
|
|
39
44
|
|
40
45
|
def content(**attributes, &)
|
41
46
|
ComboboxContent(
|
42
|
-
|
47
|
+
include_blank: @include_blank,
|
48
|
+
search_error_text: @search_error_text,
|
49
|
+
search_empty_text: @search_empty_text,
|
50
|
+
search_placeholder_text: @search_placeholder_text,
|
51
|
+
aria_id: @aria_id,
|
52
|
+
**attributes,
|
53
|
+
&
|
43
54
|
)
|
44
55
|
end
|
45
56
|
|
@@ -69,13 +80,18 @@ module ShadcnPhlexcomponents
|
|
69
80
|
ComboboxTrigger(
|
70
81
|
id: @id,
|
71
82
|
aria_id: @aria_id,
|
72
|
-
dir: @dir,
|
73
83
|
value: @value,
|
74
84
|
placeholder: @placeholder,
|
75
85
|
disabled: @disabled,
|
76
86
|
)
|
77
87
|
|
78
|
-
ComboboxContent(
|
88
|
+
ComboboxContent(
|
89
|
+
aria_id: @aria_id,
|
90
|
+
include_blank: @include_blank,
|
91
|
+
search_error_text: @search_error_text,
|
92
|
+
search_empty_text: @search_empty_text,
|
93
|
+
search_placeholder_text: @search_placeholder_text
|
94
|
+
) do
|
79
95
|
collection.each do |item|
|
80
96
|
value = item.public_send(value_method)
|
81
97
|
text = item.public_send(text_method)
|
@@ -103,6 +119,7 @@ module ShadcnPhlexcomponents
|
|
103
119
|
data: {
|
104
120
|
aria_id: @aria_id,
|
105
121
|
controller: "combobox",
|
122
|
+
search_path: @search_path,
|
106
123
|
combobox_selected_value: @value,
|
107
124
|
},
|
108
125
|
}
|
@@ -117,25 +134,22 @@ module ShadcnPhlexcomponents
|
|
117
134
|
aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex items-center
|
118
135
|
justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs
|
119
136
|
transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50
|
120
|
-
|
121
|
-
|
122
|
-
[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4
|
123
|
-
data-[placeholder]:data-[has-value=false]:text-muted-foreground w-full
|
137
|
+
h-9 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4
|
138
|
+
data-[placeholder]:data-[has-value=false]:text-muted-foreground w-full disabled:dark:hover:bg-input/30
|
124
139
|
HEREDOC
|
125
140
|
)
|
126
141
|
|
127
|
-
def initialize(id: nil, value: nil, placeholder: nil,
|
142
|
+
def initialize(id: nil, value: nil, placeholder: nil, aria_id: nil, **attributes)
|
128
143
|
@id = id
|
129
144
|
@value = value
|
130
145
|
@placeholder = placeholder
|
131
|
-
@dir = dir
|
132
146
|
@aria_id = aria_id
|
133
147
|
super(**attributes)
|
134
148
|
end
|
135
149
|
|
136
150
|
def view_template
|
137
151
|
button(**@attributes) do
|
138
|
-
span(class: "pointer-events-none", data: { combobox_target: "triggerText" }) do
|
152
|
+
span(class: "pointer-events-none line-clamp-1 flex items-center gap-2", data: { combobox_target: "triggerText" }) do
|
139
153
|
@value || @placeholder
|
140
154
|
end
|
141
155
|
|
@@ -147,7 +161,6 @@ module ShadcnPhlexcomponents
|
|
147
161
|
{
|
148
162
|
type: "button",
|
149
163
|
id: @id,
|
150
|
-
dir: @dir,
|
151
164
|
role: "combobox",
|
152
165
|
aria: {
|
153
166
|
autocomplete: "none",
|
@@ -159,8 +172,6 @@ module ShadcnPhlexcomponents
|
|
159
172
|
has_value: @value.present?.to_s,
|
160
173
|
action: <<~HEREDOC,
|
161
174
|
click->combobox#toggle
|
162
|
-
keydown.space->combobox#open
|
163
|
-
keydown.enter->combobox#open
|
164
175
|
keydown.down->combobox#open:prevent
|
165
176
|
HEREDOC
|
166
177
|
combobox_target: "trigger",
|
@@ -176,27 +187,44 @@ module ShadcnPhlexcomponents
|
|
176
187
|
data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
|
177
188
|
data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2
|
178
189
|
data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50
|
179
|
-
|
180
|
-
|
190
|
+
min-w-[8rem] origin-(--radix-popper-transform-origin)
|
191
|
+
rounded-md border shadow-md pointer-events-auto outline-none
|
181
192
|
HEREDOC
|
182
193
|
)
|
183
194
|
|
184
|
-
def initialize(
|
195
|
+
def initialize(
|
196
|
+
include_blank: false,
|
197
|
+
side: :bottom,
|
198
|
+
align: :center,
|
199
|
+
aria_id: nil,
|
200
|
+
search_error_text: nil,
|
201
|
+
search_empty_text: nil,
|
202
|
+
search_placeholder_text: nil,
|
203
|
+
**attributes
|
204
|
+
)
|
185
205
|
@include_blank = include_blank
|
186
|
-
@dir = dir
|
187
206
|
@side = side
|
188
207
|
@align = align
|
189
|
-
@
|
208
|
+
@search_error_text = search_error_text
|
209
|
+
@search_empty_text = search_empty_text
|
210
|
+
@search_placeholder_text = search_placeholder_text
|
190
211
|
@aria_id = aria_id
|
191
212
|
super(**attributes)
|
192
213
|
end
|
193
214
|
|
194
215
|
def view_template(&)
|
195
216
|
div(
|
196
|
-
|
217
|
+
style: { display: "none" },
|
218
|
+
class: "fixed top-0 left-0 w-max z-50",
|
197
219
|
data: { combobox_target: "contentContainer" },
|
198
220
|
) do
|
199
221
|
div(**@attributes) do
|
222
|
+
template do
|
223
|
+
ComboboxGroup do
|
224
|
+
ComboboxLabel { "" }
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
200
228
|
label(
|
201
229
|
class: "sr-only",
|
202
230
|
id: "#{@aria_id}-search-label",
|
@@ -224,19 +252,29 @@ module ShadcnPhlexcomponents
|
|
224
252
|
},
|
225
253
|
data: {
|
226
254
|
combobox_target: "searchInput",
|
227
|
-
action: "input->combobox#search",
|
255
|
+
action: "keydown->combobox#inputKeydown input->combobox#search",
|
228
256
|
},
|
229
257
|
)
|
230
258
|
end
|
231
259
|
|
232
|
-
div(class: "p-1 max-h-80 overflow-y-auto",
|
233
|
-
|
234
|
-
|
235
|
-
|
260
|
+
div(class: "p-1 max-h-80 overflow-y-auto", data: { combobox_target: "listContainer"}) do
|
261
|
+
ComboboxText(target: "empty") { @search_empty_text }
|
262
|
+
ComboboxText(target: "error") { @search_error_text }
|
263
|
+
ComboboxText(target: "loading") do
|
264
|
+
div(class: "flex justify-center", aria: { label: "Loading" }) do
|
265
|
+
icon("loader-circle", class: "animate-spin")
|
236
266
|
end
|
237
267
|
end
|
238
268
|
|
239
|
-
div(data: { combobox_target: "
|
269
|
+
div(id: "#{@aria_id}-list", data: { combobox_target: "list" }) do
|
270
|
+
if @include_blank
|
271
|
+
ComboboxItem(aria_id: @aria_id, value: "", class: "h-8") do
|
272
|
+
@include_blank.is_a?(String) ? @include_blank : ""
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
yield
|
277
|
+
end
|
240
278
|
end
|
241
279
|
end
|
242
280
|
end
|
@@ -245,7 +283,6 @@ module ShadcnPhlexcomponents
|
|
245
283
|
def default_attributes
|
246
284
|
{
|
247
285
|
id: "#{@aria_id}-content",
|
248
|
-
dir: @dir,
|
249
286
|
tabindex: -1,
|
250
287
|
role: "listbox",
|
251
288
|
aria: {
|
@@ -261,7 +298,7 @@ module ShadcnPhlexcomponents
|
|
261
298
|
combobox:click:outside->combobox#clickOutside
|
262
299
|
keydown.up->combobox#highlightItem:prevent
|
263
300
|
keydown.down->combobox#highlightItem:prevent
|
264
|
-
keydown.enter->combobox#select
|
301
|
+
keydown.enter->combobox#select:prevent
|
265
302
|
HEREDOC
|
266
303
|
},
|
267
304
|
}
|
@@ -280,14 +317,6 @@ module ShadcnPhlexcomponents
|
|
280
317
|
def view_template(&)
|
281
318
|
div(**@attributes, &)
|
282
319
|
end
|
283
|
-
|
284
|
-
def default_attributes
|
285
|
-
{
|
286
|
-
data: {
|
287
|
-
combobox_target: "label",
|
288
|
-
},
|
289
|
-
}
|
290
|
-
end
|
291
320
|
end
|
292
321
|
|
293
322
|
class ComboboxItem < Base
|
@@ -365,34 +394,35 @@ module ShadcnPhlexcomponents
|
|
365
394
|
end
|
366
395
|
end
|
367
396
|
|
368
|
-
class
|
369
|
-
class_variants(base: "bg-border pointer-events-none -mx-1 my-1 h-px")
|
370
|
-
|
371
|
-
def view_template(&)
|
372
|
-
div(**@attributes, &)
|
373
|
-
end
|
374
|
-
|
375
|
-
def default_attributes
|
376
|
-
{ aria: { hidden: "true" } }
|
377
|
-
end
|
378
|
-
end
|
379
|
-
|
380
|
-
class ComboboxEmpty < Base
|
397
|
+
class ComboboxText < Base
|
381
398
|
class_variants(base: "py-6 text-center text-sm hidden")
|
399
|
+
|
400
|
+
def initialize(target:, **attributes)
|
401
|
+
@target = target
|
402
|
+
super(**attributes)
|
403
|
+
end
|
382
404
|
|
383
405
|
def default_attributes
|
384
406
|
{
|
385
407
|
role: "presentation",
|
386
|
-
data: { combobox_target:
|
408
|
+
data: { combobox_target: @target },
|
387
409
|
}
|
388
410
|
end
|
389
411
|
|
390
412
|
def view_template(&)
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
413
|
+
div(**@attributes, &)
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
class ComboboxSeparator < Base
|
418
|
+
class_variants(base: "bg-border pointer-events-none -mx-1 my-1 h-px")
|
419
|
+
|
420
|
+
def view_template(&)
|
421
|
+
div(**@attributes, &)
|
422
|
+
end
|
423
|
+
|
424
|
+
def default_attributes
|
425
|
+
{ aria: { hidden: "true" } }
|
396
426
|
end
|
397
427
|
end
|
398
428
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ShadcnPhlexcomponents
|
4
4
|
class Command < Base
|
5
|
-
class_variants(base: "inline-
|
5
|
+
class_variants(base: "inline-flex max-w-fit")
|
6
6
|
|
7
7
|
MODIFIER_KEYS = [
|
8
8
|
:ctrl,
|
@@ -10,7 +10,16 @@ module ShadcnPhlexcomponents
|
|
10
10
|
:shift,
|
11
11
|
]
|
12
12
|
|
13
|
-
def initialize(
|
13
|
+
def initialize(
|
14
|
+
open: false,
|
15
|
+
modifier_key: nil,
|
16
|
+
shortcut_key: nil,
|
17
|
+
search_path: nil,
|
18
|
+
search_error_text: "Something went wrong, please try again.",
|
19
|
+
search_empty_text: "No results found",
|
20
|
+
search_placeholder_text: "Search...",
|
21
|
+
**attributes
|
22
|
+
)
|
14
23
|
if modifier_key && !MODIFIER_KEYS.include?(modifier_key)
|
15
24
|
raise ArgumentError, "Expected one of #{MODIFIER_KEYS} for \"modifier_key\", got #{modifier_key}"
|
16
25
|
end
|
@@ -19,6 +28,9 @@ module ShadcnPhlexcomponents
|
|
19
28
|
@modifier_key = modifier_key
|
20
29
|
@shortcut_key = shortcut_key
|
21
30
|
@search_path = search_path
|
31
|
+
@search_error_text = search_error_text
|
32
|
+
@search_empty_text = search_empty_text
|
33
|
+
@search_placeholder_text = search_placeholder_text
|
22
34
|
@aria_id = "command-#{SecureRandom.hex(5)}"
|
23
35
|
super(**attributes)
|
24
36
|
end
|
@@ -28,7 +40,14 @@ module ShadcnPhlexcomponents
|
|
28
40
|
end
|
29
41
|
|
30
42
|
def content(**attributes, &)
|
31
|
-
CommandContent(
|
43
|
+
CommandContent(
|
44
|
+
search_error_text: @search_error_text,
|
45
|
+
search_empty_text: @search_empty_text,
|
46
|
+
search_placeholder_text: @search_placeholder_text,
|
47
|
+
aria_id: @aria_id,
|
48
|
+
**attributes,
|
49
|
+
&
|
50
|
+
)
|
32
51
|
end
|
33
52
|
|
34
53
|
def item(**attributes, &)
|
@@ -43,24 +62,24 @@ module ShadcnPhlexcomponents
|
|
43
62
|
CommandGroup(aria_id: @aria_id, **attributes, &)
|
44
63
|
end
|
45
64
|
|
46
|
-
def empty(**attributes, &)
|
47
|
-
CommandEmpty(**attributes, &)
|
48
|
-
end
|
49
|
-
|
50
65
|
def default_attributes
|
51
66
|
{
|
52
67
|
data: {
|
53
68
|
controller: "command",
|
69
|
+
command_is_open_value: @open.to_s,
|
54
70
|
modifier_key: @modifier_key,
|
55
71
|
shortcut_key: @shortcut_key,
|
56
|
-
search_path: @search_path
|
57
|
-
|
58
|
-
},
|
72
|
+
search_path: @search_path
|
73
|
+
}
|
59
74
|
}
|
60
75
|
end
|
61
76
|
|
62
77
|
def view_template(&)
|
63
|
-
div(**@attributes
|
78
|
+
div(**@attributes) do
|
79
|
+
overlay("command")
|
80
|
+
|
81
|
+
yield
|
82
|
+
end
|
64
83
|
end
|
65
84
|
end
|
66
85
|
|
@@ -91,9 +110,8 @@ module ShadcnPhlexcomponents
|
|
91
110
|
controls: "#{@aria_id}-content",
|
92
111
|
},
|
93
112
|
data: {
|
94
|
-
action: "click->command#open",
|
95
113
|
command_target: "trigger",
|
96
|
-
|
114
|
+
action: "click->command#open"
|
97
115
|
},
|
98
116
|
}
|
99
117
|
end
|
@@ -123,18 +141,27 @@ module ShadcnPhlexcomponents
|
|
123
141
|
bg-background bg-clip-padding dark:bg-neutral-900 dark:ring-neutral-800 data-[state=closed]:animate-out#{" "}
|
124
142
|
data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0
|
125
143
|
data-[state=open]:zoom-in-95 duration-200 fixed gap-4 grid left-[50%] max-w-[calc(100%-2rem)] p-2 pb-11 ring-4 ring-neutral-200/80
|
126
|
-
rounded-xl shadow-2xl sm:max-w-lg top-[50%] translate-x-[-50%] translate-y-[-50%] w-full z-50 pointer-events-auto
|
144
|
+
rounded-xl shadow-2xl sm:max-w-lg top-[50%] translate-x-[-50%] translate-y-[-50%] w-full z-50 pointer-events-auto outline-none
|
127
145
|
HEREDOC
|
128
146
|
)
|
129
147
|
|
130
|
-
def initialize(
|
131
|
-
|
148
|
+
def initialize(
|
149
|
+
search_error_text: nil,
|
150
|
+
search_empty_text: nil,
|
151
|
+
search_placeholder_text: nil,
|
152
|
+
aria_id: nil,
|
153
|
+
**attributes
|
154
|
+
)
|
155
|
+
@search_error_text = search_error_text
|
156
|
+
@search_empty_text = search_empty_text
|
157
|
+
@search_placeholder_text = search_placeholder_text
|
132
158
|
@aria_id = aria_id
|
133
159
|
super(**attributes)
|
134
160
|
end
|
135
161
|
|
136
162
|
def default_attributes
|
137
163
|
{
|
164
|
+
style: { display: "none" },
|
138
165
|
id: "#{@aria_id}-content",
|
139
166
|
tabindex: -1,
|
140
167
|
role: "dialog",
|
@@ -143,26 +170,29 @@ module ShadcnPhlexcomponents
|
|
143
170
|
labelledby: "#{@aria_id}-title",
|
144
171
|
},
|
145
172
|
data: {
|
146
|
-
command_target: "content",
|
147
173
|
state: "closed",
|
174
|
+
command_target: "content",
|
148
175
|
action: <<~HEREDOC,
|
149
|
-
command:click:outside->command#
|
176
|
+
command:click:outside->command#clickOutside
|
150
177
|
keydown.up->command#highlightItem:prevent
|
151
178
|
keydown.down->command#highlightItem:prevent
|
152
179
|
keydown.enter->command#select
|
153
180
|
HEREDOC
|
154
|
-
|
155
181
|
},
|
156
182
|
}
|
157
183
|
end
|
158
184
|
|
159
185
|
def view_template(&)
|
160
|
-
|
186
|
+
div(**@attributes) do
|
187
|
+
template do
|
188
|
+
CommandGroup do
|
189
|
+
CommandLabel { "" }
|
190
|
+
end
|
191
|
+
end
|
161
192
|
|
162
|
-
div(class: "#{@class} hidden", **@attributes) do
|
163
193
|
div(class: "text-popover-foreground flex h-full w-full flex-col overflow-hidden bg-transparent") do
|
164
194
|
div(class: "sr-only") do
|
165
|
-
h2(id: "#{@aria_id}-title") { @
|
195
|
+
h2(id: "#{@aria_id}-title") { @search_placeholder_text }
|
166
196
|
p(id: "#{@aria_id}-description") { "Search for a command to run..." }
|
167
197
|
end
|
168
198
|
|
@@ -170,7 +200,7 @@ module ShadcnPhlexcomponents
|
|
170
200
|
class: "sr-only",
|
171
201
|
id: "#{@aria_id}-search-label",
|
172
202
|
for: "#{@aria_id}-search",
|
173
|
-
) { @
|
203
|
+
) { @search_placeholder_text }
|
174
204
|
|
175
205
|
div(class: "flex h-9 items-center gap-2 border px-3 bg-input/50 border-input rounded-md") do
|
176
206
|
icon("search", class: "size-4 shrink-0 opacity-50")
|
@@ -179,7 +209,7 @@ module ShadcnPhlexcomponents
|
|
179
209
|
class: "placeholder:text-muted-foreground flex w-full rounded-md bg-transparent py-3 text-sm
|
180
210
|
outline-hidden disabled:cursor-not-allowed disabled:opacity-50 h-9",
|
181
211
|
id: "#{@aria_id}-search",
|
182
|
-
placeholder: @
|
212
|
+
placeholder: @search_placeholder_text,
|
183
213
|
type: :text,
|
184
214
|
autocomplete: "off",
|
185
215
|
autocorrect: "off",
|
@@ -193,13 +223,21 @@ module ShadcnPhlexcomponents
|
|
193
223
|
},
|
194
224
|
data: {
|
195
225
|
command_target: "searchInput",
|
196
|
-
action: "input->command#search",
|
226
|
+
action: "keydown->command#inputKeydown input->command#search",
|
197
227
|
},
|
198
228
|
)
|
199
229
|
end
|
200
230
|
|
201
|
-
div(class: "p-1 max-h-80 min-h-80 overflow-y-auto",
|
202
|
-
|
231
|
+
div(class: "mt-3 p-1 max-h-80 min-h-80 overflow-y-auto", data: { command_target: "listContainer"}) do
|
232
|
+
CommandText(target: "empty") { @search_empty_text }
|
233
|
+
CommandText(target: "error") { @search_error_text }
|
234
|
+
CommandText(target: "loading") do
|
235
|
+
div(class: "flex justify-center", aria: { label: "Loading" }) do
|
236
|
+
icon("loader-circle", class: "animate-spin")
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
div(id: "#{@aria_id}-list", data: { command_target: "list" }, &)
|
203
241
|
end
|
204
242
|
|
205
243
|
CommandFooter()
|
@@ -251,30 +289,21 @@ module ShadcnPhlexcomponents
|
|
251
289
|
end
|
252
290
|
|
253
291
|
class CommandLabel < Base
|
254
|
-
class_variants(base: "text-muted-foreground text-xs
|
292
|
+
class_variants(base: "text-muted-foreground text-xs px-3 pb-1 text-xs font-medium")
|
255
293
|
|
256
|
-
def initialize(
|
257
|
-
@aria_id = aria_id
|
294
|
+
def initialize( **attributes)
|
258
295
|
super(**attributes)
|
259
296
|
end
|
260
297
|
|
261
298
|
def view_template(&)
|
262
299
|
div(**@attributes, &)
|
263
300
|
end
|
264
|
-
|
265
|
-
def default_attributes
|
266
|
-
{
|
267
|
-
data: {
|
268
|
-
command_target: "label",
|
269
|
-
},
|
270
|
-
}
|
271
|
-
end
|
272
301
|
end
|
273
302
|
|
274
303
|
class CommandGroup < Base
|
275
|
-
class_variants(base: "scroll-mt-16")
|
304
|
+
class_variants(base: "scroll-mt-16 first:pt-0 pt-3")
|
276
305
|
|
277
|
-
def initialize(aria_id
|
306
|
+
def initialize(aria_id: nil, **attributes)
|
278
307
|
@aria_id = aria_id
|
279
308
|
super(**attributes)
|
280
309
|
end
|
@@ -296,22 +325,23 @@ module ShadcnPhlexcomponents
|
|
296
325
|
end
|
297
326
|
end
|
298
327
|
|
299
|
-
class
|
328
|
+
class CommandText < Base
|
300
329
|
class_variants(base: "py-6 text-center text-sm hidden")
|
330
|
+
|
331
|
+
def initialize(target:, **attributes)
|
332
|
+
@target = target
|
333
|
+
super(**attributes)
|
334
|
+
end
|
301
335
|
|
302
336
|
def default_attributes
|
303
337
|
{
|
304
338
|
role: "presentation",
|
305
|
-
data: { command_target:
|
339
|
+
data: { command_target: @target },
|
306
340
|
}
|
307
341
|
end
|
308
342
|
|
309
343
|
def view_template(&)
|
310
|
-
|
311
|
-
div(**@attributes, &)
|
312
|
-
else
|
313
|
-
div(**@attributes) { "No results found" }
|
314
|
-
end
|
344
|
+
div(**@attributes, &)
|
315
345
|
end
|
316
346
|
end
|
317
347
|
|