okonomi_ui_kit 0.1.7 → 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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +165 -7
  3. data/app/assets/builds/okonomi_ui_kit/application.tailwind.css +664 -187
  4. data/app/helpers/okonomi_ui_kit/application_helper.rb +8 -0
  5. data/app/helpers/okonomi_ui_kit/attribute_section_helper.rb +5 -5
  6. data/app/helpers/okonomi_ui_kit/component.rb +44 -21
  7. data/app/helpers/okonomi_ui_kit/components/alert.rb +1 -1
  8. data/app/helpers/okonomi_ui_kit/components/badge.rb +5 -5
  9. data/app/helpers/okonomi_ui_kit/components/breadcrumbs.rb +69 -0
  10. data/app/helpers/okonomi_ui_kit/components/button_base.rb +56 -0
  11. data/app/helpers/okonomi_ui_kit/components/button_tag.rb +23 -0
  12. data/app/helpers/okonomi_ui_kit/components/button_to.rb +4 -15
  13. data/app/helpers/okonomi_ui_kit/components/code.rb +41 -37
  14. data/app/helpers/okonomi_ui_kit/components/confirmation_modal.rb +130 -0
  15. data/app/helpers/okonomi_ui_kit/components/forms/check_box_with_label.rb +38 -0
  16. data/app/helpers/okonomi_ui_kit/components/forms/collection_select.rb +57 -0
  17. data/app/helpers/okonomi_ui_kit/components/forms/date_field.rb +9 -0
  18. data/app/helpers/okonomi_ui_kit/components/forms/datetime_local_field.rb +9 -0
  19. data/app/helpers/okonomi_ui_kit/components/forms/email_field.rb +9 -0
  20. data/app/helpers/okonomi_ui_kit/components/forms/field.rb +24 -0
  21. data/app/helpers/okonomi_ui_kit/components/forms/field_set.rb +17 -0
  22. data/app/helpers/okonomi_ui_kit/components/forms/input_base.rb +57 -0
  23. data/app/helpers/okonomi_ui_kit/components/forms/label.rb +27 -0
  24. data/app/helpers/okonomi_ui_kit/components/forms/multi_select.rb +18 -0
  25. data/app/helpers/okonomi_ui_kit/components/forms/number_field.rb +9 -0
  26. data/app/helpers/okonomi_ui_kit/components/forms/password_field.rb +9 -0
  27. data/app/helpers/okonomi_ui_kit/components/forms/search_field.rb +9 -0
  28. data/app/helpers/okonomi_ui_kit/components/forms/select.rb +57 -0
  29. data/app/helpers/okonomi_ui_kit/components/forms/show_if.rb +28 -0
  30. data/app/helpers/okonomi_ui_kit/components/forms/telephone_field.rb +9 -0
  31. data/app/helpers/okonomi_ui_kit/components/forms/text_area.rb +9 -0
  32. data/app/helpers/okonomi_ui_kit/components/forms/text_field.rb +9 -0
  33. data/app/helpers/okonomi_ui_kit/components/forms/time_field.rb +9 -0
  34. data/app/helpers/okonomi_ui_kit/components/forms/upload_field.rb +25 -0
  35. data/app/helpers/okonomi_ui_kit/components/forms/url_field.rb +9 -0
  36. data/app/helpers/okonomi_ui_kit/components/forms.rb +6 -0
  37. data/app/helpers/okonomi_ui_kit/components/icon.rb +36 -0
  38. data/app/helpers/okonomi_ui_kit/components/link_to.rb +8 -19
  39. data/app/helpers/okonomi_ui_kit/components/navigation.rb +98 -0
  40. data/app/helpers/okonomi_ui_kit/components/page.rb +8 -8
  41. data/app/helpers/okonomi_ui_kit/components/table.rb +9 -10
  42. data/app/helpers/okonomi_ui_kit/components/typography.rb +16 -16
  43. data/app/helpers/okonomi_ui_kit/components.rb +4 -0
  44. data/app/helpers/okonomi_ui_kit/config.rb +5 -1
  45. data/app/helpers/okonomi_ui_kit/configs.rb +4 -0
  46. data/app/helpers/okonomi_ui_kit/form_builder.rb +39 -130
  47. data/app/helpers/okonomi_ui_kit/form_component.rb +7 -0
  48. data/app/helpers/okonomi_ui_kit/svg_icons.rb +5 -5
  49. data/app/helpers/okonomi_ui_kit/t_w_merge.rb +114 -0
  50. data/app/helpers/okonomi_ui_kit/ui_helper.rb +17 -58
  51. data/app/views/okonomi/components/breadcrumbs/_breadcrumbs.html.erb +46 -0
  52. data/app/views/okonomi/components/confirmation_modal/_confirmation_modal.html.erb +76 -0
  53. data/app/views/okonomi/components/forms/check_box_with_label/_check_box_with_label.html.erb +6 -0
  54. data/app/views/okonomi/components/forms/field/_field.html.erb +3 -0
  55. data/app/views/okonomi/components/forms/field_set/_field_set.html.erb +3 -0
  56. data/app/views/okonomi/components/forms/upload_field/_upload_field.html.erb +1 -0
  57. data/app/views/okonomi/components/icon/_icon.html.erb +38 -0
  58. data/app/views/okonomi/components/navigation/_link.html.erb +18 -0
  59. data/app/views/okonomi/components/navigation/_navigation.html.erb +4 -0
  60. data/app/views/okonomi/forms/tailwind/_checkbox_label.html.erb +2 -2
  61. data/app/views/okonomi/forms/tailwind/_field.html.erb +6 -6
  62. data/app/views/okonomi/forms/tailwind/_multi_select.html.erb +2 -4
  63. data/app/views/okonomi/forms/tailwind/_upload_field.html.erb +10 -10
  64. data/config/importmap.rb +1 -1
  65. data/lib/okonomi_ui_kit/engine.rb +0 -3
  66. data/lib/okonomi_ui_kit/version.rb +1 -1
  67. metadata +43 -12
  68. data/app/helpers/okonomi_ui_kit/breadcrumbs_helper.rb +0 -60
  69. data/app/helpers/okonomi_ui_kit/icon_helper.rb +0 -39
  70. data/app/helpers/okonomi_ui_kit/navigation_helper.rb +0 -72
  71. data/app/helpers/okonomi_ui_kit/theme.rb +0 -159
  72. data/app/helpers/okonomi_ui_kit/theme_helper.rb +0 -17
  73. data/app/views/okonomi/forms/tailwind/_field_set.html.erb +0 -3
  74. data/app/views/okonomi/modals/_confirmation_modal.html.erb +0 -77
  75. data/app/views/okonomi/navigation/_link.html.erb +0 -15
  76. data/app/views/okonomi/navigation/_menu.html.erb +0 -3
  77. data/app/views/okonomi/navigation/_navbar.html.erb +0 -105
