ruby_ui 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -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/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/alert_dialog/alert_dialog_content.rb +2 -3
- data/lib/ruby_ui/button/button.rb +32 -16
- data/lib/ruby_ui/checkbox/checkbox.rb +7 -1
- 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 +4 -4
- data/lib/ruby_ui/combobox/combobox_item.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 +2 -1
- data/lib/ruby_ui/combobox/combobox_trigger.rb +7 -1
- data/lib/ruby_ui/command/command_controller.js +0 -1
- data/lib/ruby_ui/dialog/dialog_content.rb +2 -3
- data/lib/ruby_ui/dialog/dialog_controller.js +1 -1
- 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/form/form_field_label.rb +7 -1
- data/lib/ruby_ui/input/input.rb +8 -1
- data/lib/ruby_ui/link/link.rb +32 -16
- data/lib/ruby_ui/radio_button/radio_button.rb +3 -1
- data/lib/ruby_ui/select/select_item.rb +14 -5
- data/lib/ruby_ui/select/select_trigger.rb +9 -4
- 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_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/switch/switch.rb +12 -2
- 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_trigger.rb +7 -1
- data/lib/ruby_ui/textarea/textarea.rb +8 -1
- data/lib/ruby_ui/theme_toggle/set_dark_mode.rb +16 -0
- data/lib/ruby_ui/theme_toggle/set_light_mode.rb +16 -0
- data/lib/ruby_ui/theme_toggle/theme_toggle.rb +0 -32
- data/lib/ruby_ui/tooltip/tooltip_controller.js +5 -4
- data/lib/ruby_ui.rb +1 -1
- metadata +34 -4
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarMenuAction < Base
|
5
|
+
def initialize(as: :button, show_on_hover: false, **attrs)
|
6
|
+
@as = as
|
7
|
+
super(**attrs)
|
8
|
+
end
|
9
|
+
|
10
|
+
def view_template(&)
|
11
|
+
tag(@as, **attrs, &)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def default_attrs
|
17
|
+
{
|
18
|
+
class: [
|
19
|
+
"absolute right-1 top-1.5 flex aspect-square w-5 items-center",
|
20
|
+
"justify-center rounded-md p-0 text-sidebar-foreground outline-none",
|
21
|
+
"ring-sidebar-ring transition-transform hover:bg-sidebar-accent",
|
22
|
+
"hover:text-sidebar-accent-foreground focus-visible:ring-2",
|
23
|
+
"peer-hover/menu-button:text-sidebar-accent-foreground",
|
24
|
+
"[&>svg]:size-4 [&>svg]:shrink-0",
|
25
|
+
"after:absolute after:-inset-2 after:md:hidden",
|
26
|
+
"peer-data-[size=sm]/menu-button:top-1",
|
27
|
+
"peer-data-[size=default]/menu-button:top-1.5",
|
28
|
+
"peer-data-[size=lg]/menu-button:top-2.5",
|
29
|
+
"group-data-[collapsible=icon]:hidden",
|
30
|
+
show_on_hover_classes
|
31
|
+
],
|
32
|
+
data: {
|
33
|
+
sidebar: "menu-action"
|
34
|
+
}
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def show_on_hover_classes
|
39
|
+
return unless @show_on_hover
|
40
|
+
|
41
|
+
[
|
42
|
+
"group-focus-within/menu-item:opacity-100",
|
43
|
+
"group-hover/menu-item:opacity-100 data-[state=open]:opacity-100",
|
44
|
+
"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0"
|
45
|
+
].join(" ")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarMenuBadge < Base
|
5
|
+
def view_template(&)
|
6
|
+
div(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
class: [
|
14
|
+
"pointer-events-none absolute right-1 flex h-5 min-w-5 select-none",
|
15
|
+
"items-center justify-center rounded-md px-1 text-xs font-medium",
|
16
|
+
"tabular-nums text-sidebar-foreground",
|
17
|
+
"peer-hover/menu-button:text-sidebar-accent-foreground",
|
18
|
+
"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
|
19
|
+
"peer-data-[size=sm]/menu-button:top-1",
|
20
|
+
"peer-data-[size=default]/menu-button:top-1.5",
|
21
|
+
"peer-data-[size=lg]/menu-button:top-2.5",
|
22
|
+
"group-data-[collapsible=icon]:hidden"
|
23
|
+
],
|
24
|
+
data: {
|
25
|
+
sidebar: "menu-badge"
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarMenuButton < Base
|
5
|
+
VARIANT_CLASSES = {
|
6
|
+
default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
7
|
+
outline:
|
8
|
+
"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]"
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
SIZE_CLASSES = {
|
12
|
+
default: "h-8 text-sm",
|
13
|
+
sm: "h-7 text-xs",
|
14
|
+
lg: "h-12 text-sm group-data-[collapsible=icon]:!p-0"
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
def initialize(as: :button, variant: :default, size: :default, active: false, **attrs)
|
18
|
+
raise ArgumentError, "Invalid variant: #{variant}" unless VARIANT_CLASSES.key?(variant)
|
19
|
+
raise ArgumentError, "Invalid size: #{size}" unless SIZE_CLASSES.key?(size)
|
20
|
+
|
21
|
+
@as = as
|
22
|
+
@variant = variant
|
23
|
+
@size = size
|
24
|
+
@active = active
|
25
|
+
super(**attrs)
|
26
|
+
end
|
27
|
+
|
28
|
+
def view_template(&)
|
29
|
+
tag(@as, **attrs, &)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def default_attrs
|
35
|
+
{
|
36
|
+
class: [
|
37
|
+
"peer/menu-button flex w-full items-center gap-2 overflow-hidden",
|
38
|
+
"rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring",
|
39
|
+
"transition-[width,height,padding] hover:bg-sidebar-accent",
|
40
|
+
"hover:text-sidebar-accent-foreground focus-visible:ring-2",
|
41
|
+
"active:bg-sidebar-accent active:text-sidebar-accent-foreground",
|
42
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
43
|
+
"group-has-[[data-sidebar=menu-action]]/menu-item:pr-8",
|
44
|
+
"aria-disabled:pointer-events-none aria-disabled:opacity-50",
|
45
|
+
"data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium",
|
46
|
+
"data-[active=true]:text-sidebar-accent-foreground",
|
47
|
+
"data-[state=open]:hover:bg-sidebar-accent",
|
48
|
+
"data-[state=open]:hover:text-sidebar-accent-foreground",
|
49
|
+
"group-data-[collapsible=icon]:!size-8",
|
50
|
+
"group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate",
|
51
|
+
"[&>svg]:size-4 [&>svg]:shrink-0",
|
52
|
+
VARIANT_CLASSES[@variant],
|
53
|
+
SIZE_CLASSES[@size]
|
54
|
+
],
|
55
|
+
data: {
|
56
|
+
sidebar: "menu-button",
|
57
|
+
size: @size,
|
58
|
+
active: @active.to_s
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarMenuItem < Base
|
5
|
+
def view_template(&)
|
6
|
+
ul(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
class: "group/menu-item relative",
|
14
|
+
data: {
|
15
|
+
sidebar: "menu-item"
|
16
|
+
}
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarMenuSkeleton < Base
|
5
|
+
def initialize(show_icon: false, **attrs)
|
6
|
+
@show_icon = show_icon
|
7
|
+
super(**attrs)
|
8
|
+
end
|
9
|
+
|
10
|
+
def view_template(&)
|
11
|
+
div(**attrs) do
|
12
|
+
Skeleton(class: "size-4 rounded-md", data: {sidebar: "menu-skeleton-icon"}) if @show_icon
|
13
|
+
Skeleton(
|
14
|
+
class: "h-4 max-w-[var(--skeleton-width)] flex-1",
|
15
|
+
data: {sidebar: "menu-skeleton-text"},
|
16
|
+
style: {"--skeleton-width" => "#{skeleton_width}%"}
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def default_attrs
|
24
|
+
{
|
25
|
+
class: "flex h-8 items-center gap-2 rounded-md px-2",
|
26
|
+
data: {
|
27
|
+
sidebar: "menu-skeleton"
|
28
|
+
}
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def skeleton_width
|
33
|
+
@_skeleton_width ||= rand(50..89)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarMenuSub < Base
|
5
|
+
def view_template(&)
|
6
|
+
ul(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
class: [
|
14
|
+
"mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l",
|
15
|
+
"border-sidebar-border px-2.5 py-0.5",
|
16
|
+
"group-data-[collapsible=icon]:hidden"
|
17
|
+
],
|
18
|
+
data: {
|
19
|
+
sidebar: "menu-sub"
|
20
|
+
}
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarMenuSubButton < Base
|
5
|
+
SIZE_CLASSES = {
|
6
|
+
sm: "text-xs",
|
7
|
+
md: "text-sm"
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
def initialize(as: :button, size: :md, active: false, **attrs)
|
11
|
+
raise ArgumentError, "Invalid size: #{size}" unless SIZE_CLASSES.key?(size)
|
12
|
+
|
13
|
+
@as = as
|
14
|
+
@size = size
|
15
|
+
@active = active
|
16
|
+
super(**attrs)
|
17
|
+
end
|
18
|
+
|
19
|
+
def view_template(&)
|
20
|
+
tag(@as, **attrs, &)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def default_attrs
|
26
|
+
{
|
27
|
+
class: [
|
28
|
+
"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden",
|
29
|
+
"rounded-md px-2 text-sidebar-foreground outline-none",
|
30
|
+
"ring-sidebar-ring hover:bg-sidebar-accent",
|
31
|
+
"hover:text-sidebar-accent-foreground focus-visible:ring-2",
|
32
|
+
"active:bg-sidebar-accent active:text-sidebar-accent-foreground",
|
33
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
34
|
+
"aria-disabled:pointer-events-none aria-disabled:opacity-50",
|
35
|
+
"[&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
|
36
|
+
"[&>svg]:text-sidebar-accent-foreground",
|
37
|
+
"data-[active=true]:bg-sidebar-accent",
|
38
|
+
"data-[active=true]:text-sidebar-accent-foreground",
|
39
|
+
"group-data-[collapsible=icon]:hidden",
|
40
|
+
SIZE_CLASSES[@size]
|
41
|
+
],
|
42
|
+
data: {
|
43
|
+
sidebar: "menu-sub-button",
|
44
|
+
size: @size,
|
45
|
+
active: @active.to_s
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarRail < Base
|
5
|
+
def view_template(&)
|
6
|
+
button(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
class: [
|
14
|
+
"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all",
|
15
|
+
"ease-linear after:absolute after:inset-y-0 after:left-1/2",
|
16
|
+
"after:w-[2px] hover:after:bg-sidebar-border",
|
17
|
+
"group-data-[side=left]:-right-4 group-data-[side=right]:left-0",
|
18
|
+
"sm:flex [[data-side=left]_&]:cursor-w-resize",
|
19
|
+
"[[data-side=right]_&]:cursor-e-resize",
|
20
|
+
"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize",
|
21
|
+
"[[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
|
22
|
+
"group-data-[collapsible=offcanvas]:translate-x-0",
|
23
|
+
"group-data-[collapsible=offcanvas]:after:left-full",
|
24
|
+
"group-data-[collapsible=offcanvas]:hover:bg-sidebar",
|
25
|
+
"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
|
26
|
+
"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2"
|
27
|
+
],
|
28
|
+
data: {
|
29
|
+
sidebar: "rail",
|
30
|
+
tabindex: "-1",
|
31
|
+
action: "click->ruby-ui--sidebar#toggle"
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarSeparator < Base
|
5
|
+
def view_template(&)
|
6
|
+
Separator(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
class: "mx-2 w-auto bg-sidebar-border",
|
14
|
+
data: {
|
15
|
+
sidebar: "separator"
|
16
|
+
}
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarTrigger < Base
|
5
|
+
def view_template(&)
|
6
|
+
Button(variant: :ghost, size: :icon, **attrs) do
|
7
|
+
panel_left_icon
|
8
|
+
span(class: "sr-only") { "Toggle Sidebar" }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def default_attrs
|
15
|
+
{
|
16
|
+
class: "h-7 w-7 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
17
|
+
data: {
|
18
|
+
sidebar: "trigger",
|
19
|
+
action: "click->ruby-ui--sidebar#toggle"
|
20
|
+
}
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def panel_left_icon
|
25
|
+
svg(
|
26
|
+
xmlns: "http://www.w3.org/2000/svg",
|
27
|
+
width: "24",
|
28
|
+
height: "24",
|
29
|
+
viewBox: "0 0 24 24",
|
30
|
+
fill: "none",
|
31
|
+
stroke: "currentColor",
|
32
|
+
stroke_width: "2",
|
33
|
+
stroke_linecap: "round",
|
34
|
+
stroke_linejoin: "round",
|
35
|
+
class: "lucide lucide-panel-left"
|
36
|
+
) do |s|
|
37
|
+
s.rect(width: "18", height: "18", x: "3", y: "3", rx: "2")
|
38
|
+
s.path(d: "M9 3v18")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SidebarWrapper < Base
|
5
|
+
SIDEBAR_WIDTH = "16rem"
|
6
|
+
SIDEBAR_WIDTH_ICON = "3rem"
|
7
|
+
|
8
|
+
def view_template(&)
|
9
|
+
div(**attrs, &)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def default_attrs
|
15
|
+
{
|
16
|
+
class: "group/sidebar-wrapper [&:has([data-variant=inset])]:bg-sidebar flex min-h-svh w-full",
|
17
|
+
style: "--sidebar-width: #{SIDEBAR_WIDTH}; --sidebar-width-icon: #{SIDEBAR_WIDTH_ICON};",
|
18
|
+
data: {
|
19
|
+
controller: "ruby-ui--sidebar"
|
20
|
+
}
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -12,12 +12,22 @@ module RubyUI
|
|
12
12
|
def view_template
|
13
13
|
label(
|
14
14
|
role: "switch",
|
15
|
-
class:
|
15
|
+
class: [
|
16
|
+
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors bg-input",
|
17
|
+
"has-checked:bg-primary",
|
18
|
+
"has-disabled:cursor-not-allowed has-disabled:opacity-50",
|
19
|
+
"has-aria-disabled:cursor-not-allowed has-aria-disabled:opacity-50 has-aria-disabled:pointer-events-none",
|
20
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
|
21
|
+
]
|
16
22
|
) do
|
17
23
|
input(type: "hidden", name: attrs[:name], value: @unchecked_value) if @include_hidden
|
24
|
+
|
18
25
|
input(**attrs.merge(type: "checkbox", class: "hidden peer", value: @checked_value))
|
19
26
|
|
20
|
-
span(class:
|
27
|
+
span(class: [
|
28
|
+
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform translate-x-0",
|
29
|
+
"peer-checked:translate-x-5"
|
30
|
+
])
|
21
31
|
end
|
22
32
|
end
|
23
33
|
end
|
@@ -21,7 +21,13 @@ module RubyUI
|
|
21
21
|
action: "click->ruby-ui--tabs#show",
|
22
22
|
value: @value
|
23
23
|
},
|
24
|
-
class:
|
24
|
+
class: [
|
25
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all",
|
26
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
27
|
+
"aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-disabled:cursor-not-allowed",
|
28
|
+
"data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
|
29
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
30
|
+
]
|
25
31
|
}
|
26
32
|
end
|
27
33
|
end
|
@@ -19,7 +19,14 @@ module RubyUI
|
|
19
19
|
ruby_ui__form_field_target: "input",
|
20
20
|
action: "input->ruby-ui--form-field#onInput invalid->ruby-ui--form-field#onInvalid"
|
21
21
|
},
|
22
|
-
class:
|
22
|
+
class: [
|
23
|
+
"flex w-full rounded-md border bg-background px-3 py-1 text-sm shadow-sm transition-colors border-border",
|
24
|
+
"placeholder:text-muted-foreground",
|
25
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
26
|
+
"file:border-0 file:bg-transparent file:text-sm file:font-medium",
|
27
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
28
|
+
"aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none"
|
29
|
+
]
|
23
30
|
}
|
24
31
|
end
|
25
32
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SetDarkMode < Base
|
5
|
+
def view_template(&)
|
6
|
+
div(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
def default_attrs
|
10
|
+
{
|
11
|
+
class: "hidden dark:inline-block",
|
12
|
+
data: {controller: "ruby-ui--theme-toggle", action: "click->ruby-ui--theme-toggle#setLightTheme"}
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RubyUI
|
4
|
+
class SetLightMode < Base
|
5
|
+
def view_template(&)
|
6
|
+
div(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
def default_attrs
|
10
|
+
{
|
11
|
+
class: "dark:hidden",
|
12
|
+
data: {controller: "ruby-ui--theme-toggle", action: "click->ruby-ui--theme-toggle#setDarkTheme"}
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -5,37 +5,5 @@ module RubyUI
|
|
5
5
|
def view_template(&)
|
6
6
|
div(**attrs, &)
|
7
7
|
end
|
8
|
-
|
9
|
-
def light_mode(**user_attrs, &)
|
10
|
-
light_attrs = mix(default_light_attrs, user_attrs)
|
11
|
-
div(**light_attrs, &)
|
12
|
-
end
|
13
|
-
|
14
|
-
def dark_mode(**user_attrs, &)
|
15
|
-
dark_attrs = mix(default_dark_attrs, user_attrs)
|
16
|
-
div(**dark_attrs, &)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def default_attrs
|
22
|
-
{
|
23
|
-
data: {controller: "ruby-ui--theme-toggle"}
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
def default_light_attrs
|
28
|
-
{
|
29
|
-
class: "dark:hidden",
|
30
|
-
data: {action: "click->ruby-ui--theme-toggle#setDarkTheme"}
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
def default_dark_attrs
|
35
|
-
{
|
36
|
-
class: "hidden dark:inline-block",
|
37
|
-
data: {action: "click->ruby-ui--theme-toggle#setLightTheme"}
|
38
|
-
}
|
39
|
-
end
|
40
8
|
end
|
41
9
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus";
|
2
|
-
import { computePosition, autoUpdate, offset } from "@floating-ui/dom";
|
2
|
+
import { computePosition, autoUpdate, offset, shift } from "@floating-ui/dom";
|
3
3
|
|
4
4
|
export default class extends Controller {
|
5
5
|
static targets = ["trigger", "content"];
|
@@ -23,10 +23,11 @@ export default class extends Controller {
|
|
23
23
|
}
|
24
24
|
|
25
25
|
setFloatingElement() {
|
26
|
-
console.log(this.placementValue);
|
27
|
-
|
28
26
|
this.cleanup = autoUpdate(this.triggerTarget, this.contentTarget, () => {
|
29
|
-
computePosition(this.triggerTarget, this.contentTarget, {
|
27
|
+
computePosition(this.triggerTarget, this.contentTarget, {
|
28
|
+
placement: this.placementValue,
|
29
|
+
middleware: [offset(4), shift()]
|
30
|
+
}).then(({ x, y }) => {
|
30
31
|
Object.assign(this.contentTarget.style, {
|
31
32
|
left: `${x}px`,
|
32
33
|
top: `${y}px`,
|
data/lib/ruby_ui.rb
CHANGED