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
|