phlex_ui 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/phlex_ui/alert/description.rb +17 -0
- data/lib/phlex_ui/alert/title.rb +17 -0
- data/lib/phlex_ui/alert.rb +36 -0
- data/lib/phlex_ui/alert_dialog/action.rb +17 -0
- data/lib/phlex_ui/alert_dialog/cancel.rb +21 -0
- data/lib/phlex_ui/alert_dialog/content.rb +45 -0
- data/lib/phlex_ui/alert_dialog/description.rb +17 -0
- data/lib/phlex_ui/alert_dialog/footer.rb +17 -0
- data/lib/phlex_ui/alert_dialog/header.rb +17 -0
- data/lib/phlex_ui/alert_dialog/title.rb +17 -0
- data/lib/phlex_ui/alert_dialog/trigger.rb +18 -0
- data/lib/phlex_ui/alert_dialog.rb +26 -0
- data/lib/phlex_ui/aspect_ratio.rb +33 -0
- data/lib/phlex_ui/avatar/fallback.rb +17 -0
- data/lib/phlex_ui/avatar/image.rb +26 -0
- data/lib/phlex_ui/avatar.rb +49 -0
- data/lib/phlex_ui/badge.rb +46 -62
- data/lib/phlex_ui/button.rb +86 -63
- data/lib/phlex_ui/card/content.rb +17 -0
- data/lib/phlex_ui/card/description.rb +17 -0
- data/lib/phlex_ui/card/footer.rb +17 -0
- data/lib/phlex_ui/card/header.rb +17 -0
- data/lib/phlex_ui/card/title.rb +17 -0
- data/lib/phlex_ui/card.rb +17 -0
- data/lib/phlex_ui/checkbox.rb +18 -0
- data/lib/phlex_ui/clipboard/popover.rb +36 -0
- data/lib/phlex_ui/clipboard/source.rb +19 -0
- data/lib/phlex_ui/clipboard/trigger.rb +20 -0
- data/lib/phlex_ui/clipboard.rb +39 -0
- data/lib/phlex_ui/codeblock.rb +105 -0
- data/lib/phlex_ui/collapsible/content.rb +18 -0
- data/lib/phlex_ui/collapsible/trigger.rb +19 -0
- data/lib/phlex_ui/collapsible.rb +25 -0
- data/lib/phlex_ui/context_menu/content.rb +25 -0
- data/lib/phlex_ui/context_menu/item.rb +66 -0
- data/lib/phlex_ui/context_menu/label.rb +24 -0
- data/lib/phlex_ui/context_menu/separator.rb +19 -0
- data/lib/phlex_ui/context_menu/trigger.rb +20 -0
- data/lib/phlex_ui/context_menu.rb +26 -0
- data/lib/phlex_ui/dialog/content.rb +78 -0
- data/lib/phlex_ui/dialog/description.rb +17 -0
- data/lib/phlex_ui/dialog/footer.rb +17 -0
- data/lib/phlex_ui/dialog/header.rb +17 -0
- data/lib/phlex_ui/dialog/middle.rb +17 -0
- data/lib/phlex_ui/dialog/title.rb +17 -0
- data/lib/phlex_ui/dialog/trigger.rb +19 -0
- data/lib/phlex_ui/dialog.rb +25 -0
- data/lib/phlex_ui/dropdown_menu/content.rb +22 -0
- data/lib/phlex_ui/dropdown_menu/item.rb +28 -0
- data/lib/phlex_ui/dropdown_menu/label.rb +17 -0
- data/lib/phlex_ui/dropdown_menu/separator.rb +19 -0
- data/lib/phlex_ui/dropdown_menu/trigger.rb +17 -0
- data/lib/phlex_ui/dropdown_menu.rb +26 -0
- data/lib/phlex_ui/form/item.rb +17 -0
- data/lib/phlex_ui/form/spacer.rb +17 -0
- data/lib/phlex_ui/form.rb +34 -0
- data/lib/phlex_ui/hint.rb +17 -0
- data/lib/phlex_ui/hover_card/content.rb +22 -0
- data/lib/phlex_ui/hover_card/trigger.rb +19 -0
- data/lib/phlex_ui/hover_card.rb +27 -0
- data/lib/phlex_ui/input.rb +29 -0
- data/lib/phlex_ui/input_error.rb +17 -0
- data/lib/phlex_ui/label.rb +17 -0
- data/lib/phlex_ui/link.rb +97 -0
- data/lib/phlex_ui/popover/content.rb +22 -0
- data/lib/phlex_ui/popover/trigger.rb +19 -0
- data/lib/phlex_ui/popover.rb +25 -0
- data/lib/phlex_ui/shortcut_key.rb +17 -0
- data/lib/phlex_ui/table/body.rb +17 -0
- data/lib/phlex_ui/table/builder.rb +77 -0
- data/lib/phlex_ui/table/caption.rb +17 -0
- data/lib/phlex_ui/table/cell.rb +17 -0
- data/lib/phlex_ui/table/footer.rb +17 -0
- data/lib/phlex_ui/table/head.rb +17 -0
- data/lib/phlex_ui/table/header.rb +17 -0
- data/lib/phlex_ui/table/row.rb +17 -0
- data/lib/phlex_ui/table.rb +19 -0
- data/lib/phlex_ui/tabs/content.rb +26 -0
- data/lib/phlex_ui/tabs/list.rb +17 -0
- data/lib/phlex_ui/tabs/trigger.rb +28 -0
- data/lib/phlex_ui/tabs.rb +25 -0
- data/lib/phlex_ui/theme_toggle.rb +41 -0
- data/lib/phlex_ui/tooltip/content.rb +22 -0
- data/lib/phlex_ui/tooltip/trigger.rb +17 -0
- data/lib/phlex_ui/tooltip.rb +25 -0
- data/lib/phlex_ui/typography/blockquote.rb +17 -0
- data/lib/phlex_ui/typography/h1.rb +17 -0
- data/lib/phlex_ui/typography/h2.rb +17 -0
- data/lib/phlex_ui/typography/h3.rb +17 -0
- data/lib/phlex_ui/typography/h4.rb +17 -0
- data/lib/phlex_ui/typography/inline_code.rb +17 -0
- data/lib/phlex_ui/typography/large.rb +17 -0
- data/lib/phlex_ui/typography/lead.rb +17 -0
- data/lib/phlex_ui/typography/list.rb +47 -0
- data/lib/phlex_ui/typography/list_item.rb +17 -0
- data/lib/phlex_ui/typography/muted.rb +17 -0
- data/lib/phlex_ui/typography/p.rb +17 -0
- data/lib/phlex_ui/typography/small.rb +17 -0
- metadata +112 -2
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Link < Base
|
|
5
|
+
def initialize(href: "#", variant: :link, size: :md, icon: false, **attrs)
|
|
6
|
+
@href = href
|
|
7
|
+
@variant = variant.to_sym
|
|
8
|
+
@size = size.to_sym
|
|
9
|
+
@icon = icon
|
|
10
|
+
super(**attrs)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def template(&)
|
|
14
|
+
a(href: @href, **attrs, &)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def size_classes
|
|
20
|
+
if @icon
|
|
21
|
+
case @size
|
|
22
|
+
when :sm then "h-6 w-6"
|
|
23
|
+
when :md then "h-9 w-9"
|
|
24
|
+
when :lg then "h-10 w-10"
|
|
25
|
+
when :xl then "h-12 w-12"
|
|
26
|
+
end
|
|
27
|
+
else
|
|
28
|
+
case @size
|
|
29
|
+
when :sm then "px-3 py-1.5 h-8 text-xs"
|
|
30
|
+
when :md then "px-4 py-2 h-9 text-sm"
|
|
31
|
+
when :lg then "px-4 py-2 h-10 text-base"
|
|
32
|
+
when :xl then "px-6 py-3 h-12 text-base"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def primary_classes
|
|
38
|
+
tokens(
|
|
39
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-text shadow hover:bg-primary/90",
|
|
40
|
+
size_classes
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def link_classes
|
|
45
|
+
tokens(
|
|
46
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 text-primary underline-offset-4 hover:underline",
|
|
47
|
+
size_classes
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def secondary_classes
|
|
52
|
+
tokens(
|
|
53
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-muted-background text-text shadow-sm hover:bg-opacity-80",
|
|
54
|
+
size_classes
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def destructive_classes
|
|
59
|
+
tokens(
|
|
60
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-destructive text-white shadow-sm hover:bg-destructive/90",
|
|
61
|
+
size_classes
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def outline_classes
|
|
66
|
+
tokens(
|
|
67
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 border border-input bg-background shadow-sm hover:bg-accent-background hover:text-accent-text",
|
|
68
|
+
size_classes
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def ghost_classes
|
|
73
|
+
tokens(
|
|
74
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 hover:bg-accent-background hover:text-accent-text",
|
|
75
|
+
size_classes
|
|
76
|
+
)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def default_classes
|
|
80
|
+
case @variant
|
|
81
|
+
when :primary then primary_classes
|
|
82
|
+
when :link then link_classes
|
|
83
|
+
when :secondary then secondary_classes
|
|
84
|
+
when :destructive then destructive_classes
|
|
85
|
+
when :outline then outline_classes
|
|
86
|
+
when :ghost then ghost_classes
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def default_attrs
|
|
91
|
+
{
|
|
92
|
+
type: "button",
|
|
93
|
+
class: default_classes,
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Popover::Content < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
template_tag(data: { popover_target: "content" }) do
|
|
7
|
+
div(**attrs, &)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def default_attrs
|
|
14
|
+
{
|
|
15
|
+
data: {
|
|
16
|
+
state: :open
|
|
17
|
+
},
|
|
18
|
+
class: "z-50 rounded-md border bg-background p-2 text-text shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Popover < Base
|
|
5
|
+
def initialize(options: {}, **attrs)
|
|
6
|
+
@options = options
|
|
7
|
+
super(**attrs)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def template(&)
|
|
11
|
+
div(**attrs, &)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def default_attrs
|
|
17
|
+
{
|
|
18
|
+
data: {
|
|
19
|
+
controller: "popover",
|
|
20
|
+
popover_options_value: @options.to_json
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class ShortcutKey < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
kbd(**attrs, &)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def default_attrs
|
|
12
|
+
{
|
|
13
|
+
class: "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted-background px-1.5 font-mono text-[10px] font-medium text-muted-text opacity-100"
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Table::Builder < Base
|
|
5
|
+
include Phlex::DeferredRender
|
|
6
|
+
|
|
7
|
+
Column = Struct.new(:header, :header_attrs, :footer, :footer_attrs, :block, keyword_init: true)
|
|
8
|
+
|
|
9
|
+
def initialize(records = [], caption: nil, **attrs)
|
|
10
|
+
@records = records
|
|
11
|
+
@columns = []
|
|
12
|
+
@caption = caption
|
|
13
|
+
super(**attrs)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def template(&block)
|
|
17
|
+
render PhlexUI::Table.new(**attrs) do
|
|
18
|
+
header
|
|
19
|
+
body
|
|
20
|
+
caption if @caption
|
|
21
|
+
footer if @columns.any?(&:footer)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def column(header, footer = nil, header_attrs: {}, footer_attrs: {}, &block)
|
|
26
|
+
@columns << Column.new(
|
|
27
|
+
header: header,
|
|
28
|
+
header_attrs: header_attrs,
|
|
29
|
+
footer: footer,
|
|
30
|
+
footer_attrs: footer_attrs,
|
|
31
|
+
block: block
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def header
|
|
36
|
+
render PhlexUI::Table::Header.new do
|
|
37
|
+
render PhlexUI::Table::Row.new do
|
|
38
|
+
@columns.each do |column|
|
|
39
|
+
render PhlexUI::Table::Head.new(**column.header_attrs) do
|
|
40
|
+
column.header
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def body
|
|
48
|
+
render PhlexUI::Table::Body.new do
|
|
49
|
+
@records.each do |record|
|
|
50
|
+
render PhlexUI::Table::Row.new do
|
|
51
|
+
@columns.each do |column|
|
|
52
|
+
render PhlexUI::Table::Cell.new do
|
|
53
|
+
column.block.call(record)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def footer
|
|
62
|
+
render PhlexUI::Table::Footer.new do
|
|
63
|
+
render PhlexUI::Table::Row.new do
|
|
64
|
+
@columns.each do |column|
|
|
65
|
+
render PhlexUI::Table::Head.new(**column.footer_attrs) do
|
|
66
|
+
column.footer
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def caption
|
|
74
|
+
render PhlexUI::Table::Caption.new { @caption }
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Table::Cell < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
td(**attrs, &)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def default_attrs
|
|
12
|
+
{
|
|
13
|
+
class: "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]"
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Table::Footer < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
tfoot(**attrs, &)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def default_attrs
|
|
12
|
+
{
|
|
13
|
+
class: "border-t bg-muted-background bg-opacity-50 font-medium[& amp;>tr]:last:border-b-0"
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Table::Head < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
th(**attrs, &)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def default_attrs
|
|
12
|
+
{
|
|
13
|
+
class: "h-10 px-2 text-left align-middle font-medium text-muted-text [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]"
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Table::Row < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
tr(**attrs, &)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def default_attrs
|
|
12
|
+
{
|
|
13
|
+
class: "border-b transition-colors hover:bg-muted-background hover:bg-opacity-50 data-[state=selected]:bg-muted-background"
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Table < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
div(class: "relative w-full overflow-auto") do
|
|
7
|
+
table(**attrs, &)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def default_attrs
|
|
14
|
+
{
|
|
15
|
+
class: "w-full caption-bottom text-sm"
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Tabs::Content < Base
|
|
5
|
+
def initialize(value:, **attrs)
|
|
6
|
+
@value = value
|
|
7
|
+
super(**attrs)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def template(&)
|
|
11
|
+
div(**attrs, &)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def default_attrs
|
|
17
|
+
{
|
|
18
|
+
data: {
|
|
19
|
+
tabs_target: :content,
|
|
20
|
+
value: @value
|
|
21
|
+
},
|
|
22
|
+
class: "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 hidden",
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Tabs::List < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
div(**attrs, &)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def default_attrs
|
|
12
|
+
{
|
|
13
|
+
class: "inline-flex h-9 items-center justify-center rounded-lg bg-muted-background p-1 text-muted-text"
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Tabs::Trigger < Base
|
|
5
|
+
def initialize(value:, **attrs)
|
|
6
|
+
@value = value
|
|
7
|
+
super(**attrs)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def template(&)
|
|
11
|
+
button(**attrs, &)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def default_attrs
|
|
17
|
+
{
|
|
18
|
+
type: :button,
|
|
19
|
+
data: {
|
|
20
|
+
tabs_target: :trigger,
|
|
21
|
+
action: "click->tabs#show",
|
|
22
|
+
value: @value
|
|
23
|
+
},
|
|
24
|
+
class: "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-text data-[state=active]:shadow"
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Tabs < Base
|
|
5
|
+
def initialize(default: nil, **attrs)
|
|
6
|
+
@default = default
|
|
7
|
+
super(**attrs)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def template(&)
|
|
11
|
+
div(**attrs, &)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def default_attrs
|
|
17
|
+
{
|
|
18
|
+
data: {
|
|
19
|
+
controller: 'tabs',
|
|
20
|
+
tabs_default_value_value: @default
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class ThemeToggle < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
div(**attrs, &)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def light_mode(**user_attrs, &)
|
|
10
|
+
light_attrs = PhlexUI::AttributeMerger.new(default_light_attrs, user_attrs).call
|
|
11
|
+
div(**light_attrs, &)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def dark_mode(**user_attrs, &)
|
|
15
|
+
dark_attrs = PhlexUI::AttributeMerger.new(default_dark_attrs, user_attrs).call
|
|
16
|
+
div(**dark_attrs, &)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def default_attrs
|
|
22
|
+
{
|
|
23
|
+
data: { controller: 'toggle-theme' }
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def default_light_attrs
|
|
28
|
+
{
|
|
29
|
+
class: 'dark:hidden',
|
|
30
|
+
data: { action: 'click->toggle-theme#setDarkTheme' }
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def default_dark_attrs
|
|
35
|
+
{
|
|
36
|
+
class: 'hidden dark:inline-block',
|
|
37
|
+
data: { action: 'click->toggle-theme#setLightTheme' }
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Tooltip::Content < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
template_tag(data: { popover_target: "content" }) do
|
|
7
|
+
div(**attrs, &)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def default_attrs
|
|
14
|
+
{
|
|
15
|
+
data: {
|
|
16
|
+
state: :open # used for animate-in and animate-out on tooltip
|
|
17
|
+
},
|
|
18
|
+
class: "z-50 rounded-md text-sm border bg-background px-2 py-0.5 text-text shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Tooltip < Base
|
|
5
|
+
def initialize(options: {}, **attrs)
|
|
6
|
+
@options = options
|
|
7
|
+
super(**attrs)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def template(&)
|
|
11
|
+
div(**attrs, &)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def default_attrs
|
|
17
|
+
{
|
|
18
|
+
data: {
|
|
19
|
+
controller: "popover",
|
|
20
|
+
popover_options_value: @options.to_json
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Typography::H1 < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
h1(**attrs, &)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def default_attrs
|
|
12
|
+
{
|
|
13
|
+
class: "scroll-m-20 text-3xl font-semibold leading-normal lg:leading-normal tracking-tight lg:text-4xl"
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PhlexUI
|
|
4
|
+
class Typography::H2 < Base
|
|
5
|
+
def template(&)
|
|
6
|
+
h2(**attrs, &)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def default_attrs
|
|
12
|
+
{
|
|
13
|
+
class: "scroll-m-20 text-3xl font-semibold tracking-tight transition-colors first:mt-0"
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|