nitro_kit 0.2.0 → 0.3.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +6 -4
  4. data/app/components/nitro_kit/accordion.rb +68 -32
  5. data/app/components/nitro_kit/alert.rb +69 -0
  6. data/app/components/nitro_kit/avatar.rb +52 -0
  7. data/app/components/nitro_kit/badge.rb +46 -19
  8. data/app/components/nitro_kit/button.rb +99 -66
  9. data/app/components/nitro_kit/button_group.rb +18 -13
  10. data/app/components/nitro_kit/card.rb +49 -9
  11. data/app/components/nitro_kit/checkbox.rb +59 -41
  12. data/app/components/nitro_kit/checkbox_group.rb +38 -0
  13. data/app/components/nitro_kit/combobox.rb +138 -0
  14. data/app/components/nitro_kit/component.rb +45 -14
  15. data/app/components/nitro_kit/datepicker.rb +9 -0
  16. data/app/components/nitro_kit/dialog.rb +95 -0
  17. data/app/components/nitro_kit/dropdown.rb +112 -70
  18. data/app/components/nitro_kit/field.rb +221 -56
  19. data/app/components/nitro_kit/field_group.rb +12 -6
  20. data/app/components/nitro_kit/fieldset.rb +42 -7
  21. data/app/components/nitro_kit/form_builder.rb +45 -22
  22. data/app/components/nitro_kit/icon.rb +29 -8
  23. data/app/components/nitro_kit/input.rb +20 -10
  24. data/app/components/nitro_kit/label.rb +18 -5
  25. data/app/components/nitro_kit/pagination.rb +98 -0
  26. data/app/components/nitro_kit/radio_button.rb +28 -27
  27. data/app/components/nitro_kit/radio_button_group.rb +53 -0
  28. data/app/components/nitro_kit/select.rb +72 -0
  29. data/app/components/nitro_kit/switch.rb +49 -39
  30. data/app/components/nitro_kit/table.rb +56 -0
  31. data/app/components/nitro_kit/tabs.rb +98 -0
  32. data/app/components/nitro_kit/textarea.rb +26 -0
  33. data/app/components/nitro_kit/toast.rb +104 -0
  34. data/app/components/nitro_kit/tooltip.rb +53 -0
  35. data/app/helpers/nitro_kit/accordion_helper.rb +2 -0
  36. data/app/helpers/nitro_kit/alert_helper.rb +11 -0
  37. data/app/helpers/nitro_kit/avatar_helper.rb +9 -0
  38. data/app/helpers/nitro_kit/badge_helper.rb +3 -5
  39. data/app/helpers/nitro_kit/button_group_helper.rb +2 -0
  40. data/app/helpers/nitro_kit/button_helper.rb +37 -28
  41. data/app/helpers/nitro_kit/card_helper.rb +2 -0
  42. data/app/helpers/nitro_kit/checkbox_helper.rb +19 -16
  43. data/app/helpers/nitro_kit/combobox_helper.rb +9 -0
  44. data/app/helpers/nitro_kit/datepicker_helper.rb +9 -0
  45. data/app/helpers/nitro_kit/dialog_helper.rb +9 -0
  46. data/app/helpers/nitro_kit/dropdown_helper.rb +3 -1
  47. data/app/helpers/nitro_kit/field_group_helper.rb +9 -0
  48. data/app/helpers/nitro_kit/field_helper.rb +4 -2
  49. data/app/helpers/nitro_kit/fieldset_helper.rb +9 -0
  50. data/app/helpers/nitro_kit/form_helper.rb +13 -0
  51. data/app/helpers/nitro_kit/icon_helper.rb +3 -1
  52. data/app/helpers/nitro_kit/input_helper.rb +35 -0
  53. data/app/helpers/nitro_kit/label_helper.rb +12 -9
  54. data/app/helpers/nitro_kit/pagination_helper.rb +42 -0
  55. data/app/helpers/nitro_kit/radio_button_helper.rb +15 -12
  56. data/app/helpers/nitro_kit/select_helper.rb +24 -0
  57. data/app/helpers/nitro_kit/switch_helper.rb +4 -10
  58. data/app/helpers/nitro_kit/table_helper.rb +9 -0
  59. data/app/helpers/nitro_kit/tabs_helper.rb +9 -0
  60. data/app/helpers/nitro_kit/textarea_helper.rb +9 -0
  61. data/app/helpers/nitro_kit/toast_helper.rb +36 -0
  62. data/app/helpers/nitro_kit/tooltip_helper.rb +9 -0
  63. data/lib/generators/nitro_kit/add_generator.rb +38 -41
  64. data/lib/generators/nitro_kit/install_generator.rb +2 -1
  65. data/lib/nitro_kit/engine.rb +4 -0
  66. data/lib/nitro_kit/schema_builder.rb +90 -16
  67. data/lib/nitro_kit/version.rb +1 -1
  68. data/lib/nitro_kit.rb +39 -1
  69. data/lib/tasks/nitro_kit_tasks.rake +4 -0
  70. metadata +37 -10
  71. data/app/components/nitro_kit/radio_group.rb +0 -35
  72. data/app/helpers/application_helper.rb +0 -109
  73. data/lib/nitro_kit/railtie.rb +0 -8
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ class Tooltip < Component
5
+ def initialize(content: nil, placement: nil, **attrs)
6
+ @string_content = content
7
+ @placement = placement
8
+
9
+ super(
10
+ attrs,
11
+ data: {
12
+ action: "mouseover->nk--tooltip#open mouseout->nk--tooltip#close",
13
+ controller: "nk--tooltip",
14
+ nk__tooltip_placement_value: placement
15
+ }
16
+ )
17
+ end
18
+
19
+ attr_reader :placement, :string_content
20
+
21
+ def view_template
22
+ span(**attrs) do
23
+ content(string_content) if string_content
24
+ yield
25
+ end
26
+ end
27
+
28
+ def content(text = nil, **attrs, &block)
29
+ div(
30
+ **mattr(
31
+ attrs,
32
+ class: tooltip_class,
33
+ data: {
34
+ state: "closed",
35
+ nk__tooltip_target: "content"
36
+ }
37
+ )
38
+ ) do
39
+ text_or_block(text, &block)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def tooltip_class
46
+ [
47
+ "absolute z-50 overflow-hidden w-fit max-w-sm",
48
+ "px-3 py-1.5 text-sm bg-background rounded-md border shadow-sm",
49
+ "data-[state=closed]:hidden"
50
+ ]
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module AccordionHelper
3
5
  def nk_accordion(**attrs, &block)