@@ -8,74 +8,33 @@ module OkonomiUiKit
8
8
  include ActionView::Helpers::TagHelper
9
9
  include ActionView::Helpers::CaptureHelper
10
10
 
11
- def initialize(template)
12
- @template = template
13
- end
14
-
15
- def theme(t = {}, &block)
16
- old_theme = get_theme
17
-
18
- @_okonomi_ui_kit_theme = {}.merge(old_theme).merge(t || {})
19
-
20
- yield(@_okonomi_ui_kit_theme)
11
+ attr_reader :template, :namespace
21
12
 
22
- @_okonomi_ui_kit_theme = old_theme
23
- end
24
-
25
- def get_theme
26
- @_okonomi_ui_kit_theme ||= OkonomiUiKit::Theme::DEFAULT_THEME
13
+ def initialize(template, namespace: OkonomiUiKit::Components)
14
+ @template = template
15
+ @namespace = namespace
27
16
  end
28
17
 
29
- def button_class(variant: 'contained', color: 'default', classes: '')
30
- [
31
- get_theme.dig(:components, :link, :root) || '',
32
- get_theme.dig(:components, :link, variant.to_sym, :root) || '',
33
- get_theme.dig(:components, :link, variant.to_sym, :colors, color.to_sym) || '',
34
- classes,
35
- ].join(' ')
36
- end
18
+ def method_missing(method_name, *args, &block)
19
+ component = resolve_component(method_name)
37
20
 
38
- def confirmation_modal(title:, message:, confirm_text: "Confirm", cancel_text: "Cancel", variant: :warning, size: :md, **options, &block)
39
- modal_options = {
40
- title: title,
41
- message: message,
42
- confirm_text: confirm_text,
43
- cancel_text: cancel_text,
44
- variant: variant,
45
- size: size,
46
- has_custom_actions: block_given?,
47
- **options
48
- }
49
- @template.render("okonomi/modals/confirmation_modal", options: modal_options, ui: self, &block)
21
+ if component
22
+ component.render(*args, &block)
23
+ else
24
+ super
25
+ end
50
26
  end
51
27
 
52
- def modal_data_attributes(options)
53
- return "" unless options[:data]
54
-
55
- options[:data].map { |k, v| "data-#{k.to_s.dasherize}=\"#{v}\"" }.join(' ').html_safe
56
- end
28
+ def resolve_component(name)
29
+ component_name = "#{namespace.name}::#{name.to_s.camelize}"
57
30
 
