Skip to content

Commit c3b0a89

Browse files
committed
Add the sidebar examples
1 parent 70beb82 commit c3b0a89

File tree

9 files changed

+876
-0
lines changed

9 files changed

+876
-0
lines changed

app/components/shared/menu.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ def components
9999
{name: "Separator", path: docs_separator_path, badge: "New"},
100100
{name: "Sheet", path: docs_sheet_path},
101101
{name: "Shortcut Key", path: docs_shortcut_key_path},
102+
{name: "Sidebar", path: docs_sidebar_path, badge: "New"},
102103
{name: "Skeleton", path: docs_skeleton_path, badge: "New"},
103104
{name: "Switch", path: docs_switch_path},
104105
{name: "Table", path: docs_table_path},
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
class Docs::SidebarController < ApplicationController
4+
layout -> { Views::Layouts::ExamplesLayout }
5+
6+
def example
7+
sidebar_state = cookies.fetch(:sidebar_state, "true") == "true"
8+
9+
render Views::Docs::Sidebar::Example.new(sidebar_state:)
10+
end
11+
12+
def inset_example
13+
sidebar_state = cookies.fetch(:sidebar_state, "true") == "true"
14+
15+
render Views::Docs::Sidebar::InsetExample.new(sidebar_state:)
16+
end
17+
18+
def dialog_example
19+
sidebar_state = cookies.fetch(:sidebar_state, "true") == "true"
20+
21+
render Views::Docs::Sidebar::DialogExample.new(sidebar_state:)
22+
end
23+
end

app/controllers/docs_controller.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ def shortcut_key
178178
render Views::Docs::ShortcutKey.new
179179
end
180180

181+
def sidebar
182+
render Views::Docs::Sidebar.new
183+
end
184+
181185
def skeleton
182186
render Views::Docs::Skeleton.new
183187
end