@@ -0,0 +1,11 @@
1
+ module NitroKit
2
+ module AlertHelper
3
+ include Variants
4
+
5
+ def nk_alert(**attrs, &block)
6
+ render(Alert.new(**attrs), &block)
7
+ end
8
+
9
+ automatic_variants(Alert::VARIANTS, :nk_alert)
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module AvatarHelper
5
+ def nk_avatar(src = nil, **attrs, &block)
6
+ render(Avatar.new(src, **attrs), &block)
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module BadgeHelper
3
5
  include Variants
@@ -5,11 +7,7 @@ module NitroKit
5
7
  automatic_variants(Badge::VARIANTS, :nk_badge)
6
8
 
7
9
  def nk_badge(text = nil, **attrs, &block)
8
- content = text || capture(&block)
9
-
10
- render(NitroKit::Badge.new(**attrs)) do
11
- content
12
- end
10
+ render(NitroKit::Badge.new(text, **attrs), &block)
13
11
  end
14
12
  end
15
13
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module ButtonGroupHelper
3
5
  def nk_button_group(**attrs, &block)
@@ -1,40 +1,49 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module ButtonHelper
3
5
  include Variants
4
6
 
7
+ def nk_button(text = nil, **attrs, &block)
8
+ render(NitroKit::Button.new(text, **attrs), &block)
9
+ end
10
+
5
11
  automatic_variants(Button::VARIANTS, :nk_button)
6
12
 
