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
@@ -4,74 +4,6 @@ module ShadcnPhlexcomponents
|
|
4
4
|
class DatePicker < Base
|
5
5
|
class_variants(base: "w-full")
|
6
6
|
|
7
|
-
class << self
|
8
|
-
button = Button.new
|
9
|
-
|
10
|
-
{
|
11
|
-
input_container: <<~HEREDOC,
|
12
|
-
focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]
|
13
|
-
data-[focus=true]:border-ring data-[focus=true]:ring-ring/50 data-[focus=true]:ring-[3px]
|
14
|
-
data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 flex shadow-xs transition-[color,box-shadow]
|
15
|
-
rounded-md border bg-transparent dark:bg-input/30 border-input outline-none h-9 flex items-center
|
16
|
-
aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive
|
17
|
-
HEREDOC
|
18
|
-
input: <<~HEREDOC,
|
19
|
-
md:text-sm placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground
|
20
|
-
flex h-9 w-full min-w-0 text-base outline-none px-3 py-1#{" "}
|
21
|
-
HEREDOC
|
22
|
-
calendar: {
|
23
|
-
calendar: "relative flex flex-col outline-none",
|
24
|
-
controls: "absolute z-20 -left-1 -right-1 -top-1.5 flex justify-between items-center pt-1.5 px-1 pointer-events-none box-content",
|
25
|
-
grid: "grid gap-4 grid-cols-1 md:grid-cols-2",
|
26
|
-
column: "flex flex-col",
|
27
|
-
header: "relative flex items-center mb-4",
|
28
|
-
headerContent: "grid grid-flow-col gap-x-1 auto-cols-max items-center justify-center px-4 whitespace-pre-wrap grow",
|
29
|
-
month: button.class_variants(variant: :outline, size: :sm, class: "text-xs h-7 bg-transparent"),
|
30
|
-
year: button.class_variants(variant: :outline, size: :sm, class: "text-xs h-7 bg-transparent"),
|
31
|
-
arrowPrev: button.class_variants(variant: :outline, size: :icon, class: "pointer-events-auto size-7 bg-transparent p-0 opacity-50 hover:opacity-100"),
|
32
|
-
arrowNext: button.class_variants(variant: :outline, size: :icon, class: "pointer-events-auto size-7 bg-transparent p-0 opacity-50 hover:opacity-100"),
|
33
|
-
wrapper: "flex items-center content-center h-full",
|
34
|
-
content: "flex flex-col grow h-full",
|
35
|
-
months: "grid gap-2 grid-cols-4 items-center grow",
|
36
|
-
monthsMonth: button.class_variants(variant: :ghost, class: "aria-[selected=true]:text-primary-foreground aria-[selected=true]:bg-primary aria-[selected=true]:hover:text-primary-foreground aria-[selected=true]:hover:bg-primary"),
|
37
|
-
years: "grid gap-2 grid-cols-5 items-center grow",
|
38
|
-
yearsYear: button.class_variants(variant: :ghost, class: "aria-[selected=true]:text-primary-foreground aria-[selected=true]:bg-primary aria-[selected=true]:hover:text-primary-foreground aria-[selected=true]:hover:bg-primary"),
|
39
|
-
week: "grid mb-2 grid-cols-[repeat(7,_1fr)] justify-items-center items-center text-center",
|
40
|
-
weekDay: "text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]",
|
41
|
-
weekNumbers: "vc-week-numbers",
|
42
|
-
weekNumbersTitle: "vc-week-numbers__title",
|
43
|
-
weekNumbersContent: "vc-week-numbers__content",
|
44
|
-
weekNumber: "vc-week-number",
|
45
|
-
dates: "grid gap-y-2 grid-cols-[repeat(7,_1fr)] justify-items-center items-center",
|
46
|
-
date: <<~HEREDOC,
|
47
|
-
vc-date data-[vc-date-selected]:[&_button]:bg-primary#{" "}
|
48
|
-
data-[vc-date-selected]:[&_button]:text-primary-foreground#{" "}
|
49
|
-
data-[vc-date-selected]:[&_button]:hover:bg-primary#{" "}
|
50
|
-
data-[vc-date-selected]:[&_button]:hover:text-primary-foreground#{" "}
|
51
|
-
data-[vc-date-selected]:[&_button]:focus:bg-primary#{" "}
|
52
|
-
data-[vc-date-selected]:[&_button]:focus:text-primary-foreground
|
53
|
-
data-[vc-date-today]:[&_button]:bg-accent
|
54
|
-
data-[vc-date-today]:[&_button]:text-accent-foreground
|
55
|
-
data-[vc-date-month=prev]:[&_button]:text-muted-foreground
|
56
|
-
data-[vc-date-month=next]:[&_button]:text-muted-foreground
|
57
|
-
data-[vc-date-selected='middle']:data-[vc-date-selected]:[&_button]:bg-accent
|
58
|
-
data-[vc-date-selected='middle']:data-[vc-date-selected]:[&_button]:text-accent-foreground
|
59
|
-
data-[vc-date-hover]:[&_button]:bg-accent data-[vc-date-hover]:[&_button]:text-accent-foreground
|
60
|
-
HEREDOC
|
61
|
-
dateBtn: button.class_variants(variant: :ghost, class: "size-8 p-0 font-normal aria-[disabled]:text-muted-foreground aria-[disabled]:opacity-50 aria-[disabled]:pointer-events-none"),
|
62
|
-
datePopup: "vc-date__popup",
|
63
|
-
dateRangeTooltip: "vc-date-range-tooltip",
|
64
|
-
time: "vc-time",
|
65
|
-
timeContent: "vc-time__content",
|
66
|
-
timeHour: "vc-time__hour",
|
67
|
-
timeMinute: "vc-time__minute",
|
68
|
-
timeKeeping: "vc-time__keeping",
|
69
|
-
timeRanges: "vc-time__ranges",
|
70
|
-
timeRange: "vc-time__range",
|
71
|
-
},
|
72
|
-
}
|
73
|
-
end
|
74
|
-
|
75
7
|
def initialize(
|
76
8
|
name: nil,
|
77
9
|
id: nil,
|
@@ -86,6 +18,15 @@ module ShadcnPhlexcomponents
|
|
86
18
|
)
|
87
19
|
@name = name
|
88
20
|
@id = id
|
21
|
+
|
22
|
+
if value
|
23
|
+
value = if value.is_a?(String)
|
24
|
+
DateTime.parse(value) rescue nil
|
25
|
+
else
|
26
|
+
value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
89
30
|
@value = value&.utc&.iso8601
|
90
31
|
@format = format
|
91
32
|
@select_only = select_only
|
@@ -93,8 +34,7 @@ module ShadcnPhlexcomponents
|
|
93
34
|
@disabled = disabled
|
94
35
|
@mask = mask
|
95
36
|
@aria_id = "date-picker-#{SecureRandom.hex(5)}"
|
96
|
-
@
|
97
|
-
@options = options.merge(styles: @date_picker_styles[:calendar])
|
37
|
+
@options = options
|
98
38
|
super(**attributes)
|
99
39
|
end
|
100
40
|
|
@@ -112,6 +52,8 @@ module ShadcnPhlexcomponents
|
|
112
52
|
|
113
53
|
def view_template(&)
|
114
54
|
div(**@attributes) do
|
55
|
+
overlay("date-picker")
|
56
|
+
|
115
57
|
input(
|
116
58
|
type: :hidden,
|
117
59
|
name: @name,
|
@@ -130,12 +72,19 @@ module ShadcnPhlexcomponents
|
|
130
72
|
placeholder: @placeholder,
|
131
73
|
)
|
132
74
|
else
|
133
|
-
div(class:
|
75
|
+
div(class: <<~HEREDOC,
|
76
|
+
focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]
|
77
|
+
data-[focus=true]:border-ring data-[focus=true]:ring-ring/50 data-[focus=true]:ring-[3px]
|
78
|
+
data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 flex shadow-xs transition-[color,box-shadow]
|
79
|
+
rounded-md border bg-transparent dark:bg-input/30 border-input outline-none h-9 flex items-center
|
80
|
+
aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive
|
81
|
+
HEREDOC
|
82
|
+
data: { date_picker_target: "inputContainer", disabled: @disabled }) do
|
134
83
|
input(
|
135
84
|
id: @id,
|
136
85
|
placeholder: @placeholder || @format,
|
137
86
|
type: :text,
|
138
|
-
class:
|
87
|
+
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",
|
139
88
|
disabled: @disabled,
|
140
89
|
data: {
|
141
90
|
date_picker_target: "input",
|
@@ -223,13 +172,7 @@ module ShadcnPhlexcomponents
|
|
223
172
|
end
|
224
173
|
|
225
174
|
def class_variants(**args)
|
226
|
-
PopoverContent.new.class_variants(
|
227
|
-
class: <<~HEREDOC,
|
228
|
-
fixed left-1/2 top-1/2 shadow-lg -translate-x-1/2 -translate-y-1/2 pointer-events-auto w-max
|
229
|
-
md:relative md:left-[unset] md:top-[unset] md:shadow-md md:translate-x-[unset] md:translate-y-[unset] md:pointer-events-[unset]
|
230
|
-
#{args[:class]}
|
231
|
-
HEREDOC
|
232
|
-
)
|
175
|
+
PopoverContent.new.class_variants(class: "w-fit #{args[:class]}")
|
233
176
|
end
|
234
177
|
|
235
178
|
def default_attributes
|
@@ -252,7 +195,8 @@ module ShadcnPhlexcomponents
|
|
252
195
|
|
253
196
|
def view_template(&)
|
254
197
|
div(
|
255
|
-
|
198
|
+
style: { display: "none" },
|
199
|
+
class: "fixed z-50 top-1/4 left-1/2 -translate-x-1/2 pointer-events-auto md:top-auto md:left-auto md:translate-none md:pointer-events-[unset]",
|
256
200
|
data: { "#{stimulus_controller_name}-target" => "contentContainer" },
|
257
201
|
) do
|
258
202
|
div(**@attributes) do
|
@@ -261,4 +205,4 @@ module ShadcnPhlexcomponents
|
|
261
205
|
end
|
262
206
|
end
|
263
207
|
end
|
264
|
-
end
|
208
|
+
end
|
@@ -24,6 +24,16 @@ module ShadcnPhlexcomponents
|
|
24
24
|
raise ArgumentError, "Expected an array for \"value\", got #{value.class}"
|
25
25
|
end
|
26
26
|
|
27
|
+
if value
|
28
|
+
value = value.map do |v|
|
29
|
+
if v.is_a?(String)
|
30
|
+
DateTime.parse(v) rescue nil
|
31
|
+
else
|
32
|
+
v
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
27
37
|
@name = name ? name[0] : nil
|
28
38
|
@end_name = name ? name[1] : nil
|
29
39
|
@value = (value ? value[0] : nil)&.utc&.iso8601
|
@@ -35,8 +45,7 @@ module ShadcnPhlexcomponents
|
|
35
45
|
@disabled = disabled
|
36
46
|
@mask = mask
|
37
47
|
@aria_id = "date-range-picker-#{SecureRandom.hex(5)}"
|
38
|
-
@
|
39
|
-
@options = options.merge(styles: @date_picker_styles[:calendar])
|
48
|
+
@options = options
|
40
49
|
super(**attributes)
|
41
50
|
end
|
42
51
|
|
@@ -55,6 +64,8 @@ module ShadcnPhlexcomponents
|
|
55
64
|
|
56
65
|
def view_template(&)
|
57
66
|
div(**@attributes) do
|
67
|
+
overlay('date-range-picker')
|
68
|
+
|
58
69
|
input(
|
59
70
|
type: :hidden,
|
60
71
|
name: @name,
|
@@ -81,14 +92,20 @@ module ShadcnPhlexcomponents
|
|
81
92
|
)
|
82
93
|
else
|
83
94
|
div(
|
84
|
-
class:
|
95
|
+
class: <<~HEREDOC,
|
96
|
+
focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]
|
97
|
+
data-[focus=true]:border-ring data-[focus=true]:ring-ring/50 data-[focus=true]:ring-[3px]
|
98
|
+
data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 flex shadow-xs transition-[color,box-shadow]
|
99
|
+
rounded-md border bg-transparent dark:bg-input/30 border-input outline-none h-9 flex items-center
|
100
|
+
aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive
|
101
|
+
HEREDOC
|
85
102
|
data: { date_range_picker_target: "inputContainer", disabled: @disabled },
|
86
103
|
) do
|
87
104
|
input(
|
88
105
|
id: @id,
|
89
106
|
placeholder: @placeholder || "#{@format} - #{@format}",
|
90
107
|
type: :text,
|
91
|
-
class:
|
108
|
+
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",
|
92
109
|
disabled: @disabled,
|
93
110
|
data: {
|
94
111
|
date_range_picker_target: "input",
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ShadcnPhlexcomponents
|
4
4
|
class Dialog < 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
|
@@ -42,13 +42,17 @@ module ShadcnPhlexcomponents
|
|
42
42
|
{
|
43
43
|
data: {
|
44
44
|
controller: "dialog",
|
45
|
-
dialog_is_open_value: @open.to_s
|
46
|
-
}
|
45
|
+
dialog_is_open_value: @open.to_s
|
46
|
+
}
|
47
47
|
}
|
48
48
|
end
|
49
49
|
|
50
50
|
def view_template(&)
|
51
|
-
div(**@attributes
|
51
|
+
div(**@attributes) do
|
52
|
+
overlay("dialog")
|
53
|
+
|
54
|
+
yield
|
55
|
+
end
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
@@ -67,10 +71,10 @@ module ShadcnPhlexcomponents
|
|
67
71
|
expanded: "false",
|
68
72
|
controls: "#{@aria_id}-content",
|
69
73
|
},
|
70
|
-
data: {
|
71
|
-
action: "click->dialog#open",
|
72
|
-
dialog_target: "trigger",
|
74
|
+
data: {
|
73
75
|
as_child: @as_child.to_s,
|
76
|
+
dialog_target: "trigger",
|
77
|
+
action: "click->dialog#open"
|
74
78
|
},
|
75
79
|
}
|
76
80
|
end
|
@@ -98,7 +102,7 @@ module ShadcnPhlexcomponents
|
|
98
102
|
data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
|
99
103
|
data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)]
|
100
104
|
translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg
|
101
|
-
pointer-events-auto
|
105
|
+
pointer-events-auto outline-none
|
102
106
|
HEREDOC
|
103
107
|
)
|
104
108
|
|
@@ -117,16 +121,14 @@ module ShadcnPhlexcomponents
|
|
117
121
|
labelledby: "#{@aria_id}-title",
|
118
122
|
},
|
119
123
|
data: {
|
120
|
-
dialog_target: "content",
|
121
124
|
state: "closed",
|
122
|
-
|
125
|
+
dialog_target: "content"
|
123
126
|
},
|
124
127
|
}
|
125
128
|
end
|
126
129
|
|
127
130
|
def view_template(&)
|
128
|
-
|
129
|
-
div(class: "#{@class} hidden", **@attributes) do
|
131
|
+
div(style: { display: "none" }, **@attributes) do
|
130
132
|
yield
|
131
133
|
|
132
134
|
button(
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ShadcnPhlexcomponents
|
4
4
|
class DropdownMenu < 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
|
@aria_id = "dropdown-menu-#{SecureRandom.hex(5)}"
|
@@ -93,9 +93,9 @@ module ShadcnPhlexcomponents
|
|
93
93
|
dropdown_menu_target: "trigger",
|
94
94
|
action: <<~HEREDOC,
|
95
95
|
click->dropdown-menu#toggle
|
96
|
-
keydown.space->dropdown-menu#open
|
97
|
-
keydown.enter->dropdown-menu#open
|
98
96
|
keydown.down->dropdown-menu#open:prevent
|
97
|
+
keydown.space->dropdown-menu#open:prevent
|
98
|
+
keydown.enter->dropdown-menu#open:prevent
|
99
99
|
HEREDOC
|
100
100
|
},
|
101
101
|
}
|
@@ -123,7 +123,8 @@ module ShadcnPhlexcomponents
|
|
123
123
|
|
124
124
|
def view_template(&)
|
125
125
|
div(
|
126
|
-
|
126
|
+
style: { display: "none" },
|
127
|
+
class: "fixed top-0 left-0 w-max z-50",
|
127
128
|
data: { dropdown_menu_target: "contentContainer" },
|
128
129
|
) do
|
129
130
|
div(**@attributes, &)
|
@@ -125,7 +125,8 @@ module ShadcnPhlexcomponents
|
|
125
125
|
|
126
126
|
def view_template(&)
|
127
127
|
div(
|
128
|
-
|
128
|
+
style: { display: "none" },
|
129
|
+
class: "fixed top-0 left-0 w-max z-50",
|
129
130
|
data: { dropdown_menu_sub_target: "contentContainer" },
|
130
131
|
) do
|
131
132
|
div(**@attributes, &)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class FormCombobox < Base
|
5
|
+
include FormHelpers
|
6
|
+
|
7
|
+
def initialize(
|
8
|
+
method = nil,
|
9
|
+
model: false,
|
10
|
+
object_name: nil,
|
11
|
+
collection: [],
|
12
|
+
value_method: nil,
|
13
|
+
text_method: nil,
|
14
|
+
value: nil,
|
15
|
+
name: nil,
|
16
|
+
id: nil,
|
17
|
+
label: nil,
|
18
|
+
error: nil,
|
19
|
+
hint: nil,
|
20
|
+
disabled_items: nil,
|
21
|
+
**attributes
|
22
|
+
)
|
23
|
+
@method = method
|
24
|
+
@model = model
|
25
|
+
@object_name = object_name
|
26
|
+
|
27
|
+
@collection = if collection.first&.is_a?(Hash)
|
28
|
+
convert_collection_hash_to_struct(collection, value_method: value_method, text_method: text_method)
|
29
|
+
else
|
30
|
+
collection
|
31
|
+
end
|
32
|
+
|
33
|
+
@value_method = value_method
|
34
|
+
@text_method = text_method
|
35
|
+
@value = default_value(value, method)
|
36
|
+
@name = name
|
37
|
+
@id = id
|
38
|
+
@label = label
|
39
|
+
@error = default_error(error, method)
|
40
|
+
@hint = hint
|
41
|
+
@disabled_items = disabled_items
|
42
|
+
@aria_id = "form-field-#{SecureRandom.hex(5)}"
|
43
|
+
super(**attributes)
|
44
|
+
end
|
45
|
+
|
46
|
+
def view_template(&)
|
47
|
+
vanish(&)
|
48
|
+
|
49
|
+
@id ||= field_id(@object_name, @method)
|
50
|
+
@name ||= field_name(@object_name, @method)
|
51
|
+
|
52
|
+
div(class: "space-y-2", data: label_and_hint_container_attributes) do
|
53
|
+
render_label(&)
|
54
|
+
|
55
|
+
Combobox(id: @id, name: @name, value: @value, aria: aria_attributes, **@attributes) do |c|
|
56
|
+
c.items(@collection, value_method: @value_method, text_method: @text_method, disabled_items: @disabled_items)
|
57
|
+
end
|
58
|
+
|
59
|
+
render_hint(&)
|
60
|
+
render_error
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -11,6 +11,7 @@ require_relative "form/form_checkbox_group"
|
|
11
11
|
require_relative "form/form_date_picker"
|
12
12
|
require_relative "form/form_date_range_picker"
|
13
13
|
require_relative "form/form_select"
|
14
|
+
require_relative "form/form_combobox"
|
14
15
|
require_relative "form/form_radio_group"
|
15
16
|
require_relative "form/form_slider"
|
16
17
|
|
@@ -83,6 +84,19 @@ module ShadcnPhlexcomponents
|
|
83
84
|
)
|
84
85
|
end
|
85
86
|
|
87
|
+
def combobox(method = nil, collection = [], value_method:, text_method:, **attributes, &)
|
88
|
+
FormCombobox(
|
89
|
+
method,
|
90
|
+
model: @model,
|
91
|
+
object_name: @object_name,
|
92
|
+
collection: collection,
|
93
|
+
value_method: value_method,
|
94
|
+
text_method: text_method,
|
95
|
+
**attributes,
|
96
|
+
&
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
86
100
|
def date_picker(method = nil, **attributes, &)
|
87
101
|
FormDatePicker(method, model: @model, object_name: @object_name, **attributes, &)
|
88
102
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ShadcnPhlexcomponents
|
4
4
|
class HoverCard < 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
|
@@ -88,7 +88,8 @@ module ShadcnPhlexcomponents
|
|
88
88
|
|
89
89
|
def view_template(&)
|
90
90
|
div(
|
91
|
-
|
91
|
+
style: { display: "none" },
|
92
|
+
class: "fixed top-0 left-0 w-max z-50",
|
92
93
|
data: { hover_card_target: "contentContainer" },
|
93
94
|
) do
|
94
95
|
div(**@attributes, &)
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ShadcnPhlexcomponents
|
4
4
|
class Popover < 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
|
@@ -23,7 +23,6 @@ module ShadcnPhlexcomponents
|
|
23
23
|
data: {
|
24
24
|
controller: "popover",
|
25
25
|
popover_is_open_value: @open.to_s,
|
26
|
-
side: @side,
|
27
26
|
},
|
28
27
|
}
|
29
28
|
end
|
@@ -92,7 +91,8 @@ module ShadcnPhlexcomponents
|
|
92
91
|
|
93
92
|
def view_template(&)
|
94
93
|
div(
|
95
|
-
|
94
|
+
style: { display: "none" },
|
95
|
+
class: "fixed top-0 left-0 w-max z-50",
|
96
96
|
data: { popover_target: "contentContainer" },
|
97
97
|
) do
|
98
98
|
div(**@attributes, &)
|
@@ -10,7 +10,6 @@ module ShadcnPhlexcomponents
|
|
10
10
|
value: nil,
|
11
11
|
placeholder: nil,
|
12
12
|
native: false,
|
13
|
-
dir: "ltr",
|
14
13
|
include_blank: false,
|
15
14
|
disabled: false,
|
16
15
|
**attributes
|
@@ -20,7 +19,6 @@ module ShadcnPhlexcomponents
|
|
20
19
|
@value = value
|
21
20
|
@placeholder = placeholder
|
22
21
|
@native = native
|
23
|
-
@dir = dir
|
24
22
|
@include_blank = include_blank
|
25
23
|
@disabled = disabled
|
26
24
|
@aria_id = "select-#{SecureRandom.hex(5)}"
|
@@ -39,7 +37,6 @@ module ShadcnPhlexcomponents
|
|
39
37
|
SelectTrigger(
|
40
38
|
id: @id,
|
41
39
|
aria_id: @aria_id,
|
42
|
-
dir: @dir,
|
43
40
|
value: @value,
|
44
41
|
placeholder: @placeholder,
|
45
42
|
disabled: @disabled,
|
@@ -49,7 +46,7 @@ module ShadcnPhlexcomponents
|
|
49
46
|
|
50
47
|
def content(**attributes, &)
|
51
48
|
SelectContent(
|
52
|
-
aria_id: @aria_id,
|
49
|
+
aria_id: @aria_id, include_blank: @include_blank, native: @native, **attributes, &
|
53
50
|
)
|
54
51
|
end
|
55
52
|
|
@@ -75,13 +72,12 @@ module ShadcnPhlexcomponents
|
|
75
72
|
SelectTrigger(
|
76
73
|
id: @id,
|
77
74
|
aria_id: @aria_id,
|
78
|
-
dir: @dir,
|
79
75
|
value: @value,
|
80
76
|
placeholder: @placeholder,
|
81
77
|
disabled: @disabled,
|
82
78
|
)
|
83
79
|
|
84
|
-
SelectContent(aria_id: @aria_id,
|
80
|
+
SelectContent(aria_id: @aria_id, include_blank: @include_blank, native: @native) do
|
85
81
|
collection.each do |item|
|
86
82
|
value = item.public_send(value_method)
|
87
83
|
text = item.public_send(text_method)
|
@@ -151,7 +147,7 @@ module ShadcnPhlexcomponents
|
|
151
147
|
next if content_child.is_a?(Nokogiri::XML::Text) || content_child.is_a?(Nokogiri::XML::Comment)
|
152
148
|
|
153
149
|
if content_child.attributes["data-select-target"]&.value == "group"
|
154
|
-
group_label = content_child.at_css('[data-
|
150
|
+
group_label = content_child.at_css('[data-shadcn-phlexcomponents="select-label"]')&.text
|
155
151
|
|
156
152
|
optgroup(label: group_label, class: NATIVE_OPTION_STYLES) do
|
157
153
|
content_child.css('[data-select-target="item"]').each do |i|
|
@@ -195,11 +191,10 @@ module ShadcnPhlexcomponents
|
|
195
191
|
HEREDOC
|
196
192
|
)
|
197
193
|
|
198
|
-
def initialize(id: nil, value: nil, placeholder: nil,
|
194
|
+
def initialize(id: nil, value: nil, placeholder: nil, aria_id: nil, **attributes)
|
199
195
|
@id = id
|
200
196
|
@value = value
|
201
197
|
@placeholder = placeholder
|
202
|
-
@dir = dir
|
203
198
|
@aria_id = aria_id
|
204
199
|
super(**attributes)
|
205
200
|
end
|
@@ -218,7 +213,6 @@ module ShadcnPhlexcomponents
|
|
218
213
|
{
|
219
214
|
type: "button",
|
220
215
|
id: @id,
|
221
|
-
dir: @dir,
|
222
216
|
role: "combobox",
|
223
217
|
aria: {
|
224
218
|
autocomplete: "none",
|
@@ -230,9 +224,9 @@ module ShadcnPhlexcomponents
|
|
230
224
|
has_value: @value.present?.to_s,
|
231
225
|
action: <<~HEREDOC,
|
232
226
|
click->select#toggle
|
233
|
-
keydown.space->select#open
|
234
|
-
keydown.enter->select#open
|
235
227
|
keydown.down->select#open:prevent
|
228
|
+
keydown.space->select#open:prevent
|
229
|
+
keydown.enter->select#open:prevent
|
236
230
|
HEREDOC
|
237
231
|
select_target: "trigger",
|
238
232
|
},
|
@@ -252,10 +246,9 @@ module ShadcnPhlexcomponents
|
|
252
246
|
HEREDOC
|
253
247
|
)
|
254
248
|
|
255
|
-
def initialize(include_blank: false, native: false,
|
249
|
+
def initialize(include_blank: false, native: false, side: :bottom, align: :center, aria_id: nil, **attributes)
|
256
250
|
@include_blank = include_blank
|
257
251
|
@native = native
|
258
|
-
@dir = dir
|
259
252
|
@side = side
|
260
253
|
@align = align
|
261
254
|
@aria_id = aria_id
|
@@ -264,12 +257,13 @@ module ShadcnPhlexcomponents
|
|
264
257
|
|
265
258
|
def view_template(&)
|
266
259
|
div(
|
267
|
-
|
260
|
+
style: { display: "none" },
|
261
|
+
class: "fixed top-0 left-0 w-max z-50",
|
268
262
|
data: { select_target: "contentContainer" },
|
269
263
|
) do
|
270
264
|
div(**@attributes) do
|
271
265
|
if @include_blank && !@native
|
272
|
-
SelectItem(aria_id: @aria_id, value: "", class: "h-8"
|
266
|
+
SelectItem(aria_id: @aria_id, value: "", class: "h-8") do
|
273
267
|
@include_blank.is_a?(String) ? @include_blank : ""
|
274
268
|
end
|
275
269
|
end
|
@@ -282,7 +276,6 @@ module ShadcnPhlexcomponents
|
|
282
276
|
def default_attributes
|
283
277
|
{
|
284
278
|
id: "#{@aria_id}-content",
|
285
|
-
dir: @dir,
|
286
279
|
tabindex: -1,
|
287
280
|
role: "listbox",
|
288
281
|
aria: {
|
@@ -316,14 +309,6 @@ module ShadcnPhlexcomponents
|
|
316
309
|
def view_template(&)
|
317
310
|
div(**@attributes, &)
|
318
311
|
end
|
319
|
-
|
320
|
-
def default_attributes
|
321
|
-
{
|
322
|
-
data: {
|
323
|
-
select_target: "label",
|
324
|
-
},
|
325
|
-
}
|
326
|
-
end
|
327
312
|
end
|
328
313
|
|
329
314
|
class SelectItem < Base
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ShadcnPhlexcomponents
|
4
4
|
class Sheet < 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
|
@@ -42,12 +42,17 @@ module ShadcnPhlexcomponents
|
|
42
42
|
{
|
43
43
|
data: {
|
44
44
|
controller: "dialog",
|
45
|
-
|
46
|
-
|
45
|
+
dialog_is_open_value: @open.to_s
|
46
|
+
}
|
47
|
+
}
|
47
48
|
end
|
48
49
|
|
49
50
|
def view_template(&)
|
50
|
-
div(**@attributes
|
51
|
+
div(**@attributes) do
|
52
|
+
overlay("dialog")
|
53
|
+
|
54
|
+
yield
|
55
|
+
end
|
51
56
|
end
|
52
57
|
end
|
53
58
|
|
@@ -66,10 +71,10 @@ module ShadcnPhlexcomponents
|
|
66
71
|
expanded: false,
|
67
72
|
controls: "#{@aria_id}-content",
|
68
73
|
},
|
69
|
-
data: {
|
74
|
+
data: {
|
70
75
|
as_child: @as_child.to_s,
|
71
|
-
action: "click->dialog#open",
|
72
76
|
dialog_target: "trigger",
|
77
|
+
action: "click->dialog#open"
|
73
78
|
},
|
74
79
|
}
|
75
80
|
end
|
@@ -95,7 +100,7 @@ module ShadcnPhlexcomponents
|
|
95
100
|
base: <<~HEREDOC,
|
96
101
|
bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4
|
97
102
|
shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500
|
98
|
-
pointer-events-auto
|
103
|
+
pointer-events-auto outline-none
|
99
104
|
HEREDOC
|
100
105
|
variants: {
|
101
106
|
side: {
|
@@ -117,8 +122,7 @@ module ShadcnPhlexcomponents
|
|
117
122
|
end
|
118
123
|
|
119
124
|
def view_template(&)
|
120
|
-
|
121
|
-
div(class: "#{@class} hidden", **@attributes) do
|
125
|
+
div(style: { display: "none" }, **@attributes) do
|
122
126
|
yield
|
123
127
|
|
124
128
|
button(
|
@@ -145,8 +149,8 @@ module ShadcnPhlexcomponents
|
|
145
149
|
labelledby: "#{@aria_id}-title",
|
146
150
|
},
|
147
151
|
data: {
|
148
|
-
|
149
|
-
|
152
|
+
state: "closed",
|
153
|
+
dialog_target: "content"
|
150
154
|
},
|
151
155
|
}
|
152
156
|
end
|