58
- def modal_panel_class(size)
59
- [
60
- get_theme.dig(:components, :modal, :panel, :base),
61
- get_theme.dig(:components, :modal, :panel, :sizes, size)
62
- ].compact.join(' ')
63
- end
31
+ return nil unless Object.const_defined?(component_name)
64
32
 
65
- def modal_icon_wrapper_class(variant)
66
- [
67
- get_theme.dig(:components, :modal, :icon, :wrapper),
68
- get_theme.dig(:components, :modal, :icon, :variants, variant, :wrapper)
69
- ].compact.join(' ')
33
+ component_name.constantize.new(@template)
70
34
  end
71
35
 
72
- def method_missing(method_name, *args, &block)
73
- component_name = "OkonomiUiKit::Components::#{method_name.to_s.camelize}"
74
- if Object.const_defined?(component_name)
75
- return component_name.constantize.new(@template, get_theme).render(*args, &block)
76
- else
77
- super
78
- end
36
+ def forms
37
+ @forms ||= self.class.new(@template, namespace: OkonomiUiKit::Components::Forms)
79
38
  end
80
39
  end
81
40
  end
@@ -0,0 +1,46 @@
1
+ <%= tag.nav(**options.merge(class: component.style(:nav), 'aria-label': 'Breadcrumb')) do %>
2
+ <ol role="list" class="<%= component.style(:list) %>">
3
+ <% items.each_with_index do |item, index| %>
4
+ <li>
5
+ <div class="flex items-center">
6
+ <% if index == 0 %>
7
+ <% if item[:icon] %>
8
+ <% if item[:path] %>
9
+ <%= link_to item[:path], class: "text-gray-400 hover:text-gray-500", 'aria-current': (item[:current] ? 'page' : nil) do %>
10
+ <%= item[:icon] %>
11
+ <span class="sr-only"><%= item[:text] %></span>
12
+ <% end %>
13
+ <% else %>
14
+ <span class="text-gray-400" aria-current="<%= item[:current] ? 'page' : nil %>">
15
+ <%= item[:icon] %>
16
+ <span class="sr-only"><%= item[:text] %></span>
17
+ </span>
18
+ <% end %>
19
+ <% else %>
20
+ <div class="flex items-center">
21
+ <% if item[:path] && !item[:current] %>
22
+ <%= link_to item[:text], item[:path], class: component.style(:link, :first), 'aria-current': nil %>
23
+ <% else %>
24
+ <span class="<%= component.style(:link, :first) %>" aria-current="<%= item[:current] ? 'page' : nil %>">
25
+ <%= item[:text] %>
26
+ </span>
27
+ <% end %>
28
+ </div>
29
+ <% end %>
30
+ <% else %>
31
+ <svg class="<%= component.style(:separator, :base) %>" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
32
+ <path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd" />
33
+ </svg>
34
+ <% if item[:path] && !item[:current] %>
35
+ <%= link_to item[:text], item[:path], class: component.style(:link, :base), 'aria-current': nil %>
36
+ <% else %>
37
+ <span class="<%= component.style(:link, :current) %>" aria-current="<%= item[:current] ? 'page' : nil %>">
38
+ <%= item[:text] %>
39
+ </span>
40
+ <% end %>
41
+ <% end %>
42
+ </div>
43
+ </li>
44
+ <% end %>
45
+ </ol>
46
+ <% end %>
@@ -0,0 +1,76 @@
1
+ <div data-controller="modal"
2
+ data-modal-size-value="<%= options[:size] %>"
3
+ <% if options[:auto_open] %>data-modal-auto-open-value="true"<% end %>
4
+ class="relative z-10"
5
+ style="display: none;"
6
+ data-modal-target="container"
7
+ <%= component.modal_data_attributes(options) %>>
8
+
9
+ <!-- Backdrop -->
10
+ <div class="<%= component.style(:backdrop) %>"
11
+ data-modal-target="backdrop"
12
+ data-action="click->modal#close"
13
+ aria-hidden="true"></div>
14
+
15
+ <!-- Modal container -->
16
+ <div class="<%= component.style(:container) %>">
17
+ <div class="<%= component.style(:wrapper) %>">
18
+ <!-- Modal panel -->
19
+ <div class="<%= component.modal_panel_class(options[:size]) %>"
20
+ data-modal-target="panel"
21
+ role="dialog"
22
+ aria-modal="true"
23
+ aria-labelledby="modal-title">
24
+
25
+ <!-- Close button -->
26
+ <div class="<%= component.style(:close_button, :wrapper) %>">
27
+ <button type="button"
28
+ class="<%= component.style(:close_button, :button) %>"
29
+ data-action="click->modal#close">
30
+ <span class="sr-only">Close</span>
31
+ <%= ui.icon(component.style(:close_button, :icon, :file),
32
+ class: component.style(:close_button, :icon, :class)) %>
33
+ </button>
34
+ </div>
35
+
36
+ <!-- Content -->
37
+ <div class="<%= component.style(:content, :wrapper) %>">
38
+ <!-- Icon -->
39
+ <div class="<%= component.modal_icon_wrapper_class(options[:variant]) %>">
40
+ <%= ui.icon(component.style(:icon, :variants, options[:variant], :file),
41
+ class: component.modal_icon_class(options[:variant])) %>
42
+ </div>
43
+
44
+ <!-- Text content -->
45
+ <div class="<%= component.style(:content, :text_wrapper) %>">
46
+ <h3 id="modal-title" class="<%= component.style(:content, :title) %>">
47
+ <%= options[:title] %>
48
+ </h3>
49
+ <div class="<%= component.style(:content, :message) %>">
50
+ <p><%= options[:message] %></p>
51
+ </div>
52
+ </div>
53
+ </div>
54
+
55
+ <!-- Actions -->
56
+ <div class="<%= component.style(:actions, :wrapper) %>">
57
+ <% if options[:has_custom_actions] %>
58
+ <%= yield %>
59
+ <% else %>
60
+ <% button_color = options[:variant] == :warning ? :danger : options[:variant] %>
61
+ <%= ui.button_to options[:confirm_text], "#",
62
+ variant: :contained,
63
+ color: button_color,
64
+ class: "sm:ml-3 sm:w-auto",
65
+ data: { action: "click->modal#confirm" } %>
66
+ <%= ui.button_to options[:cancel_text], "#",
67
+ variant: :outlined,
68
+ color: :default,
69
+ class: "mt-3 sm:mt-0 sm:w-auto",
70
+ data: { action: "click->modal#close" } %>
71
+ <% end %>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </div>
@@ -0,0 +1,6 @@
1
+ <% if options[:label] %>
2
+ <%= form.label method, options[:label], class: component.style(:label, :root) %>
3
+ <% end %>
4
+ <% if options[:hint] %>
5
+ <p class="<%= component.style(:hint, :root) %>"><%= options[:hint] %></p>
6
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= render "okonomi/forms/tailwind/field", component: component, form: form, field_id: field_id, options: options do %>
2
+ <%= yield %>
3
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= content_tag "div", class: component.style(:root) do %>
2
+ <%= yield %>
3
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= render "okonomi/forms/tailwind/upload_field", component: component, form: form, method: method, options: options %>
@@ -0,0 +1,38 @@
1
+ <%
2
+ # Load the SVG content
3
+ svg_content = if OkonomiUiKit::SvgIcons.exist?(name)
4
+ OkonomiUiKit::SvgIcons.read(name)
5
+ else
6
+ "<!-- SVG #{name} not found -->"
7
+ end
8
+
9
+ # Parse and modify the SVG
10
+ if svg_content.start_with?("<!--")
11
+ %><%= raw svg_content %><%
12
+ else
13
+ doc = Nokogiri::HTML::DocumentFragment.parse(svg_content)
14
+ svg = doc.at_css('svg')
15
+
16
+ if svg
17
+ # Apply classes
18
+ svg['class'] = classes if classes.present?
19
+
20
+ # Apply dimensions
21
+ svg['width'] = width if width.present?
22
+ svg['height'] = height if height.present?
23
+
24
+ # Apply any additional options as attributes
25
+ options.each do |key, value|
26
+ if key.to_s == 'data' && value.is_a?(Hash)
27
+ # Handle data attributes specially
28
+ value.each do |data_key, data_value|
29
+ svg["data-#{data_key.to_s.dasherize}"] = data_value
30
+ end
31
+ else
32
+ svg[key.to_s.dasherize] = value
33
+ end
34
+ end
35
+ end
36
+ %><%= raw doc.to_html %><%
37
+ end
38
+ %>
@@ -0,0 +1,18 @@
1
+ <%
2
+ # Get the main view context that has access to helpers
3
+ view_context = style_helper.view
4
+
5
+ options = {
6
+ exact: defined?(exact) ? exact : false,
7
+ class: style_helper.style(:link, :base),
8
+ active_class: style_helper.style(:link, :active)
9
+ }
10
+ %>
11
+ <%= view_context.active_link_to path, options do %>
12
+ <% if defined?(initials) && initials.present? %>
13
+ <span class="<%= style_helper.style(:link, :initials, :base) %>"><%= initials %></span>
14
+ <% elsif defined?(icon) && icon.present? %>
15
+ <%= view_context.ui.icon icon, class: style_helper.style(:link, :icon) %>
16
+ <% end %>
17
+ <%= title %>
18
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <% yield(builder) %>
2
+ <ul role="list" class="<%= builder.style(:menu, :base) %>">
3
+ <%= builder.render_groups %>
4
+ </ul>
@@ -3,7 +3,7 @@
3
3
  label_options[:for] = options[:id] if options[:id]
