ruby_ui 1.0.0.pre.alpha.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/generators/rbui/base_generator.rb +17 -0
- data/lib/generators/rbui/component_generator.rb +137 -0
- data/lib/generators/rbui/install/install_generator.rb +194 -0
- data/lib/rbui/accordion/accordion.rb +17 -0
- data/lib/rbui/accordion/accordion_content.rb +21 -0
- data/lib/rbui/accordion/accordion_default_content.rb +17 -0
- data/lib/rbui/accordion/accordion_default_trigger.rb +19 -0
- data/lib/rbui/accordion/accordion_icon.rb +38 -0
- data/lib/rbui/accordion/accordion_item.rb +28 -0
- data/lib/rbui/accordion/accordion_trigger.rb +16 -0
- data/lib/rbui/alert/alert.rb +36 -0
- data/lib/rbui/alert/alert_description.rb +17 -0
- data/lib/rbui/alert/alert_title.rb +17 -0
- data/lib/rbui/alert_dialog/alert_dialog.rb +26 -0
- data/lib/rbui/alert_dialog/alert_dialog_action.rb +17 -0
- data/lib/rbui/alert_dialog/alert_dialog_cancel.rb +21 -0
- data/lib/rbui/alert_dialog/alert_dialog_content.rb +45 -0
- data/lib/rbui/alert_dialog/alert_dialog_description.rb +17 -0
- data/lib/rbui/alert_dialog/alert_dialog_footer.rb +17 -0
- data/lib/rbui/alert_dialog/alert_dialog_header.rb +17 -0
- data/lib/rbui/alert_dialog/alert_dialog_title.rb +17 -0
- data/lib/rbui/alert_dialog/alert_dialog_trigger.rb +18 -0
- data/lib/rbui/aspect_ratio/aspect_ratio.rb +33 -0
- data/lib/rbui/avatar/avatar.rb +31 -0
- data/lib/rbui/avatar/avatar_fallback.rb +17 -0
- data/lib/rbui/avatar/avatar_image.rb +26 -0
- data/lib/rbui/badge/badge.rb +60 -0
- data/lib/rbui/base.rb +29 -0
- data/lib/rbui/button/button.rb +97 -0
- data/lib/rbui/calendar/calendar.rb +39 -0
- data/lib/rbui/calendar/calendar_body.rb +19 -0
- data/lib/rbui/calendar/calendar_days.rb +104 -0
- data/lib/rbui/calendar/calendar_header.rb +17 -0
- data/lib/rbui/calendar/calendar_next.rb +43 -0
- data/lib/rbui/calendar/calendar_prev.rb +43 -0
- data/lib/rbui/calendar/calendar_title.rb +27 -0
- data/lib/rbui/calendar/calendar_weekdays.rb +33 -0
- data/lib/rbui/card/card.rb +17 -0
- data/lib/rbui/card/card_content.rb +17 -0
- data/lib/rbui/card/card_description.rb +17 -0
- data/lib/rbui/card/card_footer.rb +17 -0
- data/lib/rbui/card/card_header.rb +17 -0
- data/lib/rbui/card/card_title.rb +17 -0
- data/lib/rbui/chart/chart.rb +23 -0
- data/lib/rbui/checkbox/checkbox.rb +23 -0
- data/lib/rbui/checkbox/checkbox_group.rb +20 -0
- data/lib/rbui/clipboard/clipboard.rb +42 -0
- data/lib/rbui/clipboard/clipboard_popover.rb +40 -0
- data/lib/rbui/clipboard/clipboard_source.rb +19 -0
- data/lib/rbui/clipboard/clipboard_trigger.rb +20 -0
- data/lib/rbui/codeblock/codeblock.rb +105 -0
- data/lib/rbui/collapsible/collapsible.rb +25 -0
- data/lib/rbui/collapsible/collapsible_content.rb +18 -0
- data/lib/rbui/collapsible/collapsible_trigger.rb +19 -0
- data/lib/rbui/combobox/combobox.rb +24 -0
- data/lib/rbui/combobox/combobox_content.rb +31 -0
- data/lib/rbui/combobox/combobox_empty.rb +21 -0
- data/lib/rbui/combobox/combobox_group.rb +38 -0
- data/lib/rbui/combobox/combobox_input.rb +22 -0
- data/lib/rbui/combobox/combobox_item.rb +53 -0
- data/lib/rbui/combobox/combobox_list.rb +29 -0
- data/lib/rbui/combobox/combobox_search_input.rb +56 -0
- data/lib/rbui/combobox/combobox_separator.rb +15 -0
- data/lib/rbui/combobox/combobox_trigger.rb +52 -0
- data/lib/rbui/combobox/combobox_value.rb +27 -0
- data/lib/rbui/command/command.rb +9 -0
- data/lib/rbui/command/command_dialog.rb +17 -0
- data/lib/rbui/command/command_dialog_content.rb +48 -0
- data/lib/rbui/command/command_dialog_trigger.rb +29 -0
- data/lib/rbui/command/command_empty.rb +19 -0
- data/lib/rbui/command/command_group.rb +40 -0
- data/lib/rbui/command/command_input.rb +56 -0
- data/lib/rbui/command/command_item.rb +32 -0
- data/lib/rbui/command/command_list.rb +17 -0
- data/lib/rbui/context_menu/context_menu.rb +26 -0
- data/lib/rbui/context_menu/context_menu_content.rb +25 -0
- data/lib/rbui/context_menu/context_menu_item.rb +66 -0
- data/lib/rbui/context_menu/context_menu_label.rb +24 -0
- data/lib/rbui/context_menu/context_menu_separator.rb +19 -0
- data/lib/rbui/context_menu/context_menu_trigger.rb +20 -0
- data/lib/rbui/dialog/dialog.rb +25 -0
- data/lib/rbui/dialog/dialog_content.rb +78 -0
- data/lib/rbui/dialog/dialog_description.rb +17 -0
- data/lib/rbui/dialog/dialog_footer.rb +17 -0
- data/lib/rbui/dialog/dialog_header.rb +17 -0
- data/lib/rbui/dialog/dialog_middle.rb +17 -0
- data/lib/rbui/dialog/dialog_title.rb +17 -0
- data/lib/rbui/dialog/dialog_trigger.rb +20 -0
- data/lib/rbui/dropdown_menu/dropdown_menu.rb +26 -0
- data/lib/rbui/dropdown_menu/dropdown_menu_content.rb +22 -0
- data/lib/rbui/dropdown_menu/dropdown_menu_item.rb +28 -0
- data/lib/rbui/dropdown_menu/dropdown_menu_label.rb +17 -0
- data/lib/rbui/dropdown_menu/dropdown_menu_separator.rb +19 -0
- data/lib/rbui/dropdown_menu/dropdown_menu_trigger.rb +18 -0
- data/lib/rbui/form/form.rb +15 -0
- data/lib/rbui/form/form_field.rb +20 -0
- data/lib/rbui/form/form_field_error.rb +20 -0
- data/lib/rbui/form/form_field_hint.rb +15 -0
- data/lib/rbui/form/form_field_label.rb +15 -0
- data/lib/rbui/hover_card/hover_card.rb +27 -0
- data/lib/rbui/hover_card/hover_card_content.rb +22 -0
- data/lib/rbui/hover_card/hover_card_trigger.rb +20 -0
- data/lib/rbui/input/input.rb +26 -0
- data/lib/rbui/link/link.rb +97 -0
- data/lib/rbui/pagination/pagination.rb +19 -0
- data/lib/rbui/pagination/pagination_content.rb +17 -0
- data/lib/rbui/pagination/pagination_ellipsis.rb +42 -0
- data/lib/rbui/pagination/pagination_item.rb +28 -0
- data/lib/rbui/popover/popover.rb +26 -0
- data/lib/rbui/popover/popover_content.rb +27 -0
- data/lib/rbui/popover/popover_trigger.rb +20 -0
- data/lib/rbui/radio_button/radio_button.rb +22 -0
- data/lib/rbui/railtie.rb +52 -0
- data/lib/rbui/select/select.rb +23 -0
- data/lib/rbui/select/select_content.rb +32 -0
- data/lib/rbui/select/select_group.rb +15 -0
- data/lib/rbui/select/select_input.rb +22 -0
- data/lib/rbui/select/select_item.rb +52 -0
- data/lib/rbui/select/select_label.rb +17 -0
- data/lib/rbui/select/select_trigger.rb +54 -0
- data/lib/rbui/select/select_value.rb +27 -0
- data/lib/rbui/sheet/sheet.rb +17 -0
- data/lib/rbui/sheet/sheet_content.rb +77 -0
- data/lib/rbui/sheet/sheet_description.rb +17 -0
- data/lib/rbui/sheet/sheet_footer.rb +17 -0
- data/lib/rbui/sheet/sheet_header.rb +17 -0
- data/lib/rbui/sheet/sheet_middle.rb +17 -0
- data/lib/rbui/sheet/sheet_title.rb +17 -0
- data/lib/rbui/sheet/sheet_trigger.rb +17 -0
- data/lib/rbui/shortcut_key/shortcut_key.rb +17 -0
- data/lib/rbui/table/table.rb +19 -0
- data/lib/rbui/table/table_body.rb +17 -0
- data/lib/rbui/table/table_caption.rb +17 -0
- data/lib/rbui/table/table_cell.rb +17 -0
- data/lib/rbui/table/table_footer.rb +17 -0
- data/lib/rbui/table/table_head.rb +17 -0
- data/lib/rbui/table/table_header.rb +17 -0
- data/lib/rbui/table/table_row.rb +17 -0
- data/lib/rbui/tabs/tabs.rb +25 -0
- data/lib/rbui/tabs/tabs_content.rb +26 -0
- data/lib/rbui/tabs/tabs_list.rb +17 -0
- data/lib/rbui/tabs/tabs_trigger.rb +28 -0
- data/lib/rbui/textarea/textarea.rb +26 -0
- data/lib/rbui/theme_toggle/theme_toggle.rb +41 -0
- data/lib/rbui/tooltip/tooltip.rb +26 -0
- data/lib/rbui/tooltip/tooltip_content.rb +26 -0
- data/lib/rbui/tooltip/tooltip_trigger.rb +19 -0
- data/lib/rbui/typography/typography_blockquote.rb +17 -0
- data/lib/rbui/typography/typography_h1.rb +17 -0
- data/lib/rbui/typography/typography_h2.rb +17 -0
- data/lib/rbui/typography/typography_h3.rb +17 -0
- data/lib/rbui/typography/typography_h4.rb +17 -0
- data/lib/rbui/typography/typography_inline_code.rb +17 -0
- data/lib/rbui/typography/typography_inline_link.rb +22 -0
- data/lib/rbui/typography/typography_large.rb +17 -0
- data/lib/rbui/typography/typography_lead.rb +17 -0
- data/lib/rbui/typography/typography_list.rb +47 -0
- data/lib/rbui/typography/typography_list_item.rb +17 -0
- data/lib/rbui/typography/typography_muted.rb +17 -0
- data/lib/rbui/typography/typography_p.rb +17 -0
- data/lib/rbui/typography/typography_small.rb +17 -0
- data/lib/rbui/version.rb +5 -0
- data/lib/rbui.rb +57 -0
- data/lib/ruby_ui.rb +1 -0
- metadata +291 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class AlertDialogContent < Base
|
5
|
+
def view_template(&block)
|
6
|
+
template_tag(**attrs) do
|
7
|
+
div(data: {controller: "rbui--alert-dialog"}) do
|
8
|
+
background
|
9
|
+
container(&block)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def background
|
15
|
+
div(
|
16
|
+
data_state: "open",
|
17
|
+
class:
|
18
|
+
"fixed inset-0 z-50 bg-black/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",
|
19
|
+
style: "pointer-events:auto",
|
20
|
+
data_aria_hidden: "true",
|
21
|
+
aria_hidden: "true"
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def container(&)
|
26
|
+
div(
|
27
|
+
role: "alertdialog",
|
28
|
+
data_state: "open",
|
29
|
+
class: "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg 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",
|
30
|
+
style: "pointer-events:auto",
|
31
|
+
&
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def default_attrs
|
38
|
+
{
|
39
|
+
data: {
|
40
|
+
rbui__alert_dialog_target: "content"
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class AlertDialogFooter < Base
|
5
|
+
def view_template(&)
|
6
|
+
div(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
class: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2"
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class AlertDialogHeader < Base
|
5
|
+
def view_template(&)
|
6
|
+
div(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
class: "flex flex-col space-y-2 text-center sm:text-left"
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class AlertDialogTrigger < Base
|
5
|
+
def view_template(&)
|
6
|
+
div(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
data: {action: "click->rbui--alert-dialog#open"},
|
14
|
+
class: "inline-block"
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class AspectRatio < Base
|
5
|
+
def initialize(aspect_ratio: "16/9", **attrs)
|
6
|
+
raise "aspect_ratio must be in the format of a string with a slash in the middle (eg. '16/9', '1/1')" unless aspect_ratio.is_a?(String) && aspect_ratio.include?("/")
|
7
|
+
|
8
|
+
@aspect_ratio = aspect_ratio
|
9
|
+
super(**attrs)
|
10
|
+
end
|
11
|
+
|
12
|
+
def view_template(&block)
|
13
|
+
div(
|
14
|
+
class: "relative w-full",
|
15
|
+
style: "padding-bottom: #{padding_bottom}%;"
|
16
|
+
) do
|
17
|
+
div(**attrs, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def padding_bottom
|
24
|
+
@aspect_ratio.split("/").map(&:to_i).reverse.reduce(&:fdiv) * 100
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_attrs
|
28
|
+
{
|
29
|
+
class: "bg-muted absolute inset-0 [&>img]:object-cover [&>img]:absolute [&>img]:h-full [&>img]:w-full [&>img]:inset-0 [&>img]:text-transparent"
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class Avatar < Base
|
5
|
+
SIZES = {
|
6
|
+
xs: "h-4 w-4 text-[0.5rem]",
|
7
|
+
sm: "h-6 w-6 text-xs",
|
8
|
+
md: "h-10 w-10 text-base",
|
9
|
+
lg: "h-14 w-14 text-xl",
|
10
|
+
xl: "h-20 w-20 text-3xl"
|
11
|
+
}
|
12
|
+
|
13
|
+
def initialize(size: :md, **attrs)
|
14
|
+
@size = size
|
15
|
+
@size_classes = SIZES[@size]
|
16
|
+
super(**attrs)
|
17
|
+
end
|
18
|
+
|
19
|
+
def view_template(&)
|
20
|
+
span(**attrs, &)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def default_attrs
|
26
|
+
{
|
27
|
+
class: tokens("relative flex shrink-0 overflow-hidden rounded-full", @size_classes)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class AvatarFallback < Base
|
5
|
+
def view_template(&)
|
6
|
+
span(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
class: "flex h-full w-full items-center justify-center rounded-full bg-muted"
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class AvatarImage < Base
|
5
|
+
def initialize(src:, alt: "", **attrs)
|
6
|
+
@src = src
|
7
|
+
@alt = alt
|
8
|
+
super(**attrs)
|
9
|
+
end
|
10
|
+
|
11
|
+
def view_template
|
12
|
+
img(**attrs)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def default_attrs
|
18
|
+
{
|
19
|
+
loading: "lazy",
|
20
|
+
class: "aspect-square h-full w-full",
|
21
|
+
alt: @alt,
|
22
|
+
src: @src
|
23
|
+
}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class Badge < Base
|
5
|
+
SIZES = {
|
6
|
+
sm: "px-1.5 py-0.5 text-xs",
|
7
|
+
md: "px-2 py-1 text-xs",
|
8
|
+
lg: "px-3 py-1 text-sm"
|
9
|
+
}
|
10
|
+
|
11
|
+
COLORS = {
|
12
|
+
primary: "text-primary bg-primary/5 ring-primary/20",
|
13
|
+
secondary: "text-secondary bg-secondary/10 ring-secondary/20",
|
14
|
+
outline: "text-foreground bg-background ring-border",
|
15
|
+
destructive: "text-destructive bg-destructive/10 ring-destructive/20",
|
16
|
+
success: "text-success bg-success/10 ring-success/20",
|
17
|
+
warning: "text-warning bg-warning/10 ring-warning/20",
|
18
|
+
slate: "text-slate-500 bg-slate-500/10 ring-slate-500/20",
|
19
|
+
gray: "text-gray-500 bg-gray-500/10 ring-gray-500/20",
|
20
|
+
zinc: "text-zinc-500 bg-zinc-500/10 ring-zinc-500/20",
|
21
|
+
neutral: "text-neutral-500 bg-neutral-500/10 ring-neutral-500/20",
|
22
|
+
stone: "text-stone-500 bg-stone-500/10 ring-stone-500/20",
|
23
|
+
red: "text-red-500 bg-red-500/10 ring-red-500/20",
|
24
|
+
orange: "text-orange-500 bg-orange-500/10 ring-orange-500/20",
|
25
|
+
amber: "text-amber-500 bg-amber-500/10 ring-amber-500/20",
|
26
|
+
yellow: "text-yellow-500 bg-yellow-500/10 ring-yellow-500/20",
|
27
|
+
lime: "text-lime-500 bg-lime-500/10 ring-lime-500/20",
|
28
|
+
green: "text-green-500 bg-green-500/10 ring-green-500/20",
|
29
|
+
emerald: "text-emerald-500 bg-emerald-500/10 ring-emerald-500/20",
|
30
|
+
teal: "text-teal-500 bg-teal-500/10 ring-teal-500/20",
|
31
|
+
cyan: "text-cyan-500 bg-cyan-500/10 ring-cyan-500/20",
|
32
|
+
sky: "text-sky-500 bg-sky-500/10 ring-sky-500/20",
|
33
|
+
blue: "text-blue-500 bg-blue-500/10 ring-blue-500/20",
|
34
|
+
indigo: "text-indigo-500 bg-indigo-500/10 ring-indigo-500/20",
|
35
|
+
violet: "text-violet-500 bg-violet-500/10 ring-violet-500/20",
|
36
|
+
purple: "text-purple-500 bg-purple-500/10 ring-purple-500/20",
|
37
|
+
fuchsia: "text-fuchsia-500 bg-fuchsia-500/10 ring-fuchsia-500/20",
|
38
|
+
pink: "text-pink-500 bg-pink-500/10 ring-pink-500/20",
|
39
|
+
rose: "text-rose-500 bg-rose-500/10 ring-rose-500/20"
|
40
|
+
}
|
41
|
+
|
42
|
+
def initialize(variant: :primary, size: :md, **args)
|
43
|
+
@variant = variant
|
44
|
+
@size = size
|
45
|
+
super(**args)
|
46
|
+
end
|
47
|
+
|
48
|
+
def view_template(&)
|
49
|
+
span(**attrs, &)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def default_attrs
|
55
|
+
{
|
56
|
+
class: tokens("inline-flex items-center rounded-md font-medium ring-1 ring-inset", SIZES[@size], COLORS[@variant])
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/rbui/base.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "tailwind_merge"
|
4
|
+
|
5
|
+
module RBUI
|
6
|
+
class Base < Phlex::HTML
|
7
|
+
TAILWIND_MERGER = ::TailwindMerge::Merger.new.freeze unless defined?(TAILWIND_MERGER)
|
8
|
+
|
9
|
+
attr_reader :attrs
|
10
|
+
|
11
|
+
def initialize(**user_attrs)
|
12
|
+
@attrs = mix(default_attrs, user_attrs)
|
13
|
+
@attrs[:class] = TAILWIND_MERGER.merge(@attrs[:class]) if @attrs[:class]
|
14
|
+
end
|
15
|
+
|
16
|
+
if defined?(Rails) && Rails.env.development?
|
17
|
+
def before_template
|
18
|
+
comment { "Before #{self.class.name}" }
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def default_attrs
|
26
|
+
{}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class Button < Base
|
5
|
+
def initialize(type: :button, variant: :primary, size: :md, icon: false, **attrs)
|
6
|
+
@type = type
|
7
|
+
@variant = variant.to_sym
|
8
|
+
@size = size.to_sym
|
9
|
+
@icon = icon
|
10
|
+
super(**attrs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def view_template(&)
|
14
|
+
button(**attrs, &)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def size_classes
|
20
|
+
if @icon
|
21
|
+
case @size
|
22
|
+
when :sm then "h-6 w-6"
|
23
|
+
when :md then "h-9 w-9"
|
24
|
+
when :lg then "h-10 w-10"
|
25
|
+
when :xl then "h-12 w-12"
|
26
|
+
end
|
27
|
+
else
|
28
|
+
case @size
|
29
|
+
when :sm then "px-3 py-1.5 h-8 text-xs"
|
30
|
+
when :md then "px-4 py-2 h-9 text-sm"
|
31
|
+
when :lg then "px-4 py-2 h-10 text-base"
|
32
|
+
when :xl then "px-6 py-3 h-12 text-base"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def primary_classes
|
38
|
+
tokens(
|
39
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
40
|
+
size_classes
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def link_classes
|
45
|
+
tokens(
|
46
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 text-primary underline-offset-4 hover:underline",
|
47
|
+
size_classes
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def secondary_classes
|
52
|
+
tokens(
|
53
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-secondary text-secondary-foreground hover:bg-opacity-80",
|
54
|
+
size_classes
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def destructive_classes
|
59
|
+
tokens(
|
60
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
61
|
+
size_classes
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def outline_classes
|
66
|
+
tokens(
|
67
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
68
|
+
size_classes
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def ghost_classes
|
73
|
+
tokens(
|
74
|
+
"whitespace-nowrap inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 hover:bg-accent hover:text-accent-foreground",
|
75
|
+
size_classes
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def default_classes
|
80
|
+
case @variant
|
81
|
+
when :primary then primary_classes
|
82
|
+
when :link then link_classes
|
83
|
+
when :secondary then secondary_classes
|
84
|
+
when :destructive then destructive_classes
|
85
|
+
when :outline then outline_classes
|
86
|
+
when :ghost then ghost_classes
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def default_attrs
|
91
|
+
{
|
92
|
+
type: @type,
|
93
|
+
class: default_classes
|
94
|
+
}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class Calendar < Base
|
5
|
+
def initialize(selected_date: nil, input_id: nil, date_format: "yyyy-MM-dd", **attrs)
|
6
|
+
@selected_date = selected_date
|
7
|
+
@input_id = input_id
|
8
|
+
@date_format = date_format
|
9
|
+
super(**attrs)
|
10
|
+
end
|
11
|
+
|
12
|
+
def view_template
|
13
|
+
div(**attrs) do
|
14
|
+
RBUI.CalendarHeader do
|
15
|
+
RBUI.CalendarTitle
|
16
|
+
RBUI.CalendarPrev
|
17
|
+
RBUI.CalendarNext
|
18
|
+
end
|
19
|
+
RBUI.CalendarBody # Where the calendar is rendered (Weekdays and Days)
|
20
|
+
RBUI.CalendarWeekdays # Template for the weekdays
|
21
|
+
RBUI.CalendarDays # Template for the days
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def default_attrs
|
28
|
+
{
|
29
|
+
class: "p-3 space-y-4",
|
30
|
+
data: {
|
31
|
+
controller: "rbui--calendar",
|
32
|
+
rbui__calendar_selected_date_value: @selected_date&.to_s,
|
33
|
+
rbui__calendar_format_value: @date_format,
|
34
|
+
rbui__calendar_rbui__calendar_input_outlet: @input_id
|
35
|
+
}
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class CalendarDays < Base
|
5
|
+
BASE_CLASS = "inline-flex items-center justify-center rounded-md text-sm ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 h-8 w-8 p-0 font-normal aria-selected:opacity-100"
|
6
|
+
|
7
|
+
def view_template
|
8
|
+
render_selected_date_template
|
9
|
+
render_today_date_template
|
10
|
+
render_current_month_date_template
|
11
|
+
render_other_month_date_template
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def render_selected_date_template
|
17
|
+
date_template("selectedDateTemplate") do
|
18
|
+
button(
|
19
|
+
data_day: "{{day}}",
|
20
|
+
data_action: "click->rbui--calendar#selectDay",
|
21
|
+
name: "day",
|
22
|
+
class:
|
23
|
+
tokens(
|
24
|
+
BASE_CLASS,
|
25
|
+
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground"
|
26
|
+
),
|
27
|
+
role: "gridcell",
|
28
|
+
tabindex: "0",
|
29
|
+
type: "button",
|
30
|
+
aria_selected: "true"
|
31
|
+
) { "{{dayDate}}" }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_today_date_template
|
36
|
+
date_template("todayDateTemplate") do
|
37
|
+
button(
|
38
|
+
data_day: "{{day}}",
|
39
|
+
data_action: "click->rbui--calendar#selectDay",
|
40
|
+
name: "day",
|
41
|
+
class:
|
42
|
+
tokens(
|
43
|
+
BASE_CLASS,
|
44
|
+
"bg-accent text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
|
45
|
+
),
|
46
|
+
role: "gridcell",
|
47
|
+
tabindex: "-1",
|
48
|
+
type: "button"
|
49
|
+
) { "{{dayDate}}" }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def render_current_month_date_template
|
54
|
+
date_template("currentMonthDateTemplate") do
|
55
|
+
button(
|
56
|
+
data_day: "{{day}}",
|
57
|
+
data_action: "click->rbui--calendar#selectDay",
|
58
|
+
name: "day",
|
59
|
+
class:
|
60
|
+
tokens(
|
61
|
+
BASE_CLASS,
|
62
|
+
"bg-background text-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
|
63
|
+
),
|
64
|
+
role: "gridcell",
|
65
|
+
tabindex: "-1",
|
66
|
+
type: "button"
|
67
|
+
) { "{{dayDate}}" }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def render_other_month_date_template
|
72
|
+
date_template("otherMonthDateTemplate") do
|
73
|
+
button(
|
74
|
+
data_day: "{{day}}",
|
75
|
+
data_action: " click->rbui--calendar#selectDay",
|
76
|
+
name: "day",
|
77
|
+
class:
|
78
|
+
tokens(
|
79
|
+
BASE_CLASS,
|
80
|
+
"bg-background text-muted-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
|
81
|
+
),
|
82
|
+
role: "gridcell",
|
83
|
+
tabindex: "-1",
|
84
|
+
type: "button"
|
85
|
+
) { "{{dayDate}}" }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def date_template(target, &block)
|
90
|
+
template_tag(data: {rbui__calendar_target: target}) do
|
91
|
+
td(
|
92
|
+
class:
|
93
|
+
"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected])]:rounded-md",
|
94
|
+
role: "presentation",
|
95
|
+
&block
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def default_attrs
|
101
|
+
{}
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class CalendarHeader < Base
|
5
|
+
def view_template(&)
|
6
|
+
div(**attrs, &)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def default_attrs
|
12
|
+
{
|
13
|
+
class: "flex justify-center pt-1 relative items-center"
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBUI
|
4
|
+
class CalendarNext < Base
|
5
|
+
def view_template(&block)
|
6
|
+
button(**attrs) do
|
7
|
+
icon
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def icon
|
14
|
+
svg(
|
15
|
+
width: "15",
|
16
|
+
height: "15",
|
17
|
+
viewbox: "0 0 15 15",
|
18
|
+
fill: "none",
|
19
|
+
xmlns: "http://www.w3.org/2000/svg",
|
20
|
+
class: "h-4 w-4"
|
21
|
+
) do |s|
|
22
|
+
s.path(
|
23
|
+
d:
|
24
|
+
"M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.6151 7.15788C10.7954 7.3502 10.7954 7.64949 10.6151 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z",
|
25
|
+
fill: "currentColor",
|
26
|
+
fill_rule: "evenodd",
|
27
|
+
clip_rule: "evenodd"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def default_attrs
|
33
|
+
{
|
34
|
+
name: "next-month",
|
35
|
+
aria_label: "Go to next month",
|
36
|
+
class:
|
37
|
+
"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border border-input hover:bg-accent hover:text-accent-foreground h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute right-1",
|
38
|
+
type: "button",
|
39
|
+
data_action: "click->rbui--calendar#nextMonth"
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|