ruby_ui 1.0.2 → 1.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 +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +4 -0
- data/lib/generators/ruby_ui/install/docs_generator.rb +33 -0
- data/lib/ruby_ui/accordion/accordion_docs.rb +53 -0
- data/lib/ruby_ui/alert/alert_docs.rb +135 -0
- data/lib/ruby_ui/alert_dialog/alert_dialog_docs.rb +35 -0
- data/lib/ruby_ui/aspect_ratio/aspect_ratio_docs.rb +64 -0
- data/lib/ruby_ui/avatar/avatar_docs.rb +92 -0
- data/lib/ruby_ui/badge/badge_docs.rb +80 -0
- data/lib/ruby_ui/breadcrumb/breadcrumb_docs.rb +116 -0
- data/lib/ruby_ui/button/button_docs.rb +143 -0
- data/lib/ruby_ui/calendar/calendar_docs.rb +34 -0
- data/lib/ruby_ui/card/card_docs.rb +114 -0
- data/lib/ruby_ui/carousel/carousel_docs.rb +104 -0
- data/lib/ruby_ui/chart/chart_docs.rb +115 -0
- data/lib/ruby_ui/checkbox/checkbox.rb +2 -2
- data/lib/ruby_ui/checkbox/checkbox_docs.rb +41 -0
- data/lib/ruby_ui/clipboard/clipboard_docs.rb +30 -0
- data/lib/ruby_ui/codeblock/codeblock_docs.rb +55 -0
- data/lib/ruby_ui/collapsible/collapsible_docs.rb +96 -0
- data/lib/ruby_ui/combobox/combobox_controller.js +16 -1
- data/lib/ruby_ui/combobox/combobox_docs.rb +151 -0
- data/lib/ruby_ui/combobox/combobox_popover.rb +2 -1
- data/lib/ruby_ui/combobox/combobox_toggle_all_checkbox.rb +3 -2
- data/lib/ruby_ui/combobox/combobox_trigger.rb +1 -1
- data/lib/ruby_ui/command/command_docs.rb +154 -0
- data/lib/ruby_ui/context_menu/context_menu.rb +1 -1
- data/lib/ruby_ui/context_menu/context_menu_docs.rb +85 -0
- data/lib/ruby_ui/dialog/dialog_docs.rb +102 -0
- data/lib/ruby_ui/docs/base.rb +90 -0
- data/lib/ruby_ui/docs/component_setup_tabs.rb +15 -0
- data/lib/ruby_ui/docs/components_table.rb +13 -0
- data/lib/ruby_ui/docs/header.rb +17 -0
- data/lib/ruby_ui/docs/sidebar_examples.rb +22 -0
- data/lib/ruby_ui/docs/visual_code_example.rb +22 -0
- data/lib/ruby_ui/dropdown_menu/dropdown_menu_docs.rb +212 -0
- data/lib/ruby_ui/form/form_docs.rb +178 -0
- data/lib/ruby_ui/form/form_field.rb +1 -1
- data/lib/ruby_ui/form/form_field_error.rb +1 -1
- data/lib/ruby_ui/form/form_field_hint.rb +1 -1
- data/lib/ruby_ui/form/form_field_label.rb +1 -1
- data/lib/ruby_ui/hover_card/hover_card_docs.rb +71 -0
- data/lib/ruby_ui/input/input.rb +4 -3
- data/lib/ruby_ui/input/input_docs.rb +68 -0
- data/lib/ruby_ui/link/link_docs.rb +106 -0
- data/lib/ruby_ui/masked_input/masked_input_docs.rb +47 -0
- data/lib/ruby_ui/pagination/pagination_docs.rb +127 -0
- data/lib/ruby_ui/popover/popover_docs.rb +971 -0
- data/lib/ruby_ui/progress/progress_docs.rb +27 -0
- data/lib/ruby_ui/radio_button/radio_button.rb +1 -1
- data/lib/ruby_ui/radio_button/radio_button_docs.rb +53 -0
- data/lib/ruby_ui/select/select_docs.rb +129 -0
- data/lib/ruby_ui/separator/separator_docs.rb +36 -0
- data/lib/ruby_ui/sheet/sheet_content.rb +1 -1
- data/lib/ruby_ui/sheet/sheet_docs.rb +76 -0
- data/lib/ruby_ui/shortcut_key/shortcut_key_docs.rb +29 -0
- data/lib/ruby_ui/sidebar/sidebar_docs.rb +176 -0
- data/lib/ruby_ui/skeleton/skeleton_docs.rb +29 -0
- data/lib/ruby_ui/switch/switch_docs.rb +46 -0
- data/lib/ruby_ui/table/table_docs.rb +102 -0
- data/lib/ruby_ui/tabs/tabs_docs.rb +211 -0
- data/lib/ruby_ui/textarea/textarea_docs.rb +54 -0
- data/lib/ruby_ui/theme_toggle/theme_toggle_docs.rb +71 -0
- data/lib/ruby_ui/tooltip/tooltip_docs.rb +52 -0
- data/lib/ruby_ui/typography/typography_docs.rb +107 -0
- data/lib/ruby_ui.rb +1 -1
- metadata +53 -6
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Views::Docs::Collapsible < Views::Base
|
|
4
|
+
def view_template
|
|
5
|
+
component = "Collapsible"
|
|
6
|
+
div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do
|
|
7
|
+
render Docs::Header.new(title: "Collapsible", description: "An interactive component which expands/collapses a panel.")
|
|
8
|
+
|
|
9
|
+
Heading(level: 2) { "Usage" }
|
|
10
|
+
|
|
11
|
+
render Docs::VisualCodeExample.new(title: "Example", context: self) do
|
|
12
|
+
<<~RUBY
|
|
13
|
+
Collapsible do
|
|
14
|
+
div(class: "flex items-center justify-between space-x-4 px-4 py-2") do
|
|
15
|
+
h4(class: "text-sm font-semibold") { " @joeldrapper starred 3 repositories" }
|
|
16
|
+
CollapsibleTrigger do
|
|
17
|
+
Button(variant: :ghost, icon: true) do
|
|
18
|
+
chevron_icon
|
|
19
|
+
span(class: "sr-only") { "Toggle" }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
div(class: "rounded-md border px-4 py-2 font-mono text-sm shadow-sm") do
|
|
25
|
+
"phlex-ruby/phlex"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
CollapsibleContent do
|
|
29
|
+
div(class: 'space-y-2 mt-2') do
|
|
30
|
+
div(class: "rounded-md border px-4 py-2 font-mono text-sm shadow-sm") do
|
|
31
|
+
"phlex-ruby/phlex-rails"
|
|
32
|
+
end
|
|
33
|
+
div(class: "rounded-md border px-4 py-2 font-mono text-sm shadow-sm") do
|
|
34
|
+
"ruby-ui/ruby_ui"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
RUBY
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
render Docs::VisualCodeExample.new(title: "Open", context: self) do
|
|
43
|
+
<<~RUBY
|
|
44
|
+
Collapsible(open: true) do
|
|
45
|
+
div(class: "flex items-center justify-between space-x-4 px-4 py-2") do
|
|
46
|
+
h4(class: "text-sm font-semibold") { " @joeldrapper starred 3 repositories" }
|
|
47
|
+
CollapsibleTrigger do
|
|
48
|
+
Button(variant: :ghost, icon: true) do
|
|
49
|
+
chevron_icon
|
|
50
|
+
span(class: "sr-only") { "Toggle" }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
div(class: "rounded-md border px-4 py-2 font-mono text-sm shadow-sm") do
|
|
56
|
+
"phlex-ruby/phlex"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
CollapsibleContent do
|
|
60
|
+
div(class: 'space-y-2 mt-2') do
|
|
61
|
+
div(class: "rounded-md border px-4 py-2 font-mono text-sm shadow-sm") do
|
|
62
|
+
"phlex-ruby/phlex-rails"
|
|
63
|
+
end
|
|
64
|
+
div(class: "rounded-md border px-4 py-2 font-mono text-sm shadow-sm") do
|
|
65
|
+
"ruby-ui/ruby_ui"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
RUBY
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
render Components::ComponentSetup::Tabs.new(component_name: component)
|
|
74
|
+
|
|
75
|
+
render Docs::ComponentsTable.new(component_files(component))
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def chevron_icon
|
|
82
|
+
svg(
|
|
83
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
84
|
+
viewbox: "0 0 20 20",
|
|
85
|
+
fill: "currentColor",
|
|
86
|
+
class: "w-4 h-4"
|
|
87
|
+
) do |s|
|
|
88
|
+
s.path(
|
|
89
|
+
fill_rule: "evenodd",
|
|
90
|
+
d:
|
|
91
|
+
"M10 3a.75.75 0 01.55.24l3.25 3.5a.75.75 0 11-1.1 1.02L10 4.852 7.3 7.76a.75.75 0 01-1.1-1.02l3.25-3.5A.75.75 0 0110 3zm-3.76 9.2a.75.75 0 011.06.04l2.7 2.908 2.7-2.908a.75.75 0 111.1 1.02l-3.25 3.5a.75.75 0 01-1.1 0l-3.25-3.5a.75.75 0 01.04-1.06z",
|
|
92
|
+
clip_rule: "evenodd"
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -28,6 +28,11 @@ export default class extends Controller {
|
|
|
28
28
|
if (this.cleanup) { this.cleanup() }
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
handlePopoverToggle(event) {
|
|
32
|
+
// Keep ariaExpanded in sync with the actual popover state
|
|
33
|
+
this.triggerTarget.ariaExpanded = event.newState === 'open' ? 'true' : 'false'
|
|
34
|
+
}
|
|
35
|
+
|
|
31
36
|
inputChanged(e) {
|
|
32
37
|
this.updateTriggerContent()
|
|
33
38
|
|
|
@@ -62,9 +67,19 @@ export default class extends Controller {
|
|
|
62
67
|
}
|
|
63
68
|
}
|
|
64
69
|
|
|
65
|
-
|
|
70
|
+
togglePopover(event) {
|
|
66
71
|
event.preventDefault()
|
|
67
72
|
|
|
73
|
+
if (this.triggerTarget.ariaExpanded === "true") {
|
|
74
|
+
this.closePopover()
|
|
75
|
+
} else {
|
|
76
|
+
this.openPopover(event)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
openPopover(event) {
|
|
81
|
+
if (event) event.preventDefault()
|
|
82
|
+
|
|
68
83
|
this.updatePopoverPosition()
|
|
69
84
|
this.updatePopoverWidth()
|
|
70
85
|
this.triggerTarget.ariaExpanded = "true"
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Views::Docs::Combobox < Views::Base
|
|
4
|
+
@@code_example = nil
|
|
5
|
+
|
|
6
|
+
def view_template
|
|
7
|
+
component = "Combobox"
|
|
8
|
+
div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do
|
|
9
|
+
render Docs::Header.new(title: component, description: "Autocomplete input and command palette with a list of suggestions.")
|
|
10
|
+
|
|
11
|
+
Heading(level: 2) { "Usage" }
|
|
12
|
+
|
|
13
|
+
render Docs::VisualCodeExample.new(title: "Single option", context: self) do
|
|
14
|
+
<<~RUBY
|
|
15
|
+
div class: "w-96" do
|
|
16
|
+
Combobox do
|
|
17
|
+
ComboboxTrigger placeholder: "Pick value"
|
|
18
|
+
|
|
19
|
+
ComboboxPopover do
|
|
20
|
+
ComboboxSearchInput(placeholder: "Pick value or type anything")
|
|
21
|
+
|
|
22
|
+
ComboboxList do
|
|
23
|
+
ComboboxEmptyState { "No result" }
|
|
24
|
+
|
|
25
|
+
ComboboxListGroup(label: "Fruits") do
|
|
26
|
+
ComboboxItem do
|
|
27
|
+
ComboboxRadio(name: "food", value: "apple")
|
|
28
|
+
span { "Apple" }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
ComboboxItem do
|
|
32
|
+
ComboboxRadio(name: "food", value: "banana")
|
|
33
|
+
span { "Banana" }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
ComboboxListGroup(label: "Vegetable") do
|
|
38
|
+
ComboboxItem do
|
|
39
|
+
ComboboxRadio(name: "food", value: "brocoli")
|
|
40
|
+
span { "Broccoli" }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
ComboboxItem do
|
|
44
|
+
ComboboxRadio(name: "food", value: "carrot")
|
|
45
|
+
span { "Carrot" }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
ComboboxListGroup(label: "Others") do
|
|
50
|
+
ComboboxItem do
|
|
51
|
+
ComboboxRadio(name: "food", value: "chocolate")
|
|
52
|
+
span { "Chocolate" }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
ComboboxItem do
|
|
56
|
+
ComboboxRadio(name: "food", value: "milk")
|
|
57
|
+
span { "Milk" }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
RUBY
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
render Docs::VisualCodeExample.new(title: "Multiple options", context: self) do
|
|
68
|
+
<<~RUBY
|
|
69
|
+
div class: "w-96" do
|
|
70
|
+
Combobox term: "things" do
|
|
71
|
+
ComboboxTrigger placeholder: "Pick value"
|
|
72
|
+
|
|
73
|
+
ComboboxPopover do
|
|
74
|
+
ComboboxSearchInput(placeholder: "Pick value or type anything")
|
|
75
|
+
|
|
76
|
+
ComboboxList do
|
|
77
|
+
ComboboxEmptyState { "No result" }
|
|
78
|
+
|
|
79
|
+
ComboboxItem(class: "mt-3") do
|
|
80
|
+
ComboboxToggleAllCheckbox(name: "all", value: "all")
|
|
81
|
+
span { "Select all" }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
ComboboxListGroup label: "Fruits" do
|
|
85
|
+
ComboboxItem do
|
|
86
|
+
ComboboxCheckbox(name: "food", value: "apple")
|
|
87
|
+
span { "Apple" }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
ComboboxItem do
|
|
91
|
+
ComboboxCheckbox(name: "food", value: "banana")
|
|
92
|
+
span { "Banana" }
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
ComboboxListGroup label: "Vegetable" do
|
|
97
|
+
ComboboxItem do
|
|
98
|
+
ComboboxCheckbox(name: "food", value: "brocoli")
|
|
99
|
+
span { "Broccoli" }
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
ComboboxItem do
|
|
103
|
+
ComboboxCheckbox(name: "food", value: "carrot")
|
|
104
|
+
span { "Carrot" }
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
ComboboxListGroup label: "Others" do
|
|
109
|
+
ComboboxItem do
|
|
110
|
+
ComboboxCheckbox(name: "food", value: "chocolate")
|
|
111
|
+
span { "Chocolate" }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
ComboboxItem do
|
|
115
|
+
ComboboxCheckbox(name: "food", value: "milk")
|
|
116
|
+
span { "Milk" }
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
RUBY
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
render Docs::VisualCodeExample.new(title: "Disabled", context: self) do
|
|
127
|
+
<<~RUBY
|
|
128
|
+
div(class: "w-96") do
|
|
129
|
+
Combobox do
|
|
130
|
+
ComboboxTrigger(disabled: true, placeholder: "Pick value")
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
RUBY
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
render Docs::VisualCodeExample.new(title: "Aria Disabled", context: self) do
|
|
137
|
+
<<~RUBY
|
|
138
|
+
div(class: "w-96") do
|
|
139
|
+
Combobox do
|
|
140
|
+
ComboboxTrigger(aria: {disabled: "true"}, placeholder: "Pick value")
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
RUBY
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
render Components::ComponentSetup::Tabs.new(component_name: "Combobox")
|
|
147
|
+
|
|
148
|
+
render Docs::ComponentsTable.new(component_files("Combobox"))
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -17,10 +17,11 @@ module RubyUI
|
|
|
17
17
|
data: {
|
|
18
18
|
ruby_ui__combobox_target: "popover",
|
|
19
19
|
action: %w[
|
|
20
|
+
toggle->ruby-ui--combobox#handlePopoverToggle
|
|
20
21
|
keydown.down->ruby-ui--combobox#keyDownPressed
|
|
21
22
|
keydown.up->ruby-ui--combobox#keyUpPressed
|
|
22
23
|
keydown.enter->ruby-ui--combobox#keyEnterPressed
|
|
23
|
-
keydown.esc->ruby-ui--combobox#
|
|
24
|
+
keydown.esc->ruby-ui--combobox#closePopover:prevent
|
|
24
25
|
resize@window->ruby-ui--combobox#updatePopoverWidth
|
|
25
26
|
]
|
|
26
27
|
}
|
|
@@ -12,9 +12,10 @@ module RubyUI
|
|
|
12
12
|
{
|
|
13
13
|
class: [
|
|
14
14
|
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background accent-primary",
|
|
15
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
16
15
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
17
|
-
"
|
|
16
|
+
"checked:bg-primary checked:text-primary-foreground",
|
|
17
|
+
"aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none",
|
|
18
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
|
18
19
|
],
|
|
19
20
|
data: {
|
|
20
21
|
ruby_ui__combobox_target: "toggleAll",
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Views::Docs::Command < Views::Base
|
|
4
|
+
def view_template
|
|
5
|
+
component = "Command"
|
|
6
|
+
div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do
|
|
7
|
+
render Docs::Header.new(title: "Command", description: "Fast, composable, unstyled command menu for Phlex.")
|
|
8
|
+
|
|
9
|
+
Heading(level: 2) { "Usage" }
|
|
10
|
+
|
|
11
|
+
render Docs::VisualCodeExample.new(title: "Example", context: self) do
|
|
12
|
+
<<~RUBY
|
|
13
|
+
CommandDialog do
|
|
14
|
+
CommandDialogTrigger do
|
|
15
|
+
Button(variant: "outline", class: 'w-56 pr-2 pl-3 justify-between') do
|
|
16
|
+
div(class: "flex items-center space-x-1") do
|
|
17
|
+
search_icon
|
|
18
|
+
span(class: "text-muted-foreground font-normal") do
|
|
19
|
+
plain "Search"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
ShortcutKey do
|
|
23
|
+
span(class: "text-xs") { "⌘" }
|
|
24
|
+
plain "K"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
CommandDialogContent do
|
|
29
|
+
Command do
|
|
30
|
+
CommandInput(placeholder: "Type a command or search...")
|
|
31
|
+
CommandEmpty { "No results found." }
|
|
32
|
+
CommandList do
|
|
33
|
+
CommandGroup(title: "Components") do
|
|
34
|
+
components_list.each do |component|
|
|
35
|
+
CommandItem(value: component[:name], href: component[:path]) do
|
|
36
|
+
default_icon
|
|
37
|
+
plain component[:name]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
CommandGroup(title: "Settings") do
|
|
42
|
+
settings_list.each do |setting|
|
|
43
|
+
CommandItem(value: setting[:name], href: setting[:path]) do
|
|
44
|
+
default_icon
|
|
45
|
+
plain setting[:name]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
RUBY
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
render Docs::VisualCodeExample.new(title: "With keybinding", context: self) do
|
|
57
|
+
<<~RUBY
|
|
58
|
+
CommandDialog do
|
|
59
|
+
CommandDialogTrigger(keybindings: ['keydown.ctrl+j@window', 'keydown.meta+j@window']) do
|
|
60
|
+
p(class: "text-sm text-muted-foreground") do
|
|
61
|
+
span(class: 'mr-1') { "Press" }
|
|
62
|
+
ShortcutKey do
|
|
63
|
+
span(class: "text-xs") { "⌘" }
|
|
64
|
+
plain "J"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
CommandDialogContent do
|
|
69
|
+
Command do
|
|
70
|
+
CommandInput(placeholder: "Type a command or search...")
|
|
71
|
+
CommandEmpty { "No results found." }
|
|
72
|
+
CommandList do
|
|
73
|
+
CommandGroup(title: "Components") do
|
|
74
|
+
components_list.each do |component|
|
|
75
|
+
CommandItem(value: component[:name], href: component[:path]) do
|
|
76
|
+
default_icon
|
|
77
|
+
plain component[:name]
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
CommandGroup(title: "Settings") do
|
|
82
|
+
settings_list.each do |setting|
|
|
83
|
+
CommandItem(value: setting[:name], href: setting[:path]) do
|
|
84
|
+
default_icon
|
|
85
|
+
plain setting[:name]
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
RUBY
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
render Components::ComponentSetup::Tabs.new(component_name: component)
|
|
97
|
+
|
|
98
|
+
render Docs::ComponentsTable.new(component_files(component))
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
private
|
|
103
|
+
|
|
104
|
+
def search_icon
|
|
105
|
+
svg(
|
|
106
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
107
|
+
viewbox: "0 0 20 20",
|
|
108
|
+
fill: "currentColor",
|
|
109
|
+
class: "w-4 h-4 mr-1.5"
|
|
110
|
+
) do |s|
|
|
111
|
+
s.path(
|
|
112
|
+
fill_rule: "evenodd",
|
|
113
|
+
d:
|
|
114
|
+
"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",
|
|
115
|
+
clip_rule: "evenodd"
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def default_icon
|
|
121
|
+
svg(
|
|
122
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
123
|
+
viewbox: "0 0 24 24",
|
|
124
|
+
fill: "currentColor",
|
|
125
|
+
class: "w-5 h-5"
|
|
126
|
+
) do |s|
|
|
127
|
+
s.path(
|
|
128
|
+
fill_rule: "evenodd",
|
|
129
|
+
d:
|
|
130
|
+
"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",
|
|
131
|
+
clip_rule: "evenodd"
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def components_list
|
|
137
|
+
[
|
|
138
|
+
{name: "Accordion", path: docs_accordion_path},
|
|
139
|
+
{name: "Alert", path: docs_alert_path},
|
|
140
|
+
{name: "Alert Dialog", path: docs_alert_dialog_path},
|
|
141
|
+
{name: "Aspect Ratio", path: docs_aspect_ratio_path},
|
|
142
|
+
{name: "Avatar", path: docs_avatar_path},
|
|
143
|
+
{name: "Badge", path: docs_badge_path}
|
|
144
|
+
]
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def settings_list
|
|
148
|
+
[
|
|
149
|
+
{name: "Profile", path: "#"},
|
|
150
|
+
{name: "Mail", path: "#"},
|
|
151
|
+
{name: "Settings", path: "#"}
|
|
152
|
+
]
|
|
153
|
+
end
|
|
154
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Views::Docs::ContextMenu < Views::Base
|
|
4
|
+
def view_template
|
|
5
|
+
component = "ContextMenu"
|
|
6
|
+
div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do
|
|
7
|
+
render Docs::Header.new(title: "Context Menu", description: "Displays a menu to the user — such as a set of actions or functions — triggered by a right click.")
|
|
8
|
+
|
|
9
|
+
Heading(level: 2) { "Usage" }
|
|
10
|
+
|
|
11
|
+
render Docs::VisualCodeExample.new(title: "Example", context: self) do
|
|
12
|
+
<<~RUBY
|
|
13
|
+
ContextMenu do
|
|
14
|
+
ContextMenuTrigger(class: 'flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm') { "Right click here" }
|
|
15
|
+
ContextMenuContent(class: 'w-64') do
|
|
16
|
+
ContextMenuItem(href: '#', shortcut: "⌘[") { "Back" }
|
|
17
|
+
ContextMenuItem(href: '#', shortcut: "⌘]", disabled: true) { "Forward" }
|
|
18
|
+
ContextMenuItem(href: '#', shortcut: "⌘R") { "Reload" }
|
|
19
|
+
ContextMenuSeparator
|
|
20
|
+
ContextMenuItem(href: '#', shortcut: "⌘⇧B", checked: true) { "Show Bookmarks Bar" }
|
|
21
|
+
ContextMenuItem(href: '#') { "Show Full URLs" }
|
|
22
|
+
ContextMenuSeparator
|
|
23
|
+
ContextMenuLabel(inset: true) { "More Tools" }
|
|
24
|
+
ContextMenuSeparator
|
|
25
|
+
ContextMenuItem(href: '#') { "Developer Tools" }
|
|
26
|
+
ContextMenuItem(href: '#') { "Task Manager" }
|
|
27
|
+
ContextMenuItem(href: '#') { "Extensions" }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
RUBY
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
render Docs::VisualCodeExample.new(title: "Placement", context: self) do
|
|
34
|
+
<<~RUBY
|
|
35
|
+
div(class: 'space-y-4') do
|
|
36
|
+
ContextMenu(options: { placement: 'right' }) do
|
|
37
|
+
ContextMenuTrigger(class: 'flex flex-col items-center gap-y-2 h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm') do
|
|
38
|
+
plain "Right click here"
|
|
39
|
+
Badge(variant: :primary) { "right" }
|
|
40
|
+
end
|
|
41
|
+
ContextMenuContent(class: 'w-64') do
|
|
42
|
+
ContextMenuItem(href: '#', shortcut: "⌘[") { "Back" }
|
|
43
|
+
ContextMenuItem(href: '#', shortcut: "⌘]", disabled: true) { "Forward" }
|
|
44
|
+
ContextMenuItem(href: '#', shortcut: "⌘R") { "Reload" }
|
|
45
|
+
ContextMenuSeparator
|
|
46
|
+
ContextMenuItem(href: '#', shortcut: "⌘⇧B", checked: true) { "Show Bookmarks Bar" }
|
|
47
|
+
ContextMenuItem(href: '#') { "Show Full URLs" }
|
|
48
|
+
ContextMenuSeparator
|
|
49
|
+
ContextMenuLabel(inset: true) { "More Tools" }
|
|
50
|
+
ContextMenuSeparator
|
|
51
|
+
ContextMenuItem(href: '#') { "Developer Tools" }
|
|
52
|
+
ContextMenuItem(href: '#') { "Task Manager" }
|
|
53
|
+
ContextMenuItem(href: '#') { "Extensions" }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
ContextMenu(options: { placement: 'left' }) do
|
|
57
|
+
ContextMenuTrigger(class: 'flex flex-col items-center gap-y-2 h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm') do
|
|
58
|
+
plain "Right click here"
|
|
59
|
+
Badge(variant: :primary) { "left" }
|
|
60
|
+
end
|
|
61
|
+
ContextMenuContent(class: 'w-64') do
|
|
62
|
+
ContextMenuItem(href: '#', shortcut: "⌘[") { "Back" }
|
|
63
|
+
ContextMenuItem(href: '#', shortcut: "⌘]", disabled: true) { "Forward" }
|
|
64
|
+
ContextMenuItem(href: '#', shortcut: "⌘R") { "Reload" }
|
|
65
|
+
ContextMenuSeparator
|
|
66
|
+
ContextMenuItem(href: '#', shortcut: "⌘⇧B", checked: true) { "Show Bookmarks Bar" }
|
|
67
|
+
ContextMenuItem(href: '#') { "Show Full URLs" }
|
|
68
|
+
ContextMenuSeparator
|
|
69
|
+
ContextMenuLabel(inset: true) { "More Tools" }
|
|
70
|
+
ContextMenuSeparator
|
|
71
|
+
ContextMenuItem(href: '#') { "Developer Tools" }
|
|
72
|
+
ContextMenuItem(href: '#') { "Task Manager" }
|
|
73
|
+
ContextMenuItem(href: '#') { "Extensions" }
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
RUBY
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
render Components::ComponentSetup::Tabs.new(component_name: component)
|
|
81
|
+
|
|
82
|
+
render Docs::ComponentsTable.new(component_files(component))
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Views::Docs::Dialog < Views::Base
|
|
4
|
+
def view_template
|
|
5
|
+
component = "Dialog"
|
|
6
|
+
|
|
7
|
+
div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do
|
|
8
|
+
render Docs::Header.new(title: "Dialog", description: "A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.")
|
|
9
|
+
|
|
10
|
+
Heading(level: 2) { "Usage" }
|
|
11
|
+
|
|
12
|
+
render Docs::VisualCodeExample.new(title: "Example", context: self) do
|
|
13
|
+
<<~RUBY
|
|
14
|
+
Dialog do
|
|
15
|
+
DialogTrigger do
|
|
16
|
+
Button { "Open Dialog" }
|
|
17
|
+
end
|
|
18
|
+
DialogContent do
|
|
19
|
+
DialogHeader do
|
|
20
|
+
DialogTitle { "RubyUI to the rescue" }
|
|
21
|
+
DialogDescription { "RubyUI helps you build accessible standard compliant web apps with ease" }
|
|
22
|
+
end
|
|
23
|
+
DialogMiddle do
|
|
24
|
+
AspectRatio(aspect_ratio: "16/9", class: 'rounded-md overflow-hidden border') do
|
|
25
|
+
img(
|
|
26
|
+
alt: "Placeholder",
|
|
27
|
+
loading: "lazy",
|
|
28
|
+
src: image_path("pattern.jpg")
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
DialogFooter do
|
|
33
|
+
Button(variant: :outline, data: { action: 'click->ruby-ui--dialog#dismiss' }) { "Cancel" }
|
|
34
|
+
Button { "Save" }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
RUBY
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
render Docs::VisualCodeExample.new(title: "Size", description: "Applicable for wider screens", context: self) do
|
|
42
|
+
<<~RUBY
|
|
43
|
+
div(class: 'flex flex-wrap justify-center gap-2') do
|
|
44
|
+
Dialog do
|
|
45
|
+
DialogTrigger do
|
|
46
|
+
Button { "Small Dialog" }
|
|
47
|
+
end
|
|
48
|
+
DialogContent(size: :sm) do
|
|
49
|
+
DialogHeader do
|
|
50
|
+
DialogTitle { "RubyUI to the rescue" }
|
|
51
|
+
DialogDescription { "RubyUI helps you build accessible standard compliant web apps with ease" }
|
|
52
|
+
end
|
|
53
|
+
DialogMiddle do
|
|
54
|
+
AspectRatio(aspect_ratio: "16/9", class: 'rounded-md overflow-hidden border') do
|
|
55
|
+
img(
|
|
56
|
+
alt: "Placeholder",
|
|
57
|
+
loading: "lazy",
|
|
58
|
+
src: image_path("pattern.jpg")
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
DialogFooter do
|
|
63
|
+
Button(variant: :outline, data: { action: 'click->ruby-ui--dialog#dismiss' }) { "Cancel" }
|
|
64
|
+
Button { "Save" }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
Dialog do
|
|
70
|
+
DialogTrigger do
|
|
71
|
+
Button { "Large Dialog" }
|
|
72
|
+
end
|
|
73
|
+
DialogContent(size: :lg) do
|
|
74
|
+
DialogHeader do
|
|
75
|
+
DialogTitle { "RubyUI to the rescue" }
|
|
76
|
+
DialogDescription { "RubyUI helps you build accessible standard compliant web apps with ease" }
|
|
77
|
+
end
|
|
78
|
+
DialogMiddle do
|
|
79
|
+
AspectRatio(aspect_ratio: "16/9", class: 'rounded-md overflow-hidden border') do
|
|
80
|
+
img(
|
|
81
|
+
alt: "Placeholder",
|
|
82
|
+
loading: "lazy",
|
|
83
|
+
src: image_path("pattern.jpg")
|
|
84
|
+
)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
DialogFooter do
|
|
88
|
+
Button(variant: :outline, data: { action: 'click->ruby-ui--dialog#dismiss' }) { "Cancel" }
|
|
89
|
+
Button { "Save" }
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
RUBY
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
render Components::ComponentSetup::Tabs.new(component_name: component)
|
|
98
|
+
|
|
99
|
+
render Docs::ComponentsTable.new(component_files(component))
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|