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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -0
  4. data/lib/generators/ruby_ui/install/docs_generator.rb +33 -0
  5. data/lib/ruby_ui/accordion/accordion_docs.rb +53 -0
  6. data/lib/ruby_ui/alert/alert_docs.rb +135 -0
  7. data/lib/ruby_ui/alert_dialog/alert_dialog_docs.rb +35 -0
  8. data/lib/ruby_ui/aspect_ratio/aspect_ratio_docs.rb +64 -0
  9. data/lib/ruby_ui/avatar/avatar_docs.rb +92 -0
  10. data/lib/ruby_ui/badge/badge_docs.rb +80 -0
  11. data/lib/ruby_ui/breadcrumb/breadcrumb_docs.rb +116 -0
  12. data/lib/ruby_ui/button/button_docs.rb +143 -0
  13. data/lib/ruby_ui/calendar/calendar_docs.rb +34 -0
  14. data/lib/ruby_ui/card/card_docs.rb +114 -0
  15. data/lib/ruby_ui/carousel/carousel_docs.rb +104 -0
  16. data/lib/ruby_ui/chart/chart_docs.rb +115 -0
  17. data/lib/ruby_ui/checkbox/checkbox.rb +2 -2
  18. data/lib/ruby_ui/checkbox/checkbox_docs.rb +41 -0
  19. data/lib/ruby_ui/clipboard/clipboard_docs.rb +30 -0
  20. data/lib/ruby_ui/codeblock/codeblock_docs.rb +55 -0
  21. data/lib/ruby_ui/collapsible/collapsible_docs.rb +96 -0
  22. data/lib/ruby_ui/combobox/combobox_controller.js +16 -1
  23. data/lib/ruby_ui/combobox/combobox_docs.rb +151 -0
  24. data/lib/ruby_ui/combobox/combobox_popover.rb +2 -1
  25. data/lib/ruby_ui/combobox/combobox_toggle_all_checkbox.rb +3 -2
  26. data/lib/ruby_ui/combobox/combobox_trigger.rb +1 -1
  27. data/lib/ruby_ui/command/command_docs.rb +154 -0
  28. data/lib/ruby_ui/context_menu/context_menu.rb +1 -1
  29. data/lib/ruby_ui/context_menu/context_menu_docs.rb +85 -0
  30. data/lib/ruby_ui/dialog/dialog_docs.rb +102 -0
  31. data/lib/ruby_ui/docs/base.rb +90 -0
  32. data/lib/ruby_ui/docs/component_setup_tabs.rb +15 -0
  33. data/lib/ruby_ui/docs/components_table.rb +13 -0
  34. data/lib/ruby_ui/docs/header.rb +17 -0
  35. data/lib/ruby_ui/docs/sidebar_examples.rb +22 -0
  36. data/lib/ruby_ui/docs/visual_code_example.rb +22 -0
  37. data/lib/ruby_ui/dropdown_menu/dropdown_menu_docs.rb +212 -0
  38. data/lib/ruby_ui/form/form_docs.rb +178 -0
  39. data/lib/ruby_ui/form/form_field.rb +1 -1
  40. data/lib/ruby_ui/form/form_field_error.rb +1 -1
  41. data/lib/ruby_ui/form/form_field_hint.rb +1 -1
  42. data/lib/ruby_ui/form/form_field_label.rb +1 -1
  43. data/lib/ruby_ui/hover_card/hover_card_docs.rb +71 -0
  44. data/lib/ruby_ui/input/input.rb +4 -3
  45. data/lib/ruby_ui/input/input_docs.rb +68 -0
  46. data/lib/ruby_ui/link/link_docs.rb +106 -0
  47. data/lib/ruby_ui/masked_input/masked_input_docs.rb +47 -0
  48. data/lib/ruby_ui/pagination/pagination_docs.rb +127 -0
  49. data/lib/ruby_ui/popover/popover_docs.rb +971 -0
  50. data/lib/ruby_ui/progress/progress_docs.rb +27 -0
  51. data/lib/ruby_ui/radio_button/radio_button.rb +1 -1
  52. data/lib/ruby_ui/radio_button/radio_button_docs.rb +53 -0
  53. data/lib/ruby_ui/select/select_docs.rb +129 -0
  54. data/lib/ruby_ui/separator/separator_docs.rb +36 -0
  55. data/lib/ruby_ui/sheet/sheet_content.rb +1 -1
  56. data/lib/ruby_ui/sheet/sheet_docs.rb +76 -0
  57. data/lib/ruby_ui/shortcut_key/shortcut_key_docs.rb +29 -0
  58. data/lib/ruby_ui/sidebar/sidebar_docs.rb +176 -0
  59. data/lib/ruby_ui/skeleton/skeleton_docs.rb +29 -0
  60. data/lib/ruby_ui/switch/switch_docs.rb +46 -0
  61. data/lib/ruby_ui/table/table_docs.rb +102 -0
  62. data/lib/ruby_ui/tabs/tabs_docs.rb +211 -0
  63. data/lib/ruby_ui/textarea/textarea_docs.rb +54 -0
  64. data/lib/ruby_ui/theme_toggle/theme_toggle_docs.rb +71 -0
  65. data/lib/ruby_ui/tooltip/tooltip_docs.rb +52 -0
  66. data/lib/ruby_ui/typography/typography_docs.rb +107 -0
  67. data/lib/ruby_ui.rb +1 -1
  68. 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
- openPopover(event) {
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#closeDialog:prevent
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
- "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none"
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",
@@ -31,7 +31,7 @@ module RubyUI
31
31
  data: {
32
32
  placeholder: @placeholder,
33
33
  ruby_ui__combobox_target: "trigger",
34
- action: "ruby-ui--combobox#openPopover"
34
+ action: "ruby-ui--combobox#togglePopover"
35
35
  },
36
36
  aria: {
37
37
  haspopup: "listbox",
@@ -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
@@ -18,7 +18,7 @@ module RubyUI
18
18
  {
19
19
  data: {
20
20
  controller: "ruby-ui--context-menu",
21
- popover_options_value: @options.to_json
21
+ ruby_ui__context_menu_options_value: @options.to_json
22
22
  }
23
23
  }
24
24
  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