okonomi_ui_kit 0.1.9 → 0.1.11

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.
@@ -0,0 +1,145 @@
1
+ module OkonomiUiKit
2
+ module Components
3
+ class PageSection < OkonomiUiKit::Component
4
+ def render(options = {}, &block)
5
+ options = options.with_indifferent_access
6
+ title = options.delete(:title)
7
+
8
+ classes = tw_merge(
9
+ style(:root),
10
+ options.delete(:class)
11
+ )
12
+
13
+ builder = SectionBuilder.new(view, self)
14
+ builder.title(title) if title
15
+
16
+ view.render(template_path, builder: builder, options: options.merge(class: classes), &block)
17
+ end
18
+
19
+ register_styles :default do
20
+ {
21
+ root: "overflow-hidden bg-white",
22
+ header: "py-6",
23
+ header_with_actions: "flex w-full justify-between items-start",
24
+ title: "text-base/7 font-semibold text-gray-900",
25
+ subtitle: "mt-1 max-w-2xl text-sm/6 text-gray-500",
26
+ actions: "mt-4 flex md:ml-4 md:mt-0",
27
+ attribute_list: "divide-y divide-gray-100",
28
+ attribute_row: "py-6 sm:grid sm:grid-cols-3 sm:gap-4",
29
+ attribute_label: "text-sm font-medium text-gray-900",
30
+ attribute_value: "mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0"
31
+ }
32
+ end
33
+ end
34
+
35
+ class SectionBuilder
36
+ include ActionView::Helpers::TagHelper
37
+ include ActionView::Helpers::CaptureHelper
38
+
39
+ def initialize(template, component)
40
+ @template = template
41
+ @component = component
42
+ @title_content = nil
43
+ @subtitle_content = nil
44
+ @actions_content = nil
45
+ @body_content = nil
46
+ @attributes = []
47
+ end
48
+
49
+ def title(text, **options)
50
+ @title_content = tag.h3(text, class: @component.style(:title))
51
+ end
52
+
53
+ def subtitle(text, **options)
54
+ @subtitle_content = tag.p(text, class: @component.style(:subtitle))
55
+ end
56
+
57
+ def actions(&block)
58
+ @actions_content = tag.div(class: @component.style(:actions)) do
59
+ capture(&block) if block_given?
60
+ end
61
+ end
62
+
63
+ def body(&block)
64
+ if block_given?
65
+ # Capture the content first to see if attributes were used
66
+ content = capture { yield(self) }
67
+
68
+ @body_content = if @attributes.any?
69
+ # If attributes were added, wrap them in dl
70
+ tag.div do
71
+ tag.dl(class: @component.style(:attribute_list)) do
72
+ @template.safe_join(@attributes)
73
+ end
74
+ end
75
+ else
76
+ # Otherwise, just return the captured content
77
+ tag.div do
78
+ content
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def attribute(label, value = nil, **options, &block)
85
+ content = if block_given?
86
+ capture(&block)
87
+ elsif value.respond_to?(:call)
88
+ value.call
89
+ else
90
+ value
91
+ end
92
+
93
+ attribute_html = tag.div(class: @component.style(:attribute_row)) do
94
+ dt_content = tag.dt(label, class: @component.style(:attribute_label))
95
+ dd_content = tag.dd(content, class: @component.style(:attribute_value))
96
+
97
+ dt_content + dd_content
98
+ end
99
+
100
+ @attributes << attribute_html
101
+ end
102
+
103
+ def render_header
104
+ return nil unless @title_content || @subtitle_content || @actions_content
105
+
106
+ tag.div(class: @component.style(:header)) do
107
+ if @actions_content
108
+ tag.div(class: @component.style(:header_with_actions)) do
109
+ title_section = tag.div do
110
+ content_parts = []
111
+ content_parts << @title_content if @title_content
112
+ content_parts << @subtitle_content if @subtitle_content
113
+ @template.safe_join(content_parts.compact)
114
+ end
115
+
116
+ title_section + @actions_content
117
+ end
118
+ else
119
+ content_parts = []
120
+ content_parts << @title_content if @title_content
121
+ content_parts << @subtitle_content if @subtitle_content
122
+ @template.safe_join(content_parts.compact)
123
+ end
124
+ end
125
+ end
126
+
127
+ def render_content
128
+ content_parts = []
129
+ content_parts << render_header
130
+ content_parts << @body_content if @body_content
131
+ @template.safe_join(content_parts.compact)
132
+ end
133
+
134
+ private
135
+
136
+ def tag
137
+ @template.tag
138
+ end
139
+
140
+ def capture(*args, &block)
141
+ @template.capture(*args, &block)
142
+ end
143
+ end
144
+ end
145
+ end
@@ -76,6 +76,40 @@ module OkonomiUiKit
76
76
  [ /^items-(?:start|end|center|baseline|stretch)$/, :align_items ],
