nitro_kit 0.6.0 → 0.7.0

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/app/components/nitro_kit/accordion.rb +36 -30
  3. data/app/components/nitro_kit/alert.rb +10 -6
  4. data/app/components/nitro_kit/avatar_stack.rb +23 -0
  5. data/app/components/nitro_kit/button.rb +6 -0
  6. data/app/components/nitro_kit/card.rb +25 -15
  7. data/app/components/nitro_kit/checkbox.rb +2 -0
  8. data/app/components/nitro_kit/checkbox_group.rb +10 -6
  9. data/app/components/nitro_kit/component.rb +16 -19
  10. data/app/components/nitro_kit/dialog.rb +63 -53
  11. data/app/components/nitro_kit/dropdown.rb +76 -59
  12. data/app/components/nitro_kit/field.rb +82 -65
  13. data/app/components/nitro_kit/fieldset.rb +14 -7
  14. data/app/components/nitro_kit/form_builder.rb +13 -10
  15. data/app/components/nitro_kit/input.rb +1 -1
  16. data/app/components/nitro_kit/pagination.rb +45 -37
  17. data/app/components/nitro_kit/radio_button.rb +1 -1
  18. data/app/components/nitro_kit/radio_button_group.rb +22 -18
  19. data/app/components/nitro_kit/select.rb +9 -7
  20. data/app/components/nitro_kit/table.rb +22 -12
  21. data/app/components/nitro_kit/tabs.rb +49 -43
  22. data/app/components/nitro_kit/textarea.rb +6 -2
  23. data/app/components/nitro_kit/toast.rb +9 -5
  24. data/app/components/nitro_kit/tooltip.rb +14 -12
  25. data/app/helpers/nitro_kit/accordion_helper.rb +1 -1
  26. data/app/helpers/nitro_kit/alert_helper.rb +1 -1
  27. data/app/helpers/nitro_kit/avatar_helper.rb +5 -1
  28. data/app/helpers/nitro_kit/badge_helper.rb +1 -1
  29. data/app/helpers/nitro_kit/button_group_helper.rb +1 -1
  30. data/app/helpers/nitro_kit/button_helper.rb +3 -3
  31. data/app/helpers/nitro_kit/card_helper.rb +1 -1
  32. data/app/helpers/nitro_kit/checkbox_helper.rb +3 -3
  33. data/app/helpers/nitro_kit/combobox_helper.rb +1 -1
  34. data/app/helpers/nitro_kit/datepicker_helper.rb +1 -1
  35. data/app/helpers/nitro_kit/dialog_helper.rb +1 -1
  36. data/app/helpers/nitro_kit/dropdown_helper.rb +1 -1
  37. data/app/helpers/nitro_kit/field_group_helper.rb +1 -1
  38. data/app/helpers/nitro_kit/field_helper.rb +1 -1
  39. data/app/helpers/nitro_kit/fieldset_helper.rb +1 -1
  40. data/app/helpers/nitro_kit/icon_helper.rb +1 -1
  41. data/app/helpers/nitro_kit/input_helper.rb +1 -1
  42. data/app/helpers/nitro_kit/label_helper.rb +1 -1
  43. data/app/helpers/nitro_kit/pagination_helper.rb +1 -1
  44. data/app/helpers/nitro_kit/radio_button_helper.rb +2 -2
  45. data/app/helpers/nitro_kit/select_helper.rb +1 -1
  46. data/app/helpers/nitro_kit/switch_helper.rb +1 -1
  47. data/app/helpers/nitro_kit/table_helper.rb +1 -1
  48. data/app/helpers/nitro_kit/tabs_helper.rb +1 -1
  49. data/app/helpers/nitro_kit/textarea_helper.rb +1 -1
  50. data/app/helpers/nitro_kit/toast_helper.rb +2 -2
  51. data/app/helpers/nitro_kit/tooltip_helper.rb +1 -1
  52. data/lib/nitro_kit/version.rb +1 -1
  53. metadata +4 -3
@@ -15,7 +15,7 @@ module NitroKit
15
15
  )
16
16
  @form = form
17
17
  @field_name = field_name.to_s
18
- @as = as.to_sym
18
+ @as = as.is_a?(String) ? as.to_sym : as
19
19
 