7
- def nk_button(
8
- text_or_href = nil,
9
- href = nil,
10
- icon: nil,
11
- icon_right: nil,
12
- size: :base,
13
- type: :button,
14
- variant: :default,
15
- **attrs,
16
- &block
17
- )
18
- content = block_given? ? capture(&block) : text_or_href
19
- href = text_or_href if href.nil? && block_given?
20
-
21
- if href && !href.is_a?(String)
22
- href = url_for(href)
13
+ # Matches the API of UrlHelper#button_to
14
+ def nk_button_to(name = nil, url_for_options = nil, **attrs, &block)
15
+ url_for_options = name if block_given?
16
+
17
+ form_options = attrs.delete(:form) || {}
18
+ form_options.merge!(attrs.slice(:multipart, :data, :method, :authenticity_token, :remote, :enforce_utf8))
19
+
20
+ form_tag(url_for_options, form_options) do
21
+ nk_button(name, type: "submit", **attrs, &block)
23
22
  end
23
+ end
24
24
 
25
- render(
26
- NitroKit::Button.new(
27
- href:,
28
- icon:,
29
- icon_right:,
30
- size:,
31
- type:,
32
- variant:,
33
- **attrs
34
- )
35
- ) do
36
- content
25
+ automatic_variants(Button::VARIANTS, :nk_button_to)
26
+
27
+ # Matches the API of UrlHelper#link_to
28
+ def nk_button_link_to(*args, **attrs, &block)
29
+ case args.length
30
+ when 1
31
+ options, text = args
32
+ when 2
33
+ text, options = args
34
+ else
35
+ raise ArgumentError, "1..2 arguments expected, got #{args.length}"
37
36
  end
37
+
38
+ href = attrs[:href] || url_target(text, options)
39
+
40
+ render(NitroKit::Button.new(text, **attrs, href:), &block)
41
+ end
42
+
43
+ automatic_variants(Button::VARIANTS, :nk_button_link_to)
44
+
45
+ def nk_button_group(**attrs, &block)
46
+ render(ButtonGroup.new(**attrs), &block)
38
47
  end
39
48
  end
40
49
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module CardHelper
3
5
  def nk_card(**attrs, &block)
@@ -1,24 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module CheckboxHelper
3
- # Match the signature of the Rails `check_box` helper
4
- def nk_checkbox(name, *args)
5
- if args.length >= 4
6
- raise ArgumentError, "wrong number of arguments (given #{args.length + 1}, expected 1..4)"
7
- end
8
-
9
- options = args.extract_options!
10
- value, checked = args.empty? ? ["1", false] : [*args, false]
5
+ # Make API compatible with Rails' checkbox but allow empty arguments
6
+ def nk_checkbox(
7
+ compat_object_name = nil,
8
+ compat_method = nil,
9
+ compat_options = {},
10
+ compat_checked_value = "1",
11
+ compat_unchecked_value = "0",
12
+ label: nil,
13
+ **attrs
14
+ )
15
+ name = field_name(compat_object_name, compat_method)
16
+ checked = compat_options["checked"] || attrs[:checked]
11
17
 
12
- attrs = {
13
- :type => "checkbox",
14
- :name => name,
15
- :id => sanitize_to_id(name),
16
- :value => value
17
- }.update(options.symbolize_keys)
18
+ # TODO: multiple, unchecked hidden field
18
19
 
19
- attrs[:checked] = "checked" if checked
20
+ render(Checkbox.new(name:, label:, value: compat_checked_value, checked:, **attrs))
21
+ end
20
22
 
21
- render(NitroKit::Checkbox.new(name, value:, **attrs))
23
+ def nk_checkbox_group(**attrs, &block)
24
+ render(CheckboxGroup.new(**attrs), &block)
22
25
  end
23
26
  end
24
27
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module ComboboxHelper
5
+ def nk_combobox(name = nil, options = [], **attrs)
6
+ render(NitroKit::Combobox.new(name:, options:, **attrs))
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module DatepickerHelper
5
+ def nk_datepicker(**attrs, &block)
6
+ render(Datepicker.new(**attrs), &block)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module DialogHelper
5
+ def nk_dialog(**attrs, &block)
6
+ render(Dialog.new(**attrs), &block)
7
+ end
8
+ end
9
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module DropdownHelper
3
5
  def nk_dropdown(**attrs, &block)