77
77
  [ /^justify-(?:start|end|center|between|around|evenly)$/, :justify_content ],
78
78
 
79
+ # Spacing - Padding
80
+ [ /^p(?:-(?:\d+|px|\[\S+\]))?$/, :padding_all ],
81
+ [ /^px(?:-(?:\d+|px|\[\S+\]))?$/, :padding_x ],
82
+ [ /^py(?:-(?:\d+|px|\[\S+\]))?$/, :padding_y ],
83
+ [ /^pl(?:-(?:\d+|px|\[\S+\]))?$/, :padding_left ],
84
+ [ /^pr(?:-(?:\d+|px|\[\S+\]))?$/, :padding_right ],
85
+ [ /^pt(?:-(?:\d+|px|\[\S+\]))?$/, :padding_top ],
86
+ [ /^pb(?:-(?:\d+|px|\[\S+\]))?$/, :padding_bottom ],
87
+
88
+ # Spacing - Margin (including negative margins)
89
+ [ /^-?m(?:-(?:\d+|px|auto|\[\S+\]))?$/, :margin_all ],
90
+ [ /^-?mx(?:-(?:\d+|px|auto|\[\S+\]))?$/, :margin_x ],
91
+ [ /^-?my(?:-(?:\d+|px|auto|\[\S+\]))?$/, :margin_y ],
92
+ [ /^-?ml(?:-(?:\d+|px|auto|\[\S+\]))?$/, :margin_left ],
93
+ [ /^-?mr(?:-(?:\d+|px|auto|\[\S+\]))?$/, :margin_right ],
94
+ [ /^-?mt(?:-(?:\d+|px|auto|\[\S+\]))?$/, :margin_top ],
95
+ [ /^-?mb(?:-(?:\d+|px|auto|\[\S+\]))?$/, :margin_bottom ],
96
+
97
+ # Gap
98
+ [ /^gap(?:-(?:\d+|px|\[\S+\]))?$/, :gap_all ],
99
+ [ /^gap-x(?:-(?:\d+|px|\[\S+\]))?$/, :gap_x ],
100
+ [ /^gap-y(?:-(?:\d+|px|\[\S+\]))?$/, :gap_y ],
101
+
102
+ # Space between children
103
+ [ /^-?space-x(?:-(?:\d+|px|reverse|\[\S+\]))?$/, :space_x ],
104
+ [ /^-?space-y(?:-(?:\d+|px|reverse|\[\S+\]))?$/, :space_y ],
105
+
106
+ # Ring
107
+ [ /^ring(?:-(?:\d+|inset|\[\S+\]))?$/, :ring_width ],
108
+ [ /^ring-opacity-(?:\d{1,3}|\[.+\])$/, :ring_opacity ],
109
+ [ /^ring-(?:inherit|current|transparent|black|white|[a-z]+-(?:\d{2,3}|950)|\[[^\]]+\])$/, :ring_color ],
110
+ [ /^ring-offset(?:-(?:\d+|\[\S+\]))?$/, :ring_offset_width ],
111
+ [ /^ring-offset-(?:inherit|current|transparent|black|white|[a-z]+-(?:\d{2,3}|950)|\[[^\]]+\])$/, :ring_offset_color ],
112
+
79
113
  # Borders