20
20
  @name = attrs[:name] || form&.field_name(field_name)
21
21
  @id = attrs[:id] || form&.field_id(field_name)
@@ -32,7 +32,7 @@ module NitroKit
32
32
 
33
33
  super(
34
34
  wrapper,
35
- data: {as: @as},
35
+ data: {as: @as.to_s},
36
36
  class: base_class
37
37
  )
38
38
  end
@@ -60,76 +60,86 @@ module NitroKit
60
60
 
61
61
  alias :html_label :label
62
62
 
63
- builder_method def label(text = nil, **attrs)
64
- text ||= field_label
63
+ def label(text = nil, **attrs)
64
+ builder do
65
+ text ||= field_label
65
66
 
66
- return unless text
67
+ return unless text
67
68
 
68
- render(Label.new(**mattr(attrs, for: id, data: {slot: "label"}))) do
69
- text
69
+ render(Label.new(**mattr(attrs, for: id, data: {slot: "label"}))) do
70
+ text
71
+ end
70
72
  end
71
73
  end
72
74
 
73
- builder_method def description(text = nil, **attrs, &block)
74
- text ||= field_description
75
+ def description(text = nil, **attrs, &block)
76
+ builder do
77
+ text ||= field_description
75
78
 
76
- return unless text || block_given?
79
+ return unless text || block_given?
77
80
 
78
- div(**mattr(attrs, data: {slot: "description"}, class: description_class)) do
79
- text_or_block(text, &block)
81
+ div(**mattr(attrs, data: {slot: "description"}, class: description_class)) do
82
+ text_or_block(text, &block)
83
+ end
80
84
  end
81
85
  end
82
86
 
83
- builder_method def errors(error_messages = nil, **attrs)
84
- error_messages ||= field_error_messages
87
+ def errors(error_messages = nil, **attrs)
88
+ builder do
89
+ error_messages ||= field_error_messages
85
90
 
86
- return unless error_messages&.any?
91
+ return unless error_messages&.any?
87
92
 
88
- ul(**mattr(attrs, data: {slot: "error"}, class: error_class)) do |msg|
89
- error_messages.each do |msg|
90
- li { msg }
93
+ ul(**mattr(attrs, data: {slot: "error"}, class: error_class)) do |msg|
94
+ error_messages.each do |msg|
95
+ li { msg }
96
+ end
91
97
  end
92
98
  end
93
99
  end
94
100
 
95
- builder_method def control(**attrs)
96
- case as
97
- when :string
98
- input(**attrs)
99
- when
100
- :button,
101
- :color,
102
- :date,
103
- :datetime,
104
- :datetime_local,
105
- :email,
106
- :file,
107
- :hidden,
108
- :month,
109
- :number,
110
- :password,
111
- :range,
112
- :search,
113
- :tel,
114
- :text,
115
- :time,
116
- :url,
117
- :week
118
- input(type: as, **attrs)
119
- when :select
120
- select(**attrs)
121
- when :textarea
122
- textarea(**attrs)
123
- when :checkbox
124
- checkbox(**attrs)
125
- when :combobox
126
- combobox(**attrs)
127
- when :radio, :radio_button, :radio_group
128
- radio_group(**attrs)
129
- when :switch
130
- switch(**attrs)
131
- else
132
- raise ArgumentError, "Invalid field type `#{as}'"
101
+ def control(**attrs)
102
+ builder do
103
+ case as
104
+ when :string
105
+ input(**attrs)
106
+ when
107
+ :button,
108
+ :color,
109
+ :date,
110
+ :datetime,
111
+ :datetime_local,
112
+ :email,
113
+ :file,
114
+ :hidden,
115
+ :month,
116
+ :number,
117
+ :password,
118
+ :range,
119
+ :search,
120
+ :tel,
121
+ :text,
122
+ :time,
123
+ :url,
124
+ :week
125
+ input(type: as, **attrs)
126
+ when :select
127
+ select(**attrs)
128
+ when :textarea
129
+ textarea(**attrs)
130
+ when :checkbox
131
+ checkbox(**attrs)
132
+ when :combobox
133
+ combobox(**attrs)
134
+ when :radio, :radio_button, :radio_group
135
+ radio_group(**attrs)
136
+ when :switch
137
+ switch(**attrs)
138
+ when Class
139
+ component(**attrs)
140
+ else
141
+ raise ArgumentError, "Invalid field type `#{as}'"
142
+ end
133
143
  end