4
- render(NitroKit::Dropdown.new(**attrs), &block)
6
+ render(Dropdown.new(**attrs), &block)
5
7
  end
6
8
  end
7
9
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module FieldGroupHelper
5
+ def nk_field_group(**attrs)
6
+ render(NitroKit::FieldGroup.new(**attrs)) { yield }
7
+ end
8
+ end
9
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module FieldHelper
3
- def nk_field(*args, **options, &block)
4
- render(NitroKit::Field.new(*args, **options, &block))
5
+ def nk_field(*args, **attrs, &block)
6
+ render(NitroKit::Field.new(*args, **attrs), &block)
5
7
  end
6
8
  end
7
9
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module FieldsetHelper
5
+ def nk_fieldset(**attrs, &block)
6
+ render(NitroKit::Fieldset.new(**attrs), &block)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module FormHelper
5
+ def nk_form_with(**attrs, &block)
6
+ form_with(**attrs, builder: NitroKit::FormBuilder, &block)
7
+ end
8
+
9
+ def nk_form_for(*args, **attrs, &block)
10
+ form_for(*args, **attrs, builder: NitroKit::FormBuilder, &block)
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module IconHelper
3
5
  def nk_icon(name, **attrs)
4
- render(NitroKit::Icon.new(name: name, **attrs))
6
+ render(NitroKit::Icon.new(name, **attrs))
5
7
  end
6
8
  end
7
9
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module InputHelper
5
+ def nk_input(**attrs)
6
+ render(Input.new(**attrs))
7
+ end
8
+
9
+ %w[
10
+ color
11
+ date
12
+ datetime
13
+ datetime_local
14
+ email
15
+ file
16
+ hidden
17
+ month
18
+ number
19
+ password
20
+ phone
21
+ range
22
+ search
23
+ telephone
24
+ text
25
+ time
26
+ url
27
+ week
28
+ ]
29
+ .each do |type|
30
+ define_method("nk_#{type}_field") do |**attrs|
31
+ nk_input(type:, **attrs)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,16 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module LabelHelper
3
- def nk_label(name = nil, content_or_options = nil, **attrs, &block)
4
- if block_given? && content_or_options.is_a?(Hash)
5
- attrs = content_or_options = content_or_options.symbolize_keys
6
- else
7
- attrs ||= {}
8
- attrs = attrs.symbolize_keys
9
- end
5
+ def nk_label(compat_object_name = nil, compat_method = nil, content_or_options = nil, **attrs, &block)
6
+ name = field_name(compat_object_name, compat_method)
10
7
 
11
- attrs[:for] = sanitize_to_id(name) unless name.blank? || attrs.has_key?("for")
8
+ case content_or_options
9
+ when String
10
+ text = content_or_options
11
+ when Hash
12
+ text = nil
13
+ attrs.merge!(content_or_options)
14
+ end
12
15
 
13
- render(Label.new(**attrs)) { content_or_options || name.to_s.humanize || yield }
16
+ render(Label.new(text, for: name, **attrs), &block)
14
17
  end
15
18
  end