80
114
  [ /^(?:border|border-(?:\d+|\[\S+\]))$/, :border_width_overall ],
81
115
  [ /^border-[trblxy](?:-\d+|\[\S+\])?$/, :border_width_side ],
@@ -19,6 +19,12 @@ export default class extends Controller {
19
19
  this.menuTarget.classList.add("hidden")
20
20
  }
21
21
 
22
+ closeDeferred() {
23
+ setTimeout(() => {
24
+ this.close()
25
+ }, 50)
26
+ }
27
+
22
28
  closeOnClickOutside(event) {
23
29
  if (!this.element.contains(event.target)) {
24
30
  this.close()
@@ -0,0 +1,282 @@
1
+ <%
2
+ # Extract dropdown builder from block execution
3
+ yield(dropdown_builder)
4
+
5
+ primary = dropdown_builder.primary_item
6
+ menu_items = dropdown_builder.menu_items
7
+
8
+ # Check if there are any menu items beyond the primary
9
+ has_menu_items = menu_items.any? { |item| item != primary }
10
+
11
+ # For split buttons, we need to handle borders specially for outlined variant
12
+ is_outlined = base_button_classes.include?("border")
13
+ is_text_variant = !base_button_classes.include?("border") && !base_button_classes.include?("bg-")
14
+
15
+ # Build classes for the primary action
16
+ if is_text_variant
17
+ # Text variant: keep normal rounded corners
18
+ primary_classes = base_button_classes
19
+ .gsub(/px-2/, "px-2 pr-3") # Increase right padding
20
+ else
21
+ # Other variants: remove right border radius and handle borders
22
+ primary_classes = base_button_classes
23
+ .gsub(/rounded-md/, "rounded-l-md")
24
+ .gsub(/px-2/, "px-2 pr-3") # Increase right padding
25
+
26
+ # Add border-r-0 for outlined variant to remove double border
27
+ primary_classes += " border-r-0" if is_outlined
28
+ end
29
+
30
+ # Build classes for dropdown trigger
31
+ if is_text_variant
32
+ # Text variant: keep normal rounded corners and add spacing
33
+ trigger_classes = base_button_classes
34
+ .gsub(/px-\d+/, "px-2") + " ml-1"
35
+ else
36
+ # Other variants: remove left border radius and overlap
37
+ trigger_classes = base_button_classes
38
+ .gsub(/rounded-md/, "rounded-r-md")
39
+ .gsub(/px-\d+/, "px-2") + " -ml-px"
40
+ end
41
+ %>
42
+
43
+ <div <%= tag.attributes(options.merge(
44
+ class: ["relative inline-block", options[:class]].compact.join(" "),
45
+ data: (options[:data] || {}).merge(controller: "dropdown", action: "click@window->dropdown#closeOnClickOutside")
46
+ )) %>>
47
+ <% if primary && !has_menu_items %>
48
+ <%# Render only primary button when no menu items %>
49
+ <% if primary[:type] == :link %>
50
+ <%= link_to primary[:options], primary[:html_options].merge(
51
+ class: base_button_classes
52
+ ) do %>
53
+ <% if primary[:icon] %>
54
+ <%= ui.icon(primary[:icon], class: component.style(:primary, :icon)) %>
55
+ <% end %>
56
+ <% if primary[:block] %>
57
+ <%= capture(&primary[:block]) %>
58
+ <% else %>
59
+ <%= primary[:name] %>
60
+ <% end %>
61
+ <% end %>
62
+ <% elsif primary[:type] == :button %>
63
+ <%= button_to primary[:options], primary[:html_options].merge(
64
+ class: base_button_classes
65
+ ) do %>
66
+ <% if primary[:icon] %>
67
+ <%= ui.icon(primary[:icon], class: component.style(:primary, :icon)) %>
68
+ <% end %>
69
+ <% if primary[:block] %>
70
+ <%= capture(&primary[:block]) %>
71
+ <% else %>
72
+ <%= primary[:name] %>
73
+ <% end %>
74
+ <% end %>
75
+ <% elsif primary[:type] == :button_tag %>
76
+ <%= button_tag primary[:options].merge(
77
+ class: base_button_classes
78
+ ) do %>
79
+ <% if primary[:icon] %>
80
+ <%= ui.icon(primary[:icon], class: component.style(:primary, :icon)) %>
81
+ <% end %>
82
+ <% if primary[:block] %>
83
+ <%= capture(&primary[:block]) %>
84
+ <% else %>
85
+ <%= primary[:name] %>
86
+ <% end %>
87
+ <% end %>
88
+ <% end %>
89
+ <% elsif primary && has_menu_items %>
90
+ <div class="relative inline-flex">
91
+ <% if primary[:type] == :link %>
92
+ <% primary_options = primary[:html_options].dup %>
93
+ <%= link_to primary[:options], primary_options.merge(
94
+ class: primary_classes
95
+ ) do %>
96
+ <% if primary[:icon] %>
97
+ <%= ui.icon(primary[:icon], class: component.style(:primary, :icon)) %>
98
+ <% end %>
99
+ <% if primary[:block] %>
100
+ <%= capture(&primary[:block]) %>
101
+ <% else %>
102
+ <%= primary[:name] %>
103
+ <% end %>
104
+ <% end %>
105
+ <% elsif primary[:type] == :button %>
106
+ <% primary_options = primary[:html_options].dup %>
107
+ <%= button_to primary[:options], primary_options.merge(
108
+ class: primary_classes
109
+ ) do %>
110
+ <% if primary[:icon] %>
111
+ <%= ui.icon(primary[:icon], class: component.style(:primary, :icon)) %>
112
+ <% end %>
113
+ <% if primary[:block] %>
114
+ <%= capture(&primary[:block]) %>
115
+ <% else %>
116
+ <%= primary[:name] %>
117
+ <% end %>
118
+ <% end %>
119
+ <% elsif primary[:type] == :button_tag %>
120
+ <% primary_options = primary[:options].dup %>
121
+ <%= button_tag primary_options.merge(
122
+ class: primary_classes
123
+ ) do %>
124
+ <% if primary[:icon] %>
125
+ <%= ui.icon(primary[:icon], class: component.style(:primary, :icon)) %>
126
+ <% end %>
127
+ <% if primary[:block] %>
128
+ <%= capture(&primary[:block]) %>
129
+ <% else %>
130
+ <%= primary[:name] %>
131
+ <% end %>
132
+ <% end %>
133
+ <% end %>
134
+
135
+ <button type="button"
136
+ class="<%= trigger_classes %>"
137
+ data-action="click->dropdown#toggle"
138
+ aria-haspopup="true"
139
+ aria-expanded="false">
140
+ <span class="sr-only">Open options</span>
141
+ <%= ui.icon("heroicons/solid/chevron-down", class: component.style(:primary, :chevron)) %>
142
+ </button>
143
+ </div>
144
+ <% else %>
145
+ <button type="button"
146
+ class="<%= base_button_classes %>"
147
+ data-action="click->dropdown#toggle"
148
+ aria-haspopup="true"
149
+ aria-expanded="false">
150
+ Options
151
+ <%= ui.icon("heroicons/solid/chevron-down", class: "-mr-1 h-5 w-5") %>
152
+ </button>
153
+ <% end %>
154
+
155
+ <% if has_menu_items %>
156
+ <div class="<%= menu_classes %> hidden" data-dropdown-target="menu">
157
+ <div class="py-1" role="menu" aria-orientation="vertical">
158
+ <% # Check if any menu item has an icon to ensure consistent alignment %>
159
+ <% has_any_icon = menu_items.any? { |item| item != primary && item[:icon] && item[:type] != :divider } %>
160
+
161
+ <% menu_items.each do |item| %>
162
+ <% next if item == primary %> <%# Skip the primary item in the menu %>
163
+
164
+ <% if item[:type] == :divider %>
165
+ <div class="<%= component.style(:menu, :divider) %>" role="separator"></div>
166
+ <% elsif item[:type] == :link %>
167
+ <% link_options = item[:html_options].dup %>
168
+ <% icon_path = item[:icon] %>
169
+ <% link_class = [component.style(:menu, :item, :root), link_options.delete(:class)].compact.join(" ") %>
170
+
171
+ <% # Add deferred close action %>
172
+ <% link_options[:data] ||= {} %>
173
+ <% existing_action = link_options[:data][:action] || link_options.delete("data-action") %>
174
+ <% link_options[:data][:action] = [existing_action, "click->dropdown#closeDeferred"].compact.join(" ") %>
175
+
176
+ <%= link_to item[:options], link_options.merge(
177
+ class: link_class,
178
+ role: "menuitem"
179
+ ) do %>
180
+ <% if has_any_icon %>
181
+ <span class="<%= component.style(:menu, :item, :label) %>">
182
+ <% if icon_path %>
183
+ <%= ui.icon(icon_path, class: component.style(:menu, :item, :icon)) %>
184
+ <% else %>
185
+ <span class="<%= component.style(:menu, :item, :icon) %>"></span>
186
+ <% end %>
187
+ <% if item[:block] %>
188
+ <%= capture(&item[:block]) %>
189
+ <% else %>
190
+ <%= item[:name] %>
191
+ <% end %>
192
+ </span>
193
+ <% else %>
194
+ <% if item[:block] %>
195
+ <%= capture(&item[:block]) %>
196
+ <% else %>
197
+ <%= item[:name] %>
198
+ <% end %>
199
+ <% end %>
200
+ <% end %>
201
+ <% elsif item[:type] == :button %>
202
+ <% button_options = item[:html_options].dup %>
203
+ <% icon_path = item[:icon] %>
204
+ <% button_class = [component.style(:menu, :item, :root), button_options.delete(:class)].compact.join(" ") %>
205
+
206
+ <% # Add deferred close action %>
207
+ <% button_options[:data] ||= {} %>
208
+ <% existing_action = button_options[:data][:action] || button_options.delete("data-action") %>
209
+ <% button_options[:data][:action] = [existing_action, "click->dropdown#closeDeferred"].compact.join(" ") %>
210
+
211
+ <%= button_to item[:options], button_options.merge(
212
+ class: button_class,
213
+ role: "menuitem"
214
+ ) do %>
215
+ <% if has_any_icon %>
216
+ <span class="<%= component.style(:menu, :item, :label) %>">
217
+ <% if icon_path %>
218
+ <%= ui.icon(icon_path, class: component.style(:menu, :item, :icon)) %>
219
+ <% else %>
220
+ <span class="<%= component.style(:menu, :item, :icon) %>"></span>
221
+ <% end %>
222
+ <% if item[:block] %>
223
+ <%= capture(&item[:block]) %>
224
+ <% else %>
225
+ <%= item[:name] %>
226
+ <% end %>
227
+ </span>
228
+ <% else %>
229
+ <% if item[:block] %>
230
+ <%= capture(&item[:block]) %>
231
+ <% else %>
232
+ <%= item[:name] %>
233
+ <% end %>
234
+ <% end %>
235
+ <% end %>
236
+ <% elsif item[:type] == :button_tag %>
237
+ <% button_options = item[:options].dup %>
238
+ <% icon_path = item[:icon] %>
239
+ <% button_class = [component.style(:menu, :item, :root), button_options.delete(:class)].compact.join(" ") %>
240
+
241
+ <% # Add deferred close action %>
242
+ <% button_options[:data] ||= {} %>
243
+ <% existing_action = button_options[:data][:action] || button_options.delete("data-action") %>
244
+ <% button_options[:data][:action] = [existing_action, "click->dropdown#closeDeferred"].compact.join(" ") %>
245
+
246
+ <% # Handle onclick attribute if present %>
247
+ <% if button_options[:onclick] %>
248
+ <% original_onclick = button_options[:onclick] %>
249
+ <% button_options[:onclick] = "#{original_onclick}; setTimeout(() => { this.closest('[data-controller=\"dropdown\"]').querySelector('[data-dropdown-target=\"menu\"]').classList.add('hidden'); }, 50);" %>
250
+ <% end %>
251
+
252
+ <%= button_tag button_options.merge(
253
+ class: button_class,
254
+ role: "menuitem"
255
+ ) do %>
256
+ <% if has_any_icon %>
257
+ <span class="<%= component.style(:menu, :item, :label) %>">
258
+ <% if icon_path %>
259
+ <%= ui.icon(icon_path, class: component.style(:menu, :item, :icon)) %>
260
+ <% else %>
261
+ <span class="<%= component.style(:menu, :item, :icon) %>"></span>
262
+ <% end %>
263
+ <% if item[:block] %>
264
+ <%= capture(&item[:block]) %>
265
+ <% else %>
266
+ <%= item[:name] %>
267
+ <% end %>
268
+ </span>
269
+ <% else %>
270
+ <% if item[:block] %>
271
+ <%= capture(&item[:block]) %>
272
+ <% else %>
273
+ <%= item[:name] %>
274
+ <% end %>
275
+ <% end %>
276
+ <% end %>
277
+ <% end %>
278
+ <% end %>
279
+ </div>
280
+ </div>
281
+ <% end %>
282
+ </div>
@@ -1,3 +1,34 @@
1
- <%= render "okonomi/forms/tailwind/field", component: component, form: form, field_id: field_id, options: options do %>
2
- <%= yield %>
3
- <% end %>
1
+ <div class="<%= component.style(:wrapper) %>">
2
+ <div class="<%= component.style(:header) %>" x-data="{ open: false }">
3
+ <% if field_id %>
4
+ <%= form.label field_id, t("activerecord.attributes.#{form.object_name}.#{field_id}") %>
5
+ <% end %>
6
+ <% if options[:hint] %>
7
+ <div class="relative">
8
+ <div class="<%= component.style(:hint, :trigger) %>" @mouseover="open = true" @mouseover.away = "open = false">
9
+ Hilfe
10
+ </div>
11
+ <div x-show="open"
12
+ class="<%= component.style(:hint, :content) %>"
13
+ style="top: 32px; right: -10px; width: 200px; max-width: 400px; display: none;"
14
+ x-transition:enter="transition duration-200 transform ease-out"
15
+ x-transition:enter-start="scale-75"
16
+ x-transition:leave="transition duration-100 transform ease-in"
17
+ x-transition:leave-end="opacity-0 scale-90"
18
+ >
19
+ <%= options[:hint].is_a?(String) ? options[:hint] : t("activerecord.hints.#{form.object_name}.#{field_id}") %>
20
+ </div>
21
+ </div>
22
+ <% end %>
23
+ </div>
24
+ <div class="<%= component.style(:content) %>">
25
+ <div class="grid grid-cols-<%= options[:columns] || 1 %> gap-2 p-[1px]">
26
+ <%= yield %>
27
+ </div>
28
+ <% if field_id && form.object.errors.include?(field_id) %>
29
+ <div class="<%= component.style(:error) %>">
30
+ <%= form.object.errors[field_id].join(", ") %>
31
+ </div>
32
+ <% end %>
33
+ </div>
34
+ </div>
@@ -1,4 +1,4 @@
1
- <div class="flex flex-col gap-8 p-8 <%= options[:class] || '' %>">
1
+ <div class="<%= options[:class] %>">
2
2
  <% content = capture { yield(builder) } %>
3
3
  <%= builder.render_content %>
4
4
  <%= content if builder.render_content.blank? %>
@@ -0,0 +1,4 @@
1
+ <div class="<%= options[:class] %>">
2
+ <% yield(builder) %>
3
+ <%= builder.render %>
4
+ </div>
@@ -0,0 +1,4 @@
1
+ <div class="<%= options[:class] %>">
2
+ <% yield(builder) if block_given? %>
3
+ <%= builder.render_content %>
4
+ </div>
@@ -1,3 +1,3 @@
1
1
  module OkonomiUiKit
2
- VERSION = "0.1.9"
2
+ VERSION = "0.1.11"
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.9
4
+ version: 0.1.11
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-04 00:00:00.000000000 Z
11
+ date: 2025-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -1355,6 +1355,7 @@ files:
1355
1355
  - app/assets/stylesheets/okonomi_ui_kit/application.css
1356
1356
  - app/assets/stylesheets/okonomi_ui_kit/application.tailwind.css
1357
1357
  - app/controllers/okonomi_ui_kit/application_controller.rb
1358
+ - app/helpers/okonomi_ui_kit/CLAUDE.md
1358
1359
  - app/helpers/okonomi_ui_kit/application_helper.rb
1359
1360
  - app/helpers/okonomi_ui_kit/attribute_section_helper.rb
1360
1361
  - app/helpers/okonomi_ui_kit/component.rb
@@ -1367,6 +1368,7 @@ files:
1367
1368
  - app/helpers/okonomi_ui_kit/components/button_to.rb
1368
1369
  - app/helpers/okonomi_ui_kit/components/code.rb
1369
1370
  - app/helpers/okonomi_ui_kit/components/confirmation_modal.rb
1371
+ - app/helpers/okonomi_ui_kit/components/dropdown_button.rb
1370
1372
  - app/helpers/okonomi_ui_kit/components/forms.rb
1371
1373
  - app/helpers/okonomi_ui_kit/components/forms/check_box_with_label.rb
1372
1374
  - app/helpers/okonomi_ui_kit/components/forms/collection_select.rb
@@ -1393,6 +1395,8 @@ files:
1393
1395
  - app/helpers/okonomi_ui_kit/components/link_to.rb
1394
1396
  - app/helpers/okonomi_ui_kit/components/navigation.rb
1395
1397
  - app/helpers/okonomi_ui_kit/components/page.rb
1398
+ - app/helpers/okonomi_ui_kit/components/page_header.rb
1399
+ - app/helpers/okonomi_ui_kit/components/page_section.rb
1396
1400
  - app/helpers/okonomi_ui_kit/components/table.rb
1397
1401
  - app/helpers/okonomi_ui_kit/components/typography.rb
1398
1402
  - app/helpers/okonomi_ui_kit/config.rb
@@ -1419,6 +1423,7 @@ files:
1419
1423
  - app/views/okonomi/components/breadcrumbs/_breadcrumbs.html.erb
1420
1424
  - app/views/okonomi/components/code/_code.html.erb
1421
1425
  - app/views/okonomi/components/confirmation_modal/_confirmation_modal.html.erb
1426
+ - app/views/okonomi/components/dropdown_button/_dropdown_button.html.erb
1422
1427
  - app/views/okonomi/components/forms/check_box_with_label/_check_box_with_label.html.erb
1423
1428
  - app/views/okonomi/components/forms/field/_field.html.erb
1424
1429
  - app/views/okonomi/components/forms/field_set/_field_set.html.erb
@@ -1427,14 +1432,14 @@ files:
1427
1432
  - app/views/okonomi/components/navigation/_link.html.erb
1428
1433
  - app/views/okonomi/components/navigation/_navigation.html.erb
1429
1434
  - app/views/okonomi/components/page/_page.html.erb
1435
+ - app/views/okonomi/components/page_header/_page_header.html.erb
1436
+ - app/views/okonomi/components/page_section/_page_section.html.erb
1430
1437
  - app/views/okonomi/components/table/_table.html.erb
1431
1438
  - app/views/okonomi/components/typography/_typography.html.erb
1432
1439
  - app/views/okonomi/forms/tailwind/_checkbox_label.html.erb
1433
- - app/views/okonomi/forms/tailwind/_field.html.erb
1434
1440
  - app/views/okonomi/forms/tailwind/_multi_select.html.erb
1435
1441
  - app/views/okonomi/forms/tailwind/_radio_button.html.erb
1436
1442
  - app/views/okonomi/forms/tailwind/_upload_field.html.erb
1437
- - app/views/okonomi/page_builder/_page.html.erb
1438
1443
  - app/views/okonomi/tables/_table.html.erb
1439
1444
  - config/importmap.rb
1440
1445
  - config/routes.rb
@@ -1443,13 +1448,13 @@ files:
1443
1448
  - lib/okonomi_ui_kit/engine.rb
1444
1449
  - lib/okonomi_ui_kit/version.rb
1445
1450
  - lib/tasks/okonomi_ui_kit_tasks.rake
1446
- homepage: https://okonomi.gmbh
1451
+ homepage: https://github.com/andre-l-github/okonomi_ui_kit
1447
1452
  licenses:
1448
1453
  - MIT
1449
1454
  metadata:
1450
- homepage_uri: https://okonomi.gmbh
1451
- source_code_uri: https://okonomi.gmbh
1452
- changelog_uri: https://okonomi.gmbh
1455
+ homepage_uri: https://github.com/andre-l-github/okonomi_ui_kit
1456
+ source_code_uri: https://github.com/andre-l-github/okonomi_ui_kit
1457
+ changelog_uri: https://github.com/andre-l-github/okonomi_ui_kit
1453
1458
  post_install_message:
1454
1459
  rdoc_options: []
1455
1460
  require_paths:
@@ -1,34 +0,0 @@
1
- <div class="<%= component.style(:wrapper) %>">
2
- <div class="<%= component.style(:header) %>" x-data="{ open: false }">
3
- <% if field_id %>
4
- <%= form.label field_id, t("activerecord.attributes.#{form.object_name}.#{field_id}") %>
5
- <% end %>
6
- <% if options[:hint] %>
7
- <div class="relative">
8
- <div class="<%= component.style(:hint, :trigger) %>" @mouseover="open = true" @mouseover.away = "open = false">
9
- Hilfe
10
- </div>
11
- <div x-show="open"
12
- class="<%= component.style(:hint, :content) %>"
13
- style="top: 32px; right: -10px; width: 200px; max-width: 400px; display: none;"
14
- x-transition:enter="transition duration-200 transform ease-out"
15
- x-transition:enter-start="scale-75"
16
- x-transition:leave="transition duration-100 transform ease-in"
17
- x-transition:leave-end="opacity-0 scale-90"
18
- >
19
- <%= options[:hint].is_a?(String) ? options[:hint] : t("activerecord.hints.#{form.object_name}.#{field_id}") %>
20
- </div>
21
- </div>
22
- <% end %>
23
- </div>
24
- <div class="<%= component.style(:content) %>">
25
- <div class="grid grid-cols-<%= options[:columns] || 1 %> gap-2">
26
- <%= yield %>
27
- </div>
28
- <% if field_id && form.object.errors.include?(field_id) %>
29
- <div class="<%= component.style(:error) %>">
30
- <%= form.object.errors[field_id].join(", ") %>
31
- </div>
32
- <% end %>
33
- </div>
34
- </div>
@@ -1,3 +0,0 @@
1
- <div class="flex flex-col gap-8 p-8 <%= options[:class] || '' %>">
2
- <%= yield(builder) %>
3
- </div>