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,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class TableCell < Base
|
5
|
+
STYLES = "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]".freeze
|
6
|
+
|
7
|
+
def view_template(&)
|
8
|
+
td(**@attributes, &)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class TableHead < Base
|
5
|
+
STYLES = <<~HEREDOC
|
6
|
+
h-10 px-2 text-left align-middle font-medium text-muted-foreground
|
7
|
+
[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]
|
8
|
+
HEREDOC
|
9
|
+
|
10
|
+
def view_template(&)
|
11
|
+
th(**@attributes, &)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class Tabs < Base
|
5
|
+
def initialize(value: nil, dir: "ltr", aria_id: "tabs-#{SecureRandom.hex(5)}", **attributes)
|
6
|
+
@dir = dir
|
7
|
+
@value = value
|
8
|
+
@aria_id = aria_id
|
9
|
+
super(**attributes)
|
10
|
+
end
|
11
|
+
|
12
|
+
def view_template(&)
|
13
|
+
div(**@attributes, &)
|
14
|
+
end
|
15
|
+
|
16
|
+
def default_attributes
|
17
|
+
{
|
18
|
+
dir: @dir,
|
19
|
+
data: {
|
20
|
+
controller: "shadcn-phlexcomponents--tabs",
|
21
|
+
"shadcn-phlexcomponents--tabs-selected-value": @value
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def list(**attributes, &)
|
27
|
+
TabsList(**attributes, &)
|
28
|
+
end
|
29
|
+
|
30
|
+
def trigger(**attributes, &)
|
31
|
+
TabsTrigger(aria_id: @aria_id, **attributes, &)
|
32
|
+
end
|
33
|
+
|
34
|
+
def content(**attributes, &)
|
35
|
+
TabsContent(aria_id: @aria_id, **attributes, &)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class TabsContent < Base
|
5
|
+
STYLES = <<~HEREDOC.freeze
|
6
|
+
mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2
|
7
|
+
focus-visible:ring-ring focus-visible:ring-offset-2 hidden
|
8
|
+
HEREDOC
|
9
|
+
|
10
|
+
def initialize(value: nil, aria_id: nil, **attributes)
|
11
|
+
@value = value
|
12
|
+
@aria_id = aria_id
|
13
|
+
super(**attributes)
|
14
|
+
end
|
15
|
+
|
16
|
+
def view_template(&)
|
17
|
+
div(**@attributes, &)
|
18
|
+
end
|
19
|
+
|
20
|
+
def default_attributes
|
21
|
+
{
|
22
|
+
id: "#{@aria_id}-content-#{@value}",
|
23
|
+
role: "tabpanel",
|
24
|
+
tabindex: "0",
|
25
|
+
aria: {
|
26
|
+
labelledby: "#{@aria_id}-trigger-#{@value}"
|
27
|
+
},
|
28
|
+
data: {
|
29
|
+
value: @value,
|
30
|
+
"shadcn-phlexcomponents--tabs-target": "content"
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class TabsList < Base
|
5
|
+
STYLES = <<~HEREDOC.freeze
|
6
|
+
inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground outline-none
|
7
|
+
HEREDOC
|
8
|
+
|
9
|
+
def view_template(&)
|
10
|
+
div(**@attributes, &)
|
11
|
+
end
|
12
|
+
|
13
|
+
def default_attributes
|
14
|
+
{
|
15
|
+
role: "tablist",
|
16
|
+
tabindex: "-1",
|
17
|
+
aria: {
|
18
|
+
orientation: "horizontal"
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class TabsTrigger < Base
|
5
|
+
STYLES = <<~HEREDOC.freeze
|
6
|
+
inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm
|
7
|
+
font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2
|
8
|
+
focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50
|
9
|
+
data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow
|
10
|
+
cursor-pointer
|
11
|
+
HEREDOC
|
12
|
+
|
13
|
+
def initialize(value: nil, aria_id: nil, **attributes)
|
14
|
+
@value = value
|
15
|
+
@aria_id = aria_id
|
16
|
+
super(**attributes)
|
17
|
+
end
|
18
|
+
|
19
|
+
def view_template(&)
|
20
|
+
button(**@attributes, &)
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_attributes
|
24
|
+
{
|
25
|
+
id: "#{@aria_id}-trigger-#{@value}",
|
26
|
+
role: "tab",
|
27
|
+
tabindex: "-1",
|
28
|
+
aria: {
|
29
|
+
controls: "#{@aria_id}-content-#{@value}",
|
30
|
+
selected: false,
|
31
|
+
},
|
32
|
+
data: {
|
33
|
+
"shadcn-phlexcomponents--tabs-target": "trigger",
|
34
|
+
value: @value,
|
35
|
+
state: "inactive",
|
36
|
+
action: <<~HEREDOC,
|
37
|
+
click->shadcn-phlexcomponents--tabs#setActiveTab
|
38
|
+
keydown.left->shadcn-phlexcomponents--tabs#setActiveToPrev:prevent
|
39
|
+
keydown.right->shadcn-phlexcomponents--tabs#setActiveToNext:prevent
|
40
|
+
HEREDOC
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class Textarea < Base
|
5
|
+
STYLES = <<~HEREDOC
|
6
|
+
flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3
|
7
|
+
py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none
|
8
|
+
focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm
|
9
|
+
HEREDOC
|
10
|
+
|
11
|
+
def initialize(name: nil, id: nil, **attributes)
|
12
|
+
@name = name
|
13
|
+
@id = id || @name
|
14
|
+
super(**attributes)
|
15
|
+
end
|
16
|
+
|
17
|
+
def default_attributes
|
18
|
+
{
|
19
|
+
name: @name,
|
20
|
+
id: @id,
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def view_template(&)
|
25
|
+
textarea(**@attributes, &)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class ThemeSwitcher < Base
|
5
|
+
def view_template
|
6
|
+
Button(variant: :ghost, size: :icon, **@attributes)do
|
7
|
+
icon("sun", class: "hidden dark:inline")
|
8
|
+
icon("moon", class: "inline dark:hidden")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_attributes
|
13
|
+
{
|
14
|
+
data: {
|
15
|
+
controller: "shadcn-phlexcomponents--theme-switcher",
|
16
|
+
action: "shadcn-phlexcomponents--theme-switcher#toggle",
|
17
|
+
},
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class Toast < Base
|
5
|
+
STYLES = <<~HEREDOC
|
6
|
+
group pointer-events-auto relative flex w-full items-center justify-between
|
7
|
+
space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all
|
8
|
+
data-[state=open]:animate-in data-[state=closed]:animate-out
|
9
|
+
data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full
|
10
|
+
data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full
|
11
|
+
HEREDOC
|
12
|
+
|
13
|
+
CLOSE_BUTTON_STYLES = <<~HEREDOC
|
14
|
+
absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity
|
15
|
+
hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100
|
16
|
+
group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400
|
17
|
+
group-[.destructive]:focus:ring-offset-red-600 cursor-pointer
|
18
|
+
HEREDOC
|
19
|
+
|
20
|
+
VARIANTS = {
|
21
|
+
default: "border bg-background text-foreground",
|
22
|
+
destructive: "destructive group border-destructive bg-destructive text-destructive-foreground",
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
def initialize(variant: :default, duration: 5000, **attributes)
|
26
|
+
@variant = variant
|
27
|
+
@duration = duration
|
28
|
+
super(**attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def title(**attributes, &)
|
32
|
+
ToastTitle(data: { title: ""}, **attributes, &)
|
33
|
+
end
|
34
|
+
|
35
|
+
def description(**attributes, &)
|
36
|
+
ToastDescription(data: { description: ""},**attributes, &)
|
37
|
+
end
|
38
|
+
|
39
|
+
def content(**attributes, &)
|
40
|
+
ToastContent(**attributes, &)
|
41
|
+
end
|
42
|
+
|
43
|
+
def action(**attributes, &)
|
44
|
+
ToastAction(variant: @variant, **attributes, &)
|
45
|
+
end
|
46
|
+
|
47
|
+
def action_to(name = nil, options = nil, html_options = nil, &block)
|
48
|
+
if block_given?
|
49
|
+
options ||= {}
|
50
|
+
options[:variant] = @variant
|
51
|
+
else
|
52
|
+
html_options ||= {}
|
53
|
+
html_options[:variant] = @variant
|
54
|
+
end
|
55
|
+
|
56
|
+
ToastActionTo(name, options, html_options, &block)
|
57
|
+
end
|
58
|
+
|
59
|
+
def default_styles
|
60
|
+
"#{STYLES} #{VARIANTS[@variant]}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def default_attributes
|
64
|
+
{
|
65
|
+
role: "status",
|
66
|
+
tabindex: 0,
|
67
|
+
aria: {
|
68
|
+
live: "off",
|
69
|
+
atomic: "true",
|
70
|
+
},
|
71
|
+
data: {
|
72
|
+
duration: @duration,
|
73
|
+
state: "open",
|
74
|
+
controller: "shadcn-phlexcomponents--toast",
|
75
|
+
action: <<~HEREDOC
|
76
|
+
focus->shadcn-phlexcomponents--toast#cancelDismiss
|
77
|
+
blur->shadcn-phlexcomponents--toast#dismiss
|
78
|
+
mouseover->shadcn-phlexcomponents--toast#cancelDismiss
|
79
|
+
mouseout->shadcn-phlexcomponents--toast#dismiss
|
80
|
+
keydown.esc->shadcn-phlexcomponents--toast#close
|
81
|
+
HEREDOC
|
82
|
+
}
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def view_template(&)
|
87
|
+
li(**@attributes) do
|
88
|
+
yield
|
89
|
+
button(type: "button",
|
90
|
+
class: CLOSE_BUTTON_STYLES,
|
91
|
+
data: {
|
92
|
+
action: "shadcn-phlexcomponents--toast#close",
|
93
|
+
}) do
|
94
|
+
|
95
|
+
icon("x", class: "size-4")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class ToastAction < Base
|
5
|
+
STYLES = <<~HEREDOC
|
6
|
+
inline-flex h-8 shrink-0 items-center justify-center rounded-md border
|
7
|
+
bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary
|
8
|
+
focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none
|
9
|
+
disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30
|
10
|
+
group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground
|
11
|
+
group-[.destructive]:focus:ring-destructive cursor-pointer
|
12
|
+
HEREDOC
|
13
|
+
|
14
|
+
def initialize(as_child: false, **attributes)
|
15
|
+
@as_child = as_child
|
16
|
+
super(**attributes)
|
17
|
+
end
|
18
|
+
|
19
|
+
def view_template(&)
|
20
|
+
if @as_child
|
21
|
+
content = capture(&)
|
22
|
+
element = find_as_child(content.to_s)
|
23
|
+
|
24
|
+
vanish(&)
|
25
|
+
|
26
|
+
element_attributes = nokogiri_attributes_to_hash(element)
|
27
|
+
merged_attributes = mix(@attributes, element_attributes)
|
28
|
+
merged_attributes[:class] = TAILWIND_MERGER.merge("#{STYLES} #{element_attributes[:class]}")
|
29
|
+
|
30
|
+
send(element.name, **merged_attributes) do
|
31
|
+
sanitize_as_child(element.children.to_s)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
button(**@attributes, &)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class ToastActionTo < ToastAction
|
5
|
+
def initialize(name = nil, options = nil, html_options = nil)
|
6
|
+
@name = name
|
7
|
+
@options = options
|
8
|
+
@html_options = html_options
|
9
|
+
end
|
10
|
+
|
11
|
+
def view_template(&)
|
12
|
+
@html_options, @options = @options, @name if block_given?
|
13
|
+
@html_options ||= {}
|
14
|
+
@variant = @html_options.delete(:variant) || :default
|
15
|
+
@html_options = mix(default_attributes, @html_options)
|
16
|
+
@html_options[:class] = TAILWIND_MERGER.merge("#{default_styles} #{@html_options[:class]}")
|
17
|
+
|
18
|
+
if block_given?
|
19
|
+
button_to(@options, @html_options, &)
|
20
|
+
else
|
21
|
+
button_to(@name, @options, @html_options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class ToastContainer < Base
|
5
|
+
STYLES = <<~HEREDOC
|
6
|
+
fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4
|
7
|
+
sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]
|
8
|
+
HEREDOC
|
9
|
+
|
10
|
+
def default_attributes
|
11
|
+
{
|
12
|
+
tabindex: -1,
|
13
|
+
data: {
|
14
|
+
controller: "shadcn-phlexcomponents--toast-container",
|
15
|
+
}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def view_template(&)
|
20
|
+
div(
|
21
|
+
role: "region",
|
22
|
+
tabindex: -1,
|
23
|
+
aria: {
|
24
|
+
label: "Notifications",
|
25
|
+
}
|
26
|
+
) do
|
27
|
+
ol(**@attributes) do
|
28
|
+
template(data: { variant: "default" }) { toast(:default) }
|
29
|
+
template(data: { variant: "destructive" }) { toast(:destructive) }
|
30
|
+
yield
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def toast(variant)
|
36
|
+
Toast(variant: variant) do |t|
|
37
|
+
t.content do
|
38
|
+
t.title { "" }
|
39
|
+
t.description { "" }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class Tooltip < Base
|
5
|
+
STYLES = "inline-block".freeze
|
6
|
+
|
7
|
+
def initialize(side: :top, aria_id: "tooltip-#{SecureRandom.hex(5)}", **attributes)
|
8
|
+
@side = side
|
9
|
+
@aria_id = aria_id
|
10
|
+
super(**attributes)
|
11
|
+
end
|
12
|
+
|
13
|
+
def trigger(**attributes, &)
|
14
|
+
render TooltipTrigger.new(aria_id: @aria_id, **attributes, &)
|
15
|
+
end
|
16
|
+
|
17
|
+
def content(**attributes, &)
|
18
|
+
render TooltipContent.new(side: @side, aria_id: @aria_id, **attributes, &)
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_attributes
|
22
|
+
{
|
23
|
+
data: {
|
24
|
+
controller: "shadcn-phlexcomponents--tooltip",
|
25
|
+
side: @side
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def view_template(&)
|
31
|
+
div(**@attributes, &)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class TooltipContent < Base
|
5
|
+
STYLES = <<~HEREDOC.freeze
|
6
|
+
z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground
|
7
|
+
animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0
|
8
|
+
data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2
|
9
|
+
data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2
|
10
|
+
HEREDOC
|
11
|
+
|
12
|
+
def initialize(side: :top, aria_id: nil, **attributes)
|
13
|
+
@side = side
|
14
|
+
@aria_id = aria_id
|
15
|
+
super(**attributes)
|
16
|
+
end
|
17
|
+
|
18
|
+
def view_template(&)
|
19
|
+
div(class: 'hidden fixed top-0 left-0 w-max z-50', data: { "shadcn-phlexcomponents--tooltip-target": "contentWrapper" }) do
|
20
|
+
div(**@attributes, &)
|
21
|
+
|
22
|
+
span(
|
23
|
+
id: "#{@aria_id}-content",
|
24
|
+
role: "tooltip",
|
25
|
+
class: "sr-only",
|
26
|
+
&
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_attributes
|
32
|
+
{
|
33
|
+
tabindex: -1,
|
34
|
+
data: {
|
35
|
+
side: @side,
|
36
|
+
"shadcn-phlexcomponents--tooltip-target": "content",
|
37
|
+
action: "mouseover->shadcn-phlexcomponents--tooltip#clearCloseTimer mouseout->shadcn-phlexcomponents--tooltip#closeWithDelay"
|
38
|
+
}
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShadcnPhlexcomponents
|
4
|
+
class TooltipTrigger < 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
|
+
send(element.name, **merged_attributes) do
|
23
|
+
sanitize_as_child(element.children.to_s)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
div(**@attributes, &)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_attributes
|
31
|
+
{
|
32
|
+
id: @id,
|
33
|
+
role: "button",
|
34
|
+
aria: {
|
35
|
+
describedby: "#{@aria_id}-content"
|
36
|
+
},
|
37
|
+
data: {
|
38
|
+
as_child: @as_child.to_s,
|
39
|
+
state: "closed",
|
40
|
+
action: <<~HEREDOC,
|
41
|
+
click->shadcn-phlexcomponents--tooltip#toggle
|
42
|
+
mouseover->shadcn-phlexcomponents--tooltip#openWithDelay
|
43
|
+
mouseout->shadcn-phlexcomponents--tooltip#closeWithDelay
|
44
|
+
HEREDOC
|
45
|
+
"shadcn-phlexcomponents--tooltip-target": "trigger"
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
components_path = File.expand_path("../components", __dir__)
|
4
|
+
components_install_path = Rails.root.join("vendor/shadcn_phlexcomponents")
|
5
|
+
stimulus_controllers_path = File.expand_path("../../app/javascript/controllers", __dir__)
|
6
|
+
stimulus_controllers_install_path = Rails.root.join("app/javascript/controllers/shadcn_phlexcomponents")
|
7
|
+
tailwindcss_animate_path = File.expand_path("../../app/assets/tailwind/tailwindcss-animate.css", __dir__)
|
8
|
+
tailwindcss_animate_install_path = Rails.root.join("app/assets/tailwind/shadcn_phlexcomponents/tailwindcss-animate.css")
|
9
|
+
|
10
|
+
directory(components_path, components_install_path)
|
11
|
+
directory(stimulus_controllers_path, stimulus_controllers_install_path)
|
12
|
+
copy_file(tailwindcss_animate_path, tailwindcss_animate_install_path)
|