4
4
  %>
5
5
  <%= form.label(method, label_options) do %>
6
- <div class="<%= form.ui.get_theme.dig(:components, :checkbox, :label, :root) %>">
6
+ <div class="<%= component.style(:label, :root) %>">
7
7
  <% if options[:label] %>
8
8
  <%= options[:label] %>
9
9
  <% else %>
@@ -11,7 +11,7 @@
11
11
  <% end %>
12
12
  </div>
13
13
  <% if options[:hint] %>
14
- <div class="<%= form.ui.get_theme.dig(:components, :checkbox, :hint, :root) %>">
14
+ <div class="<%= component.style(:hint, :root) %>">
15
15
  <%= t("activerecord.hints.#{form.object.class.name.underscore}.#{method}") %>
16
16
  </div>
17
17
  <% end %>
@@ -1,15 +1,15 @@
1
- <div class="w-full flex flex-col gap-2">
2
- <div class="flex justify-between items-center" x-data="{ open: false }">
1
+ <div class="<%= component.style(:wrapper) %>">
2
+ <div class="<%= component.style(:header) %>" x-data="{ open: false }">
3
3
  <% if field_id %>
4
4
  <%= form.label field_id, t("activerecord.attributes.#{form.object_name}.#{field_id}") %>
5
5
  <% end %>
