kiso 0.2.1.pre → 0.3.0.pre
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/CHANGELOG.md +27 -1
- data/app/assets/tailwind/kiso/dialog.css +46 -0
- data/app/assets/tailwind/kiso/engine.css +2 -0
- data/app/assets/tailwind/kiso/input-otp.css +17 -0
- data/app/assets/tailwind/kiso/slider.css +27 -0
- data/app/helpers/kiso/component_helper.rb +10 -0
- data/app/javascript/controllers/kiso/dialog_controller.js +140 -0
- data/app/javascript/controllers/kiso/index.js +3 -0
- data/app/javascript/controllers/kiso/slider_controller.js +276 -0
- data/app/views/kiso/components/_alert_dialog.html.erb +28 -0
- data/app/views/kiso/components/_aspect_ratio.html.erb +8 -0
- data/app/views/kiso/components/_button.html.erb +31 -17
- data/app/views/kiso/components/_dialog.html.erb +11 -0
- data/app/views/kiso/components/_slider.html.erb +42 -0
- data/app/views/kiso/components/alert_dialog/_action.html.erb +8 -0
- data/app/views/kiso/components/alert_dialog/_cancel.html.erb +8 -0
- data/app/views/kiso/components/alert_dialog/_description.html.erb +8 -0
- data/app/views/kiso/components/alert_dialog/_footer.html.erb +7 -0
- data/app/views/kiso/components/alert_dialog/_header.html.erb +7 -0
- data/app/views/kiso/components/alert_dialog/_media.html.erb +7 -0
- data/app/views/kiso/components/alert_dialog/_title.html.erb +8 -0
- data/app/views/kiso/components/dialog/_body.html.erb +7 -0
- data/app/views/kiso/components/dialog/_close.html.erb +10 -0
- data/app/views/kiso/components/dialog/_description.html.erb +7 -0
- data/app/views/kiso/components/dialog/_footer.html.erb +7 -0
- data/app/views/kiso/components/dialog/_header.html.erb +7 -0
- data/app/views/kiso/components/dialog/_title.html.erb +7 -0
- data/app/views/kiso/components/empty/_actions.html.erb +7 -0
- data/lib/kiso/themes/alert_dialog.rb +78 -0
- data/lib/kiso/themes/aspect_ratio.rb +16 -0
- data/lib/kiso/themes/dashboard.rb +5 -5
- data/lib/kiso/themes/dialog.rb +57 -0
- data/lib/kiso/themes/empty.rb +6 -1
- data/lib/kiso/themes/input_otp.rb +3 -3
- data/lib/kiso/themes/slider.rb +53 -0
- data/lib/kiso/version.rb +1 -1
- data/lib/kiso.rb +4 -0
- metadata +27 -1
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
<%# locals: (color: :primary, variant: :solid, size: :md, block: false,
|
|
2
|
-
type: :button, href: nil, disabled: false,
|
|
3
|
-
css_classes: "", **component_options) %>
|
|
4
|
-
<%
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
type: :button, href: nil, method: nil, disabled: false,
|
|
3
|
+
form: {}, css_classes: "", **component_options) %>
|
|
4
|
+
<%
|
|
5
|
+
css = Kiso::Themes::Button.render(
|
|
6
|
+
color: color, variant: variant, size: size, block: block, class: css_classes)
|
|
7
|
+
data = kiso_prepare_options(component_options, slot: "button")
|
|
8
|
+
use_button_to = href.present? && method.present? && method.to_s != "get"
|
|
9
|
+
%>
|
|
10
|
+
<% if use_button_to %>
|
|
11
|
+
<%= button_to href,
|
|
12
|
+
method: method,
|
|
13
|
+
class: css,
|
|
14
|
+
form_class: "contents",
|
|
15
|
+
data: data,
|
|
16
|
+
disabled: disabled || nil,
|
|
17
|
+
form: form.presence,
|
|
18
|
+
**component_options do %>
|
|
19
|
+
<%= yield %>
|
|
20
|
+
<% end %>
|
|
21
|
+
<% elsif href.present? %>
|
|
22
|
+
<% component_options[:href] = href
|
|
23
|
+
component_options[:"aria-disabled"] = true if disabled %>
|
|
24
|
+
<%= content_tag :a, class: css, data: data, **component_options do %>
|
|
25
|
+
<%= yield %>
|
|
26
|
+
<% end %>
|
|
27
|
+
<% else %>
|
|
28
|
+
<% component_options[:type] = type
|
|
29
|
+
component_options[:disabled] = true if disabled %>
|
|
30
|
+
<%= content_tag :button, class: css, data: data, **component_options do %>
|
|
31
|
+
<%= yield %>
|
|
32
|
+
<% end %>
|
|
19
33
|
<% end %>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<%# locals: (open: false, css_classes: "", **component_options) %>
|
|
2
|
+
<%= content_tag :dialog,
|
|
3
|
+
class: Kiso::Themes::Dialog.render(class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "dialog",
|
|
5
|
+
controller: "kiso--dialog",
|
|
6
|
+
kiso__dialog_open_value: (open ? true : nil)),
|
|
7
|
+
**component_options do %>
|
|
8
|
+
<div class="<%= Kiso::Themes::DialogContent.render %>" data-slot="dialog-content">
|
|
9
|
+
<%= yield %>
|
|
10
|
+
</div>
|
|
11
|
+
<% end %>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<%# locals: (min: 0, max: 100, step: 1, value: nil, name: nil, id: nil, disabled: false, size: :md, aria_label: nil, css_classes: "", **component_options) %>
|
|
2
|
+
<% slider_value = value || min %>
|
|
3
|
+
<% percent = ((slider_value.to_f - min) / (max - min) * 100).clamp(0, 100) %>
|
|
4
|
+
<%= content_tag :div,
|
|
5
|
+
class: Kiso::Themes::Slider.render(class: css_classes),
|
|
6
|
+
data: kiso_prepare_options(component_options, slot: "slider",
|
|
7
|
+
controller: "kiso--slider",
|
|
8
|
+
kiso__slider_min_value: min,
|
|
9
|
+
kiso__slider_max_value: max,
|
|
10
|
+
kiso__slider_step_value: step),
|
|
11
|
+
**component_options do %>
|
|
12
|
+
<%= tag.input(type: :range,
|
|
13
|
+
id: id,
|
|
14
|
+
name: name,
|
|
15
|
+
min: min,
|
|
16
|
+
max: max,
|
|
17
|
+
step: step,
|
|
18
|
+
value: slider_value,
|
|
19
|
+
disabled: disabled,
|
|
20
|
+
aria: { label: aria_label },
|
|
21
|
+
tabindex: "-1",
|
|
22
|
+
class: "sr-only",
|
|
23
|
+
data: { kiso__slider_target: "input" }) %>
|
|
24
|
+
<%= tag.div(
|
|
25
|
+
class: Kiso::Themes::SliderTrack.render(size: size),
|
|
26
|
+
data: { slot: "slider-track", kiso__slider_target: "track" }) do %>
|
|
27
|
+
<%= tag.div(
|
|
28
|
+
class: Kiso::Themes::SliderRange.render,
|
|
29
|
+
style: "width: #{percent}%",
|
|
30
|
+
data: { slot: "slider-range", kiso__slider_target: "range" }) %>
|
|
31
|
+
<% end %>
|
|
32
|
+
<%= tag.div(
|
|
33
|
+
class: Kiso::Themes::SliderThumb.render(size: size),
|
|
34
|
+
role: :slider,
|
|
35
|
+
tabindex: (disabled ? "-1" : "0"),
|
|
36
|
+
aria: { valuemin: min, valuemax: max, valuenow: slider_value,
|
|
37
|
+
label: aria_label,
|
|
38
|
+
disabled: (disabled || nil) },
|
|
39
|
+
style: "position: absolute; left: #{percent}%",
|
|
40
|
+
data: { slot: "slider-thumb", kiso__slider_target: "thumb",
|
|
41
|
+
disabled: (disabled ? "true" : nil) }) %>
|
|
42
|
+
<% end %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<%# locals: (color: :primary, variant: :solid, size: :md, css_classes: "", **component_options) %>
|
|
2
|
+
<%= tag.button type: "button",
|
|
3
|
+
class: Kiso::Themes::Button.render(color: color, variant: variant, size: size, class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "alert-dialog-action",
|
|
5
|
+
action: "kiso--dialog#close"),
|
|
6
|
+
**component_options do %>
|
|
7
|
+
<%= yield %>
|
|
8
|
+
<% end %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<%# locals: (color: :primary, variant: :outline, size: :md, css_classes: "", **component_options) %>
|
|
2
|
+
<%= tag.button type: "button",
|
|
3
|
+
class: Kiso::Themes::Button.render(color: color, variant: variant, size: size, class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "alert-dialog-cancel",
|
|
5
|
+
action: "kiso--dialog#close"),
|
|
6
|
+
**component_options do %>
|
|
7
|
+
<%= yield %>
|
|
8
|
+
<% end %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<% component_options[:id] = "#{@_kiso_alert_dialog_id}-description" if @_kiso_alert_dialog_id && !component_options.key?(:id) %>
|
|
3
|
+
<%= content_tag :p,
|
|
4
|
+
class: Kiso::Themes::AlertDialogDescription.render(class: css_classes),
|
|
5
|
+
data: kiso_prepare_options(component_options, slot: "alert-dialog-description"),
|
|
6
|
+
**component_options do %>
|
|
7
|
+
<%= yield %>
|
|
8
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<%= content_tag :div,
|
|
3
|
+
class: Kiso::Themes::AlertDialogFooter.render(class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "alert-dialog-footer"),
|
|
5
|
+
**component_options do %>
|
|
6
|
+
<%= yield %>
|
|
7
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<%= content_tag :div,
|
|
3
|
+
class: Kiso::Themes::AlertDialogHeader.render(class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "alert-dialog-header"),
|
|
5
|
+
**component_options do %>
|
|
6
|
+
<%= yield %>
|
|
7
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<%= content_tag :div,
|
|
3
|
+
class: Kiso::Themes::AlertDialogMedia.render(class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "alert-dialog-media"),
|
|
5
|
+
**component_options do %>
|
|
6
|
+
<%= yield %>
|
|
7
|
+
<% end %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<% component_options[:id] = "#{@_kiso_alert_dialog_id}-title" if @_kiso_alert_dialog_id && !component_options.key?(:id) %>
|
|
3
|
+
<%= content_tag :h2,
|
|
4
|
+
class: Kiso::Themes::AlertDialogTitle.render(class: css_classes),
|
|
5
|
+
data: kiso_prepare_options(component_options, slot: "alert-dialog-title"),
|
|
6
|
+
**component_options do %>
|
|
7
|
+
<%= yield %>
|
|
8
|
+
<% end %>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<% content = capture { yield }.presence %>
|
|
3
|
+
<%= tag.button type: "button",
|
|
4
|
+
class: Kiso::Themes::DialogClose.render(class: css_classes),
|
|
5
|
+
data: kiso_prepare_options(component_options, slot: "dialog-close",
|
|
6
|
+
action: "kiso--dialog#close"),
|
|
7
|
+
**component_options do %>
|
|
8
|
+
<%= content || kiso_component_icon(:x) %>
|
|
9
|
+
<span class="sr-only">Close</span>
|
|
10
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<%= content_tag :p,
|
|
3
|
+
class: Kiso::Themes::DialogDescription.render(class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "dialog-description"),
|
|
5
|
+
**component_options do %>
|
|
6
|
+
<%= yield %>
|
|
7
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<%= content_tag :div,
|
|
3
|
+
class: Kiso::Themes::DialogFooter.render(class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "dialog-footer"),
|
|
5
|
+
**component_options do %>
|
|
6
|
+
<%= yield %>
|
|
7
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<%= content_tag :div,
|
|
3
|
+
class: Kiso::Themes::DialogHeader.render(class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "dialog-header"),
|
|
5
|
+
**component_options do %>
|
|
6
|
+
<%= yield %>
|
|
7
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%# locals: (css_classes: "", **component_options) %>
|
|
2
|
+
<%= content_tag :div,
|
|
3
|
+
class: Kiso::Themes::EmptyActions.render(class: css_classes),
|
|
4
|
+
data: kiso_prepare_options(component_options, slot: "empty-actions"),
|
|
5
|
+
**component_options do %>
|
|
6
|
+
<%= yield %>
|
|
7
|
+
<% end %>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
module Kiso
|
|
2
|
+
module Themes
|
|
3
|
+
# Alert dialog for confirmations that require an explicit user action.
|
|
4
|
+
# Wraps the native +<dialog>+ element with +role="alertdialog"+.
|
|
5
|
+
# Unlike {Dialog}, cannot be dismissed by backdrop click or Escape key.
|
|
6
|
+
#
|
|
7
|
+
# Reuses the +kiso--dialog+ Stimulus controller with
|
|
8
|
+
# +dismissable: false+.
|
|
9
|
+
#
|
|
10
|
+
# Sub-parts: {AlertDialogContent}, {AlertDialogHeader},
|
|
11
|
+
# {AlertDialogTitle}, {AlertDialogDescription}, {AlertDialogMedia},
|
|
12
|
+
# {AlertDialogFooter}, {AlertDialogAction}, {AlertDialogCancel}
|
|
13
|
+
AlertDialog = ClassVariants.build(
|
|
14
|
+
base: "fixed inset-0 z-50 m-0 h-full w-full max-w-none max-h-none bg-black/50 p-0 " \
|
|
15
|
+
"items-center justify-center backdrop:bg-transparent open:flex"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# The centered panel inside the {AlertDialog} overlay. Supports
|
|
19
|
+
# +size:+ variant (+:default+ or +:sm+).
|
|
20
|
+
AlertDialogContent = ClassVariants.build(
|
|
21
|
+
base: "bg-background text-foreground relative grid w-full max-w-[calc(100%-2rem)] " \
|
|
22
|
+
"gap-4 rounded-lg border p-6 shadow-lg outline-none group/alert-dialog-content",
|
|
23
|
+
variants: {
|
|
24
|
+
size: {
|
|
25
|
+
default: "sm:max-w-lg",
|
|
26
|
+
sm: "max-w-xs"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
defaults: {size: :default}
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Grid container for {AlertDialogTitle}, {AlertDialogDescription},
|
|
33
|
+
# and optional {AlertDialogMedia}. Adapts layout responsively when
|
|
34
|
+
# media is present via +has-[...]+ selectors.
|
|
35
|
+
AlertDialogHeader = ClassVariants.build(
|
|
36
|
+
base: "grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center " \
|
|
37
|
+
"has-[[data-slot=alert-dialog-media]]:grid-rows-[auto_auto_1fr] " \
|
|
38
|
+
"has-[[data-slot=alert-dialog-media]]:gap-x-6 " \
|
|
39
|
+
"sm:group-data-[size=default]/alert-dialog-content:place-items-start " \
|
|
40
|
+
"sm:group-data-[size=default]/alert-dialog-content:text-left " \
|
|
41
|
+
"sm:group-data-[size=default]/alert-dialog-content:has-[[data-slot=alert-dialog-media]]:grid-rows-[auto_1fr]"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Action buttons container. Reversed column on mobile, horizontal
|
|
45
|
+
# on desktop. Grid layout when parent content is +:sm+ size.
|
|
46
|
+
AlertDialogFooter = ClassVariants.build(
|
|
47
|
+
base: "flex flex-col-reverse gap-2 " \
|
|
48
|
+
"group-data-[size=sm]/alert-dialog-content:grid " \
|
|
49
|
+
"group-data-[size=sm]/alert-dialog-content:grid-cols-2 " \
|
|
50
|
+
"sm:flex-row sm:justify-end"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# The alert dialog heading. Renders as +<h2>+. Shifts to column 2
|
|
54
|
+
# when media is present in default size.
|
|
55
|
+
AlertDialogTitle = ClassVariants.build(
|
|
56
|
+
base: "text-lg font-semibold " \
|
|
57
|
+
"sm:group-data-[size=default]/alert-dialog-content:group-has-[[data-slot=alert-dialog-media]]/alert-dialog-content:col-start-2"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Descriptive text below the {AlertDialogTitle}.
|
|
61
|
+
AlertDialogDescription = ClassVariants.build(
|
|
62
|
+
base: "text-muted-foreground text-sm"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Optional icon or image container in the header. Renders as a
|
|
66
|
+
# rounded box with muted background. Spans 2 rows in default size.
|
|
67
|
+
AlertDialogMedia = ClassVariants.build(
|
|
68
|
+
base: "bg-muted mb-2 inline-flex size-16 items-center justify-center rounded-md " \
|
|
69
|
+
"sm:group-data-[size=default]/alert-dialog-content:row-span-2 " \
|
|
70
|
+
"*:[svg:not([class*='size-'])]:size-8"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Action and Cancel buttons are styled directly via
|
|
74
|
+
# {Kiso::Themes::Button} in their partials — no theme constants
|
|
75
|
+
# needed. See +alert_dialog/_action.html.erb+ and
|
|
76
|
+
# +alert_dialog/_cancel.html.erb+.
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Kiso
|
|
2
|
+
module Themes
|
|
3
|
+
# Displays content within a desired width-to-height ratio.
|
|
4
|
+
#
|
|
5
|
+
# @example
|
|
6
|
+
# AspectRatio.render
|
|
7
|
+
#
|
|
8
|
+
# No variants — purely structural. The ratio is set via inline style
|
|
9
|
+
# on the partial (`aspect-ratio: <ratio>`).
|
|
10
|
+
#
|
|
11
|
+
# shadcn: Radix AspectRatio primitive with data-slot="aspect-ratio"
|
|
12
|
+
AspectRatio = ClassVariants.build(
|
|
13
|
+
base: "relative w-full"
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -9,7 +9,7 @@ module Kiso
|
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
DashboardNavbarToggle = ClassVariants.build(
|
|
12
|
-
base: "flex items-center justify-center w-8 h-8 rounded-md text-foreground/50 hover:text-foreground hover:bg-accent transition-colors duration-150 shrink-0"
|
|
12
|
+
base: "flex items-center justify-center w-8 h-8 rounded-md text-foreground/50 hover:text-foreground hover:bg-accent transition-colors duration-150 shrink-0 [&>svg]:size-4"
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
DashboardSidebar = ClassVariants.build(
|
|
@@ -21,19 +21,19 @@ module Kiso
|
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
DashboardSidebarHeader = ClassVariants.build(
|
|
24
|
-
base: "shrink-0 flex
|
|
24
|
+
base: "shrink-0 flex flex-col gap-2 p-2"
|
|
25
25
|
)
|
|
26
26
|
|
|
27
27
|
DashboardSidebarFooter = ClassVariants.build(
|
|
28
|
-
base: "shrink-0 flex
|
|
28
|
+
base: "shrink-0 flex flex-col gap-2 p-2"
|
|
29
29
|
)
|
|
30
30
|
|
|
31
31
|
DashboardSidebarToggle = ClassVariants.build(
|
|
32
|
-
base: "lg:hidden flex items-center justify-center w-8 h-8 rounded-md text-foreground/50 hover:text-foreground hover:bg-accent transition-colors duration-150 shrink-0 cursor-pointer"
|
|
32
|
+
base: "lg:hidden flex items-center justify-center w-8 h-8 rounded-md text-foreground/50 hover:text-foreground hover:bg-accent transition-colors duration-150 shrink-0 cursor-pointer [&>svg]:size-4"
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
DashboardSidebarCollapse = ClassVariants.build(
|
|
36
|
-
base: "hidden lg:flex items-center justify-center w-8 h-8 rounded-md text-foreground/50 hover:text-foreground hover:bg-accent transition-colors duration-150 shrink-0 cursor-pointer"
|
|
36
|
+
base: "hidden lg:flex items-center justify-center w-8 h-8 rounded-md text-foreground/50 hover:text-foreground hover:bg-accent transition-colors duration-150 shrink-0 cursor-pointer [&>svg]:size-4"
|
|
37
37
|
)
|
|
38
38
|
|
|
39
39
|
DashboardToolbar = ClassVariants.build(
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Kiso
|
|
2
|
+
module Themes
|
|
3
|
+
# Modal dialog wrapping the native +<dialog>+ element. Opens with
|
|
4
|
+
# +showModal()+ via a Stimulus controller for proper focus trapping,
|
|
5
|
+
# backdrop, and Escape-to-close behavior.
|
|
6
|
+
#
|
|
7
|
+
# The dialog element itself acts as the backdrop overlay (same
|
|
8
|
+
# pattern as {CommandDialog}). A {DialogContent} wrapper inside
|
|
9
|
+
# provides the centered panel.
|
|
10
|
+
#
|
|
11
|
+
# Sub-parts: {DialogContent}, {DialogHeader}, {DialogTitle},
|
|
12
|
+
# {DialogDescription}, {DialogBody}, {DialogFooter}, {DialogClose}
|
|
13
|
+
Dialog = ClassVariants.build(
|
|
14
|
+
base: "fixed inset-0 z-50 m-0 h-full w-full max-w-none max-h-none bg-black/50 p-0 " \
|
|
15
|
+
"items-center justify-center backdrop:bg-transparent open:flex"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# The centered panel inside the {Dialog} overlay.
|
|
19
|
+
DialogContent = ClassVariants.build(
|
|
20
|
+
base: "bg-background text-foreground relative grid w-full max-w-[calc(100%-2rem)] " \
|
|
21
|
+
"gap-4 rounded-lg border p-6 shadow-lg outline-none sm:max-w-lg"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# Flex column container for {DialogTitle} and {DialogDescription}.
|
|
25
|
+
DialogHeader = ClassVariants.build(
|
|
26
|
+
base: "flex flex-col gap-2 text-center sm:text-left"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Reversed column layout on mobile, horizontal on desktop.
|
|
30
|
+
DialogFooter = ClassVariants.build(
|
|
31
|
+
base: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
# The dialog heading. Renders as +<h2>+.
|
|
35
|
+
DialogTitle = ClassVariants.build(
|
|
36
|
+
base: "text-lg leading-none font-semibold"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Descriptive text below the {DialogTitle}.
|
|
40
|
+
DialogDescription = ClassVariants.build(
|
|
41
|
+
base: "text-muted-foreground text-sm"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Main content area between header and footer.
|
|
45
|
+
DialogBody = ClassVariants.build(
|
|
46
|
+
base: "text-sm"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Absolutely positioned close button in the top-right corner.
|
|
50
|
+
DialogClose = ClassVariants.build(
|
|
51
|
+
base: "absolute top-4 right-4 rounded-xs opacity-70 transition-opacity " \
|
|
52
|
+
"hover:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-2 " \
|
|
53
|
+
"focus-visible:outline-ring disabled:pointer-events-none " \
|
|
54
|
+
"[&>svg]:size-4 cursor-pointer"
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
end
|
data/lib/kiso/themes/empty.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Kiso
|
|
|
9
9
|
# Empty.render
|
|
10
10
|
#
|
|
11
11
|
# Sub-parts: {EmptyHeader}, {EmptyMedia}, {EmptyTitle}, {EmptyDescription},
|
|
12
|
-
# {EmptyContent}
|
|
12
|
+
# {EmptyActions}, {EmptyContent}
|
|
13
13
|
#
|
|
14
14
|
# shadcn base: flex min-w-0 flex-1 flex-col ... border-dashed p-6 ... md:p-12
|
|
15
15
|
Empty = ClassVariants.build(
|
|
@@ -46,6 +46,11 @@ module Kiso
|
|
|
46
46
|
base: "text-muted-foreground text-sm/relaxed [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4"
|
|
47
47
|
)
|
|
48
48
|
|
|
49
|
+
# Centered button group for call-to-action buttons.
|
|
50
|
+
EmptyActions = ClassVariants.build(
|
|
51
|
+
base: "flex flex-wrap items-center justify-center gap-2"
|
|
52
|
+
)
|
|
53
|
+
|
|
49
54
|
# Container for action buttons or other interactive content.
|
|
50
55
|
EmptyContent = ClassVariants.build(
|
|
51
56
|
base: "flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance"
|
|
@@ -20,9 +20,9 @@ module Kiso
|
|
|
20
20
|
# @example
|
|
21
21
|
# InputOtpSlot.render(size: :md)
|
|
22
22
|
InputOtpSlot = ClassVariants.build(
|
|
23
|
-
base: "border-
|
|
24
|
-
"border
|
|
25
|
-
"first:
|
|
23
|
+
base: "border-border relative flex items-center justify-center " \
|
|
24
|
+
"border -ml-px shadow-xs transition-all outline-none " \
|
|
25
|
+
"first:ml-0 first:rounded-l-md last:rounded-r-md " \
|
|
26
26
|
"data-[active=true]:z-10 data-[active=true]:border-primary " \
|
|
27
27
|
"data-[active=true]:ring-[3px] data-[active=true]:ring-primary/50 " \
|
|
28
28
|
"aria-invalid:border-error " \
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Kiso
|
|
2
|
+
module Themes
|
|
3
|
+
# Range slider with track, filled range, and draggable thumb.
|
|
4
|
+
#
|
|
5
|
+
# @example
|
|
6
|
+
# Slider.render(size: :md)
|
|
7
|
+
#
|
|
8
|
+
# Variants:
|
|
9
|
+
# - +size+ — :sm, :md (default), :lg
|
|
10
|
+
#
|
|
11
|
+
# Sub-parts: {SliderTrack}, {SliderRange}, {SliderThumb}
|
|
12
|
+
#
|
|
13
|
+
# shadcn base: relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50
|
|
14
|
+
Slider = ClassVariants.build(
|
|
15
|
+
base: "relative flex w-full touch-none items-center select-none"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# shadcn: relative grow overflow-hidden rounded-full bg-muted h-1.5 w-full
|
|
19
|
+
SliderTrack = ClassVariants.build(
|
|
20
|
+
base: "relative grow cursor-pointer overflow-hidden rounded-full bg-muted w-full",
|
|
21
|
+
variants: {
|
|
22
|
+
size: {
|
|
23
|
+
sm: "h-1",
|
|
24
|
+
md: "h-1.5",
|
|
25
|
+
lg: "h-2"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
defaults: {size: :md}
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# shadcn: absolute h-full bg-primary
|
|
32
|
+
SliderRange = ClassVariants.build(
|
|
33
|
+
base: "absolute h-full bg-primary"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
# shadcn: block size-4 shrink-0 rounded-full border border-primary bg-white shadow-sm
|
|
37
|
+
# ring-ring/50 transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4
|
|
38
|
+
# focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50
|
|
39
|
+
SliderThumb = ClassVariants.build(
|
|
40
|
+
base: "block shrink-0 rounded-full border border-primary bg-white shadow-sm " \
|
|
41
|
+
"ring-ring/50 transition-[color,box-shadow] hover:ring-4 " \
|
|
42
|
+
"focus-visible:ring-4 focus-visible:outline-hidden",
|
|
43
|
+
variants: {
|
|
44
|
+
size: {
|
|
45
|
+
sm: "size-3",
|
|
46
|
+
md: "size-4",
|
|
47
|
+
lg: "size-5"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
defaults: {size: :md}
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
data/lib/kiso/version.rb
CHANGED
data/lib/kiso.rb
CHANGED
|
@@ -10,6 +10,7 @@ require "kiso/engine"
|
|
|
10
10
|
require "kiso/themes/shared"
|
|
11
11
|
require "kiso/themes/badge"
|
|
12
12
|
require "kiso/themes/alert"
|
|
13
|
+
require "kiso/themes/aspect_ratio"
|
|
13
14
|
require "kiso/themes/button"
|
|
14
15
|
require "kiso/themes/card"
|
|
15
16
|
require "kiso/themes/separator"
|
|
@@ -36,6 +37,8 @@ require "kiso/themes/select_native"
|
|
|
36
37
|
require "kiso/themes/popover"
|
|
37
38
|
require "kiso/themes/combobox"
|
|
38
39
|
require "kiso/themes/command"
|
|
40
|
+
require "kiso/themes/dialog"
|
|
41
|
+
require "kiso/themes/alert_dialog"
|
|
39
42
|
require "kiso/themes/dropdown_menu"
|
|
40
43
|
require "kiso/themes/kbd"
|
|
41
44
|
require "kiso/themes/color_mode_button"
|
|
@@ -43,6 +46,7 @@ require "kiso/themes/color_mode_select"
|
|
|
43
46
|
require "kiso/themes/dashboard"
|
|
44
47
|
require "kiso/themes/nav"
|
|
45
48
|
require "kiso/themes/avatar"
|
|
49
|
+
require "kiso/themes/slider"
|
|
46
50
|
require "kiso/icons"
|
|
47
51
|
|
|
48
52
|
# Kiso — a Rails engine providing UI components inspired by shadcn/ui and Nuxt UI.
|