shadcn_phlexcomponents 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +39 -0
- data/Rakefile +12 -0
- data/app/assets/tailwind/tailwindcss-animate.css +318 -0
- data/app/assets/tailwind/vanilla-calendar-pro.css +461 -0
- data/app/javascript/controllers/accordion_controller.js +133 -0
- data/app/javascript/controllers/alert_dialog_controller.js +157 -0
- data/app/javascript/controllers/avatar_controller.js +15 -0
- data/app/javascript/controllers/checkbox_controller.js +28 -0
- data/app/javascript/controllers/collapsible_controller.js +35 -0
- data/app/javascript/controllers/combobox_controller.js +291 -0
- data/app/javascript/controllers/datepicker_controller.js +47 -0
- data/app/javascript/controllers/dialog_controller.js +159 -0
- data/app/javascript/controllers/dropdown_menu_controller.js +193 -0
- data/app/javascript/controllers/hover_card_controller.js +135 -0
- data/app/javascript/controllers/loading_button_controller.js +15 -0
- data/app/javascript/controllers/popover_controller.js +124 -0
- data/app/javascript/controllers/progress_controller.js +14 -0
- data/app/javascript/controllers/radio_group_controller.js +90 -0
- data/app/javascript/controllers/select_controller.js +294 -0
- data/app/javascript/controllers/sheet_controller.js +159 -0
- data/app/javascript/controllers/sidebar_controller.js +36 -0
- data/app/javascript/controllers/sidebar_trigger_controller.js +15 -0
- data/app/javascript/controllers/switch_controller.js +24 -0
- data/app/javascript/controllers/tabs_controller.js +73 -0
- data/app/javascript/controllers/theme_switcher_controller.js +32 -0
- data/app/javascript/controllers/toast_container_controller.js +22 -0
- data/app/javascript/controllers/toast_controller.js +45 -0
- data/app/javascript/controllers/tooltip_controller.js +135 -0
- data/lib/components/accordion.rb +38 -0
- data/lib/components/accordion_content.rb +28 -0
- data/lib/components/accordion_item.rb +26 -0
- data/lib/components/accordion_trigger.rb +45 -0
- data/lib/components/alert.rb +40 -0
- data/lib/components/alert_description.rb +11 -0
- data/lib/components/alert_dialog.rb +60 -0
- data/lib/components/alert_dialog_action.rb +22 -0
- data/lib/components/alert_dialog_action_to.rb +37 -0
- data/lib/components/alert_dialog_cancel.rb +22 -0
- data/lib/components/alert_dialog_content.rb +40 -0
- data/lib/components/alert_dialog_description.rb +22 -0
- data/lib/components/alert_dialog_footer.rb +11 -0
- data/lib/components/alert_dialog_header.rb +11 -0
- data/lib/components/alert_dialog_title.rb +22 -0
- data/lib/components/alert_dialog_trigger.rb +50 -0
- data/lib/components/alert_title.rb +11 -0
- data/lib/components/aspect_ratio.rb +19 -0
- data/lib/components/avatar.rb +31 -0
- data/lib/components/avatar_fallback.rb +21 -0
- data/lib/components/avatar_image.rb +20 -0
- data/lib/components/badge.rb +36 -0
- data/lib/components/base.rb +108 -0
- data/lib/components/breadcrumb.rb +51 -0
- data/lib/components/breadcrumb_ellipsis.rb +23 -0
- data/lib/components/breadcrumb_item.rb +11 -0
- data/lib/components/breadcrumb_link.rb +7 -0
- data/lib/components/breadcrumb_page.rb +21 -0
- data/lib/components/breadcrumb_separator.rb +26 -0
- data/lib/components/button.rb +53 -0
- data/lib/components/card.rb +31 -0
- data/lib/components/card_content.rb +11 -0
- data/lib/components/card_description.rb +11 -0
- data/lib/components/card_footer.rb +11 -0
- data/lib/components/card_header.rb +11 -0
- data/lib/components/card_title.rb +11 -0
- data/lib/components/checkbox.rb +65 -0
- data/lib/components/checkbox_group.rb +48 -0
- data/lib/components/collapsible.rb +32 -0
- data/lib/components/collapsible_content.rb +25 -0
- data/lib/components/collapsible_trigger.rb +50 -0
- data/lib/components/datepicker.rb +38 -0
- data/lib/components/dialog.rb +52 -0
- data/lib/components/dialog_close.rb +42 -0
- data/lib/components/dialog_content.rb +54 -0
- data/lib/components/dialog_description.rb +22 -0
- data/lib/components/dialog_footer.rb +11 -0
- data/lib/components/dialog_header.rb +11 -0
- data/lib/components/dialog_title.rb +22 -0
- data/lib/components/dialog_trigger.rb +50 -0
- data/lib/components/dropdown_menu.rb +50 -0
- data/lib/components/dropdown_menu_content.rb +49 -0
- data/lib/components/dropdown_menu_item.rb +57 -0
- data/lib/components/dropdown_menu_item_to.rb +25 -0
- data/lib/components/dropdown_menu_label.rb +12 -0
- data/lib/components/dropdown_menu_separator.rb +20 -0
- data/lib/components/dropdown_menu_trigger.rb +58 -0
- data/lib/components/hover_card.rb +33 -0
- data/lib/components/hover_card_content.rb +36 -0
- data/lib/components/hover_card_trigger.rb +50 -0
- data/lib/components/input.rb +32 -0
- data/lib/components/label.rb +15 -0
- data/lib/components/link.rb +26 -0
- data/lib/components/loading_button.rb +21 -0
- data/lib/components/pagination.rb +38 -0
- data/lib/components/pagination_ellipsis.rb +24 -0
- data/lib/components/pagination_link.rb +34 -0
- data/lib/components/pagination_next.rb +32 -0
- data/lib/components/pagination_previous.rb +32 -0
- data/lib/components/popover.rb +35 -0
- data/lib/components/popover_content.rb +37 -0
- data/lib/components/popover_trigger.rb +52 -0
- data/lib/components/progress.rb +37 -0
- data/lib/components/radio_group.rb +62 -0
- data/lib/components/radio_group_item.rb +66 -0
- data/lib/components/select.rb +189 -0
- data/lib/components/select_content.rb +59 -0
- data/lib/components/select_group.rb +23 -0
- data/lib/components/select_item.rb +58 -0
- data/lib/components/select_label.rb +23 -0
- data/lib/components/select_trigger.rb +54 -0
- data/lib/components/separator.rb +29 -0
- data/lib/components/sheet.rb +53 -0
- data/lib/components/sheet_close.rb +42 -0
- data/lib/components/sheet_content.rb +67 -0
- data/lib/components/sheet_description.rb +22 -0
- data/lib/components/sheet_footer.rb +11 -0
- data/lib/components/sheet_header.rb +11 -0
- data/lib/components/sheet_title.rb +22 -0
- data/lib/components/sheet_trigger.rb +50 -0
- data/lib/components/sidebar.rb +103 -0
- data/lib/components/sidebar_container.rb +11 -0
- data/lib/components/sidebar_content.rb +11 -0
- data/lib/components/sidebar_footer.rb +11 -0
- data/lib/components/sidebar_group.rb +11 -0
- data/lib/components/sidebar_group_content.rb +11 -0
- data/lib/components/sidebar_group_label.rb +16 -0
- data/lib/components/sidebar_header.rb +11 -0
- data/lib/components/sidebar_inset.rb +15 -0
- data/lib/components/sidebar_menu.rb +11 -0
- data/lib/components/sidebar_menu_button.rb +61 -0
- data/lib/components/sidebar_menu_item.rb +9 -0
- data/lib/components/sidebar_menu_sub.rb +14 -0
- data/lib/components/sidebar_menu_sub_button.rb +48 -0
- data/lib/components/sidebar_menu_sub_item.rb +9 -0
- data/lib/components/sidebar_trigger.rb +40 -0
- data/lib/components/skeleton.rb +11 -0
- data/lib/components/switch.rb +65 -0
- data/lib/components/table.rb +73 -0
- data/lib/components/table_body.rb +11 -0
- data/lib/components/table_caption.rb +11 -0
- data/lib/components/table_cell.rb +11 -0
- data/lib/components/table_footer.rb +11 -0
- data/lib/components/table_head.rb +14 -0
- data/lib/components/table_header.rb +11 -0
- data/lib/components/table_row.rb +11 -0
- data/lib/components/tabs.rb +38 -0
- data/lib/components/tabs_content.rb +35 -0
- data/lib/components/tabs_list.rb +23 -0
- data/lib/components/tabs_trigger.rb +45 -0
- data/lib/components/textarea.rb +28 -0
- data/lib/components/theme_switcher.rb +21 -0
- data/lib/components/toast.rb +100 -0
- data/lib/components/toast_action.rb +38 -0
- data/lib/components/toast_action_to.rb +25 -0
- data/lib/components/toast_container.rb +44 -0
- data/lib/components/toast_content.rb +11 -0
- data/lib/components/toast_description.rb +11 -0
- data/lib/components/toast_title.rb +11 -0
- data/lib/components/tooltip.rb +34 -0
- data/lib/components/tooltip_content.rb +42 -0
- data/lib/components/tooltip_trigger.rb +50 -0
- data/lib/install/install_shadcn_phlexcomponents.rb +12 -0
- data/lib/shadcn_phlexcomponents/alias.rb +132 -0
- data/lib/shadcn_phlexcomponents/engine.rb +11 -0
- data/lib/shadcn_phlexcomponents/version.rb +5 -0
- data/lib/shadcn_phlexcomponents.rb +9 -0
- data/lib/tasks/install.rake +10 -0
- metadata +264 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
|
|
5
|
+
class DropdownMenuTrigger < Base
|
|
6
|
+
def initialize(as_child: false, aria_id: nil, **attributes)
|
|
7
|
+
@as_child = as_child
|
|
8
|
+
@aria_id = aria_id
|
|
9
|
+
super(**attributes)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def view_template(&)
|
|
13
|
+
if @as_child
|
|
14
|
+
content = capture(&)
|
|
15
|
+
element = find_as_child(content.to_s)
|
|
16
|
+
|
|
17
|
+
vanish(&)
|
|
18
|
+
element_attributes = nokogiri_attributes_to_hash(element)
|
|
19
|
+
styles = TAILWIND_MERGER.merge("#{@attributes[:class]} #{element_attributes[:class]}")
|
|
20
|
+
merged_attributes = mix(@attributes, element_attributes)
|
|
21
|
+
merged_attributes[:class] = styles
|
|
22
|
+
|
|
23
|
+
if element.name == "button"
|
|
24
|
+
merged_attributes.delete(:role)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
send(element.name, **merged_attributes) do
|
|
28
|
+
sanitize_as_child(element.children.to_s)
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
div(**@attributes, &)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def default_attributes
|
|
36
|
+
{
|
|
37
|
+
id: "#{@aria_id}-trigger",
|
|
38
|
+
role: "button",
|
|
39
|
+
aria: {
|
|
40
|
+
haspopup: "menu",
|
|
41
|
+
expanded: false,
|
|
42
|
+
controls: "#{@aria_id}-content"
|
|
43
|
+
},
|
|
44
|
+
data: {
|
|
45
|
+
state: "closed",
|
|
46
|
+
as_child: @as_child.to_s,
|
|
47
|
+
action: <<~HEREDOC,
|
|
48
|
+
click->shadcn-phlexcomponents--dropdown-menu#toggle
|
|
49
|
+
keydown.space->shadcn-phlexcomponents--dropdown-menu#toggle
|
|
50
|
+
keydown.enter->shadcn-phlexcomponents--dropdown-menu#toggle
|
|
51
|
+
keydown.down->shadcn-phlexcomponents--dropdown-menu#toggle:prevent
|
|
52
|
+
HEREDOC
|
|
53
|
+
"shadcn-phlexcomponents--dropdown-menu-target": "trigger"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class HoverCard < Base
|
|
5
|
+
STYLES = "inline-block".freeze
|
|
6
|
+
|
|
7
|
+
def initialize(side: :bottom, **attributes)
|
|
8
|
+
@side = side
|
|
9
|
+
super(**attributes)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def content(**attributes, &)
|
|
13
|
+
HoverCardContent(**attributes, &)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def trigger(**attributes, &)
|
|
17
|
+
HoverCardTrigger(side: @side, **attributes, &)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def default_attributes
|
|
21
|
+
{
|
|
22
|
+
data: {
|
|
23
|
+
controller: "shadcn-phlexcomponents--hover-card",
|
|
24
|
+
side: @side
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def view_template(&)
|
|
30
|
+
div(**@attributes, &)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class HoverCardContent < Base
|
|
5
|
+
STYLES = <<~HEREDOC.freeze
|
|
6
|
+
z-50 rounded-md border w-64 bg-popover p-4 text-popover-foreground shadow-md outline-none
|
|
7
|
+
data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0
|
|
8
|
+
data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95
|
|
9
|
+
data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2
|
|
10
|
+
data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2
|
|
11
|
+
HEREDOC
|
|
12
|
+
|
|
13
|
+
def initialize(side: :bottom, **attributes)
|
|
14
|
+
@side = side
|
|
15
|
+
super(**attributes)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def view_template(&)
|
|
20
|
+
div(class: 'hidden fixed top-0 left-0 w-max z-50', data: { "shadcn-phlexcomponents--hover-card-target": "contentWrapper" }) do
|
|
21
|
+
div(**@attributes, &)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def default_attributes
|
|
26
|
+
{
|
|
27
|
+
tabindex: -1,
|
|
28
|
+
data: {
|
|
29
|
+
side: @side,
|
|
30
|
+
"shadcn-phlexcomponents--hover-card-target": "content",
|
|
31
|
+
action: "mouseover->shadcn-phlexcomponents--hover-card#clearCloseTimer mouseout->shadcn-phlexcomponents--hover-card#closeWithDelay"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class HoverCardTrigger < Base
|
|
5
|
+
def initialize(as_child: false, **attributes)
|
|
6
|
+
@as_child = as_child
|
|
7
|
+
super(**attributes)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def view_template(&)
|
|
11
|
+
if @as_child
|
|
12
|
+
content = capture(&)
|
|
13
|
+
element = find_as_child(content.to_s)
|
|
14
|
+
|
|
15
|
+
vanish(&)
|
|
16
|
+
element_attributes = nokogiri_attributes_to_hash(element)
|
|
17
|
+
styles = TAILWIND_MERGER.merge("#{@attributes[:class]} #{element_attributes[:class]}")
|
|
18
|
+
merged_attributes = mix(@attributes, element_attributes)
|
|
19
|
+
merged_attributes[:class] = styles
|
|
20
|
+
|
|
21
|
+
if element.name == "button"
|
|
22
|
+
merged_attributes.delete(:role)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
send(element.name, **merged_attributes) do
|
|
26
|
+
sanitize_as_child(element.children.to_s)
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
div(**@attributes, &)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def default_attributes
|
|
34
|
+
{
|
|
35
|
+
id: @id,
|
|
36
|
+
role: "button",
|
|
37
|
+
data: {
|
|
38
|
+
state: "closed",
|
|
39
|
+
as_child: @as_child.to_s,
|
|
40
|
+
action: <<~HEREDOC,
|
|
41
|
+
click->shadcn-phlexcomponents--hover-card#toggle
|
|
42
|
+
mouseover->shadcn-phlexcomponents--hover-card#openWithDelay
|
|
43
|
+
mouseout->shadcn-phlexcomponents--hover-card#closeWithDelay
|
|
44
|
+
HEREDOC
|
|
45
|
+
"shadcn-phlexcomponents--hover-card-target": "trigger"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class Input < Base
|
|
5
|
+
STYLES = <<~HEREDOC
|
|
6
|
+
flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1
|
|
7
|
+
text-base shadow-sm transition-colors file:border-0 file:bg-transparent
|
|
8
|
+
file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground
|
|
9
|
+
focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring
|
|
10
|
+
disabled:cursor-not-allowed disabled:opacity-50 md:text-sm
|
|
11
|
+
HEREDOC
|
|
12
|
+
|
|
13
|
+
def initialize(type: :text, name: nil, id: nil, **attributes)
|
|
14
|
+
@type = type
|
|
15
|
+
@name = name
|
|
16
|
+
@id = id || @name
|
|
17
|
+
super(**attributes)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def default_attributes
|
|
21
|
+
{
|
|
22
|
+
type: @type,
|
|
23
|
+
name: @name,
|
|
24
|
+
id: @id,
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def view_template(&)
|
|
29
|
+
input(**@attributes, &)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
|
|
5
|
+
class Label < Base
|
|
6
|
+
STYLES = <<~HEREDOC
|
|
7
|
+
text-sm font-medium leading-none peer-disabled:cursor-not-allowed
|
|
8
|
+
peer-disabled:opacity-70 block
|
|
9
|
+
HEREDOC
|
|
10
|
+
|
|
11
|
+
def view_template(&)
|
|
12
|
+
label(**@attributes, &)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class Link < Base
|
|
5
|
+
STYLES = "font-medium underline underline-offset-4"
|
|
6
|
+
|
|
7
|
+
def initialize(name = nil, options = nil, html_options = nil)
|
|
8
|
+
@name = name
|
|
9
|
+
@options = options
|
|
10
|
+
@html_options = html_options
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def view_template(&)
|
|
14
|
+
@html_options, @options = @options, @name if block_given?
|
|
15
|
+
@html_options ||= {}
|
|
16
|
+
@html_options = mix(default_attributes, @html_options)
|
|
17
|
+
@html_options[:class] = TAILWIND_MERGER.merge("#{default_styles} #{@html_options[:class]}")
|
|
18
|
+
|
|
19
|
+
if block_given?
|
|
20
|
+
link_to(@options, @html_options, &)
|
|
21
|
+
else
|
|
22
|
+
link_to(@name, @options, @html_options)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class LoadingButton < Button
|
|
5
|
+
def default_attributes
|
|
6
|
+
{
|
|
7
|
+
type: @type,
|
|
8
|
+
data: {
|
|
9
|
+
controller: "shadcn-phlexcomponents--loading-button",
|
|
10
|
+
},
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def view_template(&)
|
|
15
|
+
button(**@attributes) do
|
|
16
|
+
icon("loader-circle", class: "animate-spin hidden group-aria-busy:inline")
|
|
17
|
+
yield
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class Pagination < Base
|
|
5
|
+
STYLES = "mx-auto flex w-full justify-center"
|
|
6
|
+
|
|
7
|
+
def link(**attributes, &)
|
|
8
|
+
PaginationLink(**attributes, &)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def previous(**attributes, &)
|
|
12
|
+
PaginationPrevious(**attributes, &)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def next(**attributes, &)
|
|
16
|
+
PaginationNext(**attributes, &)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def ellipsis(**attributes, &)
|
|
20
|
+
PaginationEllipsis(**attributes, &)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def default_attributes
|
|
24
|
+
{
|
|
25
|
+
role: "navigation",
|
|
26
|
+
aria: {
|
|
27
|
+
label: "navigation",
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def view_template(&)
|
|
33
|
+
div(**@attributes) do
|
|
34
|
+
ul(class: "flex flex-row items-center gap-1", &)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class PaginationEllipsis < Base
|
|
5
|
+
STYLES = "flex h-9 w-9 items-center justify-center"
|
|
6
|
+
|
|
7
|
+
def default_attributes
|
|
8
|
+
{
|
|
9
|
+
aria: {
|
|
10
|
+
hidden: "true"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def view_template
|
|
16
|
+
li do
|
|
17
|
+
span(**@attributes) do
|
|
18
|
+
icon("ellipsis", class: "size-4")
|
|
19
|
+
span(class: "sr-only") { "More pages" }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class PaginationLink < Base
|
|
5
|
+
def initialize(href: nil, active: false, **attributes)
|
|
6
|
+
@href = href
|
|
7
|
+
@active = active
|
|
8
|
+
super(**attributes)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def default_styles
|
|
12
|
+
if @active
|
|
13
|
+
Button.default_styles(variant: :outline, size: :icon)
|
|
14
|
+
else
|
|
15
|
+
Button.default_styles(variant: :ghost, size: :icon)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def default_attributes
|
|
20
|
+
{
|
|
21
|
+
href: @href,
|
|
22
|
+
aria: {
|
|
23
|
+
current: @active ? "page" : nil
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def view_template(&)
|
|
29
|
+
li do
|
|
30
|
+
a(**@attributes, &)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class PaginationNext < Base
|
|
5
|
+
def initialize(href: nil, **attributes)
|
|
6
|
+
@href = href
|
|
7
|
+
super(**attributes)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def default_styles
|
|
11
|
+
"#{Button.default_styles(variant: :ghost, size: :default)} gap-1 pr-2.5"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def default_attributes
|
|
15
|
+
{
|
|
16
|
+
href: @href,
|
|
17
|
+
aria: {
|
|
18
|
+
label: "Go to next page"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def view_template(&)
|
|
24
|
+
li do
|
|
25
|
+
a(**@attributes) do
|
|
26
|
+
span { "Next" }
|
|
27
|
+
icon("chevron-right", class: "size-4")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class PaginationPrevious < Base
|
|
5
|
+
def initialize(href: nil, **attributes)
|
|
6
|
+
@href = href
|
|
7
|
+
super(**attributes)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def default_attributes
|
|
11
|
+
{
|
|
12
|
+
href: @href,
|
|
13
|
+
aria: {
|
|
14
|
+
label: "Go to previous page"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def default_styles
|
|
20
|
+
"#{Button.default_styles(variant: :ghost, size: :default)} gap-1 pl-2.5"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def view_template(&)
|
|
24
|
+
li do
|
|
25
|
+
a(**@attributes) do
|
|
26
|
+
icon("chevron-left", class: "size-4")
|
|
27
|
+
span { "Previous" }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
|
|
5
|
+
class Popover < Base
|
|
6
|
+
STYLES = "inline-block".freeze
|
|
7
|
+
|
|
8
|
+
def initialize(side: :bottom, aria_id: "popover-#{SecureRandom.hex(5)}", **attributes)
|
|
9
|
+
@side = side
|
|
10
|
+
@aria_id = aria_id
|
|
11
|
+
super(**attributes)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def content(**attributes, &)
|
|
15
|
+
PopoverContent(side: @side, aria_id: @aria_id, **attributes, &)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def trigger(**attributes, &)
|
|
19
|
+
PopoverTrigger(aria_id: @aria_id, **attributes, &)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def default_attributes
|
|
23
|
+
{
|
|
24
|
+
data: {
|
|
25
|
+
controller: "shadcn-phlexcomponents--popover",
|
|
26
|
+
side: @side
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def view_template(&)
|
|
32
|
+
div(**@attributes, &)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class PopoverContent < Base
|
|
5
|
+
STYLES = <<~HEREDOC.freeze
|
|
6
|
+
z-50 rounded-md border w-72 bg-popover p-4 text-popover-foreground shadow-md outline-none
|
|
7
|
+
data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0
|
|
8
|
+
data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95
|
|
9
|
+
data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2
|
|
10
|
+
data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2
|
|
11
|
+
HEREDOC
|
|
12
|
+
|
|
13
|
+
def initialize(side: :bottom, aria_id: nil, **attributes)
|
|
14
|
+
@side = side
|
|
15
|
+
@aria_id = aria_id
|
|
16
|
+
super(**attributes)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def view_template(&)
|
|
20
|
+
div(class: 'hidden fixed top-0 left-0 w-max z-50', data: { "shadcn-phlexcomponents--popover-target": "contentWrapper" }) do
|
|
21
|
+
div(**@attributes, &)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def default_attributes
|
|
26
|
+
{
|
|
27
|
+
id: "#{@aria_id}-content",
|
|
28
|
+
tabindex: -1,
|
|
29
|
+
role: "dialog",
|
|
30
|
+
data: {
|
|
31
|
+
side: @side,
|
|
32
|
+
"shadcn-phlexcomponents--popover-target": "content"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
|
|
5
|
+
class PopoverTrigger < Base
|
|
6
|
+
def initialize(as_child: false, aria_id: nil, **attributes)
|
|
7
|
+
@as_child = as_child
|
|
8
|
+
@aria_id = aria_id
|
|
9
|
+
super(**attributes)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def view_template(&)
|
|
13
|
+
if @as_child
|
|
14
|
+
content = capture(&)
|
|
15
|
+
element = find_as_child(content.to_s)
|
|
16
|
+
|
|
17
|
+
vanish(&)
|
|
18
|
+
element_attributes = nokogiri_attributes_to_hash(element)
|
|
19
|
+
styles = TAILWIND_MERGER.merge("#{@attributes[:class]} #{element_attributes[:class]}")
|
|
20
|
+
merged_attributes = mix(@attributes, element_attributes)
|
|
21
|
+
merged_attributes[:class] = styles
|
|
22
|
+
|
|
23
|
+
if element.name == "button"
|
|
24
|
+
merged_attributes.delete(:role)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
send(element.name, **merged_attributes) do
|
|
28
|
+
sanitize_as_child(element.children.to_s)
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
div(**@attributes, &)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def default_attributes
|
|
36
|
+
{
|
|
37
|
+
id: @id,
|
|
38
|
+
role: "button",
|
|
39
|
+
aria: {
|
|
40
|
+
haspopup: "dialog",
|
|
41
|
+
expanded: false,
|
|
42
|
+
controls: "#{@aria_id}-content"
|
|
43
|
+
},
|
|
44
|
+
data: {
|
|
45
|
+
as_child: @as_child.to_s,
|
|
46
|
+
action: "click->shadcn-phlexcomponents--popover#toggle",
|
|
47
|
+
"shadcn-phlexcomponents--popover-target": "trigger"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class Progress < Base
|
|
5
|
+
STYLES = "relative h-2 w-full overflow-hidden rounded-full bg-primary/20"
|
|
6
|
+
|
|
7
|
+
def initialize(value: 0, **attributes)
|
|
8
|
+
@value = value
|
|
9
|
+
super(**attributes)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def default_attributes
|
|
13
|
+
{
|
|
14
|
+
role: "progressbar",
|
|
15
|
+
aria: {
|
|
16
|
+
valuemax: 100,
|
|
17
|
+
valuemin: 0,
|
|
18
|
+
valuenow: @value,
|
|
19
|
+
},
|
|
20
|
+
data: {
|
|
21
|
+
controller: "shadcn-phlexcomponents--progress",
|
|
22
|
+
"shadcn-phlexcomponents--progress-progress-value": @value
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def view_template
|
|
28
|
+
div(**@attributes) do
|
|
29
|
+
div(
|
|
30
|
+
class: "h-full w-full flex-1 bg-primary transition-all",
|
|
31
|
+
style: "transform: translateX(-#{100-@value}%)",
|
|
32
|
+
data: { "shadcn-phlexcomponents--progress-target": "bar"}
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class RadioGroup < Base
|
|
5
|
+
STYLES = "grid gap-2 outline-none"
|
|
6
|
+
|
|
7
|
+
def initialize(name: nil, value: nil, dir: "ltr", include_hidden: true, **attributes)
|
|
8
|
+
@name = name
|
|
9
|
+
@value = value
|
|
10
|
+
@dir = dir
|
|
11
|
+
@include_hidden = include_hidden
|
|
12
|
+
super(**attributes)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def item(name: nil, value: nil, **attributes)
|
|
16
|
+
RadioGroupItem(name: name || @name, value: value, checked: @value == value, **attributes)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def items(collection, value_method:, text_method:, wrapper_class: nil)
|
|
20
|
+
wrapper_class = TAILWIND_MERGER.merge("flex items-center space-x-2 #{wrapper_class}")
|
|
21
|
+
|
|
22
|
+
if collection.first && collection.first.is_a?(Hash)
|
|
23
|
+
collection = convert_collection_hash_to_struct(collection, value_method: value_method, text_method: text_method)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
collection.each do |item|
|
|
27
|
+
value = item.public_send(value_method)
|
|
28
|
+
text = item.public_send(text_method)
|
|
29
|
+
id = "#{@name.parameterize.underscore}_#{value}"
|
|
30
|
+
|
|
31
|
+
div(class: wrapper_class) do
|
|
32
|
+
RadioGroupItem(name: @name, value: value, checked: @value == value, id: id)
|
|
33
|
+
Label(for: id) { text }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def view_template(&)
|
|
39
|
+
div(**@attributes) do
|
|
40
|
+
if @include_hidden
|
|
41
|
+
input(type: "hidden", name: @name, autocomplete: "off")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
yield
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def default_attributes
|
|
49
|
+
{
|
|
50
|
+
role: "radiogroup",
|
|
51
|
+
dir: @dir,
|
|
52
|
+
aria: {
|
|
53
|
+
required: false,
|
|
54
|
+
},
|
|
55
|
+
data: {
|
|
56
|
+
controller: "shadcn-phlexcomponents--radio-group",
|
|
57
|
+
"shadcn-phlexcomponents--radio-group-selected-value": @value,
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|