6
6
  <% if options[:hint] %>
7
7
  <div class="relative">
8
- <div class="text-primary-600 text-sm hover:cursor-help" @mouseover="open = true" @mouseover.away = "open = false">
8
+ <div class="<%= component.style(:hint, :trigger) %>" @mouseover="open = true" @mouseover.away = "open = false">
9
9
  Hilfe
10
10
  </div>
11
11
  <div x-show="open"
12
- class="text-xs absolute border rounded-md bg-gray-100 border-gray-600 text-gray-600 p-1 z-10"
12
+ class="<%= component.style(:hint, :content) %>"
13
13
  style="top: 32px; right: -10px; width: 200px; max-width: 400px; display: none;"
14
14
  x-transition:enter="transition duration-200 transform ease-out"
15
15
  x-transition:enter-start="scale-75"
@@ -21,12 +21,12 @@
21
21
  </div>
22
22
  <% end %>
23
23
  </div>
24
- <div class="block">
24
+ <div class="<%= component.style(:content) %>">
25
25
  <div class="grid grid-cols-<%= options[:columns] || 1 %> gap-2">
26
26
  <%= yield %>
27
27
  </div>
28
28
  <% if field_id && form.object.errors.include?(field_id) %>
29
- <div class="mt-1 text-danger-600 text-sm">
29
+ <div class="<%= component.style(:error) %>">
30
30
  <%= form.object.errors[field_id].join(", ") %>
31
31
  </div>
32
32
  <% end %>
@@ -5,11 +5,9 @@
5
5
  <% associated_class = association.klass %>
6
6
  <% associated_records = options[:collection] || associated_class.all %>
7
7
 
8
- <% p associated_records %>
9
-
10
- <div class="grid grid-cols-2 gap-2">
8
+ <div class="<%= component.style(:wrapper) %>">
11
9
  <% associated_records.each do |record| %>
12
- <div class="flex items-center">
10
+ <div class="<%= component.style(:item) %>">
13
11
  <% id = "#{method}_#{record.id}" %>
14
12
  <%= form.check_box_with_label method, { label: record.send(options[:label] || :name), multiple: true, id: id, checked: form.object.send(method).include?(record) }, record.id, nil %>
15
13
  </div>
@@ -1,24 +1,24 @@
1
1
  <div
2
2
  data-controller="upload"
3
3
  data-upload-target="dropzone"
4
- class="border-2 border-dashed border-gray-300 rounded-md p-6 text-center cursor-pointer hover:bg-gray-50 relative"
4
+ class="<%= component.style(:dropzone) %>"
5
5
  >
6
- <%= form.label method, class: "block cursor-pointer" do %>
7
- <div class="flex flex-col items-center text-gray-600 space-y-2">
8
- <div data-upload-target="preview" class="w-full flex justify-center items-center">
6
+ <%= form.label method, class: component.style(:label) do %>
7
+ <div class="<%= component.style(:content) %>">
8
+ <div data-upload-target="preview" class="<%= component.style(:preview) %>">
9
9
  <% if form.object.send(method).attached? %>
