Skip to content

Commit 634ba80

Browse files
authored
Migrate the themes components to align with Phlex conversions (#170)
1 parent 34b4988 commit 634ba80

24 files changed

+747
-723
lines changed

app/components/themes/copy_code.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# frozen_string_literal: true
2+
3+
module Components
4+
module Themes
5+
class CopyCode < Components::Base
6+
def initialize(theme:)
7+
@theme = theme
8+
end
9+
10+
def view_template
11+
style do
12+
Theme::CSS.retrieve(@theme, with_directive: false)
13+
end
14+
Sheet do
15+
SheetTrigger do
16+
Button(variant: :primary) { "Copy Code" }
17+
end
18+
SheetContent(class: "sm:max-w-md w-screen flex flex-col h-screen overflow-y-scroll") do
19+
SheetHeader do
20+
SheetTitle { "Theme" }
21+
SheetDescription { "Copy and paste the following code into your CSS file." }
22+
end
23+
SheetMiddle(class: "flex-1 relative") do
24+
Codeblock(Theme::CSS.retrieve(@theme, with_directive: true), syntax: :css, class: "h-full max-h-none")
25+
end
26+
end
27+
end
28+
end
29+
end
30+
end
31+
end
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# frozen_string_literal: true
2+
3+
module Components
4+
module Themes
5+
class CustomizePopover < Components::Base
6+
def initialize(theme:)
7+
@theme = theme
8+
end
9+
10+
def view_template
11+
Popover(options: {trigger: "click", placement: "bottom-end"}) do
12+
PopoverTrigger do
13+
Button(variant: :outline) do
14+
color_swatch_icon
15+
plain "Customize Theme"
16+
end
17+
end
18+
PopoverContent(class: "w-96 p-6") do
19+
div(class: "space-y-0") do
20+
Text(size: "4", weight: "semibold") { "Customize" }
21+
Text(class: "text-muted-foreground") { "Choose how your app looks" }
22+
end
23+
div(class: "grid grid-cols-3 gap-2 mt-4") do
24+
Theme::CSS.all_themes.each do |name, color_hash|
25+
render_color_picker(name, color_hash, selected: name.to_s.downcase == @theme)
26+
end
27+
end
28+
end
29+
end
30+
end
31+
32+
private
33+
34+
def render_color_picker(name, color_hash, selected: false)
35+
Link(href: theme_path(name&.downcase), variant: :outline, class: ["!justify-start", ("ring-neutral-950 ring-1" if selected)]) do
36+
div(class: "w-4 h-4 rounded-full shrink-0 mr-2 ring-white dark:hidden", style: "background-color: hsl(#{color_hash[:root][:primary].split.join(",")})") do
37+
end
38+
div(class: "w-4 h-4 rounded-full shrink-0 mr-2 ring-white hidden dark:block", style: "background-color: hsl(#{color_hash[:dark][:primary].split.join(",")})") do
39+
end
40+
plain name&.capitalize
41+
end
42+
end
43+
44+
def color_swatch_icon
45+
svg(
46+
xmlns: "http://www.w3.org/2000/svg",
47+
fill: "currentColor",
48+
viewbox: "0 0 256 256",
49+
class: "w-5 h-5 shrink-0 mr-2 -ml-1"
50+
) do |s|
51+
s.path(
52+
d:
53+
"M200.77,53.89A103.27,103.27,0,0,0,128,24h-1.07A104,104,0,0,0,24,128c0,43,26.58,79.06,69.36,94.17A32,32,0,0,0,136,192a16,16,0,0,1,16-16h46.21a31.81,31.81,0,0,0,31.2-24.88,104.43,104.43,0,0,0,2.59-24A103.28,103.28,0,0,0,200.77,53.89Zm13,93.71A15.89,15.89,0,0,1,198.21,160H152a32,32,0,0,0-32,32,16,16,0,0,1-21.31,15.07C62.49,194.3,40,164,40,128a88,88,0,0,1,87.09-88h.9a88.35,88.35,0,0,1,88,87.25A88.86,88.86,0,0,1,213.81,147.6ZM140,76a12,12,0,1,1-12-12A12,12,0,0,1,140,76ZM96,100A12,12,0,1,1,84,88,12,12,0,0,1,96,100Zm0,56a12,12,0,1,1-12-12A12,12,0,0,1,96,156Zm88-56a12,12,0,1,1-12-12A12,12,0,0,1,184,100Z"
54+
)
55+
end
56+
end
57+
end
58+
end
59+
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module Components
2+
module Themes
3+
module Grid
4+
class Calendar < Components::Base
5+
def view_template
6+
div(class: "space-y-4 w-full") do
7+
Input(type: "string", placeholder: "Select a date", class: "rounded-md border shadow", id: "formatted-date", data_controller: "input")
8+
Calendar(input_id: "#formatted-date", date_format: "PPPP", class: "rounded-md border shadow")
9+
end
10+
end
11+
end
12+
end
13+
end
14+
end

app/components/themes/grid/card.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module Components
2+
module Themes
3+
module Grid
4+
class Card < Components::Base
5+
def view_template
6+
RubyUI::Card(class: "w-full") do
7+
CardHeader do
8+
CardTitle { 'You might like "RubyUI"' }
9+
CardDescription { "@joeldrapper" }
10+
end
11+
CardContent do
12+
AspectRatio(aspect_ratio: "16/9", class: "rounded-md overflow-hidden border") do
13+
img(
14+
alt: "Placeholder",
15+
loading: "lazy",
16+
src: image_url("pattern.jpg")
17+
)
18+
end
19+
end
20+
CardFooter(class: "flex justify-end gap-x-2") do
21+
Button(variant: :outline) { "See more" }
22+
Button(variant: :primary) { "Buy now" }
23+
end
24+
end
25+
end
26+
end
27+
end
28+
end
29+
end

app/components/themes/grid/chart.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# frozen_string_literal: true
2+
3+
module Components
4+
module Themes
5+
module Grid
6+
class Chart < Components::Base
7+
def view_template
8+
RubyUI::Card(class: "p-8 space-y-6") do
9+
div do
10+
Text(size: "4", weight: "semibold") { "Phlex Speed Tests" }
11+
Text(size: "2", class: "text-muted-foreground") { "Render time for a simple page" }
12+
end
13+
RubyUI::Chart(options: chart_options)
14+
end
15+
end
16+
17+
private
18+
19+
def chart_options
20+
{
21+
type: "bar",
22+
data: {
23+
labels: ["Phlex", "VC", "ERB"],
24+
datasets: [{
25+
label: "render time (ms)",
26+
data: [100, 520, 1200]
27+
}]
28+
},
29+
options: {
30+
indexAxis: "y",
31+
scales: {
32+
y: {
33+
beginAtZero: true
34+
}
35+
}
36+
}
37+
}
38+
end
39+
end
40+
end
41+
end
42+
end

app/components/themes/grid/chat.rb

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# frozen_string_literal: true
2+
3+
module Components
4+
module Themes
5+
module Grid
6+
class Chat < Components::Base
7+
MESSAGES = [
8+
"You should checkout RubyUI's new release, it makes life sooo much easier",
9+
"What's RubyUI?",
10+
"Don't ask questions, just get on that ASAP and thank me later",
11+
"Alright, alright, I'll check it out"
12+
]
13+
14+
def view_template
15+
RubyUI::Card(class: "p-8 space-y-6") do
16+
header
17+
messages(MESSAGES)
18+
message_form
19+
end
20+
end
21+
22+
private
23+
24+
def header
25+
div(class: "flex items-center justify-between") do
26+
div(class: "flex items-center space-x-4") do
27+
div do
28+
Text(class: "font-medium") { "Joel Drapper" }
29+
Text(size: "2", class: "text-muted-foreground") { "[email protected]" }
30+
end
31+
end
32+
Tooltip do
33+
TooltipTrigger do
34+
Button(variant: :outline, icon: true) do
35+
bookmark_icon
36+
end
37+
end
38+
TooltipContent do
39+
Text { "Save contact" }
40+
end
41+
end
42+
end
43+
end
44+
45+
def messages(messages)
46+
div(class: "space-y-4") do
47+
messages.each_with_index do |message, index|
48+
message(message, right: index.odd?)
49+
end
50+
end
51+
end
52+
53+
def message(content, right: false)
54+
div(class: ["w-full flex", ("justify-end" if right)]) do
55+
div(class: [
56+
"rounded-2xl p-4 w-3/4",
57+
(right ? "bg-primary text-primary-foreground rounded-br-sm" : "bg-muted text-foreground rounded-bl-sm")
58+
]) do
59+
content
60+
end
61+
end
62+
end
63+
64+
def message_form
65+
div(class: "flex w-full items-center space-x-2") do
66+
Input(type: "message", placeholder: "Write something...")
67+
Button { "Send" }
68+
end
69+
end
70+
71+
def bookmark_icon
72+
svg(
73+
xmlns: "http://www.w3.org/2000/svg",
74+
fill: "none",
75+
viewbox: "0 0 24 24",
76+
stroke_width: "1.5",
77+
stroke: "currentColor",
78+
class: "w-4 h-4"
79+
) do |s|
80+
s.path(
81+
stroke_linecap: "round",
82+
stroke_linejoin: "round",
83+
d:
84+
"M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0111.186 0z"
85+
)
86+
end
87+
end
88+
end
89+
end
90+
end
91+
end

app/components/themes/grid/command.rb

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# frozen_string_literal: true
2+
3+
module Components
4+
module Themes
5+
module Grid
6+
class Command < Components::Base
7+
def view_template
8+
CommandDialog do
9+
CommandDialogTrigger do
10+
Button(variant: "outline", class: "w-full pr-2 pl-3 justify-between") do
11+
div(class: "flex items-center space-x-1") do
12+
search_icon
13+
span(class: "text-muted-foreground font-normal") do
14+
plain "Search"
15+
end
16+
end
17+
ShortcutKey do
18+
span(class: "text-xs") { "⌘" }
19+
plain "K"
20+
end
21+
end
22+
end
23+
CommandDialogContent do
24+
Command do
25+
CommandInput(placeholder: "Type a command or search...")
26+
CommandEmpty { "No results found." }
27+
CommandList do
28+
CommandGroup(title: "Components") do
29+
components_list.each do |component|
30+
CommandItem(value: component[:name], href: component[:path]) do
31+
default_icon
32+
plain component[:name]
33+
end
34+
end
35+
end
36+
CommandGroup(title: "Settings") do
37+
settings_list.each do |setting|
38+
CommandItem(value: setting[:name], href: setting[:path]) do
39+
default_icon
40+
plain setting[:name]
41+
end
42+
end
43+
end
44+
end
45+
end
46+
end
47+
end
48+
end
49+
50+
private
51+
52+
def components
53+
[
54+
::Docs::ComponentStruct.new(name: "CommandController", source: "https://github.com/PhlexUI/phlex_ui_stimulus_pro/blob/main/controllers/command_controller.js", built_using: :stimulus),
55+
::Docs::ComponentStruct.new(name: "CommandDialog", source: "https://github.com/PhlexUI/phlex_ui_pro/blob/main/lib/phlex_ui_pro/command/dialog.rb", built_using: :phlex),
56+
::Docs::ComponentStruct.new(name: "CommandDialogTrigger", source: "https://github.com/PhlexUI/phlex_ui_pro/blob/main/lib/phlex_ui_pro/command/dialog_trigger.rb", built_using: :phlex),
57+
::Docs::ComponentStruct.new(name: "CommandDialogContent", source: "https://github.com/PhlexUI/phlex_ui_pro/blob/main/lib/phlex_ui_pro/command/dialog_content.rb", built_using: :phlex),
58+
::Docs::ComponentStruct.new(name: "Command", source: "https://github.com/PhlexUI/phlex_ui_pro/blob/main/lib/phlex_ui_pro/command.rb", built_using: :phlex),
59+
::Docs::ComponentStruct.new(name: "CommandInput", source: "https://github.com/PhlexUI/phlex_ui_pro/blob/main/lib/phlex_ui_pro/command/input.rb", built_using: :phlex),
60+
::Docs::ComponentStruct.new(name: "CommandEmpty", source: "https://github.com/PhlexUI/phlex_ui_pro/blob/main/lib/phlex_ui_pro/command/empty.rb", built_using: :phlex),
61+
::Docs::ComponentStruct.new(name: "CommandList", source: "https://github.com/PhlexUI/phlex_ui_pro/blob/main/lib/phlex_ui_pro/command/list.rb", built_using: :phlex),
62+
::Docs::ComponentStruct.new(name: "CommandGroup", source: "https://github.com/PhlexUI/phlex_ui_pro/blob/main/lib/phlex_ui_pro/command/group.rb", built_using: :phlex),
63+
::Docs::ComponentStruct.new(name: "CommandItem", source: "https://github.com/PhlexUI/phlex_ui_pro/blob/main/lib/phlex_ui_pro/command/item.rb", built_using: :phlex)
64+
]
65+
end
66+
67+
def search_icon
68+
svg(
69+
xmlns: "http://www.w3.org/2000/svg",
70+
viewbox: "0 0 20 20",
71+
fill: "currentColor",
72+
class: "w-4 h-4 mr-1.5"
73+
) do |s|
74+
s.path(
75+
fill_rule: "evenodd",
76+
d:
77+
"M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z",
78+
clip_rule: "evenodd"
79+
)
80+
end
81+
end
82+
83+
def default_icon
84+
svg(
85+
xmlns: "http://www.w3.org/2000/svg",
86+
viewbox: "0 0 24 24",
87+
fill: "currentColor",
88+
class: "w-5 h-5"
89+
) do |s|
90+
s.path(
91+
fill_rule: "evenodd",
92+
d:
93+
"M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zm4.28 10.28a.75.75 0 000-1.06l-3-3a.75.75 0 10-1.06 1.06l1.72 1.72H8.25a.75.75 0 000 1.5h5.69l-1.72 1.72a.75.75 0 101.06 1.06l3-3z",
94+
clip_rule: "evenodd"
95+
)
96+
end
97+
end
98+
99+
def components_list
100+
[
101+
{name: "Accordion", path: docs_accordion_path},
102+
{name: "Alert", path: docs_alert_path},
103+
{name: "Alert Dialog", path: docs_alert_dialog_path},
104+
{name: "Aspect Ratio", path: docs_aspect_ratio_path},
105+
{name: "Avatar", path: docs_avatar_path},
106+
{name: "Badge", path: docs_badge_path}
107+
]
108+
end
109+
110+
def settings_list
111+
[
112+
{name: "Profile", path: "#"},
113+
{name: "Mail", path: "#"},
114+
{name: "Settings", path: "#"}
115+
]
116+
end
117+
end
118+
end
119+
end
120+
end

0 commit comments

Comments
 (0)