134
144
  end
135
145
 
@@ -201,20 +211,16 @@ module NitroKit
201
211
  end
202
212
 
203
213
  def checkbox(**attrs)
204
- render(
205
- Checkbox.new(
206
- checked: checked?,
207
- **control_attrs(
208
- **field_attrs,
209
- **attrs
210
- )
211
- )
212
- )
214
+ control_attrs(**field_attrs, **attrs).tap do |attrs|
215
+ input(type: "hidden", **attrs, id: nil, value: "0")
216
+ render(Checkbox.new(checked: checked?, **attrs, value: "1"))
217
+ end
213
218
  end
214
219
 
215
220
  def combobox(**attrs)
216
221
  render(
217
222
  Combobox.new(
223
+ options: @options,
218
224
  **control_attrs(
219
225
  **field_attrs,
220
226
  **attrs
@@ -247,6 +253,17 @@ module NitroKit
247
253
  )
248
254
  end
249
255
 
256
+ def component(**attrs)
257
+ render(
258
+ as.new(
259
+ **control_attrs(
260
+ **field_attrs,
261
+ **attrs
262
+ )
263
+ )
264
+ )
265
+ end
266
+
250
267
  private
251
268
 
252
269
  def base_class
@@ -22,22 +22,29 @@ module NitroKit
22
22
 
23
23
  alias :html_legend :legend
24
24
 
25
- builder_method def legend(text = nil, **attrs, &block)
26
- html_legend(**mattr(attrs, class: legend_class)) do
27
- text_or_block(text, &block)
25
+ def legend(text = nil, **attrs, &block)
26
+ builder do
27
+ html_legend(**mattr(attrs, class: legend_class)) do
28
+ text_or_block(text, &block)
29
+ end
28
30
  end
29
31
  end
30
32
 
31
- builder_method def description(text = nil, **attrs, &block)
32
- div(**mattr(attrs, class: description_class, data: {slot: "text"})) do
33
- text_or_block(text, &block)
33
+ def description(text = nil, **attrs, &block)
34
+ builder do
35
+ div(**mattr(attrs, class: description_class, data: {slot: "text"})) do
36
+ text_or_block(text, &block)
37
+ end
34
38
  end
35
39
  end
36
40
 
37
41
  private
38
42
 
39
43
  def base_class
40
- "[&>*+[data-slot=control]]:mt-6 [&>*+[data-slot=text]]:mt-1"
44
+ [
45
+ "[&>*+[data-slot=control]]:mt-6 [&>*+[data-slot=text]]:mt-1",
46
+ "[&+&]:mt-8"
47
+ ]
41
48
  end
42
49
 
43
50
  def legend_class
@@ -57,6 +57,10 @@ module NitroKit
57
57
  end
58
58
  end
59
59
 
60
+ def radio_button(method, value = "1", **attrs)
61
+ field(method, as: :radio_button, label: false, value:, **attrs)
62
+ end
63
+
60
64
  def checkbox(method, checked_value = "1", unchecked_value = "0", *args, include_hidden: true, **attrs)
61
65
  if include_hidden
62
66
  @template.concat(hidden_field(method, value: unchecked_value))
@@ -68,20 +72,19 @@ module NitroKit
68
72
  # Buttons
69
73
 
70
74
  def submit(value = nil, **attrs, &block)
71
- if value
72
- content = value
73
- elsif block_given?
74
- content = @template.capture(&block)
75
- else
76
- content = I18n.t("save_changes")
75
+ if value.nil? && !block_given?
76
+ value = "Save changes"
77
77
  end
78
78
 
79
- @template.render(NitroKit::Button.new(variant: :primary, type: :submit, **attrs)) { content }
79
+ @template.render(NitroKit::Button.new(value, variant: :primary, type: :submit, **attrs), &block)
80
80
  end
81
81
 
82
- def button(value = "Save changes", **attrs)
83
- content = value || @template.capture(&block)
84
- @template.render(NitroKit::Button.new(**attrs)) { content }
82
+ def button(value = nil, **attrs, &block)
83
+ if value.nil? && !block_given?
84
+ value = "Save changes"
85
+ end
86
+
87
+ @template.render(NitroKit::Button.new(value, **attrs), &block)
85
88
  end
86
89
  end
87
90
  end
@@ -19,7 +19,7 @@ module NitroKit
19
19
  [
20
20
  "block rounded-md border bg-background border-border text-base px-3 py-2 h-10",
21
21
  # Focus
22
- "focus:outline-none ring-ring ring-offset-2 ring-offset-background focus-visible:ring-2"
22
+ "focus-visible:outline-none ring-ring ring-offset-2 ring-offset-background focus-visible:ring-2"
23
23
  ]
24
24
  end
25
25
  end
@@ -16,55 +16,63 @@ module NitroKit
16
16
  end
17
17
  end
18
18
 
19
- builder_method def prev(text = nil, **attrs, &block)
20
- page_link(**mattr(attrs, aria: {label: "Previous page"})) do
21
- if text || block_given?
22
- text_or_block(text, &block)
23
- else
24
- render(Icon.new("arrow-left"))
25
- plain("Previous")
19
+ def prev(text = nil, **attrs, &block)
20
+ builder do
21
+ page_link(**mattr(attrs, aria: {label: "Previous page"})) do
22
+ if text || block_given?
23
+ text_or_block(text, &block)
24
+ else
25
+ render(Icon.new("arrow-left"))
26
+ plain("Previous")
27
+ end
26
28
  end
27
29
  end
28
30
  end
29
31
 
30
- builder_method def next(text = nil, **attrs, &block)
31
- page_link(**mattr(attrs, aria: {label: "Next page"})) do
32
- if text || block_given?
33
- text_or_block(text, &block)
34
- else
35
- plain("Next")
36
- render(Icon.new("arrow-right"))
32
+ def next(text = nil, **attrs, &block)
33
+ builder do
34
+ page_link(**mattr(attrs, aria: {label: "Next page"})) do
35
+ if text || block_given?
36
+ text_or_block(text, &block)
37
+ else
38
+ plain("Next")
39
+ render(Icon.new("arrow-right"))
40
+ end
37
41
  end
38
42
  end
39
43
  end
40
44
 
41
- builder_method def page(text = nil, current: false, **attrs, &block)
42
- page_link(
43
- **mattr(
44
- attrs,
45
- aria: {
46
- current: current ? "page" : nil
47
- },
48
- disabled: current,
49
- class: [page_class, current && "bg-zinc-200/50 dark:bg-zinc-800/50"]
50
- )
51
- ) do
52
- text_or_block(text, &block)
45
+ def page(text = nil, current: false, **attrs, &block)
46
+ builder do
47
+ page_link(
48
+ **mattr(
49
+ attrs,
50
+ aria: {
51
+ current: current ? "page" : nil
52
+ },
53
+ disabled: current,
54
+ class: [page_class, current && "bg-zinc-200/50 dark:bg-zinc-800/50"]
55
+ )
56
+ ) do
57
+ text_or_block(text, &block)
58
+ end
53
59
  end
54
60
  end
55
61
 
56
- builder_method def ellipsis(**attrs)
57
- render(
58
- Button.new(
59
- **mattr(
60
- attrs,
61
- variant: :ghost,
62
- disabled: true,
63
- class: page_class
62
+ def ellipsis(**attrs)
63
+ builder do
64
+ render(
65
+ Button.new(
66
+ **mattr(
67
+ attrs,
68
+ variant: :ghost,
69
+ disabled: true,
70
+ class: page_class
71
+ )
64
72
  )
65
- )
66
- ) do
67
- "…"
73
+ ) do
74
+ "…"
75
+ end
68
76
  end
69
77
  end
70
78
 
@@ -68,7 +68,7 @@ module NitroKit
68
68
  when :md
69
69
  "[&>input]:size-5 [&>svg]:size-2.5"
70
70
  when :lg
71
- "[&>input]:size-7 [&>svg]:size-[calc(var(--spacing)*3+1px)]"
71
+ "[&>input]:size-7 [&>svg]:size-3.5"
72
72
  else
73
73
  raise ArgumentError, "Unknown size `#{size}'"
74
74
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module NitroKit
4
4
  class RadioButtonGroup < Component
5
- def initialize(options = nil, name: nil, value: nil, **attrs)
6
- @options = options
5
+ def initialize(options_arg = nil, options: [], name: nil, value: nil, **attrs)
6
+ @options = options_arg || options
7
7
 
8
8
  @name = name
9
9
  @group_value = value
@@ -27,26 +27,30 @@ module NitroKit
27
27
  end
28
28
  end
29
29
 
30
- builder_method def title(text = nil, **attrs, &block)
31
- render(Label.new(**attrs)) do
32
- text_or_block(text, &block)
30
+ def title(text = nil, **attrs, &block)
31
+ builder do
32
+ render(Label.new(**attrs)) do
33
+ text_or_block(text, &block)
34
+ end
33
35
  end
34
36
  end
35
37
 
36
- builder_method def item(text = nil, value_as_arg = nil, value: nil, **attrs, &block)
37
- value ||= value_as_arg
38
-
39
- render(
40
- RadioButton.new(
41
- **mattr(
42
- attrs,
43
- name: attrs.fetch(:name, name),
44
- value:,
45
- checked: group_value.presence == value
38
+ def item(text = nil, value_as_arg = nil, value: nil, **attrs, &block)
39
+ builder do
40
+ value ||= value_as_arg
41
+
42
+ render(
43
+ RadioButton.new(
44
+ **mattr(
45
+ attrs,
46
+ name: attrs.fetch(:name, name),
47
+ value:,
48
+ checked: group_value.presence == value
49
+ )
46
50
  )
47
- )
48
- ) do
49
- text_or_block(text, &block)
51
+ ) do
52
+ text_or_block(text, &block)
53
+ end
50
54
  end
51
55
  end
52
56
  end
@@ -30,14 +30,16 @@ module NitroKit
30
30
 
31
31
  alias :html_option :option
32
32
 
33
- builder_method def option(key_or_value = nil, value = nil, **attrs, &block)
34
- value ||= key_or_value
33
+ def option(key_or_value = nil, value = nil, **attrs, &block)
34
+ builder do
35
+ value ||= key_or_value
35
36
 
36
- html_option(value:, selected: @value == value.to_s, **attrs) do
37
- if block_given?
38
- yield
39
- else
40
- key_or_value
37
+ html_option(value:, selected: @value == value.to_s, **attrs) do
38
+ if block_given?
39
+ yield
40
+ else
41
+ key_or_value
42
+ end
41
43
  end
42
44
  end
43
45
  end
@@ -23,27 +23,37 @@ module NitroKit
23
23
  alias :html_th :th
24
24
  alias :html_td :td
25
25
 
26
- builder_method def thead(**attrs)
27
- html_thead(**attrs) { yield }
26
+ def thead(**attrs)
27
+ builder do
28
+ html_thead(**attrs) { yield }
29
+ end
28
30
  end
29
31
 
30
- builder_method def tbody(**attrs)
31
- html_tbody(**mattr(attrs, class: "[&_tr:last-child]:border-0")) { yield }
32
+ def tbody(**attrs)
33
+ builder do
34
+ html_tbody(**mattr(attrs, class: "[&_tr:last-child]:border-0")) { yield }
35
+ end
32
36
  end
33
37
 
34
- builder_method def tr(**attrs)
35
- html_tr(**mattr(attrs, class: "border-b")) { yield }
38
+ def tr(**attrs)
39
+ builder do
40
+ html_tr(**mattr(attrs, class: "border-b")) { yield }
41
+ end
36
42
  end
37
43
 
38
- builder_method def th(text = nil, align: :left, **attrs, &block)
39
- html_th(**mattr(attrs, class: [header_cell_classes, cell_classes, align_classes(align), "font-medium"])) do
40
- text_or_block(text, &block)
44
+ def th(text = nil, align: :left, **attrs, &block)
45
+ builder do
46
+ html_th(**mattr(attrs, class: [header_cell_classes, cell_classes, align_classes(align), "font-medium"])) do
47
+ text_or_block(text, &block)
48
+ end
41
49
  end
42
50
  end
43
51
 
44
- builder_method def td(text = nil, align: nil, **attrs, &block)
45
- html_td(**mattr(attrs, class: [cell_classes, align_classes(align)])) do
46
- text_or_block(text, &block)
52
+ def td(text = nil, align: nil, **attrs, &block)
53
+ builder do
54
+ html_td(**mattr(attrs, class: [cell_classes, align_classes(align)])) do
55
+ text_or_block(text, &block)
56
+ end
47
57
  end
48
58
  end
49
59
 
@@ -21,55 +21,61 @@ module NitroKit
21
21
  end
22
22
  end
23
23
 
24
- builder_method def tabs(**attrs)
25
- div(**mattr, role: "tabtabs", class: tabs_class) do
26
- yield
24
+ def tabs(**attrs)
25
+ builder do
26
+ div(**mattr, role: "tabtabs", class: tabs_class) do
27
+ yield
28
+ end
27
29
  end
28
30
  end
29
31
 
30
- builder_method def tab(key, text = nil, **attrs, &block)
31
- button(
32
- **mattr(
33
- attrs,
34
- aria: {
35
- selected: (default == key).to_s,
36
- controls: tab_id(key, :panel)
37
- },
38
- class: tab_class,
39
- data: {
40
- action: "nk--tabs#setActiveTab keydown.left->nk--tabs#prevTab keydown.right->nk--tabs#nextTab",
41
- key:,
42
- nk__tabs_key_param: key,
43
- nk__tabs_target: "tab"
44
- },
45
- id: tab_id(key, :tab),
46
- role: "tab",
47
- tabindex: default == key ? 0 : -1
48
- )
49
- ) do
50
- text_or_block(text, &block)
32
+ def tab(key, text = nil, **attrs, &block)
33
+ builder do
34
+ button(
35
+ **mattr(
36
+ attrs,
37
+ aria: {
38
+ selected: (default == key).to_s,
39
+ controls: tab_id(key, :panel)
40
+ },
41
+ class: tab_class,
42
+ data: {
43
+ action: "nk--tabs#setActiveTab keydown.left->nk--tabs#prevTab keydown.right->nk--tabs#nextTab",
44
+ key:,
45
+ nk__tabs_key_param: key,
46
+ nk__tabs_target: "tab"
47
+ },
48
+ id: tab_id(key, :tab),
49
+ role: "tab",
50
+ tabindex: default == key ? 0 : -1
51
+ )
52
+ ) do
53
+ text_or_block(text, &block)
54
+ end
51
55
  end
52
56
  end
53
57
 
54
- builder_method def panel(key, **attrs)
55
- div(
56
- **mattr(
57
- attrs,
58
- aria: {
59
- hidden: (default != key).to_s,
60
- labelledby: tab_id(key, :tab)
61
- },
62
- class: panel_class,
63
- data: {
64
- key:,
65
- nk__tabs_target: "panel"
66
- },
67
- id: tab_id(key, :panel),
68
- name: key,
69
- role: "tabpanel"
70
- )
71
- ) do
72
- yield
58
+ def panel(key, **attrs)
59
+ builder do
60
+ div(
61
+ **mattr(
62
+ attrs,
63
+ aria: {
64
+ hidden: (default != key).to_s,
65
+ labelledby: tab_id(key, :tab)
66
+ },
67
+ class: panel_class,
68
+ data: {
69
+ key:,
70
+ nk__tabs_target: "panel"
71
+ },
72
+ id: tab_id(key, :panel),
73
+ name: key,
74
+ role: "tabpanel"
75
+ )
76
+ ) do
77
+ yield
78
+ end
73
79
  end
74
80
  end
75
81
 
@@ -2,15 +2,19 @@
2
2
 
3
3
  module NitroKit
4
4
  class Textarea < Component
5
- def initialize(**attrs)
5
+ def initialize(value: nil, **attrs)
6
+ @value = value
7
+
6
8
  super(
7
9
  attrs,
8
10
  class: default_class
9
11
  )
10
12
  end
11
13
 
14
+ attr_reader :value
15
+
12
16
  def view_template
13
- textarea(**attrs)
17
+ textarea(**attrs) { plain(value) }
14
18
  end
15
19
 
16
20
  private