10
10
  <% blob = form.object.send(method).blob %>
11
11
  <% if blob.image? %>
12
- <%= image_tag url_for(blob), class: "max-h-32" %>
12
+ <%= image_tag url_for(blob), class: component.style(:preview_image) %>
13
13
  <% else %>
14
- <%= svg_icon("heroicons/solid/document", class: "size-12 text-gray-400") %>
14
+ <%= ui.icon("heroicons/solid/document", class: component.style(:icon)) %>
15
15
  <% end %>
16
16
  <% else %>
17
- <%= svg_icon("heroicons/solid/plus", class: "size-12 w-12 text-gray-400") %>
17
+ <%= ui.icon("heroicons/solid/plus", class: component.style(:icon)) %>
18
18
  <% end %>
19
19
  </div>
20
20
 
21
- <p class="text-sm text-gray-500" data-upload-target="filename">
21
+ <p class="<%= component.style(:filename) %>" data-upload-target="filename">
22
22
  <% if form.object.send(method).attached? %>
23
23
  <%= form.object.send(method).filename %>
24
24
  <% else %>
@@ -28,7 +28,7 @@
28
28
  </div>
29
29
 
30
30
  <%= form.file_field method,
31
- class: "hidden",
31
+ class: component.style(:file_input),
32
32
  data: {
33
33
  upload_target: "input",
34
34
  action: "change->upload#updatePreview"
@@ -39,7 +39,7 @@
39
39
 
40
40
  <button type="button"
41
41
  data-action="upload#clear"
42
- class="absolute top-2 right-2 bg-red-100 text-red-700 px-2 py-1 text-xs rounded hover:bg-red-200">
42
+ class="<%= component.style(:clear_button) %>">
43
43
  Clear
44
44
  </button>
45
45
  </div>
data/config/importmap.rb CHANGED
@@ -4,4 +4,4 @@ pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
4
4
  pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
5
5
 
6
6
  pin "okonomi_ui_kit", to: "okonomi_ui_kit/application.js", preload: true
7
- pin_all_from OkonomiUiKit::Engine.root.join("app/javascript/okonomi_ui_kit/controllers"), under: "controllers", to: "okonomi_ui_kit/controllers"
7
+ pin_all_from OkonomiUiKit::Engine.root.join("app/javascript/okonomi_ui_kit/controllers"), under: "controllers", to: "okonomi_ui_kit/controllers"
@@ -22,9 +22,6 @@ module OkonomiUiKit
22
22
  ActiveSupport.on_load(:action_view) do
23
23
  include OkonomiUiKit::ApplicationHelper
24
24
  include OkonomiUiKit::AttributeSectionHelper
25
- include OkonomiUiKit::BreadcrumbsHelper
26
- include OkonomiUiKit::IconHelper
27
- include OkonomiUiKit::NavigationHelper
28
25
  include OkonomiUiKit::UiHelper
29
26
 
30
27
  ActionView::Base.field_error_proc = ->(html_tag, _instance) { html_tag.html_safe }
@@ -1,3 +1,3 @@
1
1
  module OkonomiUiKit
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.9"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: okonomi_ui_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Okonomi GmbH
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-08-01 00:00:00.000000000 Z
11
+ date: 2025-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -1357,23 +1357,50 @@ files:
1357
1357
  - app/controllers/okonomi_ui_kit/application_controller.rb
1358
1358
  - app/helpers/okonomi_ui_kit/application_helper.rb
1359
1359
  - app/helpers/okonomi_ui_kit/attribute_section_helper.rb
1360
- - app/helpers/okonomi_ui_kit/breadcrumbs_helper.rb
1361
1360
  - app/helpers/okonomi_ui_kit/component.rb
1361
+ - app/helpers/okonomi_ui_kit/components.rb
1362
1362
  - app/helpers/okonomi_ui_kit/components/alert.rb
1363
1363
  - app/helpers/okonomi_ui_kit/components/badge.rb
1364
+ - app/helpers/okonomi_ui_kit/components/breadcrumbs.rb
1365
+ - app/helpers/okonomi_ui_kit/components/button_base.rb
1366
+ - app/helpers/okonomi_ui_kit/components/button_tag.rb
1364
1367
  - app/helpers/okonomi_ui_kit/components/button_to.rb
1365
1368
  - app/helpers/okonomi_ui_kit/components/code.rb
1369
+ - app/helpers/okonomi_ui_kit/components/confirmation_modal.rb
1370
+ - app/helpers/okonomi_ui_kit/components/forms.rb
1371
+ - app/helpers/okonomi_ui_kit/components/forms/check_box_with_label.rb
1372
+ - app/helpers/okonomi_ui_kit/components/forms/collection_select.rb
1373
+ - app/helpers/okonomi_ui_kit/components/forms/date_field.rb
1374
+ - app/helpers/okonomi_ui_kit/components/forms/datetime_local_field.rb
1375
+ - app/helpers/okonomi_ui_kit/components/forms/email_field.rb
1376
+ - app/helpers/okonomi_ui_kit/components/forms/field.rb
1377
+ - app/helpers/okonomi_ui_kit/components/forms/field_set.rb
1378
+ - app/helpers/okonomi_ui_kit/components/forms/input_base.rb
1379
+ - app/helpers/okonomi_ui_kit/components/forms/label.rb
1380
+ - app/helpers/okonomi_ui_kit/components/forms/multi_select.rb
1381
+ - app/helpers/okonomi_ui_kit/components/forms/number_field.rb
1382
+ - app/helpers/okonomi_ui_kit/components/forms/password_field.rb
1383
+ - app/helpers/okonomi_ui_kit/components/forms/search_field.rb
1384
+ - app/helpers/okonomi_ui_kit/components/forms/select.rb
1385
+ - app/helpers/okonomi_ui_kit/components/forms/show_if.rb
1386
+ - app/helpers/okonomi_ui_kit/components/forms/telephone_field.rb
1387
+ - app/helpers/okonomi_ui_kit/components/forms/text_area.rb
1388
+ - app/helpers/okonomi_ui_kit/components/forms/text_field.rb
1389
+ - app/helpers/okonomi_ui_kit/components/forms/time_field.rb
1390
+ - app/helpers/okonomi_ui_kit/components/forms/upload_field.rb
1391
+ - app/helpers/okonomi_ui_kit/components/forms/url_field.rb
1392
+ - app/helpers/okonomi_ui_kit/components/icon.rb
1366
1393
  - app/helpers/okonomi_ui_kit/components/link_to.rb
1394
+ - app/helpers/okonomi_ui_kit/components/navigation.rb
1367
1395
  - app/helpers/okonomi_ui_kit/components/page.rb
1368
1396
  - app/helpers/okonomi_ui_kit/components/table.rb
1369
1397
  - app/helpers/okonomi_ui_kit/components/typography.rb
1370
1398
  - app/helpers/okonomi_ui_kit/config.rb
1399
+ - app/helpers/okonomi_ui_kit/configs.rb
1371
1400
  - app/helpers/okonomi_ui_kit/form_builder.rb
1372
- - app/helpers/okonomi_ui_kit/icon_helper.rb
1373
- - app/helpers/okonomi_ui_kit/navigation_helper.rb
1401
+ - app/helpers/okonomi_ui_kit/form_component.rb
1374
1402
  - app/helpers/okonomi_ui_kit/svg_icons.rb
1375
- - app/helpers/okonomi_ui_kit/theme.rb
1376
- - app/helpers/okonomi_ui_kit/theme_helper.rb
1403
+ - app/helpers/okonomi_ui_kit/t_w_merge.rb
1377
1404
  - app/helpers/okonomi_ui_kit/ui_helper.rb
1378
1405
  - app/javascript/okonomi_ui_kit/application.js
1379
1406
  - app/javascript/okonomi_ui_kit/controllers/dropdown_controller.js
@@ -1389,20 +1416,24 @@ files:
1389
1416
  - app/views/layouts/okonomi_ui_kit/application.html.erb
1390
1417
  - app/views/okonomi/attribute_sections/_section.html.erb
1391
1418
  - app/views/okonomi/components/alert/_alert.html.erb
1419
+ - app/views/okonomi/components/breadcrumbs/_breadcrumbs.html.erb
1392
1420
  - app/views/okonomi/components/code/_code.html.erb
1421
+ - app/views/okonomi/components/confirmation_modal/_confirmation_modal.html.erb
1422
+ - app/views/okonomi/components/forms/check_box_with_label/_check_box_with_label.html.erb
1423
+ - app/views/okonomi/components/forms/field/_field.html.erb
1424
+ - app/views/okonomi/components/forms/field_set/_field_set.html.erb
1425
+ - app/views/okonomi/components/forms/upload_field/_upload_field.html.erb
1426
+ - app/views/okonomi/components/icon/_icon.html.erb
1427
+ - app/views/okonomi/components/navigation/_link.html.erb
1428
+ - app/views/okonomi/components/navigation/_navigation.html.erb
1393
1429
  - app/views/okonomi/components/page/_page.html.erb
1394
1430
  - app/views/okonomi/components/table/_table.html.erb
1395
1431
  - app/views/okonomi/components/typography/_typography.html.erb
1396
1432
  - app/views/okonomi/forms/tailwind/_checkbox_label.html.erb
1397
1433
  - app/views/okonomi/forms/tailwind/_field.html.erb
1398
- - app/views/okonomi/forms/tailwind/_field_set.html.erb
1399
1434
  - app/views/okonomi/forms/tailwind/_multi_select.html.erb
1400
1435
  - app/views/okonomi/forms/tailwind/_radio_button.html.erb
1401
1436
  - app/views/okonomi/forms/tailwind/_upload_field.html.erb
1402
- - app/views/okonomi/modals/_confirmation_modal.html.erb
1403
- - app/views/okonomi/navigation/_link.html.erb
1404
- - app/views/okonomi/navigation/_menu.html.erb
1405
- - app/views/okonomi/navigation/_navbar.html.erb
1406
1437
  - app/views/okonomi/page_builder/_page.html.erb
1407
1438
  - app/views/okonomi/tables/_table.html.erb
1408
1439
  - config/importmap.rb
@@ -1,60 +0,0 @@
1
- module OkonomiUiKit
2
- module BreadcrumbsHelper
3
- def breadcrumbs
4
- content_tag(:nav, class: "flex", aria: { label: "Breadcrumb" }) do
5
- content_tag(:ol, class: "flex items-center space-x-4", role: "list") do
6
- builder = BreadcrumbBuilder.new(self)
7
- yield builder
8
- safe_join(builder.items)
9
- end
10
- end
11
- end
12
-
13
- class BreadcrumbBuilder
14
- attr_reader :items
15
-
16
- def initialize(view)
17
- @view = view
18
- @items = []
19
- @first = true
20
- end
21
-
22
- def link(label, url, icon: nil, current: false)
23
- if @first
24
- @items << @view.content_tag(:li) do
25
- @view.content_tag(:div) do
26
- if icon.present?
27
- @view.link_to(url, class: "text-gray-400 hover:text-gray-500") do
28
- @view.svg_icon(icon, class: "size-5") + @view.content_tag(:span, label, class: "sr-only")
29
- end
30
- else
31
- @view.content_tag(:div, class: "flex items-center") do
32
- @view.link_to(label, url, class: breadcrumb_classes(current, first: true), aria: (current ? { current: "page" } : {}))
33
- end
34
- end
35
- end
36
- end
37
- @first = false
38
- else
39
- @items << @view.content_tag(:li) do
40
- @view.content_tag(:div, class: "flex items-center") do
41
- chevron + @view.link_to(label, url, class: breadcrumb_classes(current), aria: (current ? { current: "page" } : {}))
42
- end
43
- end
44
- end
45
- end
46
-
47
- private
48
-
49
- def chevron
50
- @view.svg_icon("heroicons/solid/chevron-right", class: "size-5 shrink-0 text-gray-400")
51
- end
52
-
53
- def breadcrumb_classes(current, first: false)
54
- base = "text-sm font-medium"
55
- base = "#{base} ml-4" unless first
56
- current ? "#{base} text-gray-500" : "#{base} text-gray-500 hover:text-gray-700"
57
- end
58
- end
59
- end
60
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module OkonomiUiKit
4
- module IconHelper
5
- def icon_tag(icon, variant = :outlined, options = {})
6
- if icon.is_a?(Icon)
7
- doc = Nokogiri::HTML::DocumentFragment.parse icon.send(:"content_#{variant}")
8
- svg = doc.at_css 'svg'
9
-
10
- svg['class'] = options[:class] if options[:class].present?
11
- svg['style'] = options[:style] if options[:style].present?
12
-
13
- svg['width'] = options[:width] if options[:width].present?
14
- svg['height'] = options[:height] if options[:height].present?
15
-
16
- raw doc
17
- else
18
- svg_icon(icon, options)
19
- end
20
- end
21
-
22
- def svg_icon(name, options = {})
23
- if OkonomiUiKit::SvgIcons.exist?(name)
24
- doc = Nokogiri::HTML::DocumentFragment.parse OkonomiUiKit::SvgIcons.read(name)
25
- svg = doc.at_css 'svg'
26
-
27
- svg['class'] = options[:class] if options[:class].present?
28
- svg['style'] = options[:style] if options[:style].present?
29
-
30
- svg['width'] = options[:width] if options[:width].present?
31
- svg['height'] = options[:height] if options[:height].present?
32
- else
33
- doc = "<!-- SVG #{name} not found -->"
34
- end
35
-
36
- raw doc
37
- end
38
- end
39
- end