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,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class SheetTitle < Base
|
|
5
|
+
STYLES = "text-lg font-semibold text-foreground".freeze
|
|
6
|
+
|
|
7
|
+
def initialize(aria_id: nil, **attributes)
|
|
8
|
+
@aria_id = aria_id
|
|
9
|
+
super(**attributes)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def default_attributes
|
|
13
|
+
{
|
|
14
|
+
id: "#{@aria_id}-title"
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def view_template(&)
|
|
19
|
+
h2(**@attributes, &)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class SheetTrigger < Base
|
|
5
|
+
def initialize(as_child: false, aria_id: nil, **attributes)
|
|
6
|
+
@as_child = as_child
|
|
7
|
+
@aria_id = aria_id
|
|
8
|
+
super(**attributes)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def view_template(&)
|
|
12
|
+
if @as_child
|
|
13
|
+
content = capture(&)
|
|
14
|
+
element = find_as_child(content.to_s)
|
|
15
|
+
|
|
16
|
+
vanish(&)
|
|
17
|
+
element_attributes = nokogiri_attributes_to_hash(element)
|
|
18
|
+
styles = TAILWIND_MERGER.merge("#{@attributes[:class]} #{element_attributes[:class]}")
|
|
19
|
+
merged_attributes = mix(@attributes, element_attributes)
|
|
20
|
+
merged_attributes[:class] = styles
|
|
21
|
+
|
|
22
|
+
if element.name == "button"
|
|
23
|
+
merged_attributes.delete(:role)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
send(element.name, **merged_attributes) do
|
|
27
|
+
sanitize_as_child(element.children.to_s)
|
|
28
|
+
end
|
|
29
|
+
else
|
|
30
|
+
div(**@attributes, &)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def default_attributes
|
|
35
|
+
{
|
|
36
|
+
role: "button",
|
|
37
|
+
aria: {
|
|
38
|
+
haspopup: "dialog",
|
|
39
|
+
expanded: false,
|
|
40
|
+
controls: "#{@aria_id}-content"
|
|
41
|
+
},
|
|
42
|
+
data: {
|
|
43
|
+
as_child: @as_child.to_s,
|
|
44
|
+
action: "click->shadcn-phlexcomponents--sheet#open",
|
|
45
|
+
"shadcn-phlexcomponents--sheet-target": "trigger"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class Sidebar < Base
|
|
5
|
+
STYLES = <<~HEREDOC
|
|
6
|
+
bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col
|
|
7
|
+
group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border
|
|
8
|
+
group-data-[variant=floating]:shadow
|
|
9
|
+
HEREDOC
|
|
10
|
+
|
|
11
|
+
PANEL_STYLES = {
|
|
12
|
+
sidebar: "group-data-[side=left]:border-r group-data-[side=right]:border-l",
|
|
13
|
+
floating: "p-2",
|
|
14
|
+
inset: "p-2"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
def initialize(id:, variant: :sidebar, side: :left, width: "16rem", expanded: true, **attributes)
|
|
18
|
+
@id = id
|
|
19
|
+
@variant = variant
|
|
20
|
+
@side = side
|
|
21
|
+
@width = width
|
|
22
|
+
@expanded = expanded
|
|
23
|
+
super(**attributes)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def header(**attributes, &)
|
|
27
|
+
SidebarHeader(**attributes, &)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def content(**attributes, &)
|
|
31
|
+
SidebarContent(**attributes, &)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def group(**attributes, &)
|
|
35
|
+
SidebarGroup(**attributes, &)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def group_content(**attributes, &)
|
|
39
|
+
SidebarGroupContent(**attributes, &)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def group_label(**attributes, &)
|
|
43
|
+
SidebarGroupLabel(**attributes, &)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def menu(**attributes, &)
|
|
47
|
+
SidebarMenu(**attributes, &)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def menu_item(**attributes, &)
|
|
51
|
+
SidebarMenuItem(**attributes, &)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def menu_button(**attributes, &)
|
|
55
|
+
SidebarMenuButton(**attributes, &)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def menu_sub(**attributes, &)
|
|
59
|
+
SidebarMenuSub(**attributes, &)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def menu_sub_item(**attributes, &)
|
|
63
|
+
SidebarMenuSubItem(**attributes, &)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def menu_sub_button(**attributes, &)
|
|
67
|
+
SidebarMenuSubButton(**attributes, &)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def footer(**attributes, &)
|
|
71
|
+
SidebarFooter(**attributes, &)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def view_template(&)
|
|
75
|
+
div(id: @id,
|
|
76
|
+
class: "group peer hidden md:block",
|
|
77
|
+
style: { "--sidebar-width": @width },
|
|
78
|
+
data: {
|
|
79
|
+
side: @side,
|
|
80
|
+
variant: @variant,
|
|
81
|
+
collapsible: @expanded ? "" : "offcanvas",
|
|
82
|
+
sidebar_id: @sidebar_id,
|
|
83
|
+
state: @expanded ? "expanded" : "collapsed",
|
|
84
|
+
controller: "shadcn-phlexcomponents--sidebar"
|
|
85
|
+
}) do
|
|
86
|
+
div(class: "relative h-svh w-[var(--sidebar-width)] bg-transparent transition-[width] duration-200
|
|
87
|
+
ease-linear group-data-[collapsible=offcanvas]:w-0 group-data-[side=right]:rotate-180
|
|
88
|
+
group-data-[collapsible=icon]:w-[--sidebar-width-icon]", data: { "shadcn-phlexcomponents--sidebar-target": "panelOffset" })
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
div(class: "fixed inset-y-0 z-10 hidden h-svh w-[var(--sidebar-width)] transition-[left,right,width] duration-200
|
|
92
|
+
ease-linear md:flex left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]
|
|
93
|
+
group-data-[collapsible=icon]:w-[--sidebar-width-icon] #{PANEL_STYLES[@variant]}",
|
|
94
|
+
data: {
|
|
95
|
+
"shadcn-phlexcomponents--sidebar-target": "panel"
|
|
96
|
+
}) do
|
|
97
|
+
|
|
98
|
+
div(**@attributes, &)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class SidebarContainer < Base
|
|
5
|
+
STYLES = "group/sidebar-wrapper text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar flex min-h-svh w-full"
|
|
6
|
+
|
|
7
|
+
def view_template(&)
|
|
8
|
+
div(**@attributes, &)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class SidebarGroupLabel < Base
|
|
5
|
+
STYLES = <<~HEREDOC
|
|
6
|
+
text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center
|
|
7
|
+
rounded-md px-2 text-xs font-medium outline-none transition-[margin,opa]
|
|
8
|
+
duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0
|
|
9
|
+
group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0
|
|
10
|
+
HEREDOC
|
|
11
|
+
|
|
12
|
+
def view_template(&)
|
|
13
|
+
div(**@attributes, &)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class SidebarInset < Base
|
|
5
|
+
STYLES = <<~HEREDOC
|
|
6
|
+
relative flex min-h-svh flex-1 flex-col bg-background peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))]
|
|
7
|
+
md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2
|
|
8
|
+
md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow
|
|
9
|
+
HEREDOC
|
|
10
|
+
|
|
11
|
+
def view_template(&)
|
|
12
|
+
main(**@attributes, &)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class SidebarMenuButton < Base
|
|
5
|
+
STYLES = <<~HEREDOC
|
|
6
|
+
peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left
|
|
7
|
+
text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground
|
|
8
|
+
focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground
|
|
9
|
+
disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8
|
|
10
|
+
aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent
|
|
11
|
+
data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent
|
|
12
|
+
data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2!
|
|
13
|
+
[&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 cursor-pointer
|
|
14
|
+
HEREDOC
|
|
15
|
+
|
|
16
|
+
SIZES = {
|
|
17
|
+
default: "h-8 text-sm",
|
|
18
|
+
sm: "h-7 text-xs",
|
|
19
|
+
lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
def initialize(size: :default, type: :button, active: false, as_child: false, **attributes)
|
|
23
|
+
@type = type
|
|
24
|
+
@size = size
|
|
25
|
+
@active = active
|
|
26
|
+
@as_child = as_child
|
|
27
|
+
super(**attributes)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def default_attributes
|
|
31
|
+
{
|
|
32
|
+
data: {
|
|
33
|
+
active: @active.to_s
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def default_styles
|
|
39
|
+
"#{STYLES} #{SIZES[@size]}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def view_template(&)
|
|
43
|
+
if @as_child
|
|
44
|
+
content = capture(&)
|
|
45
|
+
element = find_as_child(content.to_s)
|
|
46
|
+
|
|
47
|
+
vanish(&)
|
|
48
|
+
element_attributes = nokogiri_attributes_to_hash(element)
|
|
49
|
+
styles = TAILWIND_MERGER.merge("#{@attributes[:class]} #{element_attributes[:class]}")
|
|
50
|
+
merged_attributes = mix(@attributes, element_attributes)
|
|
51
|
+
merged_attributes[:class] = styles
|
|
52
|
+
|
|
53
|
+
send(element.name, **merged_attributes) do
|
|
54
|
+
sanitize_as_child(element.children.to_s)
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
button(**@attributes, &)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class SidebarMenuSub < Base
|
|
5
|
+
STYLES = <<~HEREDOC
|
|
6
|
+
border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col
|
|
7
|
+
gap-1 border-l px-2.5 py-0.5 group-data-[collapsible=icon]:hidden
|
|
8
|
+
HEREDOC
|
|
9
|
+
|
|
10
|
+
def view_template(&)
|
|
11
|
+
ul(**@attributes, &)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class SidebarMenuSubButton < Base
|
|
5
|
+
STYLES = <<~HEREDOC
|
|
6
|
+
text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground
|
|
7
|
+
active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground
|
|
8
|
+
flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-none
|
|
9
|
+
focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none
|
|
10
|
+
aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0
|
|
11
|
+
data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground
|
|
12
|
+
text-sm group-data-[collapsible=icon]:hidden cursor-pointer
|
|
13
|
+
HEREDOC
|
|
14
|
+
|
|
15
|
+
def initialize(type: :button, active: false, as_child: false, **attributes)
|
|
16
|
+
@active = active
|
|
17
|
+
@as_child = as_child
|
|
18
|
+
super(**attributes)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def default_attributes
|
|
22
|
+
{
|
|
23
|
+
data: {
|
|
24
|
+
active: @active.to_s
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def view_template(&)
|
|
30
|
+
if @as_child
|
|
31
|
+
content = capture(&)
|
|
32
|
+
element = find_as_child(content.to_s)
|
|
33
|
+
|
|
34
|
+
vanish(&)
|
|
35
|
+
element_attributes = nokogiri_attributes_to_hash(element)
|
|
36
|
+
styles = TAILWIND_MERGER.merge("#{@attributes[:class]} #{element_attributes[:class]}")
|
|
37
|
+
merged_attributes = mix(@attributes, element_attributes)
|
|
38
|
+
merged_attributes[:class] = styles
|
|
39
|
+
|
|
40
|
+
send(element.name, **merged_attributes) do
|
|
41
|
+
sanitize_as_child(element.children.to_s)
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
button(**@attributes, &)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class SidebarTrigger < Base
|
|
5
|
+
STYLES = <<~HEREDOC
|
|
6
|
+
inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md
|
|
7
|
+
text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none
|
|
8
|
+
focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none
|
|
9
|
+
disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-accent
|
|
10
|
+
hover:text-accent-foreground h-7 w-7 -ml-1 cursor-pointer
|
|
11
|
+
HEREDOC
|
|
12
|
+
|
|
13
|
+
def initialize(sidebar_id:, **attributes)
|
|
14
|
+
@sidebar_id = sidebar_id
|
|
15
|
+
super(**attributes)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def default_attributes
|
|
19
|
+
{
|
|
20
|
+
data: {
|
|
21
|
+
sidebar_id: @sidebar_id,
|
|
22
|
+
controller: "shadcn-phlexcomponents--sidebar-trigger",
|
|
23
|
+
action: "click->shadcn-phlexcomponents--sidebar-trigger#toggle"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def view_template(&)
|
|
29
|
+
button(**@attributes) do
|
|
30
|
+
if block_given?
|
|
31
|
+
yield
|
|
32
|
+
else
|
|
33
|
+
icon("panel-left", class: "")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
span(class: "sr-only") { "Toggle Sidebar" }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class Switch < Base
|
|
5
|
+
STYLES = <<~HEREDOC.freeze
|
|
6
|
+
peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full
|
|
7
|
+
border-2 border-transparent transition-colors focus-visible:outline-none
|
|
8
|
+
focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
|
|
9
|
+
focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50
|
|
10
|
+
data-[checked=true]:bg-primary data-[checked=false]:bg-input group/switch
|
|
11
|
+
HEREDOC
|
|
12
|
+
|
|
13
|
+
def initialize(name: nil, value: "1", unchecked_value: "0", checked: false, id: nil, include_hidden: true, **attributes)
|
|
14
|
+
@name = name
|
|
15
|
+
@value = value
|
|
16
|
+
@unchecked_value = unchecked_value
|
|
17
|
+
@checked = checked
|
|
18
|
+
@id = id || name
|
|
19
|
+
@include_hidden = include_hidden
|
|
20
|
+
super(**attributes)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def view_template(&)
|
|
24
|
+
button(**@attributes) do
|
|
25
|
+
span(class: "pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg
|
|
26
|
+
ring-0 transition-transform group-data-[checked=true]/switch:translate-x-5
|
|
27
|
+
group-data-[checked=false]/switch:translate-x-0")
|
|
28
|
+
|
|
29
|
+
if @include_hidden
|
|
30
|
+
input(name: @name, type: "hidden", value: @unchecked_value, autocomplete: "off")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
input(
|
|
34
|
+
type: "checkbox",
|
|
35
|
+
value: @value,
|
|
36
|
+
class: "-translate-x-full pointer-events-none absolute top-0 left-0 size-4 opacity-0",
|
|
37
|
+
name: @name,
|
|
38
|
+
tabindex: -1,
|
|
39
|
+
checked: @checked,
|
|
40
|
+
aria: { hidden: true },
|
|
41
|
+
data: {
|
|
42
|
+
"shadcn-phlexcomponents--switch-target": "input"
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def default_attributes
|
|
49
|
+
{
|
|
50
|
+
id: @id,
|
|
51
|
+
type: "button",
|
|
52
|
+
role: "switch",
|
|
53
|
+
aria: {
|
|
54
|
+
checked: @checked.to_s,
|
|
55
|
+
},
|
|
56
|
+
data: {
|
|
57
|
+
checked: @checked.to_s,
|
|
58
|
+
controller: "shadcn-phlexcomponents--switch",
|
|
59
|
+
action: "click->shadcn-phlexcomponents--switch#toggle",
|
|
60
|
+
"shadcn-phlexcomponents--switch-checked-value": @checked,
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShadcnPhlexcomponents
|
|
4
|
+
class Table < Base
|
|
5
|
+
STYLES = "w-full caption-bottom text-sm".freeze
|
|
6
|
+
|
|
7
|
+
def initialize( **attributes)
|
|
8
|
+
@columns = []
|
|
9
|
+
super(**attributes)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def view_template(&)
|
|
13
|
+
table(**@attributes, &)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def header(**attributes, &)
|
|
17
|
+
TableHeader(**attributes, &)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def caption(**attributes, &)
|
|
21
|
+
TableCaption(**attributes, &)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def row(**attributes, &)
|
|
25
|
+
TableRow(**attributes, &)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def head(**attributes, &)
|
|
29
|
+
TableHead(**attributes, &)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def body(**attributes, &)
|
|
33
|
+
TableBody(**attributes, &)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def cell(**attributes, &)
|
|
37
|
+
TableCell(**attributes, &)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def footer(**attributes, &)
|
|
41
|
+
TableFooter(**attributes, &)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def rows(rows, &)
|
|
45
|
+
@rows = rows
|
|
46
|
+
|
|
47
|
+
vanish(&)
|
|
48
|
+
|
|
49
|
+
thead(class: TableHeader::STYLES) do
|
|
50
|
+
tr(class: TableRow::STYLES) do
|
|
51
|
+
@columns.each do |column|
|
|
52
|
+
th(class: TAILWIND_MERGER.merge("#{TableHead::STYLES} #{column[:head_class]}")) { column[:header] }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
tbody(class: TableBody::STYLES) do
|
|
58
|
+
@rows.each do |row|
|
|
59
|
+
tr(class: TableRow::STYLES) do
|
|
60
|
+
@columns.each do |column|
|
|
61
|
+
td(class: TAILWIND_MERGER.merge("#{TableCell::STYLES} #{column[:cell_class]}")) { column[:content].call(row) }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def column(header, head_class: nil, cell_class: nil, &content)
|
|
69
|
+
@columns << { header:, head_class:, cell_class:, content: }
|
|
70
|
+
nil
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|