okonomi_ui_kit 0.1.8 → 0.1.9
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 -3
- data/app/assets/builds/okonomi_ui_kit/application.tailwind.css +409 -187
- data/app/helpers/okonomi_ui_kit/application_helper.rb +8 -0
- data/app/helpers/okonomi_ui_kit/attribute_section_helper.rb +5 -5
- data/app/helpers/okonomi_ui_kit/component.rb +10 -6
- data/app/helpers/okonomi_ui_kit/components/alert.rb +1 -1
- data/app/helpers/okonomi_ui_kit/components/badge.rb +3 -3
- data/app/helpers/okonomi_ui_kit/components/breadcrumbs.rb +4 -4
- data/app/helpers/okonomi_ui_kit/components/button_base.rb +6 -6
- data/app/helpers/okonomi_ui_kit/components/button_tag.rb +3 -3
- data/app/helpers/okonomi_ui_kit/components/button_to.rb +3 -3
- data/app/helpers/okonomi_ui_kit/components/code.rb +41 -37
- data/app/helpers/okonomi_ui_kit/components/confirmation_modal.rb +130 -0
- data/app/helpers/okonomi_ui_kit/components/forms/check_box_with_label.rb +38 -0
- data/app/helpers/okonomi_ui_kit/components/forms/collection_select.rb +57 -0
- data/app/helpers/okonomi_ui_kit/components/forms/date_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/datetime_local_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/email_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/field.rb +24 -0
- data/app/helpers/okonomi_ui_kit/components/forms/field_set.rb +17 -0
- data/app/helpers/okonomi_ui_kit/components/forms/input_base.rb +57 -0
- data/app/helpers/okonomi_ui_kit/components/forms/label.rb +27 -0
- data/app/helpers/okonomi_ui_kit/components/forms/multi_select.rb +18 -0
- data/app/helpers/okonomi_ui_kit/components/forms/number_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/password_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/search_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/select.rb +57 -0
- data/app/helpers/okonomi_ui_kit/components/forms/show_if.rb +28 -0
- data/app/helpers/okonomi_ui_kit/components/forms/telephone_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/text_area.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/text_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/time_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms/upload_field.rb +25 -0
- data/app/helpers/okonomi_ui_kit/components/forms/url_field.rb +9 -0
- data/app/helpers/okonomi_ui_kit/components/forms.rb +6 -0
- data/app/helpers/okonomi_ui_kit/components/icon.rb +6 -6
- data/app/helpers/okonomi_ui_kit/components/link_to.rb +7 -7
- data/app/helpers/okonomi_ui_kit/components/navigation.rb +98 -0
- data/app/helpers/okonomi_ui_kit/components/page.rb +7 -7
- data/app/helpers/okonomi_ui_kit/components/table.rb +7 -8
- data/app/helpers/okonomi_ui_kit/components/typography.rb +16 -16
- data/app/helpers/okonomi_ui_kit/components.rb +4 -0
- data/app/helpers/okonomi_ui_kit/configs.rb +4 -0
- data/app/helpers/okonomi_ui_kit/form_builder.rb +39 -130
- data/app/helpers/okonomi_ui_kit/form_component.rb +7 -0
- data/app/helpers/okonomi_ui_kit/svg_icons.rb +5 -5
- data/app/helpers/okonomi_ui_kit/t_w_merge.rb +33 -27
- data/app/helpers/okonomi_ui_kit/ui_helper.rb +17 -58
- data/app/views/okonomi/components/confirmation_modal/_confirmation_modal.html.erb +76 -0
- data/app/views/okonomi/components/forms/check_box_with_label/_check_box_with_label.html.erb +6 -0
- data/app/views/okonomi/components/forms/field/_field.html.erb +3 -0
- data/app/views/okonomi/components/forms/field_set/_field_set.html.erb +3 -0
- data/app/views/okonomi/components/forms/upload_field/_upload_field.html.erb +1 -0
- data/app/views/okonomi/components/navigation/_link.html.erb +18 -0
- data/app/views/okonomi/components/navigation/_navigation.html.erb +4 -0
- data/app/views/okonomi/forms/tailwind/_checkbox_label.html.erb +2 -2
- data/app/views/okonomi/forms/tailwind/_field.html.erb +6 -6
- data/app/views/okonomi/forms/tailwind/_multi_select.html.erb +2 -4
- data/app/views/okonomi/forms/tailwind/_upload_field.html.erb +10 -10
- data/config/importmap.rb +1 -1
- data/lib/okonomi_ui_kit/engine.rb +0 -1
- data/lib/okonomi_ui_kit/version.rb +1 -1
- metadata +36 -10
- data/app/helpers/okonomi_ui_kit/navigation_helper.rb +0 -72
- data/app/helpers/okonomi_ui_kit/theme.rb +0 -136
- data/app/helpers/okonomi_ui_kit/theme_helper.rb +0 -17
- data/app/views/okonomi/forms/tailwind/_field_set.html.erb +0 -3
- data/app/views/okonomi/modals/_confirmation_modal.html.erb +0 -77
- data/app/views/okonomi/navigation/_link.html.erb +0 -15
- data/app/views/okonomi/navigation/_menu.html.erb +0 -3
- data/app/views/okonomi/navigation/_navbar.html.erb +0 -105
@@ -1,4 +1,12 @@
|
|
1
1
|
module OkonomiUiKit
|
2
2
|
module ApplicationHelper
|
3
|
+
def active_link_to(path, options = {}, &block)
|
4
|
+
path_to_check = path.split("?").first
|
5
|
+
if (options[:exact] && request.path == path_to_check) || (!options[:exact] && request.path.include?(path_to_check))
|
6
|
+
options[:class] = options[:active_class].presence || [ options[:class], "active" ].compact.join(" ")
|
7
|
+
end
|
8
|
+
|
9
|
+
link_to(path, options, &block)
|
10
|
+
end
|
3
11
|
end
|
4
12
|
end
|
@@ -3,7 +3,7 @@ module OkonomiUiKit
|
|
3
3
|
def attribute_section(title:, description: nil, **options, &block)
|
4
4
|
builder = AttributeSectionBuilder.new(self)
|
5
5
|
|
6
|
-
render
|
6
|
+
render "okonomi/attribute_sections/section",
|
7
7
|
builder: builder,
|
8
8
|
title: title,
|
9
9
|
description: description,
|
@@ -22,11 +22,11 @@ module OkonomiUiKit
|
|
22
22
|
def attribute(label, value = nil, **options, &block)
|
23
23
|
content = if block_given?
|
24
24
|
capture(&block)
|
25
|
-
|
25
|
+
elsif value.respond_to?(:call)
|
26
26
|
value.call
|
27
|
-
|
27
|
+
else
|
28
28
|
value
|
29
|
-
|
29
|
+
end
|
30
30
|
|
31
31
|
tag.div(class: "py-6 sm:grid sm:grid-cols-3 sm:gap-4") do
|
32
32
|
dt_content = tag.dt(label, class: "text-sm font-medium text-gray-900")
|
@@ -47,4 +47,4 @@ module OkonomiUiKit
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
-
end
|
50
|
+
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
module OkonomiUiKit
|
2
2
|
class Component
|
3
|
-
attr_reader :view
|
3
|
+
attr_reader :view
|
4
4
|
|
5
|
-
def initialize(view
|
5
|
+
def initialize(view)
|
6
6
|
@view = view
|
7
|
-
@theme = theme || OkonomiUiKit::Theme::DEFAULT_THEME
|
8
7
|
end
|
9
8
|
|
10
9
|
def template_path
|
11
|
-
"okonomi/
|
10
|
+
[ self.class.name.underscore.gsub("okonomi_ui_kit/", "okonomi/"), name ].join("/")
|
12
11
|
end
|
13
12
|
|
14
13
|
def name
|
@@ -50,7 +49,8 @@ module OkonomiUiKit
|
|
50
49
|
|
51
50
|
raise ArgumentError, "Styles must be a Hash" unless styles.is_a?(Hash)
|
52
51
|
|
53
|
-
internal_styles_registry[theme]
|
52
|
+
internal_styles_registry[theme] ||= {}
|
53
|
+
internal_styles_registry[theme] = deep_merge(internal_styles_registry[theme], styles)
|
54
54
|
end
|
55
55
|
|
56
56
|
def self.internal_styles_registry
|
@@ -84,7 +84,11 @@ module OkonomiUiKit
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def self.config_class_name
|
87
|
-
"
|
87
|
+
"#{config_namespace.name}::#{name.demodulize}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.config_namespace
|
91
|
+
OkonomiUiKit::Configs
|
88
92
|
end
|
89
93
|
|
90
94
|
def self.config_class?
|
@@ -2,7 +2,7 @@ module OkonomiUiKit
|
|
2
2
|
module Components
|
3
3
|
class Alert < OkonomiUiKit::Component
|
4
4
|
def render(title, options = {}, &block)
|
5
|
-
view.render(template_path, title
|
5
|
+
view.render(template_path, title: title, options: options.with_indifferent_access, &block)
|
6
6
|
end
|
7
7
|
end
|
8
8
|
end
|
@@ -7,9 +7,9 @@ module OkonomiUiKit
|
|
7
7
|
|
8
8
|
classes = [
|
9
9
|
style(:base),
|
10
|
-
style(:severities, severity) ||
|
11
|
-
options.delete(:class) ||
|
12
|
-
].reject(&:blank?).join(
|
10
|
+
style(:severities, severity) || "",
|
11
|
+
options.delete(:class) || ""
|
12
|
+
].reject(&:blank?).join(" ")
|
13
13
|
|
14
14
|
view.tag.span(text, class: classes, **options)
|
15
15
|
end
|
@@ -28,7 +28,7 @@ module OkonomiUiKit
|
|
28
28
|
}
|
29
29
|
end
|
30
30
|
|
31
|
-
def initialize(template
|
31
|
+
def initialize(template)
|
32
32
|
super
|
33
33
|
@items = []
|
34
34
|
@builder = BreadcrumbBuilder.new(self)
|
@@ -36,9 +36,9 @@ module OkonomiUiKit
|
|
36
36
|
|
37
37
|
def render(options = {}, &block)
|
38
38
|
return "" if block.nil?
|
39
|
-
|
39
|
+
|
40
40
|
block.call(@builder)
|
41
|
-
view.render("okonomi/components/breadcrumbs/breadcrumbs",
|
41
|
+
view.render("okonomi/components/breadcrumbs/breadcrumbs",
|
42
42
|
component: self,
|
43
43
|
items: @items,
|
44
44
|
options: options
|
@@ -66,4 +66,4 @@ module OkonomiUiKit
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
69
|
-
end
|
69
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module OkonomiUiKit
|
2
2
|
module Components
|
3
3
|
class ButtonBase < OkonomiUiKit::Component
|
4
|
-
def build_button_class(variant:, color:, classes:
|
4
|
+
def build_button_class(variant:, color:, classes: "")
|
5
5
|
[
|
6
|
-
style(:root) ||
|
7
|
-
style(variant.to_sym, :root) ||
|
8
|
-
style(variant.to_sym, :colors, color.to_sym) ||
|
9
|
-
classes
|
10
|
-
].reject(&:blank?).join(
|
6
|
+
style(:root) || "",
|
7
|
+
style(variant.to_sym, :root) || "",
|
8
|
+
style(variant.to_sym, :colors, color.to_sym) || "",
|
9
|
+
classes
|
10
|
+
].reject(&:blank?).join(" ")
|
11
11
|
end
|
12
12
|
|
13
13
|
register_styles :default do
|
@@ -7,8 +7,8 @@ module OkonomiUiKit
|
|
7
7
|
options ||= {}
|
8
8
|
options = options.with_indifferent_access
|
9
9
|
|
10
|
-
variant = (options.delete(:variant) ||
|
11
|
-
color = (options.delete(:color) ||
|
10
|
+
variant = (options.delete(:variant) || "contained").to_sym
|
11
|
+
color = (options.delete(:color) || "default").to_sym
|
12
12
|
|
13
13
|
options[:class] = build_button_class(variant: variant, color: color, classes: options[:class])
|
14
14
|
|
@@ -20,4 +20,4 @@ module OkonomiUiKit
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
|
-
end
|
23
|
+
end
|
@@ -7,8 +7,8 @@ module OkonomiUiKit
|
|
7
7
|
html_options ||= {}
|
8
8
|
html_options = html_options.with_indifferent_access
|
9
9
|
|
10
|
-
variant = (html_options.delete(:variant) ||
|
11
|
-
color = (html_options.delete(:color) ||
|
10
|
+
variant = (html_options.delete(:variant) || "contained").to_sym
|
11
|
+
color = (html_options.delete(:color) || "default").to_sym
|
12
12
|
|
13
13
|
html_options[:class] = build_button_class(variant: variant, color: color, classes: html_options[:class])
|
14
14
|
|
@@ -20,4 +20,4 @@ module OkonomiUiKit
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
|
-
end
|
23
|
+
end
|
@@ -8,61 +8,65 @@ module OkonomiUiKit
|
|
8
8
|
|
9
9
|
# Extract component-specific options
|
10
10
|
language = options.delete(:language) || options.delete(:lang)
|
11
|
-
variant = (options.delete(:variant) ||
|
12
|
-
size = (options.delete(:size) ||
|
11
|
+
variant = (options.delete(:variant) || "default").to_sym
|
12
|
+
size = (options.delete(:size) || "default").to_sym
|
13
13
|
wrap = options.delete(:wrap) != false # Default to true
|
14
14
|
|
15
15
|
# Build classes
|
16
16
|
classes = build_classes(variant: variant, size: size, wrap: wrap, custom_class: options.delete(:class))
|
17
17
|
|
18
18
|
# Escape HTML entities in content
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
raw_content = if block_given?
|
20
|
+
view.capture(&block)
|
21
|
+
elsif content
|
22
|
+
content
|
23
|
+
else
|
24
|
+
""
|
25
|
+
end
|
26
|
+
|
27
|
+
escaped_content = html_escape(raw_content)
|
26
28
|
|
27
29
|
view.render(
|
28
30
|
template_path,
|
29
|
-
content: escaped_content
|
31
|
+
content: escaped_content,
|
30
32
|
options: options,
|
31
33
|
classes: classes,
|
32
34
|
language: language
|
33
35
|
)
|
34
36
|
end
|
35
37
|
|
38
|
+
register_styles :default do
|
39
|
+
{
|
40
|
+
base: "",
|
41
|
+
variants: {
|
42
|
+
default: "bg-gray-900 text-gray-100 p-4 rounded-lg",
|
43
|
+
inline: "bg-gray-100 text-gray-900 px-1 py-0.5 rounded text-sm font-mono",
|
44
|
+
minimal: "bg-gray-900 text-gray-100 p-3 rounded text-xs"
|
45
|
+
},
|
46
|
+
sizes: {
|
47
|
+
xs: "text-xs",
|
48
|
+
sm: "text-sm",
|
49
|
+
default: "text-sm",
|
50
|
+
lg: "text-base"
|
51
|
+
},
|
52
|
+
wrap: {
|
53
|
+
true: "overflow-x-auto",
|
54
|
+
false: "overflow-hidden"
|
55
|
+
}
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
36
59
|
private
|
37
60
|
|
38
61
|
def build_classes(variant:, size:, wrap:, custom_class: nil)
|
39
|
-
base_classes =
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
"bg-gray-900 text-gray-100 p-3 rounded text-xs"
|
46
|
-
else
|
47
|
-
# :default
|
48
|
-
"bg-gray-900 text-gray-100 p-4 rounded-lg"
|
49
|
-
end
|
50
|
-
|
51
|
-
size_classes = case size
|
52
|
-
when :xs
|
53
|
-
"text-xs"
|
54
|
-
when :sm
|
55
|
-
"text-sm"
|
56
|
-
when :lg
|
57
|
-
"text-base"
|
58
|
-
else
|
59
|
-
# :default
|
60
|
-
"text-sm"
|
61
|
-
end
|
62
|
-
|
63
|
-
wrap_classes = wrap ? "overflow-x-auto" : "overflow-hidden"
|
62
|
+
base_classes = style(:base) || ""
|
63
|
+
variant_classes = style(:variants, variant) || ""
|
64
|
+
size_classes = style(:sizes, size) || ""
|
65
|
+
# Convert boolean wrap to symbol for hash access
|
66
|
+
wrap_key = wrap ? :true : :false
|
67
|
+
wrap_classes = style(:wrap, wrap_key) || ""
|
64
68
|
|
65
|
-
[base_classes, variant_classes, size_classes, wrap_classes, custom_class].
|
69
|
+
[ base_classes, variant_classes, size_classes, wrap_classes, custom_class ].reject(&:blank?).join(" ")
|
66
70
|
end
|
67
71
|
|
68
72
|
def html_escape(content)
|
@@ -70,4 +74,4 @@ module OkonomiUiKit
|
|
70
74
|
end
|
71
75
|
end
|
72
76
|
end
|
73
|
-
end
|
77
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module OkonomiUiKit
|
2
|
+
module Components
|
3
|
+
class ConfirmationModal < OkonomiUiKit::Component
|
4
|
+
def render(options = {}, &block)
|
5
|
+
options = options.with_indifferent_access
|
6
|
+
|
7
|
+
# Extract and validate required options
|
8
|
+
title = options.fetch(:title) { raise ArgumentError, "title is required" }
|
9
|
+
message = options.fetch(:message) { raise ArgumentError, "message is required" }
|
10
|
+
|
11
|
+
# Extract optional parameters with defaults
|
12
|
+
confirm_text = options.delete(:confirm_text) || "Confirm"
|
13
|
+
cancel_text = options.delete(:cancel_text) || "Cancel"
|
14
|
+
variant = (options.delete(:variant) || :warning).to_sym
|
15
|
+
size = (options.delete(:size) || :md).to_sym
|
16
|
+
auto_open = options.delete(:auto_open) || false
|
17
|
+
|
18
|
+
# Build component options
|
19
|
+
modal_options = {
|
20
|
+
title: title,
|
21
|
+
message: message,
|
22
|
+
confirm_text: confirm_text,
|
23
|
+
cancel_text: cancel_text,
|
24
|
+
variant: variant,
|
25
|
+
size: size,
|
26
|
+
auto_open: auto_open,
|
27
|
+
has_custom_actions: block_given?,
|
28
|
+
data: options.delete(:data) || {}
|
29
|
+
}.merge(options)
|
30
|
+
|
31
|
+
view.render(template_path, component: self, options: modal_options, &block)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Register default styles for the confirmation modal
|
35
|
+
register_styles :default do
|
36
|
+
{
|
37
|
+
# Modal container and backdrop
|
38
|
+
backdrop: "fixed inset-0 bg-gray-500/75 transition-opacity duration-300 ease-out opacity-0",
|
39
|
+
container: "fixed inset-0 z-10 w-screen overflow-y-auto",
|
40
|
+
wrapper: "flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0",
|
41
|
+
|
42
|
+
# Modal panel
|
43
|
+
panel: {
|
44
|
+
base: "relative transform overflow-hidden rounded-lg bg-white px-4 pt-5 pb-4 text-left shadow-xl transition-all duration-300 ease-out sm:my-8 sm:w-full sm:p-6 opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95",
|
45
|
+
sizes: {
|
46
|
+
sm: "sm:max-w-sm",
|
47
|
+
md: "sm:max-w-lg",
|
48
|
+
lg: "sm:max-w-2xl",
|
49
|
+
xl: "sm:max-w-4xl"
|
50
|
+
}
|
51
|
+
},
|
52
|
+
|
53
|
+
# Close button
|
54
|
+
close_button: {
|
55
|
+
wrapper: "absolute top-0 right-0 hidden pt-4 pr-4 sm:block",
|
56
|
+
button: "rounded-md bg-white text-gray-400 hover:text-gray-500 focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:outline-none",
|
57
|
+
icon: {
|
58
|
+
file: "heroicons/outline/x-mark",
|
59
|
+
class: "size-6"
|
60
|
+
}
|
61
|
+
},
|
62
|
+
|
63
|
+
# Icon configuration
|
64
|
+
icon: {
|
65
|
+
wrapper: "mx-auto flex size-12 shrink-0 items-center justify-center rounded-full sm:mx-0 sm:size-10",
|
66
|
+
class: "size-6",
|
67
|
+
variants: {
|
68
|
+
warning: {
|
69
|
+
wrapper: "bg-red-100",
|
70
|
+
icon: "text-red-600",
|
71
|
+
file: "heroicons/outline/exclamation-triangle"
|
72
|
+
},
|
73
|
+
info: {
|
74
|
+
wrapper: "bg-blue-100",
|
75
|
+
icon: "text-blue-600",
|
76
|
+
file: "heroicons/outline/information-circle"
|
77
|
+
},
|
78
|
+
success: {
|
79
|
+
wrapper: "bg-green-100",
|
80
|
+
icon: "text-green-600",
|
81
|
+
file: "heroicons/outline/check-circle"
|
82
|
+
}
|
83
|
+
}
|
84
|
+
},
|
85
|
+
|
86
|
+
# Content styling
|
87
|
+
content: {
|
88
|
+
wrapper: "sm:flex sm:items-start",
|
89
|
+
text_wrapper: "mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",
|
90
|
+
title: "text-base font-semibold text-gray-900",
|
91
|
+
message: "mt-2 text-sm text-gray-500"
|
92
|
+
},
|
93
|
+
|
94
|
+
# Actions container
|
95
|
+
actions: {
|
96
|
+
wrapper: "mt-5 sm:mt-4 sm:flex sm:flex-row-reverse"
|
97
|
+
}
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
# Helper methods to build classes from styles
|
102
|
+
def modal_panel_class(size)
|
103
|
+
[
|
104
|
+
style(:panel, :base),
|
105
|
+
style(:panel, :sizes, size)
|
106
|
+
].compact.join(" ")
|
107
|
+
end
|
108
|
+
|
109
|
+
def modal_icon_wrapper_class(variant)
|
110
|
+
[
|
111
|
+
style(:icon, :wrapper),
|
112
|
+
style(:icon, :variants, variant, :wrapper)
|
113
|
+
].compact.join(" ")
|
114
|
+
end
|
115
|
+
|
116
|
+
def modal_icon_class(variant)
|
117
|
+
[
|
118
|
+
style(:icon, :class),
|
119
|
+
style(:icon, :variants, variant, :icon)
|
120
|
+
].compact.join(" ")
|
121
|
+
end
|
122
|
+
|
123
|
+
def modal_data_attributes(options)
|
124
|
+
return "" unless options[:data]
|
125
|
+
|
126
|
+
options[:data].map { |k, v| "data-#{k.to_s.dasherize}=\"#{v}\"" }.join(" ").html_safe
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module OkonomiUiKit
|
2
|
+
module Components
|
3
|
+
module Forms
|
4
|
+
class CheckBoxWithLabel < OkonomiUiKit::FormComponent
|
5
|
+
def render(form, method, options = {}, checked_value = true, unchecked_value = false)
|
6
|
+
options = options.with_indifferent_access
|
7
|
+
|
8
|
+
view.content_tag(:div, class: style(:wrapper)) do
|
9
|
+
view.concat form.check_box(
|
10
|
+
method,
|
11
|
+
{
|
12
|
+
class: style(:input, :root)
|
13
|
+
}.merge(options || {}),
|
14
|
+
checked_value,
|
15
|
+
unchecked_value
|
16
|
+
)
|
17
|
+
view.concat view.render(template_path, component: self, method: method, options: options, form: form)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
register_styles :default do
|
22
|
+
{
|
23
|
+
wrapper: "flex gap-x-3",
|
24
|
+
input: {
|
25
|
+
root: "size-4 rounded border-gray-300 text-primary-600 focus:ring-primary-600"
|
26
|
+
},
|
27
|
+
label: {
|
28
|
+
root: "text-sm/6 font-medium text-gray-900"
|
29
|
+
},
|
30
|
+
hint: {
|
31
|
+
root: "text-gray-500"
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module OkonomiUiKit
|
2
|
+
module Components
|
3
|
+
module Forms
|
4
|
+
class CollectionSelect < OkonomiUiKit::FormComponent
|
5
|
+
def render(form, method, collection, value_method, text_method, options = {}, html_options = {})
|
6
|
+
html_options = html_options.with_indifferent_access
|
7
|
+
css = build_select_classes(form, method, html_options)
|
8
|
+
|
9
|
+
select_html = form.collection_select(method, collection, value_method, text_method, options, html_options.merge(class: css))
|
10
|
+
icon_html = view.ui.icon(
|
11
|
+
style(:icon, :file),
|
12
|
+
class: style(:icon, :class)
|
13
|
+
)
|
14
|
+
|
15
|
+
view.content_tag(:div, class: style(:wrapper)) do
|
16
|
+
view.concat(select_html)
|
17
|
+
view.concat(icon_html)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
register_styles :default do
|
22
|
+
{
|
23
|
+
wrapper: "relative",
|
24
|
+
root: "w-full appearance-none border-0 pl-3 pr-10 py-2 rounded-md ring-1 focus:outline-none focus-within:ring-1",
|
25
|
+
error: "bg-danger-100 text-danger-400 ring-danger-400 focus:ring-danger-600",
|
26
|
+
valid: "text-default-700 ring-gray-300 focus-within:ring-gray-400",
|
27
|
+
icon: {
|
28
|
+
file: "heroicons/mini/chevron-down",
|
29
|
+
class: "absolute right-2 top-1/2 -translate-y-1/2 size-5 text-gray-400 pointer-events-none"
|
30
|
+
}
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def build_select_classes(form, method, html_options)
|
37
|
+
css = [
|
38
|
+
style(:root),
|
39
|
+
when_errors(form, method, style(:error), style(:valid)),
|
40
|
+
html_options[:class]
|
41
|
+
].compact.join(" ").split(" ").uniq
|
42
|
+
|
43
|
+
TWMerge.merge(css)
|
44
|
+
end
|
45
|
+
|
46
|
+
def when_errors(form, method, value, default_value = nil)
|
47
|
+
key = method.to_s.gsub("_id", "").to_sym
|
48
|
+
if form.object.errors.include?(key) || form.object.errors.include?(method)
|
49
|
+
value
|
50
|
+
else
|
51
|
+
default_value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module OkonomiUiKit
|
2
|
+
module Components
|
3
|
+
module Forms
|
4
|
+
class Field < OkonomiUiKit::FormComponent
|
5
|
+
def render(form, field_id = nil, options = {}, &block)
|
6
|
+
view.render(template_path, component: self, form: form, field_id: field_id, options: options, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
register_styles :default do
|
10
|
+
{
|
11
|
+
wrapper: "w-full flex flex-col gap-2",
|
12
|
+
header: "flex justify-between items-center",
|
13
|
+
hint: {
|
14
|
+
trigger: "text-primary-600 text-sm hover:cursor-help",
|
15
|
+
content: "text-xs absolute border rounded-md bg-gray-100 border-gray-600 text-gray-600 p-1 z-10"
|
16
|
+
},
|
17
|
+
content: "block",
|
18
|
+
error: "mt-1 text-danger-600 text-sm"
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module OkonomiUiKit
|
2
|
+
module Components
|
3
|
+
module Forms
|
4
|
+
class FieldSet < OkonomiUiKit::FormComponent
|
5
|
+
def render(form, options = {}, &block)
|
6
|
+
view.render(template_path, component: self, options: options, form: form, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
register_styles :default do
|
10
|
+
{
|
11
|
+
root: "w-full flex flex-col gap-4 col-span-1 sm:col-span-3 md:col-span-5"
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module OkonomiUiKit
|
2
|
+
module Components
|
3
|
+
module Forms
|
4
|
+
class InputBase < OkonomiUiKit::FormComponent
|
5
|
+
def render_arguments(object, method, options = {})
|
6
|
+
css = input_field_classes(object, method, self.class.type_value, options)
|
7
|
+
[ method, { autocomplete: "off" }.merge(options).merge(class: css) ]
|
8
|
+
end
|
9
|
+
|
10
|
+
register_styles :default do
|
11
|
+
{
|
12
|
+
root: "w-full border-0 px-3 py-2 rounded-md ring-1 focus:outline-none focus-within:ring-1",
|
13
|
+
error: "bg-danger-100 text-danger-400 ring-danger-400 focus:ring-danger-600",
|
14
|
+
valid: "text-default-700 ring-gray-300 focus-within:ring-gray-400",
|
15
|
+
disabled: "disabled:bg-gray-50 disabled:cursor-not-allowed"
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.type(type)
|
20
|
+
@type = type
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.type_value
|
24
|
+
@type || :text
|
25
|
+
end
|
26
|
+
|
27
|
+
def input_field_classes(object, method, type, options, include_disabled: true)
|
28
|
+
css_classes = OkonomiUiKit::TWMerge.merge_all(
|
29
|
+
style(:root),
|
30
|
+
when_errors(
|
31
|
+
object,
|
32
|
+
method,
|
33
|
+
style(:error),
|
34
|
+
style(:valid)
|
35
|
+
),
|
36
|
+
options[:class]
|
37
|
+
)
|
38
|
+
|
39
|
+
if include_disabled
|
40
|
+
css_classes = OkonomiUiKit::TWMerge.merge_all(css_classes, style(:disabled))
|
41
|
+
end
|
42
|
+
|
43
|
+
css_classes
|
44
|
+
end
|
45
|
+
|
46
|
+
def when_errors(object, method, value, default_value = nil)
|
47
|
+
key = method.to_s.gsub("_id", "").to_sym
|
48
|
+
if object.errors.include?(key) || object.errors.include?(method)
|
49
|
+
value
|
50
|
+
else
|
51
|
+
default_value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|