ruby_ui 1.0.0.pre.alpha.4 → 1.0.0.rc1
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 +21 -0
- data/README.md +85 -0
- data/lib/generators/ruby_ui/component_generator.rb +94 -0
- data/lib/generators/ruby_ui/dependencies.yml +74 -0
- data/lib/generators/ruby_ui/install/install_generator.rb +89 -0
- data/lib/generators/ruby_ui/install/templates/ruby_ui.rb.erb +18 -0
- data/lib/generators/ruby_ui/install/templates/tailwind.css.erb +156 -0
- data/lib/generators/ruby_ui/javascript_utils.rb +57 -0
- data/lib/{rbui → ruby_ui}/accordion/accordion.rb +1 -1
- data/lib/{rbui → ruby_ui}/accordion/accordion_content.rb +2 -2
- data/lib/ruby_ui/accordion/accordion_controller.js +97 -0
- data/lib/{rbui → ruby_ui}/accordion/accordion_default_content.rb +1 -1
- data/lib/{rbui → ruby_ui}/accordion/accordion_default_trigger.rb +3 -3
- data/lib/{rbui → ruby_ui}/accordion/accordion_icon.rb +2 -2
- data/lib/{rbui → ruby_ui}/accordion/accordion_item.rb +4 -4
- data/lib/{rbui → ruby_ui}/accordion/accordion_trigger.rb +3 -2
- data/lib/{rbui → ruby_ui}/alert/alert.rb +3 -3
- data/lib/{rbui → ruby_ui}/alert/alert_description.rb +1 -1
- data/lib/{rbui → ruby_ui}/alert/alert_title.rb +1 -1
- data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog.rb +3 -3
- data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_action.rb +2 -2
- data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_cancel.rb +3 -3
- data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_content.rb +5 -5
- data/lib/ruby_ui/alert_dialog/alert_dialog_controller.js +31 -0
- data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_description.rb +1 -1
- data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_footer.rb +2 -2
- data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_header.rb +2 -2
- data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_title.rb +1 -1
- data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_trigger.rb +2 -2
- data/lib/{rbui → ruby_ui}/aspect_ratio/aspect_ratio.rb +1 -1
- data/lib/{rbui → ruby_ui}/avatar/avatar.rb +2 -2
- data/lib/{rbui → ruby_ui}/avatar/avatar_fallback.rb +1 -1
- data/lib/{rbui → ruby_ui}/avatar/avatar_image.rb +1 -1
- data/lib/{rbui → ruby_ui}/badge/badge.rb +2 -2
- data/lib/{rbui → ruby_ui}/base.rb +1 -8
- data/lib/ruby_ui/breadcrumb/breadcrumb.rb +17 -0
- data/lib/ruby_ui/breadcrumb/breadcrumb_ellipsis.rb +39 -0
- data/lib/{rbui/typography/typography_list_item.rb → ruby_ui/breadcrumb/breadcrumb_item.rb} +3 -3
- data/lib/ruby_ui/breadcrumb/breadcrumb_link.rb +22 -0
- data/lib/ruby_ui/breadcrumb/breadcrumb_list.rb +17 -0
- data/lib/ruby_ui/breadcrumb/breadcrumb_page.rb +19 -0
- data/lib/ruby_ui/breadcrumb/breadcrumb_separator.rb +38 -0
- data/lib/{rbui → ruby_ui}/button/button.rb +13 -13
- data/lib/ruby_ui/calendar/calendar.rb +39 -0
- data/lib/{rbui → ruby_ui}/calendar/calendar_body.rb +2 -2
- data/lib/ruby_ui/calendar/calendar_controller.js +249 -0
- data/lib/{rbui → ruby_ui}/calendar/calendar_days.rb +14 -14
- data/lib/{rbui → ruby_ui}/calendar/calendar_header.rb +1 -1
- data/lib/ruby_ui/calendar/calendar_input_controller.js +8 -0
- data/lib/{rbui → ruby_ui}/calendar/calendar_next.rb +2 -2
- data/lib/{rbui → ruby_ui}/calendar/calendar_prev.rb +2 -2
- data/lib/{rbui → ruby_ui}/calendar/calendar_title.rb +2 -2
- data/lib/{rbui → ruby_ui}/calendar/calendar_weekdays.rb +2 -2
- data/lib/{rbui → ruby_ui}/card/card.rb +1 -1
- data/lib/{rbui → ruby_ui}/card/card_content.rb +1 -1
- data/lib/{rbui → ruby_ui}/card/card_description.rb +1 -1
- data/lib/{rbui → ruby_ui}/card/card_footer.rb +1 -1
- data/lib/{rbui → ruby_ui}/card/card_header.rb +1 -1
- data/lib/{rbui → ruby_ui}/card/card_title.rb +1 -1
- data/lib/ruby_ui/carousel/carousel.rb +44 -0
- data/lib/ruby_ui/carousel/carousel_content.rb +23 -0
- data/lib/ruby_ui/carousel/carousel_controller.js +60 -0
- data/lib/ruby_ui/carousel/carousel_item.rb +23 -0
- data/lib/ruby_ui/carousel/carousel_next.rb +48 -0
- data/lib/ruby_ui/carousel/carousel_previous.rb +49 -0
- data/lib/{rbui → ruby_ui}/chart/chart.rb +3 -3
- data/lib/ruby_ui/chart/chart_controller.js +103 -0
- data/lib/{rbui → ruby_ui}/checkbox/checkbox.rb +4 -4
- data/lib/{rbui → ruby_ui}/checkbox/checkbox_group.rb +2 -2
- data/lib/ruby_ui/checkbox/checkbox_group_controller.js +21 -0
- data/lib/{rbui → ruby_ui}/clipboard/clipboard.rb +6 -6
- data/lib/ruby_ui/clipboard/clipboard_controller.js +54 -0
- data/lib/{rbui → ruby_ui}/clipboard/clipboard_popover.rb +2 -2
- data/lib/{rbui → ruby_ui}/clipboard/clipboard_source.rb +2 -2
- data/lib/{rbui → ruby_ui}/clipboard/clipboard_trigger.rb +3 -3
- data/lib/{rbui → ruby_ui}/codeblock/codeblock.rb +7 -10
- data/lib/{rbui → ruby_ui}/collapsible/collapsible.rb +3 -3
- data/lib/{rbui → ruby_ui}/collapsible/collapsible_content.rb +2 -2
- data/lib/ruby_ui/collapsible/collapsible_controller.js +47 -0
- data/lib/{rbui → ruby_ui}/collapsible/collapsible_trigger.rb +2 -2
- data/lib/ruby_ui/combobox/combobox.rb +26 -0
- data/lib/ruby_ui/combobox/combobox_checkbox.rb +25 -0
- data/lib/ruby_ui/combobox/combobox_controller.js +176 -0
- data/lib/{rbui/combobox/combobox_empty.rb → ruby_ui/combobox/combobox_empty_state.rb} +3 -3
- data/lib/ruby_ui/combobox/combobox_item.rb +25 -0
- data/lib/ruby_ui/combobox/combobox_list.rb +18 -0
- data/lib/ruby_ui/combobox/combobox_list_group.rb +20 -0
- data/lib/ruby_ui/combobox/combobox_popover.rb +30 -0
- data/lib/ruby_ui/combobox/combobox_radio.rb +26 -0
- data/lib/{rbui → ruby_ui}/combobox/combobox_search_input.rb +22 -25
- data/lib/ruby_ui/combobox/combobox_toggle_all_checkbox.rb +25 -0
- data/lib/{rbui → ruby_ui}/combobox/combobox_trigger.rb +26 -21
- data/lib/{rbui → ruby_ui}/command/command.rb +1 -1
- data/lib/ruby_ui/command/command_controller.js +136 -0
- data/lib/{rbui → ruby_ui}/command/command_dialog.rb +2 -2
- data/lib/{rbui → ruby_ui}/command/command_dialog_content.rb +6 -6
- data/lib/{rbui → ruby_ui}/command/command_dialog_trigger.rb +3 -3
- data/lib/{rbui → ruby_ui}/command/command_empty.rb +2 -2
- data/lib/{rbui → ruby_ui}/command/command_group.rb +2 -2
- data/lib/{rbui → ruby_ui}/command/command_input.rb +3 -3
- data/lib/{rbui → ruby_ui}/command/command_item.rb +2 -2
- data/lib/{rbui → ruby_ui}/command/command_list.rb +1 -1
- data/lib/{rbui → ruby_ui}/context_menu/context_menu.rb +2 -2
- data/lib/{rbui → ruby_ui}/context_menu/context_menu_content.rb +2 -2
- data/lib/ruby_ui/context_menu/context_menu_controller.js +144 -0
- data/lib/{rbui → ruby_ui}/context_menu/context_menu_item.rb +3 -3
- data/lib/{rbui → ruby_ui}/context_menu/context_menu_label.rb +2 -2
- data/lib/{rbui → ruby_ui}/context_menu/context_menu_separator.rb +1 -1
- data/lib/{rbui → ruby_ui}/context_menu/context_menu_trigger.rb +3 -3
- data/lib/{rbui → ruby_ui}/dialog/dialog.rb +3 -3
- data/lib/{rbui → ruby_ui}/dialog/dialog_content.rb +9 -9
- data/lib/ruby_ui/dialog/dialog_controller.js +32 -0
- data/lib/{rbui → ruby_ui}/dialog/dialog_description.rb +1 -1
- data/lib/{rbui → ruby_ui}/dialog/dialog_footer.rb +2 -2
- data/lib/{rbui → ruby_ui}/dialog/dialog_header.rb +2 -2
- data/lib/{rbui → ruby_ui}/dialog/dialog_middle.rb +1 -1
- data/lib/{rbui → ruby_ui}/dialog/dialog_title.rb +1 -1
- data/lib/{rbui → ruby_ui}/dialog/dialog_trigger.rb +2 -2
- data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu.rb +4 -4
- data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_content.rb +2 -2
- data/lib/ruby_ui/dropdown_menu/dropdown_menu_controller.js +120 -0
- data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_item.rb +3 -3
- data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_label.rb +1 -1
- data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_separator.rb +1 -1
- data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_trigger.rb +2 -2
- data/lib/{rbui → ruby_ui}/form/form.rb +1 -1
- data/lib/{rbui → ruby_ui}/form/form_field.rb +2 -2
- data/lib/ruby_ui/form/form_field_controller.js +61 -0
- data/lib/{rbui → ruby_ui}/form/form_field_error.rb +2 -2
- data/lib/{rbui → ruby_ui}/form/form_field_hint.rb +1 -1
- data/lib/{rbui → ruby_ui}/form/form_field_label.rb +1 -1
- data/lib/{rbui → ruby_ui}/hover_card/hover_card.rb +3 -3
- data/lib/{rbui → ruby_ui}/hover_card/hover_card_content.rb +2 -2
- data/lib/ruby_ui/hover_card/hover_card_controller.js +144 -0
- data/lib/{rbui → ruby_ui}/hover_card/hover_card_trigger.rb +2 -2
- data/lib/{rbui → ruby_ui}/input/input.rb +3 -3
- data/lib/{rbui → ruby_ui}/link/link.rb +13 -13
- data/lib/ruby_ui/masked_input/masked_input.rb +15 -0
- data/lib/ruby_ui/masked_input/masked_input_controller.js +9 -0
- data/lib/{rbui → ruby_ui}/pagination/pagination.rb +1 -1
- data/lib/{rbui → ruby_ui}/pagination/pagination_content.rb +1 -1
- data/lib/{rbui → ruby_ui}/pagination/pagination_ellipsis.rb +1 -1
- data/lib/{rbui → ruby_ui}/pagination/pagination_item.rb +4 -4
- data/lib/{rbui → ruby_ui}/popover/popover.rb +4 -4
- data/lib/{rbui → ruby_ui}/popover/popover_content.rb +2 -2
- data/lib/ruby_ui/popover/popover_controller.js +107 -0
- data/lib/{rbui → ruby_ui}/popover/popover_trigger.rb +2 -2
- data/lib/ruby_ui/progress/progress.rb +37 -0
- data/lib/ruby_ui/radio_button/radio_button.rb +25 -0
- data/lib/{rbui → ruby_ui}/select/select.rb +5 -5
- data/lib/{rbui → ruby_ui}/select/select_content.rb +3 -3
- data/lib/ruby_ui/select/select_controller.js +171 -0
- data/lib/{rbui → ruby_ui}/select/select_group.rb +1 -1
- data/lib/{rbui → ruby_ui}/select/select_input.rb +4 -4
- data/lib/{rbui → ruby_ui}/select/select_item.rb +4 -4
- data/lib/ruby_ui/select/select_item_controller.js +11 -0
- data/lib/{rbui → ruby_ui}/select/select_label.rb +1 -1
- data/lib/{rbui → ruby_ui}/select/select_trigger.rb +3 -3
- data/lib/{rbui → ruby_ui}/select/select_value.rb +3 -3
- data/lib/ruby_ui/separator/separator.rb +38 -0
- data/lib/{rbui → ruby_ui}/sheet/sheet.rb +2 -2
- data/lib/{rbui → ruby_ui}/sheet/sheet_content.rb +8 -8
- data/lib/ruby_ui/sheet/sheet_content_controller.js +7 -0
- data/lib/ruby_ui/sheet/sheet_controller.js +9 -0
- data/lib/{rbui → ruby_ui}/sheet/sheet_description.rb +1 -1
- data/lib/{rbui → ruby_ui}/sheet/sheet_footer.rb +1 -1
- data/lib/{rbui → ruby_ui}/sheet/sheet_header.rb +1 -1
- data/lib/{rbui → ruby_ui}/sheet/sheet_middle.rb +1 -1
- data/lib/{rbui → ruby_ui}/sheet/sheet_title.rb +1 -1
- data/lib/{rbui → ruby_ui}/sheet/sheet_trigger.rb +2 -2
- data/lib/{rbui → ruby_ui}/shortcut_key/shortcut_key.rb +1 -1
- data/lib/ruby_ui/skeleton/skeleton.rb +17 -0
- data/lib/ruby_ui/switch/switch.rb +24 -0
- data/lib/{rbui → ruby_ui}/table/table.rb +1 -1
- data/lib/{rbui → ruby_ui}/table/table_body.rb +1 -1
- data/lib/{rbui → ruby_ui}/table/table_caption.rb +1 -1
- data/lib/{rbui → ruby_ui}/table/table_cell.rb +1 -1
- data/lib/{rbui → ruby_ui}/table/table_footer.rb +1 -1
- data/lib/{rbui → ruby_ui}/table/table_head.rb +1 -1
- data/lib/{rbui → ruby_ui}/table/table_header.rb +1 -1
- data/lib/{rbui → ruby_ui}/table/table_row.rb +1 -1
- data/lib/{rbui → ruby_ui}/tabs/tabs.rb +3 -3
- data/lib/{rbui → ruby_ui}/tabs/tabs_content.rb +2 -2
- data/lib/ruby_ui/tabs/tabs_controller.js +45 -0
- data/lib/{rbui → ruby_ui}/tabs/tabs_list.rb +1 -1
- data/lib/{rbui → ruby_ui}/tabs/tabs_trigger.rb +3 -3
- data/lib/{rbui → ruby_ui}/textarea/textarea.rb +3 -3
- data/lib/{rbui → ruby_ui}/theme_toggle/theme_toggle.rb +4 -4
- data/lib/ruby_ui/theme_toggle/theme_toggle_controller.js +30 -0
- data/lib/{rbui → ruby_ui}/tooltip/tooltip.rb +3 -3
- data/lib/{rbui → ruby_ui}/tooltip/tooltip_content.rb +3 -3
- data/lib/ruby_ui/tooltip/tooltip_controller.js +37 -0
- data/lib/{rbui → ruby_ui}/tooltip/tooltip_trigger.rb +2 -2
- data/lib/ruby_ui/typography/heading.rb +60 -0
- data/lib/{rbui/typography/typography_inline_code.rb → ruby_ui/typography/inline_code.rb} +2 -2
- data/lib/{rbui/typography/typography_inline_link.rb → ruby_ui/typography/inline_link.rb} +2 -2
- data/lib/ruby_ui/typography/text.rb +53 -0
- data/lib/{rbui → ruby_ui}/typography/typography_blockquote.rb +1 -1
- data/lib/ruby_ui.rb +5 -1
- metadata +208 -173
- data/lib/generators/rbui/base_generator.rb +0 -17
- data/lib/generators/rbui/component_generator.rb +0 -137
- data/lib/generators/rbui/install/install_generator.rb +0 -194
- data/lib/rbui/calendar/calendar.rb +0 -39
- data/lib/rbui/combobox/combobox.rb +0 -24
- data/lib/rbui/combobox/combobox_content.rb +0 -31
- data/lib/rbui/combobox/combobox_group.rb +0 -38
- data/lib/rbui/combobox/combobox_input.rb +0 -22
- data/lib/rbui/combobox/combobox_item.rb +0 -53
- data/lib/rbui/combobox/combobox_list.rb +0 -29
- data/lib/rbui/combobox/combobox_separator.rb +0 -15
- data/lib/rbui/combobox/combobox_value.rb +0 -27
- data/lib/rbui/radio_button/radio_button.rb +0 -22
- data/lib/rbui/railtie.rb +0 -52
- data/lib/rbui/typography/typography_h1.rb +0 -17
- data/lib/rbui/typography/typography_h2.rb +0 -17
- data/lib/rbui/typography/typography_h3.rb +0 -17
- data/lib/rbui/typography/typography_h4.rb +0 -17
- data/lib/rbui/typography/typography_large.rb +0 -17
- data/lib/rbui/typography/typography_lead.rb +0 -17
- data/lib/rbui/typography/typography_list.rb +0 -47
- data/lib/rbui/typography/typography_muted.rb +0 -17
- data/lib/rbui/typography/typography_p.rb +0 -17
- data/lib/rbui/typography/typography_small.rb +0 -17
- data/lib/rbui/version.rb +0 -5
- data/lib/rbui.rb +0 -57
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class CommandDialogContent < Base
|
5
5
|
SIZES = {
|
6
6
|
xs: "max-w-sm",
|
@@ -17,8 +17,8 @@ module RBUI
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def view_template(&block)
|
20
|
-
|
21
|
-
div(data: {controller: "
|
20
|
+
template(data: {ruby_ui__command_target: "content"}) do
|
21
|
+
div(data: {controller: "ruby-ui--command"}) do
|
22
22
|
backdrop
|
23
23
|
div(**attrs, &block)
|
24
24
|
end
|
@@ -30,17 +30,17 @@ module RBUI
|
|
30
30
|
def default_attrs
|
31
31
|
{
|
32
32
|
data_state: "open",
|
33
|
-
class:
|
33
|
+
class: [
|
34
34
|
"fixed pointer-events-auto left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full",
|
35
35
|
SIZES[@size]
|
36
|
-
|
36
|
+
]
|
37
37
|
}
|
38
38
|
end
|
39
39
|
|
40
40
|
def backdrop
|
41
41
|
div(
|
42
42
|
data_state: "open",
|
43
|
-
data_action: "click->
|
43
|
+
data_action: "click->ruby-ui--command#dismiss esc->ruby-ui--command#dismiss",
|
44
44
|
class: "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"
|
45
45
|
)
|
46
46
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class CommandDialogTrigger < Base
|
5
5
|
DEFAULT_KEYBINDINGS = [
|
6
6
|
"keydown.ctrl+k@window",
|
@@ -8,7 +8,7 @@ module RBUI
|
|
8
8
|
].freeze
|
9
9
|
|
10
10
|
def initialize(keybindings: DEFAULT_KEYBINDINGS, **attrs)
|
11
|
-
@keybindings = keybindings.map { |kb| "#{kb}->
|
11
|
+
@keybindings = keybindings.map { |kb| "#{kb}->ruby-ui--command#open" }
|
12
12
|
super(**attrs)
|
13
13
|
end
|
14
14
|
|
@@ -21,7 +21,7 @@ module RBUI
|
|
21
21
|
def default_attrs
|
22
22
|
{
|
23
23
|
data: {
|
24
|
-
action:
|
24
|
+
action: ["click->ruby-ui--command#open", @keybindings.join(" ")]
|
25
25
|
}
|
26
26
|
}
|
27
27
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class CommandEmpty < Base
|
5
5
|
def view_template(&)
|
6
6
|
div(**attrs, &)
|
@@ -12,7 +12,7 @@ module RBUI
|
|
12
12
|
{
|
13
13
|
class: "py-6 text-center text-sm",
|
14
14
|
role: "presentation",
|
15
|
-
data: {
|
15
|
+
data: {ruby_ui__command_target: "empty"}
|
16
16
|
}
|
17
17
|
end
|
18
18
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class CommandGroup < Base
|
5
5
|
def initialize(title: nil, **attrs)
|
6
6
|
@title = title
|
@@ -32,7 +32,7 @@ module RBUI
|
|
32
32
|
role: "presentation",
|
33
33
|
data: {
|
34
34
|
value: @title,
|
35
|
-
|
35
|
+
ruby_ui__command_target: "group"
|
36
36
|
}
|
37
37
|
}
|
38
38
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class CommandInput < Base
|
5
5
|
def initialize(placeholder: "Type a command or search...", **attrs)
|
6
6
|
@placeholder = placeholder
|
@@ -40,8 +40,8 @@ module RBUI
|
|
40
40
|
{
|
41
41
|
class: "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
42
42
|
placeholder: @placeholder,
|
43
|
-
data_action: "input->
|
44
|
-
|
43
|
+
data_action: "input->ruby-ui--command#filter keydown.down->ruby-ui--command#handleKeydown keydown.up->ruby-ui--command#handleKeydown keydown.enter->ruby-ui--command#handleKeydown keydown.esc->ruby-ui--command#dismiss",
|
44
|
+
data_ruby_ui__command_target: "input",
|
45
45
|
autocomplete: "off",
|
46
46
|
autocorrect: "off",
|
47
47
|
spellcheck: false,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class CommandItem < Base
|
5
5
|
def initialize(value:, text: "", href: "#", **attrs)
|
6
6
|
@value = value
|
@@ -21,7 +21,7 @@ module RBUI
|
|
21
21
|
href: @href,
|
22
22
|
role: "option",
|
23
23
|
data: {
|
24
|
-
|
24
|
+
ruby_ui__command_target: "item",
|
25
25
|
value: @value,
|
26
26
|
text: @text
|
27
27
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class ContextMenu < Base
|
5
5
|
def initialize(options: {}, **attrs)
|
6
6
|
@options = options
|
@@ -17,7 +17,7 @@ module RBUI
|
|
17
17
|
def default_attrs
|
18
18
|
{
|
19
19
|
data: {
|
20
|
-
controller: "
|
20
|
+
controller: "ruby-ui--context-menu",
|
21
21
|
popover_options_value: @options.to_json
|
22
22
|
}
|
23
23
|
}
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class ContextMenuContent < Base
|
5
5
|
def view_template(&block)
|
6
|
-
|
6
|
+
template(data: {ruby_ui__context_menu_target: "content"}) do
|
7
7
|
div(**attrs, &block)
|
8
8
|
end
|
9
9
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
import tippy from "tippy.js";
|
3
|
+
|
4
|
+
export default class extends Controller {
|
5
|
+
static targets = ["trigger", "content", "menuItem"];
|
6
|
+
static values = {
|
7
|
+
options: {
|
8
|
+
type: Object,
|
9
|
+
default: {},
|
10
|
+
},
|
11
|
+
// make content width of the trigger element (true/false)
|
12
|
+
matchWidth: {
|
13
|
+
type: Boolean,
|
14
|
+
default: false,
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
connect() {
|
19
|
+
this.boundHandleKeydown = this.handleKeydown.bind(this); // Bind the function so we can remove it later
|
20
|
+
this.initializeTippy();
|
21
|
+
this.selectedIndex = -1;
|
22
|
+
}
|
23
|
+
|
24
|
+
disconnect() {
|
25
|
+
this.destroyTippy();
|
26
|
+
}
|
27
|
+
|
28
|
+
initializeTippy() {
|
29
|
+
const defaultOptions = {
|
30
|
+
content: this.contentTarget.innerHTML,
|
31
|
+
allowHTML: true,
|
32
|
+
interactive: true,
|
33
|
+
onShow: (instance) => {
|
34
|
+
this.matchWidthValue && this.setContentWidth(instance); // ensure content width matches trigger width
|
35
|
+
this.addEventListeners();
|
36
|
+
},
|
37
|
+
onHide: () => {
|
38
|
+
this.removeEventListeners();
|
39
|
+
this.deselectAll();
|
40
|
+
},
|
41
|
+
popperOptions: {
|
42
|
+
modifiers: [
|
43
|
+
{
|
44
|
+
name: "offset",
|
45
|
+
options: {
|
46
|
+
offset: [0, 4]
|
47
|
+
},
|
48
|
+
},
|
49
|
+
],
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
const mergedOptions = { ...this.optionsValue, ...defaultOptions };
|
54
|
+
this.tippy = tippy(this.triggerTarget, mergedOptions);
|
55
|
+
}
|
56
|
+
|
57
|
+
destroyTippy() {
|
58
|
+
if (this.tippy) {
|
59
|
+
this.tippy.destroy();
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
setContentWidth(instance) {
|
64
|
+
// box-sizing: border-box
|
65
|
+
const content = instance.popper.querySelector('.tippy-content');
|
66
|
+
if (content) {
|
67
|
+
content.style.width = `${instance.reference.offsetWidth}px`;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
handleContextMenu(event) {
|
72
|
+
event.preventDefault();
|
73
|
+
this.open();
|
74
|
+
}
|
75
|
+
|
76
|
+
open() {
|
77
|
+
this.tippy.show();
|
78
|
+
}
|
79
|
+
|
80
|
+
close() {
|
81
|
+
this.tippy.hide();
|
82
|
+
}
|
83
|
+
|
84
|
+
handleKeydown(e) {
|
85
|
+
// return if no menu items (one line fix for)
|
86
|
+
if (this.menuItemTargets.length === 0) { return; }
|
87
|
+
|
88
|
+
if (e.key === 'ArrowDown') {
|
89
|
+
e.preventDefault();
|
90
|
+
this.updateSelectedItem(1);
|
91
|
+
} else if (e.key === 'ArrowUp') {
|
92
|
+
e.preventDefault();
|
93
|
+
this.updateSelectedItem(-1);
|
94
|
+
} else if (e.key === 'Enter' && this.selectedIndex !== -1) {
|
95
|
+
e.preventDefault();
|
96
|
+
this.menuItemTargets[this.selectedIndex].click();
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
updateSelectedItem(direction) {
|
101
|
+
// Check if any of the menuItemTargets have aria-selected="true" and set the selectedIndex to that index
|
102
|
+
this.menuItemTargets.forEach((item, index) => {
|
103
|
+
if (item.getAttribute('aria-selected') === 'true') {
|
104
|
+
this.selectedIndex = index;
|
105
|
+
}
|
106
|
+
});
|
107
|
+
|
108
|
+
if (this.selectedIndex >= 0) {
|
109
|
+
this.toggleAriaSelected(this.menuItemTargets[this.selectedIndex], false);
|
110
|
+
}
|
111
|
+
|
112
|
+
this.selectedIndex += direction;
|
113
|
+
|
114
|
+
if (this.selectedIndex < 0) {
|
115
|
+
this.selectedIndex = this.menuItemTargets.length - 1;
|
116
|
+
} else if (this.selectedIndex >= this.menuItemTargets.length) {
|
117
|
+
this.selectedIndex = 0;
|
118
|
+
}
|
119
|
+
|
120
|
+
this.toggleAriaSelected(this.menuItemTargets[this.selectedIndex], true);
|
121
|
+
}
|
122
|
+
|
123
|
+
toggleAriaSelected(element, isSelected) {
|
124
|
+
// Add or remove attribute
|
125
|
+
if (isSelected) {
|
126
|
+
element.setAttribute('aria-selected', 'true');
|
127
|
+
} else {
|
128
|
+
element.removeAttribute('aria-selected');
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
deselectAll() {
|
133
|
+
this.menuItemTargets.forEach(item => this.toggleAriaSelected(item, false));
|
134
|
+
this.selectedIndex = -1;
|
135
|
+
}
|
136
|
+
|
137
|
+
addEventListeners() {
|
138
|
+
document.addEventListener('keydown', this.boundHandleKeydown);
|
139
|
+
}
|
140
|
+
|
141
|
+
removeEventListeners() {
|
142
|
+
document.removeEventListener('keydown', this.boundHandleKeydown);
|
143
|
+
}
|
144
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class ContextMenuItem < Base
|
5
5
|
def initialize(href: "#", checked: false, shortcut: nil, disabled: false, **attrs)
|
6
6
|
@href = href
|
@@ -56,8 +56,8 @@ module RBUI
|
|
56
56
|
"relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 pl-8",
|
57
57
|
tabindex: "-1",
|
58
58
|
data_orientation: "vertical",
|
59
|
-
data_action: "click->
|
60
|
-
|
59
|
+
data_action: "click->ruby-ui--context-menu#close",
|
60
|
+
data_ruby_ui__context_menu_target: "menuItem",
|
61
61
|
data_disabled: @disabled,
|
62
62
|
disabled: @disabled
|
63
63
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class ContextMenuLabel < Base
|
5
5
|
def initialize(inset: false, **attrs)
|
6
6
|
@inset = inset
|
@@ -17,7 +17,7 @@ module RBUI
|
|
17
17
|
|
18
18
|
def default_attrs
|
19
19
|
{
|
20
|
-
class:
|
20
|
+
class: ["px-2 py-1.5 text-sm font-semibold text-foreground", inset?: "pl-8"]
|
21
21
|
}
|
22
22
|
end
|
23
23
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class ContextMenuTrigger < Base
|
5
5
|
def view_template(&)
|
6
6
|
div(**attrs, &)
|
@@ -11,8 +11,8 @@ module RBUI
|
|
11
11
|
def default_attrs
|
12
12
|
{
|
13
13
|
data: {
|
14
|
-
|
15
|
-
action: "contextmenu->
|
14
|
+
ruby_ui__context_menu_target: "trigger",
|
15
|
+
action: "contextmenu->ruby-ui--context-menu#handleContextMenu"
|
16
16
|
}
|
17
17
|
}
|
18
18
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class Dialog < Base
|
5
5
|
def initialize(open: false, **attrs)
|
6
6
|
@open = open
|
@@ -16,8 +16,8 @@ module RBUI
|
|
16
16
|
def default_attrs
|
17
17
|
{
|
18
18
|
data: {
|
19
|
-
controller: "
|
20
|
-
|
19
|
+
controller: "ruby-ui--dialog",
|
20
|
+
ruby_ui__dialog_open_value: @open
|
21
21
|
}
|
22
22
|
}
|
23
23
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class DialogContent < Base
|
5
5
|
SIZES = {
|
6
6
|
xs: "max-w-sm",
|
@@ -17,8 +17,8 @@ module RBUI
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def view_template
|
20
|
-
|
21
|
-
div(data_controller: "
|
20
|
+
template(data: {ruby_ui__dialog_target: "content"}) do
|
21
|
+
div(data_controller: "ruby-ui--dialog") do
|
22
22
|
backdrop
|
23
23
|
div(**attrs) do
|
24
24
|
yield
|
@@ -33,18 +33,18 @@ module RBUI
|
|
33
33
|
def default_attrs
|
34
34
|
{
|
35
35
|
data_state: "open",
|
36
|
-
class:
|
37
|
-
"fixed pointer-events-auto left-[50%] top-[50%] z-50
|
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=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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full",
|
38
38
|
SIZES[@size]
|
39
|
-
|
39
|
+
]
|
40
40
|
}
|
41
41
|
end
|
42
42
|
|
43
43
|
def close_button
|
44
44
|
button(
|
45
45
|
type: "button",
|
46
|
-
class: "absolute
|
47
|
-
data_action: "click->
|
46
|
+
class: "absolute end-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
|
47
|
+
data_action: "click->ruby-ui--dialog#dismiss"
|
48
48
|
) do
|
49
49
|
svg(
|
50
50
|
width: "15",
|
@@ -69,7 +69,7 @@ module RBUI
|
|
69
69
|
def backdrop
|
70
70
|
div(
|
71
71
|
data_state: "open",
|
72
|
-
data_action: "click->
|
72
|
+
data_action: "click->ruby-ui--dialog#dismiss esc->ruby-ui--dialog#dismiss",
|
73
73
|
class:
|
74
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"
|
75
75
|
)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
|
3
|
+
// Connects to data-controller="dialog"
|
4
|
+
export default class extends Controller {
|
5
|
+
static targets = ["content"]
|
6
|
+
static values = {
|
7
|
+
open: {
|
8
|
+
type: Boolean,
|
9
|
+
default: false
|
10
|
+
},
|
11
|
+
}
|
12
|
+
|
13
|
+
connect() {
|
14
|
+
if (this.openValue) {
|
15
|
+
this.open()
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
open(e) {
|
20
|
+
e.preventDefault()
|
21
|
+
document.body.insertAdjacentHTML('beforeend', this.contentTarget.innerHTML)
|
22
|
+
// prevent scroll on body
|
23
|
+
document.body.classList.add('overflow-hidden')
|
24
|
+
}
|
25
|
+
|
26
|
+
dismiss() {
|
27
|
+
// allow scroll on body
|
28
|
+
document.body.classList.remove('overflow-hidden')
|
29
|
+
// remove the element
|
30
|
+
this.element.remove()
|
31
|
+
}
|
32
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class DialogFooter < Base
|
5
5
|
def view_template(&)
|
6
6
|
div(**attrs, &)
|
@@ -10,7 +10,7 @@ module RBUI
|
|
10
10
|
|
11
11
|
def default_attrs
|
12
12
|
{
|
13
|
-
class: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 gap-y-2 sm:gap-y-0"
|
13
|
+
class: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 gap-y-2 sm:gap-y-0 rtl:space-x-reverse"
|
14
14
|
}
|
15
15
|
end
|
16
16
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class DialogHeader < Base
|
5
5
|
def view_template(&)
|
6
6
|
div(**attrs, &)
|
@@ -10,7 +10,7 @@ module RBUI
|
|
10
10
|
|
11
11
|
def default_attrs
|
12
12
|
{
|
13
|
-
class: "flex flex-col space-y-1.5 text-center sm:text-left"
|
13
|
+
class: "flex flex-col space-y-1.5 text-center sm:text-left rtl:sm:text-right"
|
14
14
|
}
|
15
15
|
end
|
16
16
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class DialogTrigger < Base
|
5
5
|
def view_template(&)
|
6
6
|
div(**attrs, &)
|
@@ -11,7 +11,7 @@ module RBUI
|
|
11
11
|
def default_attrs
|
12
12
|
{
|
13
13
|
data: {
|
14
|
-
action: "click->
|
14
|
+
action: "click->ruby-ui--dialog#open"
|
15
15
|
},
|
16
16
|
class: "inline-block"
|
17
17
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class DropdownMenu < Base
|
5
5
|
def initialize(options: {}, **attrs)
|
6
6
|
@options = options
|
@@ -16,9 +16,9 @@ module RBUI
|
|
16
16
|
def default_attrs
|
17
17
|
{
|
18
18
|
data: {
|
19
|
-
controller: "
|
20
|
-
action: "click@window->
|
21
|
-
|
19
|
+
controller: "ruby-ui--dropdown-menu",
|
20
|
+
action: "click@window->ruby-ui--dropdown-menu#onClickOutside",
|
21
|
+
ruby_ui__dropdown_menu_options_value: @options.to_json
|
22
22
|
}
|
23
23
|
}
|
24
24
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module RubyUI
|
4
4
|
class DropdownMenuContent < Base
|
5
5
|
def view_template(&block)
|
6
|
-
div(data: {
|
6
|
+
div(data: {ruby_ui__dropdown_menu_target: "content"}, class: "hidden", style: "width: max-content; position: absolute; top: 0; left: 0;") do
|
7
7
|
div(**attrs, &block)
|
8
8
|
end
|
9
9
|
end
|