kiso 0.1.0.pre → 0.2.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 +36 -2
- data/README.md +67 -27
- data/Rakefile +8 -0
- data/app/assets/tailwind/kiso/checkbox.css +18 -0
- data/app/assets/tailwind/kiso/color-mode.css +9 -0
- data/app/assets/tailwind/kiso/dashboard.css +194 -0
- data/app/assets/tailwind/kiso/engine.css +117 -0
- data/app/assets/tailwind/kiso/input-otp.css +10 -0
- data/app/assets/tailwind/kiso/radio-group.css +17 -0
- data/app/helpers/kiso/component_helper.rb +46 -27
- data/app/helpers/kiso/icon_helper.rb +53 -9
- data/app/helpers/kiso/theme_helper.rb +38 -0
- data/app/javascript/controllers/kiso/combobox_controller.js +616 -0
- data/app/javascript/controllers/kiso/command_controller.js +184 -0
- data/app/javascript/controllers/kiso/command_dialog_controller.js +104 -0
- data/app/javascript/controllers/kiso/dropdown_menu_controller.js +684 -0
- data/app/javascript/controllers/kiso/index.d.ts +12 -0
- data/app/javascript/controllers/kiso/index.js +42 -0
- data/app/javascript/controllers/kiso/input_otp_controller.js +195 -0
- data/app/javascript/controllers/kiso/popover_controller.js +254 -0
- data/app/javascript/controllers/kiso/select_controller.js +307 -0
- data/app/javascript/controllers/kiso/sidebar_controller.js +84 -0
- data/app/javascript/controllers/kiso/theme_controller.js +89 -0
- data/app/javascript/controllers/kiso/toggle_controller.js +24 -0
- data/app/javascript/controllers/kiso/toggle_group_controller.js +128 -0
- data/app/javascript/kiso/utils/focusable.js +8 -0
- data/app/javascript/kiso/utils/highlight.js +43 -0
- data/app/javascript/kiso/utils/positioning.js +86 -0
- data/app/javascript/kiso/vendor/floating-ui-core.js +1 -0
- data/app/javascript/kiso/vendor/floating-ui-dom.js +1 -0
- data/app/views/kiso/components/_alert.html.erb +1 -1
- data/app/views/kiso/components/_avatar.html.erb +23 -0
- data/app/views/kiso/components/_badge.html.erb +1 -1
- data/app/views/kiso/components/_breadcrumb.html.erb +8 -0
- data/app/views/kiso/components/_button.html.erb +1 -1
- data/app/views/kiso/components/_card.html.erb +1 -1
- data/app/views/kiso/components/_checkbox.html.erb +7 -0
- data/app/views/kiso/components/_color_mode_button.html.erb +14 -0
- data/app/views/kiso/components/_color_mode_select.html.erb +24 -0
- data/app/views/kiso/components/_combobox.html.erb +12 -0
- data/app/views/kiso/components/_command.html.erb +7 -0
- data/app/views/kiso/components/_dashboard_group.html.erb +14 -0
- data/app/views/kiso/components/_dashboard_navbar.html.erb +7 -0
- data/app/views/kiso/components/_dashboard_panel.html.erb +7 -0
- data/app/views/kiso/components/_dashboard_sidebar.html.erb +11 -0
- data/app/views/kiso/components/_dashboard_toolbar.html.erb +7 -0
- data/app/views/kiso/components/_dropdown_menu.html.erb +7 -0
- data/app/views/kiso/components/{_empty_state.html.erb → _empty.html.erb} +2 -2
- data/app/views/kiso/components/_field.html.erb +12 -0
- data/app/views/kiso/components/_field_group.html.erb +7 -0
- data/app/views/kiso/components/_field_set.html.erb +7 -0
- data/app/views/kiso/components/_input.html.erb +8 -0
- data/app/views/kiso/components/_input_group.html.erb +8 -0
- data/app/views/kiso/components/_input_otp.html.erb +22 -0
- data/app/views/kiso/components/_kbd.html.erb +7 -0
- data/app/views/kiso/components/_label.html.erb +5 -0
- data/app/views/kiso/components/_nav.html.erb +7 -0
- data/app/views/kiso/components/_pagination.html.erb +9 -0
- data/app/views/kiso/components/_popover.html.erb +8 -0
- data/app/views/kiso/components/_radio_group.html.erb +8 -0
- data/app/views/kiso/components/_select.html.erb +8 -0
- data/app/views/kiso/components/_select_native.html.erb +16 -0
- data/app/views/kiso/components/_separator.html.erb +1 -1
- data/app/views/kiso/components/_stats_card.html.erb +1 -1
- data/app/views/kiso/components/_stats_grid.html.erb +1 -1
- data/app/views/kiso/components/_switch.html.erb +10 -0
- data/app/views/kiso/components/_table.html.erb +2 -1
- data/app/views/kiso/components/_textarea.html.erb +9 -0
- data/app/views/kiso/components/_toggle.html.erb +12 -0
- data/app/views/kiso/components/_toggle_group.html.erb +12 -0
- data/app/views/kiso/components/alert/_description.html.erb +1 -1
- data/app/views/kiso/components/alert/_title.html.erb +1 -1
- data/app/views/kiso/components/avatar/_badge.html.erb +7 -0
- data/app/views/kiso/components/avatar/_fallback.html.erb +7 -0
- data/app/views/kiso/components/avatar/_group.html.erb +7 -0
- data/app/views/kiso/components/avatar/_group_count.html.erb +7 -0
- data/app/views/kiso/components/avatar/_image.html.erb +6 -0
- data/app/views/kiso/components/breadcrumb/_ellipsis.html.erb +10 -0
- data/app/views/kiso/components/breadcrumb/_item.html.erb +7 -0
- data/app/views/kiso/components/breadcrumb/_link.html.erb +7 -0
- data/app/views/kiso/components/breadcrumb/_list.html.erb +7 -0
- data/app/views/kiso/components/breadcrumb/_page.html.erb +9 -0
- data/app/views/kiso/components/breadcrumb/_separator.html.erb +9 -0
- data/app/views/kiso/components/card/_action.html.erb +7 -0
- data/app/views/kiso/components/card/_content.html.erb +1 -1
- data/app/views/kiso/components/card/_description.html.erb +1 -1
- data/app/views/kiso/components/card/_footer.html.erb +1 -1
- data/app/views/kiso/components/card/_header.html.erb +1 -1
- data/app/views/kiso/components/card/_title.html.erb +1 -1
- data/app/views/kiso/components/combobox/_chip.html.erb +19 -0
- data/app/views/kiso/components/combobox/_chips.html.erb +20 -0
- data/app/views/kiso/components/combobox/_chips_input.html.erb +10 -0
- data/app/views/kiso/components/combobox/_content.html.erb +9 -0
- data/app/views/kiso/components/combobox/_empty.html.erb +9 -0
- data/app/views/kiso/components/combobox/_group.html.erb +8 -0
- data/app/views/kiso/components/combobox/_input.html.erb +23 -0
- data/app/views/kiso/components/combobox/_item.html.erb +19 -0
- data/app/views/kiso/components/combobox/_label.html.erb +7 -0
- data/app/views/kiso/components/combobox/_list.html.erb +10 -0
- data/app/views/kiso/components/combobox/_separator.html.erb +6 -0
- data/app/views/kiso/components/command/_dialog.html.erb +11 -0
- data/app/views/kiso/components/command/_empty.html.erb +9 -0
- data/app/views/kiso/components/command/_group.html.erb +14 -0
- data/app/views/kiso/components/command/_input.html.erb +16 -0
- data/app/views/kiso/components/command/_item.html.erb +13 -0
- data/app/views/kiso/components/command/_list.html.erb +10 -0
- data/app/views/kiso/components/command/_separator.html.erb +7 -0
- data/app/views/kiso/components/command/_shortcut.html.erb +7 -0
- data/app/views/kiso/components/dashboard_navbar/_toggle.html.erb +11 -0
- data/app/views/kiso/components/dashboard_sidebar/_collapse.html.erb +12 -0
- data/app/views/kiso/components/dashboard_sidebar/_footer.html.erb +7 -0
- data/app/views/kiso/components/dashboard_sidebar/_header.html.erb +7 -0
- data/app/views/kiso/components/dashboard_sidebar/_toggle.html.erb +11 -0
- data/app/views/kiso/components/dashboard_toolbar/_left.html.erb +7 -0
- data/app/views/kiso/components/dashboard_toolbar/_right.html.erb +7 -0
- data/app/views/kiso/components/dropdown_menu/_checkbox_item.html.erb +18 -0
- data/app/views/kiso/components/dropdown_menu/_content.html.erb +10 -0
- data/app/views/kiso/components/dropdown_menu/_group.html.erb +8 -0
- data/app/views/kiso/components/dropdown_menu/_item.html.erb +15 -0
- data/app/views/kiso/components/dropdown_menu/_label.html.erb +8 -0
- data/app/views/kiso/components/dropdown_menu/_radio_group.html.erb +10 -0
- data/app/views/kiso/components/dropdown_menu/_radio_item.html.erb +19 -0
- data/app/views/kiso/components/dropdown_menu/_separator.html.erb +6 -0
- data/app/views/kiso/components/dropdown_menu/_shortcut.html.erb +7 -0
- data/app/views/kiso/components/dropdown_menu/_sub.html.erb +8 -0
- data/app/views/kiso/components/dropdown_menu/_sub_content.html.erb +10 -0
- data/app/views/kiso/components/dropdown_menu/_sub_trigger.html.erb +12 -0
- data/app/views/kiso/components/dropdown_menu/_trigger.html.erb +9 -0
- data/app/views/kiso/components/empty/_content.html.erb +7 -0
- data/app/views/kiso/components/empty/_description.html.erb +7 -0
- data/app/views/kiso/components/empty/_header.html.erb +7 -0
- data/app/views/kiso/components/empty/_media.html.erb +7 -0
- data/app/views/kiso/components/empty/_title.html.erb +7 -0
- data/app/views/kiso/components/field/_content.html.erb +7 -0
- data/app/views/kiso/components/field/_description.html.erb +7 -0
- data/app/views/kiso/components/field/_error.html.erb +22 -0
- data/app/views/kiso/components/field/_label.html.erb +5 -0
- data/app/views/kiso/components/field/_separator.html.erb +15 -0
- data/app/views/kiso/components/field/_title.html.erb +7 -0
- data/app/views/kiso/components/field_set/_legend.html.erb +9 -0
- data/app/views/kiso/components/input_group/_addon.html.erb +7 -0
- data/app/views/kiso/components/input_otp/_group.html.erb +7 -0
- data/app/views/kiso/components/input_otp/_separator.html.erb +8 -0
- data/app/views/kiso/components/input_otp/_slot.html.erb +11 -0
- data/app/views/kiso/components/kbd/_group.html.erb +7 -0
- data/app/views/kiso/components/nav/_item.html.erb +15 -0
- data/app/views/kiso/components/nav/_section.html.erb +37 -0
- data/app/views/kiso/components/nav/_section_title.html.erb +7 -0
- data/app/views/kiso/components/pagination/_content.html.erb +7 -0
- data/app/views/kiso/components/pagination/_ellipsis.html.erb +9 -0
- data/app/views/kiso/components/pagination/_item.html.erb +7 -0
- data/app/views/kiso/components/pagination/_link.html.erb +9 -0
- data/app/views/kiso/components/pagination/_next.html.erb +12 -0
- data/app/views/kiso/components/pagination/_previous.html.erb +12 -0
- data/app/views/kiso/components/popover/_anchor.html.erb +8 -0
- data/app/views/kiso/components/popover/_content.html.erb +11 -0
- data/app/views/kiso/components/popover/_description.html.erb +7 -0
- data/app/views/kiso/components/popover/_header.html.erb +7 -0
- data/app/views/kiso/components/popover/_title.html.erb +7 -0
- data/app/views/kiso/components/popover/_trigger.html.erb +9 -0
- data/app/views/kiso/components/radio_group/_item.html.erb +6 -0
- data/app/views/kiso/components/select/_content.html.erb +10 -0
- data/app/views/kiso/components/select/_group.html.erb +8 -0
- data/app/views/kiso/components/select/_item.html.erb +19 -0
- data/app/views/kiso/components/select/_label.html.erb +7 -0
- data/app/views/kiso/components/select/_separator.html.erb +6 -0
- data/app/views/kiso/components/select/_trigger.html.erb +13 -0
- data/app/views/kiso/components/select/_value.html.erb +11 -0
- data/app/views/kiso/components/stats_card/_description.html.erb +1 -1
- data/app/views/kiso/components/stats_card/_header.html.erb +1 -1
- data/app/views/kiso/components/stats_card/_label.html.erb +1 -1
- data/app/views/kiso/components/stats_card/_value.html.erb +1 -1
- data/app/views/kiso/components/table/_body.html.erb +1 -1
- data/app/views/kiso/components/table/_caption.html.erb +1 -1
- data/app/views/kiso/components/table/_cell.html.erb +1 -1
- data/app/views/kiso/components/table/_footer.html.erb +1 -1
- data/app/views/kiso/components/table/_head.html.erb +1 -1
- data/app/views/kiso/components/table/_header.html.erb +1 -1
- data/app/views/kiso/components/table/_row.html.erb +1 -1
- data/app/views/kiso/components/toggle_group/_item.html.erb +13 -0
- data/config/deploy.docs.yml +31 -0
- data/config/deploy.yml +34 -0
- data/config/importmap.rb +10 -0
- data/lib/kiso/cli/base.rb +15 -0
- data/lib/kiso/cli/icons.rb +2 -1
- data/lib/kiso/cli/main.rb +6 -0
- data/lib/kiso/cli/make.rb +22 -12
- data/lib/kiso/configuration.rb +54 -0
- data/lib/kiso/engine.rb +36 -1
- data/lib/kiso/theme_overrides.rb +130 -0
- data/lib/kiso/themes/alert.rb +16 -1
- data/lib/kiso/themes/avatar.rb +53 -0
- data/lib/kiso/themes/badge.rb +15 -5
- data/lib/kiso/themes/breadcrumb.rb +44 -0
- data/lib/kiso/themes/button.rb +15 -2
- data/lib/kiso/themes/card.rb +18 -2
- data/lib/kiso/themes/checkbox.rb +33 -0
- data/lib/kiso/themes/color_mode_button.rb +15 -0
- data/lib/kiso/themes/color_mode_select.rb +7 -0
- data/lib/kiso/themes/combobox.rb +97 -0
- data/lib/kiso/themes/command.rb +79 -0
- data/lib/kiso/themes/dashboard.rb +51 -0
- data/lib/kiso/themes/dropdown_menu.rb +108 -0
- data/lib/kiso/themes/empty.rb +54 -0
- data/lib/kiso/themes/field.rb +76 -0
- data/lib/kiso/themes/field_group.rb +15 -0
- data/lib/kiso/themes/field_set.rb +32 -0
- data/lib/kiso/themes/input.rb +33 -0
- data/lib/kiso/themes/input_group.rb +39 -0
- data/lib/kiso/themes/input_otp.rb +46 -0
- data/lib/kiso/themes/kbd.rb +31 -0
- data/lib/kiso/themes/label.rb +16 -0
- data/lib/kiso/themes/nav.rb +27 -0
- data/lib/kiso/themes/pagination.rb +73 -0
- data/lib/kiso/themes/popover.rb +32 -0
- data/lib/kiso/themes/radio_group.rb +43 -0
- data/lib/kiso/themes/select.rb +78 -0
- data/lib/kiso/themes/select_native.rb +49 -0
- data/lib/kiso/themes/separator.rb +8 -2
- data/lib/kiso/themes/shared.rb +51 -0
- data/lib/kiso/themes/stats_card.rb +26 -14
- data/lib/kiso/themes/switch.rb +56 -0
- data/lib/kiso/themes/table.rb +18 -15
- data/lib/kiso/themes/textarea.rb +33 -0
- data/lib/kiso/themes/toggle.rb +71 -0
- data/lib/kiso/themes/toggle_group.rb +13 -0
- data/lib/kiso/version.rb +4 -1
- data/lib/kiso.rb +70 -2
- metadata +183 -22
- data/app/views/kiso/components/empty_state/_content.html.erb +0 -7
- data/app/views/kiso/components/empty_state/_description.html.erb +0 -7
- data/app/views/kiso/components/empty_state/_header.html.erb +0 -7
- data/app/views/kiso/components/empty_state/_media.html.erb +0 -7
- data/app/views/kiso/components/empty_state/_title.html.erb +0 -7
- data/lib/kiso/themes/empty_state.rb +0 -42
|
@@ -1,36 +1,29 @@
|
|
|
1
1
|
module Kiso
|
|
2
|
+
# View helpers for rendering Kiso components.
|
|
3
|
+
#
|
|
4
|
+
# Included in all views automatically by {Engine}.
|
|
2
5
|
module ComponentHelper
|
|
3
|
-
# Renders a component
|
|
6
|
+
# Renders a Kiso component partial.
|
|
4
7
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
8
|
+
# Components live in +app/views/kiso/components/+. Sub-parts are nested
|
|
9
|
+
# in a directory matching the parent component name.
|
|
7
10
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
11
|
+
# @param component [Symbol] the component name (e.g. +:badge+, +:card+)
|
|
12
|
+
# @param part [Symbol, nil] optional sub-part name (e.g. +:header+, +:footer+)
|
|
13
|
+
# @param collection [Array, nil] renders the partial once per item when present
|
|
14
|
+
# @param kwargs [Hash] locals passed to the partial (e.g. +color:+, +variant:+, +css_classes:+)
|
|
15
|
+
# @yield optional block for component content
|
|
16
|
+
# @return [ActiveSupport::SafeBuffer] rendered HTML
|
|
10
17
|
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if part
|
|
15
|
-
data[:"#{component}-part"] = part
|
|
16
|
-
else
|
|
17
|
-
data[:component] = component
|
|
18
|
-
data[:variant] = variant if variant
|
|
19
|
-
data[:size] = size if size
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
options[:data] = data
|
|
23
|
-
|
|
24
|
-
content_tag(element, **options, &block)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Renders a Kiso component partial.
|
|
18
|
+
# @example Render a badge
|
|
19
|
+
# kui(:badge, color: :success, variant: :soft) { "Active" }
|
|
28
20
|
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# kiso(:badge, collection: @statuses)
|
|
21
|
+
# @example Render a card sub-part
|
|
22
|
+
# kui(:card, :header) { "Title" }
|
|
32
23
|
#
|
|
33
|
-
|
|
24
|
+
# @example Render a collection
|
|
25
|
+
# kui(:badge, collection: @tags)
|
|
26
|
+
def kui(component, part = nil, collection: nil, **kwargs, &block)
|
|
34
27
|
path = if part
|
|
35
28
|
"kiso/components/#{component}/#{part}"
|
|
36
29
|
else
|
|
@@ -38,10 +31,36 @@ module Kiso
|
|
|
38
31
|
end
|
|
39
32
|
|
|
40
33
|
if collection
|
|
41
|
-
render partial: path, collection: collection,
|
|
34
|
+
render partial: path, collection: collection, locals: kwargs, &block
|
|
42
35
|
else
|
|
43
36
|
render path, **kwargs, &block
|
|
44
37
|
end
|
|
45
38
|
end
|
|
39
|
+
|
|
40
|
+
# Prepares +component_options+ for use with +content_tag+.
|
|
41
|
+
#
|
|
42
|
+
# Sets +data-slot+ for component identity (shadcn v4 convention) and
|
|
43
|
+
# merges any additional data attributes. Raises if +class:+ is passed
|
|
44
|
+
# (use +css_classes:+ instead).
|
|
45
|
+
#
|
|
46
|
+
# @param component_options [Hash] the +**component_options+ splat from the partial.
|
|
47
|
+
# Any +data:+ key is extracted and merged with +slot+ and +data_attrs+.
|
|
48
|
+
# @param slot [String] the +data-slot+ value (kebab-case, e.g. +"card-header"+)
|
|
49
|
+
# @param data_attrs [Hash] additional data attributes (e.g. +controller: "kiso--toggle"+)
|
|
50
|
+
# @return [Hash] merged data attributes hash for +content_tag+
|
|
51
|
+
# @raise [ArgumentError] if +component_options+ contains a +class:+ key
|
|
52
|
+
#
|
|
53
|
+
# @example In a component partial
|
|
54
|
+
# data: kiso_prepare_options(component_options, slot: "badge")
|
|
55
|
+
#
|
|
56
|
+
# @example With a Stimulus controller
|
|
57
|
+
# data: kiso_prepare_options(component_options, slot: "toggle", controller: "kiso--toggle")
|
|
58
|
+
def kiso_prepare_options(component_options, slot:, **data_attrs)
|
|
59
|
+
if component_options.key?(:class)
|
|
60
|
+
raise ArgumentError, "Use css_classes: instead of class: for Kiso components"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
(component_options.delete(:data) || {}).merge(slot: slot, **data_attrs)
|
|
64
|
+
end
|
|
46
65
|
end
|
|
47
66
|
end
|
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
require "tailwind_merge"
|
|
4
4
|
|
|
5
5
|
module Kiso
|
|
6
|
+
# View helpers for rendering inline SVG icons.
|
|
7
|
+
#
|
|
8
|
+
# Included in all views automatically by {Engine}.
|
|
9
|
+
# Delegates to +kiso_icon_tag+ (provided by the kiso-icons gem) for
|
|
10
|
+
# actual SVG rendering.
|
|
6
11
|
module IconHelper
|
|
12
|
+
# @return [Hash{Symbol => String}] maps size presets to Tailwind size utilities
|
|
7
13
|
SIZE_PRESETS = {
|
|
8
14
|
xs: "size-3",
|
|
9
15
|
sm: "size-4",
|
|
@@ -12,23 +18,56 @@ module Kiso
|
|
|
12
18
|
xl: "size-8"
|
|
13
19
|
}.freeze
|
|
14
20
|
|
|
21
|
+
# @return [String] base Tailwind classes applied to every icon
|
|
15
22
|
BASE_CLASSES = "shrink-0"
|
|
16
23
|
|
|
24
|
+
# Renders a configurable component icon.
|
|
25
|
+
#
|
|
26
|
+
# Components call this instead of {#kiso_icon} when the icon name should
|
|
27
|
+
# be overridable by host apps via {Configuration#icons Kiso.config.icons}.
|
|
28
|
+
#
|
|
29
|
+
# @param semantic_name [Symbol] a key from {Configuration#icons}
|
|
30
|
+
# (e.g. +:chevron_right+, +:check+, +:x+)
|
|
31
|
+
# @param options [Hash] forwarded to {#kiso_icon}
|
|
32
|
+
# @return [ActiveSupport::SafeBuffer] rendered SVG
|
|
33
|
+
# @raise [KeyError] if +semantic_name+ is not registered
|
|
34
|
+
#
|
|
35
|
+
# @example
|
|
36
|
+
# kiso_component_icon(:chevron_right, class: "size-3.5")
|
|
37
|
+
# kiso_component_icon(:ellipsis, size: :sm)
|
|
38
|
+
def kiso_component_icon(semantic_name, **)
|
|
39
|
+
icon_name = Kiso.config.icons.fetch(semantic_name) {
|
|
40
|
+
raise KeyError, "Unknown Kiso icon: #{semantic_name.inspect}. " \
|
|
41
|
+
"Known icons: #{Kiso.config.icons.keys.join(", ")}"
|
|
42
|
+
}
|
|
43
|
+
kiso_icon(icon_name, **)
|
|
44
|
+
end
|
|
45
|
+
|
|
17
46
|
# Renders an inline SVG icon with Tailwind classes.
|
|
18
47
|
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
# kiso_icon("check", class: "text-success") # extra classes
|
|
23
|
-
# kiso_icon("check", aria: { label: "Done" }) # accessible icon
|
|
48
|
+
# Size defaults to +nil+ so parent components (Button, Alert, Badge) can
|
|
49
|
+
# control icon sizing via CSS selectors like +[&_svg]:size-4+.
|
|
50
|
+
# Pass an explicit +size:+ for standalone icons outside components.
|
|
24
51
|
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
52
|
+
# @param name [String] icon identifier, optionally prefixed with set
|
|
53
|
+
# (e.g. +"check"+, +"lucide:check"+)
|
|
54
|
+
# @param size [Symbol, nil] size preset from {SIZE_PRESETS}
|
|
55
|
+
# (+:xs+, +:sm+, +:md+, +:lg+, +:xl+)
|
|
56
|
+
# @param options [Hash] forwarded to +kiso_icon_tag+
|
|
57
|
+
# (e.g. +class:+, +aria:+, +data:+)
|
|
58
|
+
# @return [ActiveSupport::SafeBuffer] rendered SVG
|
|
28
59
|
#
|
|
60
|
+
# @example Basic usage
|
|
61
|
+
# kiso_icon("check")
|
|
62
|
+
# @example With size preset
|
|
63
|
+
# kiso_icon("check", size: :md)
|
|
64
|
+
# @example With extra classes
|
|
65
|
+
# kiso_icon("check", class: "text-success")
|
|
66
|
+
# @example Accessible icon
|
|
67
|
+
# kiso_icon("check", aria: { label: "Done" })
|
|
29
68
|
def kiso_icon(name, size: nil, **options)
|
|
30
69
|
css_classes = options.delete(:class) || ""
|
|
31
|
-
size_class = size ? SIZE_PRESETS.fetch(size
|
|
70
|
+
size_class = size ? SIZE_PRESETS.fetch(size) : nil
|
|
32
71
|
merged = merge_icon_classes(BASE_CLASSES, size_class, css_classes)
|
|
33
72
|
|
|
34
73
|
kiso_icon_tag(name, class: merged, **options)
|
|
@@ -36,11 +75,16 @@ module Kiso
|
|
|
36
75
|
|
|
37
76
|
private
|
|
38
77
|
|
|
78
|
+
# Merges icon class parts via TailwindMerge, filtering out blanks.
|
|
79
|
+
#
|
|
80
|
+
# @param parts [Array<String, nil>] class strings to merge
|
|
81
|
+
# @return [String] deduplicated class string
|
|
39
82
|
def merge_icon_classes(*parts)
|
|
40
83
|
combined = parts.reject { |p| p.nil? || p.to_s.empty? }.join(" ")
|
|
41
84
|
icon_class_merger.merge(combined)
|
|
42
85
|
end
|
|
43
86
|
|
|
87
|
+
# @return [TailwindMerge::Merger] memoized merger instance
|
|
44
88
|
def icon_class_merger
|
|
45
89
|
@icon_class_merger ||= TailwindMerge::Merger.new
|
|
46
90
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Kiso
|
|
4
|
+
# View helper for dark mode FOUC prevention.
|
|
5
|
+
#
|
|
6
|
+
# Included in all views automatically by {Engine}.
|
|
7
|
+
module ThemeHelper
|
|
8
|
+
THEME_SCRIPT = <<~JS.squish.freeze
|
|
9
|
+
(function(){
|
|
10
|
+
var k="theme";
|
|
11
|
+
var t=localStorage.getItem(k);
|
|
12
|
+
if(!t){var m=document.cookie.match(new RegExp("(?:^|; )"+k+"=([^;]*)"));t=m&&m[1]}
|
|
13
|
+
if(t==="dark"||((!t||t==="system")&&matchMedia("(prefers-color-scheme:dark)").matches)){
|
|
14
|
+
document.documentElement.classList.add("dark")
|
|
15
|
+
}
|
|
16
|
+
})()
|
|
17
|
+
JS
|
|
18
|
+
|
|
19
|
+
# Outputs an inline script that prevents dark mode FOUC.
|
|
20
|
+
#
|
|
21
|
+
# Reads the theme preference from localStorage (primary) or cookie
|
|
22
|
+
# (fallback), respects +prefers-color-scheme+ as default, and sets
|
|
23
|
+
# +.dark+ on +<html>+ synchronously before first paint.
|
|
24
|
+
#
|
|
25
|
+
# Call in +<head>+, ideally before stylesheet links.
|
|
26
|
+
#
|
|
27
|
+
# @example In a layout
|
|
28
|
+
# <head>
|
|
29
|
+
# <%= kiso_theme_script %>
|
|
30
|
+
# <%= stylesheet_link_tag "tailwind" %>
|
|
31
|
+
# </head>
|
|
32
|
+
#
|
|
33
|
+
# @return [ActiveSupport::SafeBuffer]
|
|
34
|
+
def kiso_theme_script
|
|
35
|
+
javascript_tag(THEME_SCRIPT, nonce: true)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|