ruby_ui 1.0.1 → 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 +6 -0
- data/lib/generators/ruby_ui/component/all_generator.rb +22 -0
- data/lib/generators/ruby_ui/component_generator.rb +4 -3
- data/lib/generators/ruby_ui/install/docs_generator.rb +33 -0
- data/lib/generators/ruby_ui/install/install_generator.rb +1 -7
- data/lib/generators/ruby_ui/install/templates/tailwind.css.erb +0 -3
- data/lib/generators/ruby_ui/javascript_utils.rb +4 -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_content.rb +2 -3
- 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.rb +32 -16
- 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 +7 -1
- 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.rb +3 -2
- data/lib/ruby_ui/combobox/combobox_checkbox.rb +4 -2
- data/lib/ruby_ui/combobox/combobox_controller.js +20 -5
- data/lib/ruby_ui/combobox/combobox_docs.rb +151 -0
- data/lib/ruby_ui/combobox/combobox_item.rb +2 -1
- data/lib/ruby_ui/combobox/combobox_popover.rb +2 -1
- data/lib/ruby_ui/combobox/combobox_radio.rb +8 -1
- data/lib/ruby_ui/combobox/combobox_search_input.rb +11 -5
- data/lib/ruby_ui/combobox/combobox_toggle_all_checkbox.rb +4 -2
- data/lib/ruby_ui/combobox/combobox_trigger.rb +8 -2
- data/lib/ruby_ui/command/command_controller.js +0 -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_content.rb +2 -3
- data/lib/ruby_ui/dialog/dialog_controller.js +1 -1
- 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.rb +9 -0
- data/lib/ruby_ui/dropdown_menu/dropdown_menu_content.rb +17 -2
- data/lib/ruby_ui/dropdown_menu/dropdown_menu_controller.js +43 -14
- 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 +7 -1
- data/lib/ruby_ui/hover_card/hover_card_docs.rb +71 -0
- data/lib/ruby_ui/input/input.rb +9 -1
- data/lib/ruby_ui/input/input_docs.rb +68 -0
- data/lib/ruby_ui/link/link.rb +32 -16
- 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 +3 -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/select/select_item.rb +14 -5
- data/lib/ruby_ui/select/select_trigger.rb +9 -4
- 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/collapsible_sidebar.rb +99 -0
- data/lib/ruby_ui/sidebar/mobile_sidebar.rb +45 -0
- data/lib/ruby_ui/sidebar/non_collapsible_sidebar.rb +17 -0
- data/lib/ruby_ui/sidebar/sidebar.rb +29 -0
- data/lib/ruby_ui/sidebar/sidebar_content.rb +20 -0
- data/lib/ruby_ui/sidebar/sidebar_controller.js +67 -0
- data/lib/ruby_ui/sidebar/sidebar_docs.rb +176 -0
- data/lib/ruby_ui/sidebar/sidebar_footer.rb +20 -0
- data/lib/ruby_ui/sidebar/sidebar_group.rb +20 -0
- data/lib/ruby_ui/sidebar/sidebar_group_action.rb +33 -0
- data/lib/ruby_ui/sidebar/sidebar_group_content.rb +20 -0
- data/lib/ruby_ui/sidebar/sidebar_group_label.rb +26 -0
- data/lib/ruby_ui/sidebar/sidebar_header.rb +20 -0
- data/lib/ruby_ui/sidebar/sidebar_input.rb +20 -0
- data/lib/ruby_ui/sidebar/sidebar_inset.rb +23 -0
- data/lib/ruby_ui/sidebar/sidebar_menu.rb +20 -0
- data/lib/ruby_ui/sidebar/sidebar_menu_action.rb +48 -0
- data/lib/ruby_ui/sidebar/sidebar_menu_badge.rb +30 -0
- data/lib/ruby_ui/sidebar/sidebar_menu_button.rb +63 -0
- data/lib/ruby_ui/sidebar/sidebar_menu_item.rb +20 -0
- data/lib/ruby_ui/sidebar/sidebar_menu_skeleton.rb +36 -0
- data/lib/ruby_ui/sidebar/sidebar_menu_sub.rb +24 -0
- data/lib/ruby_ui/sidebar/sidebar_menu_sub_button.rb +50 -0
- data/lib/ruby_ui/sidebar/sidebar_menu_sub_item.rb +9 -0
- data/lib/ruby_ui/sidebar/sidebar_rail.rb +36 -0
- data/lib/ruby_ui/sidebar/sidebar_separator.rb +20 -0
- data/lib/ruby_ui/sidebar/sidebar_trigger.rb +42 -0
- data/lib/ruby_ui/sidebar/sidebar_wrapper.rb +24 -0
- data/lib/ruby_ui/skeleton/skeleton_docs.rb +29 -0
- data/lib/ruby_ui/switch/switch.rb +12 -2
- data/lib/ruby_ui/switch/switch_docs.rb +46 -0
- data/lib/ruby_ui/table/table_docs.rb +102 -0
- data/lib/ruby_ui/table/table_footer.rb +1 -1
- data/lib/ruby_ui/table/table_row.rb +1 -1
- data/lib/ruby_ui/tabs/tabs_docs.rb +211 -0
- data/lib/ruby_ui/tabs/tabs_trigger.rb +7 -1
- data/lib/ruby_ui/textarea/textarea.rb +8 -1
- 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_controller.js +5 -4
- 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 +81 -6
|
@@ -21,11 +21,17 @@ module RubyUI
|
|
|
21
21
|
def default_attrs
|
|
22
22
|
{
|
|
23
23
|
type: "button",
|
|
24
|
-
class:
|
|
24
|
+
class: [
|
|
25
|
+
"flex h-full w-full items-center whitespace-nowrap rounded-md text-sm ring-offset-background transition-colors border border-input bg-background h-9 px-4 py-2 justify-between",
|
|
26
|
+
"hover:bg-accent hover:text-accent-foreground",
|
|
27
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
28
|
+
"aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-disabled:cursor-not-allowed",
|
|
29
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
|
30
|
+
],
|
|
25
31
|
data: {
|
|
26
32
|
placeholder: @placeholder,
|
|
27
33
|
ruby_ui__combobox_target: "trigger",
|
|
28
|
-
action: "ruby-ui--combobox#
|
|
34
|
+
action: "ruby-ui--combobox#togglePopover"
|
|
29
35
|
},
|
|
30
36
|
aria: {
|
|
31
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
|
|
@@ -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
|
|
@@ -34,7 +34,7 @@ module RubyUI
|
|
|
34
34
|
{
|
|
35
35
|
data_state: "open",
|
|
36
36
|
class: [
|
|
37
|
-
"fixed flex flex-col pointer-events-auto left-[50%] top-[50%] z-50 w-full max-h-screen overflow-y-auto translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=
|
|
37
|
+
"fixed flex flex-col pointer-events-auto left-[50%] top-[50%] z-50 w-full max-h-screen overflow-y-auto translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:rounded-lg md:w-full",
|
|
38
38
|
SIZES[@size]
|
|
39
39
|
]
|
|
40
40
|
}
|
|
@@ -70,8 +70,7 @@ module RubyUI
|
|
|
70
70
|
div(
|
|
71
71
|
data_state: "open",
|
|
72
72
|
data_action: "click->ruby-ui--dialog#dismiss esc->ruby-ui--dialog#dismiss",
|
|
73
|
-
class:
|
|
74
|
-
"fixed pointer-events-auto inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
|
|
73
|
+
class: "fixed pointer-events-auto inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=open]:fade-in-0"
|
|
75
74
|
)
|
|
76
75
|
end
|
|
77
76
|
end
|
|
@@ -17,7 +17,7 @@ export default class extends Controller {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
open(e) {
|
|
20
|
-
e
|
|
20
|
+
e?.preventDefault();
|
|
21
21
|
document.body.insertAdjacentHTML('beforeend', this.contentTarget.innerHTML)
|
|
22
22
|
// prevent scroll on body
|
|
23
23
|
document.body.classList.add('overflow-hidden')
|
|
@@ -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
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Views
|
|
4
|
+
class Base < Phlex::HTML
|
|
5
|
+
def Heading(level:, &)
|
|
6
|
+
tag = :"h#{level}"
|
|
7
|
+
send(tag, &)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def component_files(component_name)
|
|
11
|
+
[]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Text helper for wrapping paragraphs
|
|
15
|
+
def Text(&)
|
|
16
|
+
p(&)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# InlineLink helper for documentation links
|
|
20
|
+
def InlineLink(href:, target: nil, class: nil, &)
|
|
21
|
+
a(href: href, target: target, class: binding.local_variable_get(:class), &)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Alert component helpers
|
|
25
|
+
def Alert(&)
|
|
26
|
+
div(&)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def AlertTitle(&)
|
|
30
|
+
h4(&)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def AlertDescription(&)
|
|
34
|
+
p(&)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Route helper stubs - return "#" as placeholder
|
|
38
|
+
def docs_sheet_path
|
|
39
|
+
"#"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def docs_separator_path
|
|
43
|
+
"#"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def docs_accordion_path
|
|
47
|
+
"#"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def docs_alert_path
|
|
51
|
+
"#"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def docs_alert_dialog_path
|
|
55
|
+
"#"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def docs_aspect_ratio_path
|
|
59
|
+
"#"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def docs_avatar_path
|
|
63
|
+
"#"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def docs_badge_path
|
|
67
|
+
"#"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def docs_installation_path
|
|
71
|
+
"#"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# InlineCode helper for typography examples
|
|
75
|
+
def InlineCode(&)
|
|
76
|
+
code(&)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Module-level components stub
|
|
82
|
+
module Components
|
|
83
|
+
def self.Heading(level:, &block)
|
|
84
|
+
# Stub for module-level Heading calls
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def self.TypographyList(items:, numbered: false)
|
|
88
|
+
# Stub for TypographyList component
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Components
|
|
4
|
+
module ComponentSetup
|
|
5
|
+
class Tabs < Phlex::HTML
|
|
6
|
+
def initialize(component_name:)
|
|
7
|
+
@component_name = component_name
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def view_template
|
|
11
|
+
# Minimal stub - empty by default
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Docs
|
|
4
|
+
class Header < Phlex::HTML
|
|
5
|
+
def initialize(title:, description: nil)
|
|
6
|
+
@title = title
|
|
7
|
+
@description = description
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def view_template
|
|
11
|
+
div do
|
|
12
|
+
h1 { @title }
|
|
13
|
+
p { @description } if @description
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Stub constants for sidebar documentation examples
|
|
4
|
+
# These are replaced with actual implementations in the web app
|
|
5
|
+
|
|
6
|
+
module Views
|
|
7
|
+
module Docs
|
|
8
|
+
class Sidebar < Views::Base
|
|
9
|
+
class Example
|
|
10
|
+
CODE = <<~RUBY
|
|
11
|
+
# Sidebar example code placeholder
|
|
12
|
+
RUBY
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class InsetExample
|
|
16
|
+
CODE = <<~RUBY
|
|
17
|
+
# Sidebar inset example code placeholder
|
|
18
|
+
RUBY
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Docs
|
|
4
|
+
class VisualCodeExample < Phlex::HTML
|
|
5
|
+
def initialize(title:, context:, description: nil, src: nil)
|
|
6
|
+
@title = title
|
|
7
|
+
@context = context
|
|
8
|
+
@description = description
|
|
9
|
+
@src = src
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def view_template(&block)
|
|
13
|
+
code = block.call
|
|
14
|
+
div do
|
|
15
|
+
h3 { @title }
|
|
16
|
+
p { @description } if @description
|
|
17
|
+
pre { code }
|
|
18
|
+
@context.instance_eval(code)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -15,6 +15,11 @@ module RubyUI
|
|
|
15
15
|
|
|
16
16
|
def default_attrs
|
|
17
17
|
{
|
|
18
|
+
class: [
|
|
19
|
+
"z-50",
|
|
20
|
+
"group/dropdown-menu",
|
|
21
|
+
(strategy == "absolute") ? "is-absolute" : "is-fixed"
|
|
22
|
+
],
|
|
18
23
|
data: {
|
|
19
24
|
controller: "ruby-ui--dropdown-menu",
|
|
20
25
|
action: "click@window->ruby-ui--dropdown-menu#onClickOutside",
|
|
@@ -22,5 +27,9 @@ module RubyUI
|
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
29
|
end
|
|
30
|
+
|
|
31
|
+
def strategy
|
|
32
|
+
@_strategy ||= @options[:strategy] || "absolute"
|
|
33
|
+
end
|
|
25
34
|
end
|
|
26
35
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module RubyUI
|
|
4
4
|
class DropdownMenuContent < Base
|
|
5
5
|
def view_template(&block)
|
|
6
|
-
div(
|
|
6
|
+
div(**wrapper_attrs) do
|
|
7
7
|
div(**attrs, &block)
|
|
8
8
|
end
|
|
9
9
|
end
|
|
@@ -15,7 +15,22 @@ module RubyUI
|
|
|
15
15
|
data: {
|
|
16
16
|
state: :open
|
|
17
17
|
},
|
|
18
|
-
class: "z-50 min-w-[8rem]
|
|
18
|
+
class: "z-50 min-w-[8rem] rounded-md border bg-background p-1 text-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 w-56"
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def wrapper_attrs
|
|
23
|
+
{
|
|
24
|
+
class: [
|
|
25
|
+
"z-50 hidden group-[.is-absolute]/dropdown-menu:absolute",
|
|
26
|
+
"group-[.is-fixed]/dropdown-menu:fixed"
|
|
27
|
+
],
|
|
28
|
+
data: {ruby_ui__dropdown_menu_target: "content"},
|
|
29
|
+
style: {
|
|
30
|
+
width: "max-content",
|
|
31
|
+
top: "0",
|
|
32
|
+
left: "0"
|
|
33
|
+
}
|
|
19
34
|
}
|
|
20
35
|
end
|
|
21
36
|
end
|