app/views/docs/sidebar.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# frozen_string_literal: true
2+
3+
class Views::Docs::Sidebar < Views::Base
4+
def view_template
5+
component = "Sidebar"
6+
7+
div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do
8+
render Docs::Header.new(title: "Sidebar", description: "A composable, themeable and customizable sidebar component.")
9+
10+
Heading(level: 2) { "Usage" }
11+
12+
render Docs::VisualCodeExample.new(title: "Example", src: "/docs/sidebar/example", context: self) do
13+
Views::Docs::Sidebar::Example::CODE
14+
end
15+
16+
render Docs::VisualCodeExample.new(title: "Inset variant", src: "/docs/sidebar/inset", context: self) do
17+
Views::Docs::Sidebar::InsetExample::CODE
18+
end
19+
20+
render div do
21+
div do
22+
Components.Heading(level: 4) { "Dialog variant" }
23+
24+
Tabs(default_value: "preview") do
25+
TabsList do
26+
TabsTrigger(value: "preview") do
27+
span { "Preview" }
28+
end
29+
TabsTrigger(value: "code") do
30+
span { "Code" }
31+
end
32+
end
33+
34+
TabsContent(value: "preview") do
35+
Link(href: "/docs/sidebar/dialog", target: :_blank, variant: :primary) { "Open in another tab" }
36+
end
37+
38+
TabsContent(value: "code") do
39+
div(class: "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 relative rounded-md border") do
40+
Codeblock(Views::Docs::Sidebar::DialogExample::CODE, syntax: :ruby, class: "-m-px")
41+
end
42+
end
43+
end
44+
end
45+
end
46+
47+
render Components::ComponentSetup::Tabs.new(component_name: component)
48+
49+
render Docs::ComponentsTable.new(component_files(component))
50+
end
51+
end
52+
end
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# frozen_string_literal: true
2+
3+
class Views::Docs::Sidebar::DialogExample < Views::Base
4+
def initialize(sidebar_state:)
5+
@sidebar_state = sidebar_state
6+
end
7+
8+
CODE = <<~RUBY
9+
Dialog(data: {action: "ruby-ui--dialog:connect->ruby-ui--dialog#open"}) do
10+
DialogTrigger do
11+
Button { "Open Dialog" }
12+
end
13+
DialogContent(class: "grid overflow-hidden p-0 md:max-h-[500px] md:max-w-[700px] lg:max-w-[800px]") do
14+
SidebarWrapper(class: "items-start") do
15+
Sidebar(collapsible: :none, class: "hidden md:flex") do
16+
SidebarContent do
17+
SidebarGroup do
18+
SidebarGroupContent do
19+
SidebarMenu do
20+
SidebarMenuItem do
21+
SidebarMenuButton(as: :a, href: "#") do
22+
search_icon()
23+
span { "Search" }
24+
end
25+
end
26+
SidebarMenuItem do
27+
SidebarMenuButton(as: :a, href: "#", active: true) do
28+
home_icon()
29+
span { "Home" }
30+
end
31+
end
32+
SidebarMenuItem do
33+
SidebarMenuButton(as: :a, href: "#") do
34+
inbox_icon()
35+
span { "Inbox" }
36+
end
37+
end
38+
end
39+
end
40+
end
41+
end
42+
end
43+
main(class: "flex h-[480px] flex-1 flex-col overflow-hidden") do
44+
end
45+
end
46+
end
47+
end
48+
RUBY
49+
50+
def view_template
51+
decoded_code = CGI.unescapeHTML(CODE)
52+
instance_eval(decoded_code)
53+
end
54+
55+
private
56+
57+
def nav_secondary
58+
[
59+
{label: "Settings", icon: -> { settings_icon }},
60+
{label: "Help & Support", icon: -> { message_circle_question }}
61+
]
62+
end
63+
64+
def home_icon
65+
svg(
66+
xmlns: "http://www.w3.org/2000/svg",
67+
width: "24",
68+
height: "24",
69+
viewBox: "0 0 24 24",
70+
fill: "none",
71+
stroke: "currentColor",
72+
stroke_width: "2",
73+
stroke_linecap: "round",
74+
stroke_linejoin: "round",
75+
class: "lucide lucide-house"
76+
) do |s|
77+
s.path(d: "M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8")
78+
s.path(d: "M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z")
79+
end
80+
end
81+
82+
def inbox_icon
83+
svg(
84+
xmlns: "http://www.w3.org/2000/svg",
85+
width: "24",
86+
height: "24",
87+
viewBox: "0 0 24 24",
88+
fill: "none",
89+
stroke: "currentColor",
90+
stroke_width: "2",
91+
stroke_linecap: "round",
92+
stroke_linejoin: "round",
93+
class: "lucide lucide-inbox"
94+
) do |s|
95+
s.polyline(points: "22 12 16 12 14 15 10 15 8 12 2 12")
96+
s.path(d: "M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z")
97+
end
98+
end
99+
100+
def calendar_icon
101+
svg(
102+
xmlns: "http://www.w3.org/2000/svg",
103+
width: "24",
104+
height: "24",
105+
viewBox: "0 0 24 24",
106+
fill: "none",
107+
stroke: "currentColor",
108+
stroke_width: "2",
109+
stroke_linecap: "round",
110+
stroke_linejoin: "round",
111+
class: "lucide lucide-calendar"
112+
) do |s|
113+
s.path(d: "M8 2v4")
114+
s.path(d: "M16 2v4")
115+
s.rect(width: "18", height: "18", x: "3", y: "4", rx: "2")
116+
s.path(d: "M3 10h18")
117+
end
118+
end
119+
120+
def search_icon
121+
svg(
122+
xmlns: "http://www.w3.org/2000/svg",
123+
width: "24",
124+
height: "24",
125+
viewBox: "0 0 24 24",
126+
fill: "none",
127+
stroke: "currentColor",
128+
stroke_width: "2",
129+
stroke_linecap: "round",
130+
stroke_linejoin: "round",
131+
class: "lucide lucide-search"
132+
) do |s|
133+
s.circle(cx: "11", cy: "11", r: "8")
134+
s.path(d: "M21 21L16.7 16.7")
135+
end
136+
end
137+
138+
def settings_icon
139+
svg(
140+
xmlns: "http://www.w3.org/2000/svg",
141+
width: "24",
142+
height: "24",
143+
viewBox: "0 0 24 24",
144+
fill: "none",
145+
stroke: "currentColor",
146+
stroke_width: "2",
147+
stroke_linecap: "round",
148+
stroke_linejoin: "round",
149+
class: "lucide lucide-settings"
150+
) do |s|
151+
s.path(d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73
152+
l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z")
153+
s.circle(cx: "12", cy: "12", r: "3")
154+
end
155+
end
156+
157+
def plus_icon
158+
svg(
159+
xmlns: "http://www.w3.org/2000/svg",
160+
width: "24",
161+
height: "24",
162+
viewBox: "0 0 24 24",
163+
fill: "none",
164+
stroke: "currentColor",
165+
stroke_width: "2",
166+
stroke_linecap: "round",
167+
stroke_linejoin: "round",
168+
class: "lucide lucide-plus"
169+
) do |s|
170+
s.path(d: "M5 12h14")
171+
s.path(d: "M12 5v14")
172+
end
173+
end
174+
175+
def gallery_vertical_end
176+
svg(xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", view_box: "0 0 24 24", fill: "none", stroke: "currentColor", stroke_width: "2", stroke_linecap: "round", stroke_linejoin: "round", class: "lucide lucide-gallery-vertical-end size-4") do |s|
177+
s.path d: "M7 2h10"
178+
s.path d: "M5 6h14"
179+
s.rect width: "18", height: "12", x: "3", y: "10", rx: "2"
180+
end
181+
end
182+
183+
def ellipsis_icon
184+
svg(xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", stroke_width: "2", stroke_linecap: "round", stroke_line_join: "round", class: "lucide lucide-ellipsis-icon lucide-ellipsis") do |s|
185+
s.circle cx: "12", cy: "12", r: "1"
186+
s.circle cx: "19", cy: "12", r: "1"
187+
s.circle cx: "5", cy: "12", r: "1"
188+
end
189+
end
190+
191+
def message_circle_question
192+
svg(xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", stroke_width: "2", stroke_linecap: "round", stroke_line_join: "round", class: "lucide lucide-message-circle-question-icon lucide-message-circle-question") do |s|
193+
s.path d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z"
194+
s.path d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"
195+
s.path d: "M12 17h.01"
196+
end
197+
end
198+
end

0 commit comments

Comments
 (0)