16
19
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module PaginationHelper
5
+ include Pagy::UrlHelpers if defined?(Pagy)
6
+
7
+ def nk_pagination(**attrs, &block)
8
+ render(Pagination.new(**attrs), &block)
9
+ end
10
+
11
+ def nk_pagy_nav(pagy, id: nil, aria_label: nil, **attrs)
12
+ attrs[:aria] ||= {label: aria_label}
13
+
14
+ nk_pagination(id:, **attrs) do |p|
15
+ if prev_page = pagy.prev
16
+ p.prev(href: pagy_url_for(pagy, prev_page))
17
+ else
18
+ p.prev(disabled: true)
19
+ end
20
+
21
+ pagy.series.each do |item|
22
+ case item
23
+ when Integer
24
+ p.page(item.to_s, href: pagy_url_for(pagy, item))
25
+ when String
26
+ p.page(item, current: true)
27
+ when :gap
28
+ p.ellipsis
29
+ else
30
+ raise ArgumentError, "Unknown item type: #{item.class}"
31
+ end
32
+ end
33
+
34
+ if next_page = pagy.next
35
+ p.next(href: pagy_url_for(pagy, next_page))
36
+ else
37
+ p.next(disabled: true)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,20 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module RadioButtonHelper
3
- def nk_radio_button(name, value, *args)
4
- if args.length >= 3
5
- raise ArgumentError, "wrong number of arguments (given #{args.length + 2}, expected 2..4)"
6
- end
7
-
8
- options = args.extract_options!
9
- checked = args.empty? ? false : args.first
10
-
11
- options[:checked] = "checked" if checked
5
+ def nk_radio_button(
6
+ compat_object_name = nil,
7
+ compat_method = nil,
8
+ compat_tag_value = nil,
9
+ compat_options = {},
10
+ label: nil,
11
+ **attrs
12
+ )
13
+ name = field_name(compat_object_name, compat_method)
14
+ value = compat_tag_value || attrs[:value]
12
15
 
13
- render(RadioButton.new(name, value:, name:, value:, **options))
16
+ render(RadioButton.new(label:, name:, value:, **attrs))
14
17
  end
15
18
 
16
- def nk_radio_group(name, **options, &block)
17
- render(RadioGroup.new(name, **options, &block))
19
+ def nk_radio_button_group(**attrs, &block)
20
+ render(RadioButtonGroup.new(**attrs), &block)
18
21
  end
19
22
  end
20
23
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module SelectHelper
5
+ def nk_select(
6
+ compat_object_name = nil,
7
+ compat_method = nil,
8
+ options = nil,
9
+ compat_options = {},
10
+ value: nil,
11
+ include_blank: false,
12
+ prompt: nil,
13
+ index: nil,
14
+ **attrs,
15
+ &block
16
+ )
17
+ name = field_name(compat_object_name, compat_method)
18
+
19
+ # TODO: support index
20
+
21
+ render(Select.new(options, value:, include_blank:, prompt:, **compat_options, **attrs), &block)
22
+ end
23
+ end
24
+ end
@@ -1,15 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NitroKit
2
4
  module SwitchHelper
3
- def nk_switch(
4
- name,
5
- checked: false,
6
- disabled: false,
7
- size: :base,
8
- description: nil,
9
- **attrs,
10
- &block
11
- )
12
- render(NitroKit::Switch.new(name, checked:, disabled:, size:, description:, **attrs), &block)
5
+ def nk_switch(**attrs, &block)
6
+ render(Switch.new(**attrs), &block)
13
7
  end
14
8
  end
15
9
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module TableHelper
5
+ def nk_table(**attrs, &block)
6
+ render(Table.new(**attrs), &block)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module TabsHelper
5
+ def nk_tabs(**attrs, &block)
6
+ render(Tabs.new(**attrs), &block)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module TextareaHelper
5
+ def nk_textarea(**attrs)
6
+ render(Textarea.new(**attrs))
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module ToastHelper
5
+ def nk_toast(**attrs, &block)
6
+ render(Toast.new(**attrs), &block)
7
+ end
8
+
9
+ def nk_toast_action(title: nil, description: nil, event: nil)
10
+ {
11
+ action: "#{event ? "#{event}->" : ""}nk--toast#toast",
12
+ nk__toast_title_param: title,
13
+ nk__toast_description_param: description
14
+ }
15
+ end
16
+
17
+ def nk_toast_flash_messages
18
+ capture do
19
+ flash.each do |severity, message|
20
+ concat(
21
+ render(
22
+ Toast::Item.new(
23
+ description: message,
24
+ variant: severity.to_sym == :alert ? :error : :default
25
+ )
26
+ )
27
+ )
28
+ end
29
+ end
30
+ end
31
+
32
+ def nk_toast_turbo_stream_refresh
33
+ turbo_stream.append("nk--toast-sink", nk_toast_flash_messages)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NitroKit
4
+ module TooltipHelper
5
+ def nk_tooltip(**attrs, &block)
6
+ render(Tooltip.new(**attrs), &block)
7
+ end
8
+ end
9
+ end