m9sh 0.2.1 → 0.2.2
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/.idea/hotcdn.iml +30 -0
- data/.mise.toml +2 -2
- data/app/assets/config/manifest.js +4 -0
- data/app/assets/images/icons/activity.svg +3 -0
- data/app/assets/images/icons/bell.svg +4 -0
- data/app/assets/images/icons/book.svg +4 -0
- data/app/assets/images/icons/chevron-down.svg +3 -0
- data/app/assets/images/icons/chevron-left.svg +3 -0
- data/app/assets/images/icons/chevron-right.svg +3 -0
- data/app/assets/images/icons/credit-card.svg +4 -0
- data/app/assets/images/icons/dollar-sign.svg +3 -0
- data/app/assets/images/icons/edit.svg +4 -0
- data/app/assets/images/icons/github.svg +3 -0
- data/app/assets/images/icons/home.svg +4 -0
- data/app/assets/images/icons/info.svg +5 -0
- data/app/assets/images/icons/layout.svg +6 -0
- data/app/assets/images/icons/logout.svg +5 -0
- data/app/assets/images/icons/menu.svg +5 -0
- data/app/assets/images/icons/moon.svg +3 -0
- data/app/assets/images/icons/paintbrush.svg +6 -0
- data/app/assets/images/icons/search.svg +4 -0
- data/app/assets/images/icons/settings.svg +4 -0
- data/app/assets/images/icons/sun.svg +11 -0
- data/app/assets/images/icons/user.svg +4 -0
- data/app/assets/images/icons/users.svg +5 -0
- data/app/assets/stylesheets/tailwind.css +1180 -0
- data/app/components/backdrop_component.rb +103 -0
- data/app/components/docs/code_block_component.rb +56 -0
- data/app/components/docs/component_api_component.rb +16 -0
- data/app/components/docs/component_examples_component.rb +16 -0
- data/app/components/docs/component_header_component.html.erb +8 -0
- data/app/components/docs/component_header_component.rb +14 -0
- data/app/components/docs/component_installation_component.html.erb +15 -0
- data/app/components/docs/component_installation_component.rb +13 -0
- data/app/components/docs/component_page_component.html.erb +9 -0
- data/app/components/docs/component_page_component.rb +19 -0
- data/app/components/docs/component_preview_component.rb +318 -0
- data/app/components/docs/component_usage_component.rb +18 -0
- data/app/components/docs/prop_table_component.rb +64 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/blocks_controller.rb +51 -0
- data/app/controllers/docs_controller.rb +162 -0
- data/app/controllers/showcase_controller.rb +42 -0
- data/app/helpers/blocks_helper.rb +343 -0
- data/app/helpers/docs_helper.rb +3807 -0
- data/app/helpers/m9sh/toast_helper.rb +46 -0
- data/app/helpers/m9sh_helper.rb +343 -0
- data/app/javascript/application.js +3 -0
- data/app/javascript/controllers/application.js +9 -0
- data/app/javascript/controllers/backdrop_controller.js +137 -0
- data/app/javascript/controllers/color_customizer_controller.js +569 -0
- data/app/javascript/controllers/color_theme_controller.js +120 -0
- data/app/javascript/controllers/docs/component_preview_controller.js +149 -0
- data/app/javascript/controllers/docs/copy_button_controller.js +20 -0
- data/app/javascript/controllers/index.js +6 -0
- data/app/javascript/controllers/theme_controller.js +23 -0
- data/app/views/blocks/_sidebar.html.erb +31 -0
- data/app/views/blocks/_toc.html.erb +29 -0
- data/app/views/blocks/examples/dashboard-01.html.erb +180 -0
- data/app/views/blocks/examples/dashboard-02.html.erb +190 -0
- data/app/views/blocks/examples/dashboard-03.html.erb +210 -0
- data/app/views/blocks/examples/settings-01.html.erb +220 -0
- data/app/views/blocks/examples/settings-02.html.erb +231 -0
- data/app/views/blocks/examples/settings-03.html.erb +340 -0
- data/app/views/blocks/index.html.erb +65 -0
- data/app/views/docs/_sidebar.html.erb +47 -0
- data/app/views/docs/_toc.html.erb +19 -0
- data/app/views/docs/about.html.erb +68 -0
- data/app/views/docs/components/accordion.html.erb +196 -0
- data/app/views/docs/components/alert.html.erb +272 -0
- data/app/views/docs/components/alert_dialog.html.erb +232 -0
- data/app/views/docs/components/avatar.html.erb +207 -0
- data/app/views/docs/components/badge.html.erb +145 -0
- data/app/views/docs/components/breadcrumb.html.erb +264 -0
- data/app/views/docs/components/button.html.erb +229 -0
- data/app/views/docs/components/card.html.erb +378 -0
- data/app/views/docs/components/checkbox.html.erb +212 -0
- data/app/views/docs/components/collapsible.html.erb +252 -0
- data/app/views/docs/components/dialog.html.erb +323 -0
- data/app/views/docs/components/dropdown_menu.html.erb +289 -0
- data/app/views/docs/components/hover_card.html.erb +220 -0
- data/app/views/docs/components/input.html.erb +254 -0
- data/app/views/docs/components/label.html.erb +128 -0
- data/app/views/docs/components/main.html.erb +352 -0
- data/app/views/docs/components/navbar.html.erb +394 -0
- data/app/views/docs/components/navigation_menu.html.erb +226 -0
- data/app/views/docs/components/popover.html.erb +267 -0
- data/app/views/docs/components/progress.html.erb +107 -0
- data/app/views/docs/components/radio_group.html.erb +209 -0
- data/app/views/docs/components/select.html.erb +260 -0
- data/app/views/docs/components/separator.html.erb +162 -0
- data/app/views/docs/components/sheet.html.erb +270 -0
- data/app/views/docs/components/sidebar.html.erb +597 -0
- data/app/views/docs/components/skeleton.html.erb +150 -0
- data/app/views/docs/components/slider.html.erb +218 -0
- data/app/views/docs/components/spinner.html.erb +132 -0
- data/app/views/docs/components/switch.html.erb +148 -0
- data/app/views/docs/components/table.html.erb +259 -0
- data/app/views/docs/components/tabs.html.erb +225 -0
- data/app/views/docs/components/textarea.html.erb +239 -0
- data/app/views/docs/components/theme_toggle.html.erb +135 -0
- data/app/views/docs/components/toast.html.erb +205 -0
- data/app/views/docs/components/toaster.html.erb +227 -0
- data/app/views/docs/components/toggle.html.erb +154 -0
- data/app/views/docs/components/tooltip.html.erb +216 -0
- data/app/views/docs/components/typography.html.erb +180 -0
- data/app/views/docs/index.html.erb +143 -0
- data/app/views/docs/installation.html.erb +155 -0
- data/app/views/docs/simple_test.html.erb +13 -0
- data/app/views/docs/test_accordion.html.erb +14 -0
- data/app/views/docs/usage.html.erb +272 -0
- data/app/views/layouts/application.html.erb +107 -0
- data/app/views/layouts/backdrop.html.erb +77 -0
- data/app/views/shared/_app_navbar.html.erb +240 -0
- data/app/views/shared/_navbar.html.erb +69 -0
- data/app/views/showcase/v2/_components_grid.html.erb +38 -0
- data/app/views/showcase/v2/_features.html.erb +59 -0
- data/app/views/showcase/v2/_forms.html.erb +195 -0
- data/app/views/showcase/v2/_hero.html.erb +55 -0
- data/app/views/showcase/v2/_metrics.html.erb +107 -0
- data/app/views/showcase/v2.html.erb +18 -0
- data/lib/m9sh/version.rb +1 -1
- data/m9sh.gemspec +1 -1
- metadata +120 -1
@@ -0,0 +1,252 @@
|
|
1
|
+
<%= render Docs::ComponentPageComponent.new(title: "Collapsible") do |page| %>
|
2
|
+
<% page.with_header(
|
3
|
+
name: "Collapsible",
|
4
|
+
description: "An interactive component that expands and collapses content."
|
5
|
+
) %>
|
6
|
+
|
7
|
+
<% page.with_installation(component_name: "collapsible") %>
|
8
|
+
|
9
|
+
<% page.with_usage do %>
|
10
|
+
<%= render Docs::CodeBlockComponent.new(
|
11
|
+
code: collapsible_usage_code,
|
12
|
+
language: "erb"
|
13
|
+
) %>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<% page.with_examples do %>
|
17
|
+
<!-- Default Example -->
|
18
|
+
<% default_html = capture do %>
|
19
|
+
<div class="w-full max-w-md">
|
20
|
+
<%= render M9sh::CollapsibleComponent.new(class: "space-y-2") do |c| %>
|
21
|
+
<% c.with_trigger do %>
|
22
|
+
<button class="flex w-full items-center justify-between rounded-md bg-muted px-4 py-2 text-sm font-medium transition-colors hover:bg-muted">
|
23
|
+
<span>@peduarte starred 3 repositories</span>
|
24
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="transition-transform">
|
25
|
+
<polyline points="6 9 12 15 18 9"/>
|
26
|
+
</svg>
|
27
|
+
</button>
|
28
|
+
<% end %>
|
29
|
+
<% c.with_collapsible_content do %>
|
30
|
+
<div class="space-y-2 pt-2">
|
31
|
+
<div class="rounded-md border px-4 py-3 text-sm">
|
32
|
+
@radix-ui/primitives
|
33
|
+
</div>
|
34
|
+
<div class="rounded-md border px-4 py-3 text-sm">
|
35
|
+
@radix-ui/colors
|
36
|
+
</div>
|
37
|
+
<div class="rounded-md border px-4 py-3 text-sm">
|
38
|
+
@stitches/react
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
<% end %>
|
42
|
+
<% end %>
|
43
|
+
</div>
|
44
|
+
<% end %>
|
45
|
+
|
46
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
47
|
+
title: "Default",
|
48
|
+
preview_content: default_html,
|
49
|
+
code: collapsible_default_code,
|
50
|
+
ai_command: collapsible_default_code
|
51
|
+
) %>
|
52
|
+
|
53
|
+
<!-- Open by Default Example -->
|
54
|
+
<% open_html = capture do %>
|
55
|
+
<div class="w-full max-w-md">
|
56
|
+
<%= render M9sh::CollapsibleComponent.new(open: true, class: "space-y-2") do |c| %>
|
57
|
+
<% c.with_trigger do %>
|
58
|
+
<button class="flex w-full items-center justify-between rounded-md bg-muted px-4 py-2 text-sm font-medium transition-colors hover:bg-muted">
|
59
|
+
<span>Project Information</span>
|
60
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="transition-transform">
|
61
|
+
<polyline points="6 9 12 15 18 9"/>
|
62
|
+
</svg>
|
63
|
+
</button>
|
64
|
+
<% end %>
|
65
|
+
<% c.with_collapsible_content do %>
|
66
|
+
<div class="space-y-2 pt-2">
|
67
|
+
<div class="rounded-md border px-4 py-3 text-sm">
|
68
|
+
<strong>Name:</strong> m9sh Components
|
69
|
+
</div>
|
70
|
+
<div class="rounded-md border px-4 py-3 text-sm">
|
71
|
+
<strong>Status:</strong> Active Development
|
72
|
+
</div>
|
73
|
+
<div class="rounded-md border px-4 py-3 text-sm">
|
74
|
+
<strong>Version:</strong> 1.0.0
|
75
|
+
</div>
|
76
|
+
</div>
|
77
|
+
<% end %>
|
78
|
+
<% end %>
|
79
|
+
</div>
|
80
|
+
<% end %>
|
81
|
+
|
82
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
83
|
+
title: "Open by Default",
|
84
|
+
preview_content: open_html,
|
85
|
+
code: collapsible_open_code,
|
86
|
+
ai_command: collapsible_open_code
|
87
|
+
) %>
|
88
|
+
|
89
|
+
<!-- With Button Example -->
|
90
|
+
<% button_html = capture do %>
|
91
|
+
<div class="w-full max-w-md">
|
92
|
+
<%= render M9sh::CollapsibleComponent.new(class: "space-y-2") do |c| %>
|
93
|
+
<% c.with_trigger do %>
|
94
|
+
<%= render M9sh::ButtonComponent.new(variant: :outline, class: "w-full justify-between") do %>
|
95
|
+
<span>Show more details</span>
|
96
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
97
|
+
<polyline points="6 9 12 15 18 9"/>
|
98
|
+
</svg>
|
99
|
+
<% end %>
|
100
|
+
<% end %>
|
101
|
+
<% c.with_collapsible_content do %>
|
102
|
+
<div class="rounded-md border p-4 text-sm">
|
103
|
+
<p class="text-muted-foreground">
|
104
|
+
This is additional content that can be toggled. The collapsible component
|
105
|
+
works with any trigger element, including buttons, links, or custom elements.
|
106
|
+
</p>
|
107
|
+
</div>
|
108
|
+
<% end %>
|
109
|
+
<% end %>
|
110
|
+
</div>
|
111
|
+
<% end %>
|
112
|
+
|
113
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
114
|
+
title: "With Button Component",
|
115
|
+
preview_content: button_html,
|
116
|
+
code: collapsible_button_code,
|
117
|
+
ai_command: collapsible_button_code
|
118
|
+
) %>
|
119
|
+
|
120
|
+
<!-- FAQ Example -->
|
121
|
+
<% faq_html = capture do %>
|
122
|
+
<div class="w-full max-w-md space-y-4">
|
123
|
+
<%= render M9sh::CollapsibleComponent.new(class: "space-y-2") do |c| %>
|
124
|
+
<% c.with_trigger do %>
|
125
|
+
<button class="flex w-full items-center justify-between rounded-md border px-4 py-2 text-sm font-medium transition-colors hover:bg-muted">
|
126
|
+
<span>What is m9sh Components?</span>
|
127
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
128
|
+
<polyline points="6 9 12 15 18 9"/>
|
129
|
+
</svg>
|
130
|
+
</button>
|
131
|
+
<% end %>
|
132
|
+
<% c.with_collapsible_content do %>
|
133
|
+
<div class="border-x border-b rounded-b-md px-4 py-3 text-sm text-muted-foreground">
|
134
|
+
m9sh Components is a collection of reusable UI components for Rails applications,
|
135
|
+
built with ViewComponent and styled with Tailwind CSS.
|
136
|
+
</div>
|
137
|
+
<% end %>
|
138
|
+
<% end %>
|
139
|
+
|
140
|
+
<%= render M9sh::CollapsibleComponent.new(class: "space-y-2") do |c| %>
|
141
|
+
<% c.with_trigger do %>
|
142
|
+
<button class="flex w-full items-center justify-between rounded-md border px-4 py-2 text-sm font-medium transition-colors hover:bg-muted">
|
143
|
+
<span>How do I install it?</span>
|
144
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
145
|
+
<polyline points="6 9 12 15 18 9"/>
|
146
|
+
</svg>
|
147
|
+
</button>
|
148
|
+
<% end %>
|
149
|
+
<% c.with_collapsible_content do %>
|
150
|
+
<div class="border-x border-b rounded-b-md px-4 py-3 text-sm text-muted-foreground">
|
151
|
+
Simply copy the component files into your Rails application and start using them
|
152
|
+
in your views. Each component is self-contained and easy to customize.
|
153
|
+
</div>
|
154
|
+
<% end %>
|
155
|
+
<% end %>
|
156
|
+
</div>
|
157
|
+
<% end %>
|
158
|
+
|
159
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
160
|
+
title: "FAQ Style",
|
161
|
+
preview_content: faq_html,
|
162
|
+
code: collapsible_faq_code,
|
163
|
+
ai_command: collapsible_faq_code
|
164
|
+
) %>
|
165
|
+
<% end %>
|
166
|
+
|
167
|
+
<% page.with_api do %>
|
168
|
+
<h3 class="text-lg font-semibold">CollapsibleComponent</h3>
|
169
|
+
|
170
|
+
<%= render Docs::PropTableComponent.new(
|
171
|
+
props: [
|
172
|
+
{
|
173
|
+
name: "open",
|
174
|
+
type: "Boolean",
|
175
|
+
default: "false",
|
176
|
+
description: "Whether the collapsible is open by default"
|
177
|
+
}
|
178
|
+
]
|
179
|
+
) %>
|
180
|
+
|
181
|
+
<h3 class="text-lg font-semibold mt-6">Slots</h3>
|
182
|
+
|
183
|
+
<%= render Docs::PropTableComponent.new(
|
184
|
+
props: [
|
185
|
+
{
|
186
|
+
name: "trigger",
|
187
|
+
type: "Slot",
|
188
|
+
default: "-",
|
189
|
+
description: "The element that toggles the collapsible when clicked. Can be any clickable element like a button, link, or div."
|
190
|
+
},
|
191
|
+
{
|
192
|
+
name: "collapsible_content",
|
193
|
+
type: "Slot",
|
194
|
+
default: "-",
|
195
|
+
description: "The content that will be shown or hidden when the trigger is clicked"
|
196
|
+
}
|
197
|
+
]
|
198
|
+
) %>
|
199
|
+
|
200
|
+
<div class="mt-6 space-y-4">
|
201
|
+
<h3 class="text-lg font-semibold">Accessibility</h3>
|
202
|
+
|
203
|
+
<div class="space-y-3 text-sm">
|
204
|
+
<p>
|
205
|
+
The Collapsible component uses Stimulus to manage state and animations:
|
206
|
+
</p>
|
207
|
+
|
208
|
+
<ul class="list-disc list-inside space-y-2 text-muted-foreground">
|
209
|
+
<li>
|
210
|
+
Animated height transitions provide smooth visual feedback when expanding/collapsing
|
211
|
+
</li>
|
212
|
+
<li>
|
213
|
+
The trigger can be any interactive element - ensure it's keyboard accessible
|
214
|
+
</li>
|
215
|
+
<li>
|
216
|
+
Consider adding <code class="text-xs bg-muted px-1 py-0.5 rounded">aria-expanded</code> and <code class="text-xs bg-muted px-1 py-0.5 rounded">aria-controls</code> attributes to the trigger for better screen reader support
|
217
|
+
</li>
|
218
|
+
<li>
|
219
|
+
The component uses <code class="text-xs bg-muted px-1 py-0.5 rounded">data-state</code> attributes for styling based on open/closed state
|
220
|
+
</li>
|
221
|
+
<li>
|
222
|
+
Transitions are handled via CSS with a 300ms duration for smooth animations
|
223
|
+
</li>
|
224
|
+
</ul>
|
225
|
+
</div>
|
226
|
+
</div>
|
227
|
+
|
228
|
+
<div class="mt-6 space-y-4">
|
229
|
+
<h3 class="text-lg font-semibold">Notes</h3>
|
230
|
+
|
231
|
+
<div class="space-y-3 text-sm">
|
232
|
+
<ul class="list-disc list-inside space-y-2 text-muted-foreground">
|
233
|
+
<li>
|
234
|
+
The trigger slot is required and must contain a clickable element
|
235
|
+
</li>
|
236
|
+
<li>
|
237
|
+
The component automatically attaches a click handler to the trigger element
|
238
|
+
</li>
|
239
|
+
<li>
|
240
|
+
Use the <code class="text-xs bg-muted px-1 py-0.5 rounded">open</code> parameter to set the initial state
|
241
|
+
</li>
|
242
|
+
<li>
|
243
|
+
Multiple collapsible components can exist on the same page independently
|
244
|
+
</li>
|
245
|
+
<li>
|
246
|
+
The component works well with other m9sh components like Button, Card, etc.
|
247
|
+
</li>
|
248
|
+
</ul>
|
249
|
+
</div>
|
250
|
+
</div>
|
251
|
+
<% end %>
|
252
|
+
<% end %>
|
@@ -0,0 +1,323 @@
|
|
1
|
+
<%= render Docs::ComponentPageComponent.new(title: "Dialog") do |page| %>
|
2
|
+
<% page.with_header(
|
3
|
+
name: "Dialog",
|
4
|
+
description: "A modal dialog that interrupts the user with important content and expects a response."
|
5
|
+
) %>
|
6
|
+
|
7
|
+
<% page.with_installation(component_name: "dialog") %>
|
8
|
+
|
9
|
+
<% page.with_usage do %>
|
10
|
+
<%= render Docs::CodeBlockComponent.new(
|
11
|
+
code: dialog_usage_code,
|
12
|
+
language: "erb"
|
13
|
+
) %>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<% page.with_examples do %>
|
17
|
+
<!-- Default Example -->
|
18
|
+
<% default_dialog_html = capture do %>
|
19
|
+
<%= render M9sh::DialogComponent.new do |dialog| %>
|
20
|
+
<% dialog.with_dialog_trigger do %>
|
21
|
+
<%= render M9sh::ButtonComponent.new do %>
|
22
|
+
Open Dialog
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
25
|
+
<% dialog.with_dialog_content do |content| %>
|
26
|
+
<% content.with_dialog_header do |header| %>
|
27
|
+
<% header.with_dialog_title do %>
|
28
|
+
Are you absolutely sure?
|
29
|
+
<% end %>
|
30
|
+
<% header.with_dialog_description do %>
|
31
|
+
This action cannot be undone. This will permanently delete your account
|
32
|
+
and remove your data from our servers.
|
33
|
+
<% end %>
|
34
|
+
<% end %>
|
35
|
+
<% end %>
|
36
|
+
<% end %>
|
37
|
+
<% end %>
|
38
|
+
|
39
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
40
|
+
title: "Default",
|
41
|
+
preview_content: default_dialog_html,
|
42
|
+
code: dialog_default_code,
|
43
|
+
ai_command: dialog_default_code
|
44
|
+
) %>
|
45
|
+
|
46
|
+
<!-- With Header Example -->
|
47
|
+
<% with_header_dialog_html = capture do %>
|
48
|
+
<%= render M9sh::DialogComponent.new do |dialog| %>
|
49
|
+
<% dialog.with_dialog_trigger do %>
|
50
|
+
<%= render M9sh::ButtonComponent.new(variant: :outline) do %>
|
51
|
+
Edit Profile
|
52
|
+
<% end %>
|
53
|
+
<% end %>
|
54
|
+
<% dialog.with_dialog_content do |content| %>
|
55
|
+
<% content.with_dialog_header do |header| %>
|
56
|
+
<% header.with_dialog_title do %>
|
57
|
+
Edit profile
|
58
|
+
<% end %>
|
59
|
+
<% header.with_dialog_description do %>
|
60
|
+
Make changes to your profile here. Click save when you're done.
|
61
|
+
<% end %>
|
62
|
+
<% end %>
|
63
|
+
<div class="space-y-4">
|
64
|
+
<div class="space-y-2">
|
65
|
+
<%= render M9sh::LabelComponent.new(text: "Name") %>
|
66
|
+
<%= render M9sh::InputComponent.new(type: "text", placeholder: "Pedro Duarte") %>
|
67
|
+
</div>
|
68
|
+
<div class="space-y-2">
|
69
|
+
<%= render M9sh::LabelComponent.new(text: "Username") %>
|
70
|
+
<%= render M9sh::InputComponent.new(type: "text", placeholder: "@peduarte") %>
|
71
|
+
</div>
|
72
|
+
</div>
|
73
|
+
<% content.with_dialog_footer do %>
|
74
|
+
<%= render M9sh::ButtonComponent.new(type: "submit") do %>
|
75
|
+
Save changes
|
76
|
+
<% end %>
|
77
|
+
<% end %>
|
78
|
+
<% end %>
|
79
|
+
<% end %>
|
80
|
+
<% end %>
|
81
|
+
|
82
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
83
|
+
title: "With Header",
|
84
|
+
preview_content: with_header_dialog_html,
|
85
|
+
code: dialog_with_header_code,
|
86
|
+
ai_command: dialog_with_header_code
|
87
|
+
) %>
|
88
|
+
|
89
|
+
<!-- With Footer Example -->
|
90
|
+
<% with_footer_dialog_html = capture do %>
|
91
|
+
<%= render M9sh::DialogComponent.new do |dialog| %>
|
92
|
+
<% dialog.with_dialog_trigger do %>
|
93
|
+
<%= render M9sh::ButtonComponent.new do %>
|
94
|
+
Open Dialog
|
95
|
+
<% end %>
|
96
|
+
<% end %>
|
97
|
+
<% dialog.with_dialog_content do |content| %>
|
98
|
+
<% content.with_dialog_header do |header| %>
|
99
|
+
<% header.with_dialog_title do %>
|
100
|
+
Confirm Action
|
101
|
+
<% end %>
|
102
|
+
<% header.with_dialog_description do %>
|
103
|
+
This is a dialog with a footer containing action buttons.
|
104
|
+
<% end %>
|
105
|
+
<% end %>
|
106
|
+
<p class="text-sm">Are you sure you want to proceed with this action?</p>
|
107
|
+
<% content.with_dialog_footer do %>
|
108
|
+
<%= render M9sh::DialogCloseComponent.new(as_child: true) do %>
|
109
|
+
<%= render M9sh::ButtonComponent.new(variant: :outline) do %>
|
110
|
+
Cancel
|
111
|
+
<% end %>
|
112
|
+
<% end %>
|
113
|
+
<%= render M9sh::ButtonComponent.new do %>
|
114
|
+
Continue
|
115
|
+
<% end %>
|
116
|
+
<% end %>
|
117
|
+
<% end %>
|
118
|
+
<% end %>
|
119
|
+
<% end %>
|
120
|
+
|
121
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
122
|
+
title: "With Footer",
|
123
|
+
preview_content: with_footer_dialog_html,
|
124
|
+
code: dialog_with_footer_code,
|
125
|
+
ai_command: dialog_with_footer_code
|
126
|
+
) %>
|
127
|
+
|
128
|
+
<!-- Form Dialog Example -->
|
129
|
+
<% form_dialog_html = capture do %>
|
130
|
+
<%= render M9sh::DialogComponent.new do |dialog| %>
|
131
|
+
<% dialog.with_dialog_trigger do %>
|
132
|
+
<%= render M9sh::ButtonComponent.new(variant: :outline) do %>
|
133
|
+
Share
|
134
|
+
<% end %>
|
135
|
+
<% end %>
|
136
|
+
<% dialog.with_dialog_content do |content| %>
|
137
|
+
<% content.with_dialog_header do |header| %>
|
138
|
+
<% header.with_dialog_title do %>
|
139
|
+
Share link
|
140
|
+
<% end %>
|
141
|
+
<% header.with_dialog_description do %>
|
142
|
+
Anyone who has this link will be able to view this.
|
143
|
+
<% end %>
|
144
|
+
<% end %>
|
145
|
+
<div class="flex items-center space-x-2">
|
146
|
+
<%= render M9sh::InputComponent.new(
|
147
|
+
value: "https://ui.shadcn.com/docs/installation",
|
148
|
+
readonly: true,
|
149
|
+
class: "flex-1"
|
150
|
+
) %>
|
151
|
+
<%= render M9sh::ButtonComponent.new(type: "button", variant: :secondary, size: :sm) do %>
|
152
|
+
Copy
|
153
|
+
<% end %>
|
154
|
+
</div>
|
155
|
+
<% content.with_dialog_footer do %>
|
156
|
+
<%= render M9sh::DialogCloseComponent.new %>
|
157
|
+
<% end %>
|
158
|
+
<% end %>
|
159
|
+
<% end %>
|
160
|
+
<% end %>
|
161
|
+
|
162
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
163
|
+
title: "Form Dialog",
|
164
|
+
preview_content: form_dialog_html,
|
165
|
+
code: dialog_form_code,
|
166
|
+
ai_command: dialog_form_code
|
167
|
+
) %>
|
168
|
+
|
169
|
+
<!-- Scrollable Content Example -->
|
170
|
+
<% scrollable_dialog_html = capture do %>
|
171
|
+
<%= render M9sh::DialogComponent.new do |dialog| %>
|
172
|
+
<% dialog.with_dialog_trigger do %>
|
173
|
+
<%= render M9sh::ButtonComponent.new do %>
|
174
|
+
View Terms
|
175
|
+
<% end %>
|
176
|
+
<% end %>
|
177
|
+
<% dialog.with_dialog_content do |content| %>
|
178
|
+
<% content.with_dialog_header do |header| %>
|
179
|
+
<% header.with_dialog_title do %>
|
180
|
+
Terms and Conditions
|
181
|
+
<% end %>
|
182
|
+
<% header.with_dialog_description do %>
|
183
|
+
Please read and accept our terms and conditions.
|
184
|
+
<% end %>
|
185
|
+
<% end %>
|
186
|
+
<div class="max-h-[300px] overflow-y-auto space-y-4">
|
187
|
+
<p class="text-sm">
|
188
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
189
|
+
</p>
|
190
|
+
<p class="text-sm">
|
191
|
+
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
192
|
+
</p>
|
193
|
+
<p class="text-sm">
|
194
|
+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
195
|
+
</p>
|
196
|
+
<p class="text-sm">
|
197
|
+
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
198
|
+
</p>
|
199
|
+
</div>
|
200
|
+
<% content.with_dialog_footer do %>
|
201
|
+
<%= render M9sh::DialogCloseComponent.new(as_child: true) do %>
|
202
|
+
<%= render M9sh::ButtonComponent.new(variant: :outline) do %>
|
203
|
+
Decline
|
204
|
+
<% end %>
|
205
|
+
<% end %>
|
206
|
+
<%= render M9sh::ButtonComponent.new do %>
|
207
|
+
Accept
|
208
|
+
<% end %>
|
209
|
+
<% end %>
|
210
|
+
<% end %>
|
211
|
+
<% end %>
|
212
|
+
<% end %>
|
213
|
+
|
214
|
+
<%= render Docs::ComponentPreviewComponent.new(
|
215
|
+
title: "Scrollable Content",
|
216
|
+
preview_content: scrollable_dialog_html,
|
217
|
+
code: dialog_scrollable_code,
|
218
|
+
ai_command: dialog_scrollable_code
|
219
|
+
) %>
|
220
|
+
<% end %>
|
221
|
+
|
222
|
+
<% page.with_api do %>
|
223
|
+
<h3 class="text-lg font-semibold">Dialog Component Props</h3>
|
224
|
+
<%= render Docs::PropTableComponent.new(
|
225
|
+
props: [
|
226
|
+
{
|
227
|
+
name: "open",
|
228
|
+
type: "Boolean",
|
229
|
+
default: "false",
|
230
|
+
description: "Controls whether the dialog is open by default"
|
231
|
+
}
|
232
|
+
]
|
233
|
+
) %>
|
234
|
+
|
235
|
+
<h3 class="text-lg font-semibold mt-6">Dialog Slots</h3>
|
236
|
+
<%= render Docs::PropTableComponent.new(
|
237
|
+
props: [
|
238
|
+
{
|
239
|
+
name: "dialog_trigger",
|
240
|
+
type: "Slot",
|
241
|
+
default: nil,
|
242
|
+
description: "The element that triggers the dialog to open. Use with_dialog_trigger. Supports as_child pattern."
|
243
|
+
},
|
244
|
+
{
|
245
|
+
name: "dialog_content",
|
246
|
+
type: "Slot",
|
247
|
+
default: nil,
|
248
|
+
description: "The main dialog content container. Use with_dialog_content. Contains header, body content, and footer."
|
249
|
+
}
|
250
|
+
]
|
251
|
+
) %>
|
252
|
+
|
253
|
+
<h3 class="text-lg font-semibold mt-6">Dialog Content Slots</h3>
|
254
|
+
<%= render Docs::PropTableComponent.new(
|
255
|
+
props: [
|
256
|
+
{
|
257
|
+
name: "dialog_header",
|
258
|
+
type: "Slot",
|
259
|
+
default: nil,
|
260
|
+
description: "Header container with title and description. Use with_dialog_header."
|
261
|
+
},
|
262
|
+
{
|
263
|
+
name: "dialog_footer",
|
264
|
+
type: "Slot",
|
265
|
+
default: nil,
|
266
|
+
description: "Footer container for action buttons. Use with_dialog_footer."
|
267
|
+
}
|
268
|
+
]
|
269
|
+
) %>
|
270
|
+
|
271
|
+
<h3 class="text-lg font-semibold mt-6">Dialog Header Slots</h3>
|
272
|
+
<%= render Docs::PropTableComponent.new(
|
273
|
+
props: [
|
274
|
+
{
|
275
|
+
name: "dialog_title",
|
276
|
+
type: "Slot",
|
277
|
+
default: nil,
|
278
|
+
description: "The title/heading of the dialog. Use with_dialog_title within dialog_header."
|
279
|
+
},
|
280
|
+
{
|
281
|
+
name: "dialog_description",
|
282
|
+
type: "Slot",
|
283
|
+
default: nil,
|
284
|
+
description: "The description text below the title. Use with_dialog_description within dialog_header."
|
285
|
+
}
|
286
|
+
]
|
287
|
+
) %>
|
288
|
+
|
289
|
+
<h3 class="text-lg font-semibold mt-6">Additional Components</h3>
|
290
|
+
<%= render Docs::PropTableComponent.new(
|
291
|
+
props: [
|
292
|
+
{
|
293
|
+
name: "DialogCloseComponent",
|
294
|
+
type: "Component",
|
295
|
+
default: nil,
|
296
|
+
description: "A close button component. Supports as_child: true to wrap custom elements with close functionality."
|
297
|
+
}
|
298
|
+
]
|
299
|
+
) %>
|
300
|
+
|
301
|
+
<div class="mt-6 space-y-2">
|
302
|
+
<h3 class="text-lg font-semibold">JavaScript Actions</h3>
|
303
|
+
<ul class="list-disc list-inside text-sm text-muted-foreground space-y-1">
|
304
|
+
<li><code>data-action="click->m9sh--dialog#open"</code> - Opens the dialog</li>
|
305
|
+
<li><code>data-action="click->m9sh--dialog#close"</code> - Closes the dialog</li>
|
306
|
+
<li>The dialog automatically closes when clicking outside (on the overlay)</li>
|
307
|
+
<li>The close button (X) is automatically rendered in the top-right corner</li>
|
308
|
+
</ul>
|
309
|
+
</div>
|
310
|
+
|
311
|
+
<div class="mt-6 space-y-2">
|
312
|
+
<h3 class="text-lg font-semibold">Notes</h3>
|
313
|
+
<ul class="list-disc list-inside text-sm text-muted-foreground space-y-1">
|
314
|
+
<li>The dialog is centered on the screen with a dark overlay backdrop</li>
|
315
|
+
<li>Includes smooth animations for opening and closing</li>
|
316
|
+
<li>Automatically manages focus and accessibility with proper ARIA attributes</li>
|
317
|
+
<li>The dialog can be closed by clicking the backdrop or the close button</li>
|
318
|
+
<li>Content is automatically scrollable if it exceeds the dialog height</li>
|
319
|
+
<li>Use the footer slot for action buttons like Cancel and Confirm</li>
|
320
|
+
</ul>
|
321
|
+
</div>
|
322
|
+
<% end %>
|
323
|
+
<% end %>
|