nitro_kit 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +28 -1
- data/app/components/nitro_kit/accordion.rb +10 -10
- data/app/components/nitro_kit/badge.rb +10 -13
- data/app/components/nitro_kit/button.rb +14 -15
- data/app/components/nitro_kit/checkbox.rb +2 -2
- data/app/components/nitro_kit/component.rb +10 -12
- data/app/components/nitro_kit/dropdown.rb +35 -34
- data/app/components/nitro_kit/field.rb +109 -23
- data/app/components/nitro_kit/field_group.rb +5 -6
- data/app/components/nitro_kit/icon.rb +1 -1
- data/app/components/nitro_kit/input.rb +16 -0
- data/app/components/nitro_kit/label.rb +1 -1
- data/app/components/nitro_kit/radio_button.rb +2 -2
- data/app/components/nitro_kit/switch.rb +2 -2
- data/app/helpers/application_helper.rb +48 -28
- data/app/helpers/nitro_kit/accordion_helper.rb +1 -1
- data/app/helpers/nitro_kit/field_helper.rb +2 -2
- data/app/helpers/nitro_kit/label_helper.rb +7 -6
- data/lib/nitro_kit/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf2f2dc76bda92752d48ee5f90a51987dedc72d5a40e04567016abc906606092
|
4
|
+
data.tar.gz: fa123bb3e2185331ec19cf7c79fb56e977b7a0daf301c6cdc7537be23ddc4d06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80004192401f6199f2dbe0aad196707028248584084615c4f7f85f5bf567e674eaa7ecdf9e487deb3886ba3b2899d1dc9153697b79b91aa6209c66350b0ff900
|
7
|
+
data.tar.gz: fb0b55d92309a50f46a2f8c93641c57eedafc4c817434e812ff46259e2e98d3b66869b4a321e499f02b7e818bd97e88e8c98ba7c65a19c98a1e35254eaa0d8e3
|
data/README.md
CHANGED
@@ -1 +1,28 @@
|
|
1
|
-
|
1
|
+
<center><a href="https://nitrokit.dev"><img src="https://s3.brnbw.com/Artboard-q85JFfA8Auat32ByIAXtDAsbYGgs5MeTM4GDaonKhlxVniioPDLQTZUeynCfdBSHAfiRYhMWkGaYZC9ClkZS9aFgkBjx9mrAmnFs.png" alt="Nitro Kit" width="335" /></a></center>
|
2
|
+
|
3
|
+
<p></p>
|
4
|
+
|
5
|
+
**Nitro Kit** is a set of **generic UI components** to help you build your **Ruby on Rails** application.
|
6
|
+
|
7
|
+
Rather than being fancy it is **purposefully modest**. Instead of giving you a black box, it is provided as a bunch of generators that give you a starting point to build upon.
|
8
|
+
|
9
|
+
Easy to customize, accessible, Rails native.
|
10
|
+
|
11
|
+
_Nitro Kit is still pre 1.0 and is in active development._
|
12
|
+
|
13
|
+
See [nitrokit.dev](https://nitrokit.dev).
|
14
|
+
|
15
|
+
[](https://rubygems.org/gems/nitro_kit)
|
16
|
+
|
17
|
+
---
|
18
|
+
|
19
|
+
### Development
|
20
|
+
|
21
|
+
```sh
|
22
|
+
bin/setup
|
23
|
+
bin/dev
|
24
|
+
```
|
25
|
+
|
26
|
+
### License
|
27
|
+
|
28
|
+
MIT
|
@@ -14,13 +14,13 @@ module NitroKit
|
|
14
14
|
"[&[aria-hidden='true']]:h-0 [&[aria-hidden='false']]:h-auto"
|
15
15
|
].freeze
|
16
16
|
|
17
|
-
ARROW =
|
17
|
+
ARROW = "transition-transform duration-200 text-muted-foreground group-hover/accordion-trigger:text-primary"
|
18
18
|
|
19
19
|
def view_template
|
20
20
|
div(
|
21
21
|
**attrs,
|
22
|
-
class: merge(
|
23
|
-
data: {
|
22
|
+
class: merge(ITEM, attrs[:class]),
|
23
|
+
data: {controller: "nk--accordion"}
|
24
24
|
) do
|
25
25
|
yield
|
26
26
|
end
|
@@ -37,24 +37,24 @@ module NitroKit
|
|
37
37
|
type: "button",
|
38
38
|
class: TRIGGER,
|
39
39
|
data: {
|
40
|
-
action
|
41
|
-
"nk--accordion-target"
|
40
|
+
:action => "nk--accordion#toggle",
|
41
|
+
:"nk--accordion-target" => "trigger"
|
42
42
|
},
|
43
|
-
aria: {
|
43
|
+
aria: {expanded: "false", controls: "content"}
|
44
44
|
) do
|
45
45
|
div(**attrs) { text || yield }
|
46
|
-
render
|
46
|
+
render(NitroKit::Icon.new(name: "chevron-down", class: ARROW))
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
def content(**attrs)
|
51
51
|
div(
|
52
52
|
class: merge(CONTENT),
|
53
|
-
data: {
|
54
|
-
aria: {
|
53
|
+
data: {:"nk--accordion-target" => "content"},
|
54
|
+
aria: {hidden: "true"}
|
55
55
|
) do
|
56
56
|
div(class: "pb-4") { yield }
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
60
|
-
end
|
60
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module NitroKit
|
2
2
|
class Badge < Component
|
3
|
-
|
3
|
+
BADGE = "inline-flex items-center gap-x-1.5 rounded-md font-medium"
|
4
4
|
|
5
5
|
VARIANTS = {
|
6
6
|
default: "border border-transparent bg-zinc-200 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300",
|
@@ -13,22 +13,19 @@ module NitroKit
|
|
13
13
|
}
|
14
14
|
|
15
15
|
def initialize(variant: :default, size: :md, **attrs)
|
16
|
-
|
16
|
+
super(**attrs)
|
17
17
|
|
18
|
-
@
|
19
|
-
|
20
|
-
BASE,
|
21
|
-
VARIANTS[variant],
|
22
|
-
SIZES[size],
|
23
|
-
attrs[:class]
|
24
|
-
]
|
25
|
-
)
|
18
|
+
@variant = variant
|
19
|
+
@size = size
|
26
20
|
end
|
27
21
|
|
28
|
-
attr_reader :
|
22
|
+
attr_reader :variant, :size
|
29
23
|
|
30
|
-
def view_template
|
31
|
-
span(
|
24
|
+
def view_template
|
25
|
+
span(
|
26
|
+
**attrs,
|
27
|
+
class: merge(BADGE, VARIANTS[variant], SIZES[size], attrs[:class])
|
28
|
+
) { yield }
|
32
29
|
end
|
33
30
|
end
|
34
31
|
end
|
@@ -28,7 +28,7 @@ module NitroKit
|
|
28
28
|
],
|
29
29
|
ghost: [
|
30
30
|
"bg-transparent text-foreground border-transparent",
|
31
|
-
"hover:bg-zinc-
|
31
|
+
"hover:bg-zinc-100 dark:hover:bg-zinc-900",
|
32
32
|
"disabled:text-muted-foreground"
|
33
33
|
]
|
34
34
|
}.freeze
|
@@ -37,7 +37,7 @@ module NitroKit
|
|
37
37
|
base: "px-4 h-9",
|
38
38
|
sm: "px-2.5 h-7 text-sm",
|
39
39
|
xs: "px-1.5 h-6 text-xs"
|
40
|
-
}
|
40
|
+
}.freeze
|
41
41
|
|
42
42
|
def initialize(
|
43
43
|
href: nil,
|
@@ -48,36 +48,35 @@ module NitroKit
|
|
48
48
|
variant: :default,
|
49
49
|
**attrs
|
50
50
|
)
|
51
|
+
super(**attrs)
|
52
|
+
|
51
53
|
@href = href
|
52
54
|
@icon = icon
|
53
55
|
@icon_right = icon_right
|
54
56
|
@size = size
|
55
57
|
@type = type
|
56
58
|
@variant = variant
|
57
|
-
@attrs = attrs
|
58
|
-
|
59
|
-
@class_list = merge(
|
60
|
-
[
|
61
|
-
BASE,
|
62
|
-
VARIANTS[variant],
|
63
|
-
SIZES[size],
|
64
|
-
attrs[:class]
|
65
|
-
]
|
66
|
-
)
|
67
59
|
end
|
68
60
|
|
69
61
|
attr_reader(
|
70
|
-
:class_list,
|
71
62
|
:href,
|
72
63
|
:icon,
|
73
64
|
:icon_right,
|
74
65
|
:size,
|
75
66
|
:type,
|
76
|
-
:variant
|
77
|
-
:attrs
|
67
|
+
:variant
|
78
68
|
)
|
79
69
|
|
80
70
|
def view_template(&block)
|
71
|
+
class_list = merge(
|
72
|
+
[
|
73
|
+
BASE,
|
74
|
+
VARIANTS[variant],
|
75
|
+
SIZES[size],
|
76
|
+
attrs[:class]
|
77
|
+
]
|
78
|
+
)
|
79
|
+
|
81
80
|
if href
|
82
81
|
a(href:, **attrs, class: class_list) do
|
83
82
|
contents(&block)
|
@@ -16,13 +16,13 @@ module NitroKit
|
|
16
16
|
)
|
17
17
|
|
18
18
|
def view_template
|
19
|
-
div(class: merge(["isolate inline-flex items-center gap-2",
|
19
|
+
div(class: merge(["isolate inline-flex items-center gap-2", attrs[:class]])) do
|
20
20
|
label(class: "relative flex shrink-0") do
|
21
21
|
input(
|
22
22
|
**attrs,
|
23
23
|
type: "checkbox",
|
24
24
|
class: class_names(
|
25
|
-
"peer appearance-none shadow size-4 rounded border text-foreground",
|
25
|
+
"peer appearance-none shadow-sm size-4 rounded-sm border text-foreground",
|
26
26
|
"checked:bg-primary checked:border-primary",
|
27
27
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
28
28
|
)
|
@@ -1,30 +1,28 @@
|
|
1
1
|
module NitroKit
|
2
|
+
Merger = TailwindMerge::Merger.new
|
3
|
+
|
2
4
|
class Component < Phlex::HTML
|
3
|
-
attr_reader :attrs
|
5
|
+
attr_reader :attrs
|
4
6
|
|
5
7
|
def initialize(**attrs)
|
6
|
-
@class_list = attrs.delete(:class)
|
7
8
|
@attrs = attrs.symbolize_keys
|
8
9
|
end
|
9
10
|
|
10
|
-
attr_reader :
|
11
|
+
attr_reader :attrs
|
11
12
|
|
12
13
|
def merge(*args)
|
13
14
|
self.class.merge(*args)
|
14
15
|
end
|
15
16
|
|
16
17
|
def self.merge(*args)
|
17
|
-
|
18
|
-
@merger.merge(*args)
|
18
|
+
Merger.merge(args)
|
19
19
|
end
|
20
20
|
|
21
|
-
def data_merge(
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# Put new value first so overrides can stopPropagation to old value
|
27
|
-
[new_val, old_val].compact.join(" ")
|
21
|
+
def data_merge(*hashes)
|
22
|
+
hashes.compact.reverse.reduce({}) do |acc, hash|
|
23
|
+
acc.deep_merge(hash) do |_key, old_val, new_val|
|
24
|
+
[old_val, new_val].compact.join(" ")
|
25
|
+
end
|
28
26
|
end
|
29
27
|
end
|
30
28
|
end
|
@@ -9,6 +9,10 @@ module NitroKit
|
|
9
9
|
"[&[aria-hidden=true]]:hidden flex"
|
10
10
|
].freeze
|
11
11
|
|
12
|
+
TRIGGER = "inline-block"
|
13
|
+
|
14
|
+
TITLE = "px-3 pt-2 pb-1.5 text-muted-foreground text-sm"
|
15
|
+
|
12
16
|
ITEM = [
|
13
17
|
"px-3 py-1.5 rounded",
|
14
18
|
"font-medium truncate",
|
@@ -30,44 +34,45 @@ module NitroKit
|
|
30
34
|
attr_reader :placement
|
31
35
|
|
32
36
|
def view_template(&block)
|
33
|
-
div(
|
37
|
+
div(
|
38
|
+
data: data_merge(
|
39
|
+
{:controller => "nk--dropdown", :"nk--dropdown-placement-value" => placement},
|
40
|
+
attrs[:data]
|
41
|
+
),
|
42
|
+
&block
|
43
|
+
)
|
34
44
|
end
|
35
45
|
|
36
46
|
def trigger(**attrs, &block)
|
37
|
-
class_list = "inline-block"
|
38
|
-
data = {
|
39
|
-
:"nk--dropdown-target" => "trigger",
|
40
|
-
:action => "click->nk--dropdown#toggle",
|
41
|
-
**attrs.fetch(:data, {})
|
42
|
-
}
|
43
47
|
div(
|
44
|
-
**attrs,
|
45
|
-
class: class_list,
|
46
|
-
data:,
|
47
48
|
aria: {haspopup: "true", expanded: "false"},
|
49
|
+
**attrs,
|
50
|
+
class: merge([TRIGGER, attrs[:class]]),
|
51
|
+
data: data_merge(
|
52
|
+
{:"nk--dropdown-target" => "trigger", :action => "click->nk--dropdown#toggle"},
|
53
|
+
attrs[:data]
|
54
|
+
),
|
48
55
|
&block
|
49
56
|
)
|
50
57
|
end
|
51
58
|
|
52
59
|
def content(**attrs, &block)
|
53
|
-
class_list = merge([CONTENT, attrs[:class]])
|
54
60
|
|
55
|
-
|
56
|
-
:"nk--dropdown-target" => "content",
|
57
|
-
**attrs.fetch(:data, {})
|
58
|
-
}
|
59
|
-
div(
|
60
|
-
**attrs,
|
61
|
-
class: class_list,
|
62
|
-
data:,
|
61
|
+
class_list = div(
|
63
62
|
role: "menu",
|
64
63
|
aria: {hidden: "true"},
|
64
|
+
**attrs,
|
65
|
+
class: merge([CONTENT, attrs[:class]]),
|
66
|
+
data: data_merge(
|
67
|
+
{:"nk--dropdown-target" => "content"},
|
68
|
+
attrs[:data]
|
69
|
+
),
|
65
70
|
&block
|
66
71
|
)
|
67
72
|
end
|
68
73
|
|
69
74
|
def title(text = nil, **attrs, &block)
|
70
|
-
class_list = merge([
|
75
|
+
class_list = merge([TITLE, attrs[:class]])
|
71
76
|
div(**attrs, class: class_list) { text || block.call }
|
72
77
|
end
|
73
78
|
|
@@ -75,27 +80,23 @@ module NitroKit
|
|
75
80
|
text = nil,
|
76
81
|
href = nil,
|
77
82
|
variant: :default,
|
78
|
-
**attrs
|
79
|
-
&block
|
83
|
+
**attrs
|
80
84
|
)
|
81
|
-
class_list = merge([ITEM, ITEM_VARIANTS[variant], attrs[:class]])
|
82
|
-
|
83
85
|
common_attrs = {
|
84
|
-
**attrs,
|
85
|
-
class: class_list,
|
86
86
|
role: "menuitem",
|
87
|
-
tabindex: "-1"
|
87
|
+
tabindex: "-1",
|
88
|
+
**attrs,
|
89
|
+
class: merge([ITEM, ITEM_VARIANTS[variant], attrs[:class]])
|
88
90
|
}
|
89
91
|
|
90
92
|
if href
|
91
|
-
link_to(
|
92
|
-
|
93
|
-
|
94
|
-
) {
|
95
|
-
text || block.call
|
96
|
-
}
|
93
|
+
link_to(href, **common_attrs) do
|
94
|
+
text || yield
|
95
|
+
end
|
97
96
|
else
|
98
|
-
div(**common_attrs)
|
97
|
+
div(**common_attrs) do
|
98
|
+
text || yield
|
99
|
+
end
|
99
100
|
end
|
100
101
|
end
|
101
102
|
|
@@ -1,37 +1,123 @@
|
|
1
1
|
module NitroKit
|
2
2
|
class Field < Component
|
3
|
-
|
3
|
+
FIELD = [
|
4
4
|
"flex flex-col gap-2 align-start",
|
5
|
+
"[&:has([data-slot='error'])_[data-slot='label']]:text-destructive",
|
5
6
|
"[&:has([data-slot='error'])_[data-slot='control']]:border-destructive"
|
6
7
|
].freeze
|
7
|
-
LABEL_BASE = "text-sm font-medium"
|
8
|
-
DESCRIPTION_BASE = "text-sm text-muted-foreground"
|
9
|
-
ERROR_BASE = "text-sm text-destructive"
|
10
|
-
INPUT_BASE = [
|
11
|
-
"rounded-md border bg-background border-border text-base px-3 py-2",
|
12
|
-
"focus:outline-none focus:ring-2 focus:ring-primary",
|
13
|
-
""
|
14
|
-
].freeze
|
15
8
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
9
|
+
DESCRIPTION = "text-sm text-muted-foreground"
|
10
|
+
ERROR = "text-sm text-destructive"
|
11
|
+
|
12
|
+
def initialize(
|
13
|
+
name,
|
14
|
+
as: :string,
|
15
|
+
label: nil,
|
16
|
+
description: nil,
|
17
|
+
errors: nil,
|
18
|
+
**attrs
|
19
|
+
)
|
20
|
+
super(**attrs)
|
21
|
+
|
22
|
+
@name = name
|
23
|
+
@as = as.to_sym
|
24
|
+
|
25
|
+
@field_attrs = attrs
|
26
|
+
@field_label = label || name.to_s.humanize
|
27
|
+
@field_description = description
|
28
|
+
@field_error_messages = errors
|
23
29
|
end
|
24
30
|
|
25
|
-
attr_reader
|
31
|
+
attr_reader(
|
32
|
+
:name,
|
33
|
+
:as,
|
34
|
+
:field_attrs,
|
35
|
+
:field_label,
|
36
|
+
:field_description,
|
37
|
+
:field_error_messages
|
38
|
+
)
|
26
39
|
|
27
|
-
def view_template
|
28
|
-
div(**attrs, class:
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
40
|
+
def view_template
|
41
|
+
div(**attrs, class: merge(FIELD, attrs[:class])) do
|
42
|
+
if !block_given?
|
43
|
+
default_field
|
44
|
+
else
|
45
|
+
yield
|
33
46
|
end
|
34
47
|
end
|
35
48
|
end
|
49
|
+
|
50
|
+
alias :original_label :label
|
51
|
+
|
52
|
+
def label(text = nil, **attrs)
|
53
|
+
text ||= field_label
|
54
|
+
|
55
|
+
return unless text
|
56
|
+
|
57
|
+
render(
|
58
|
+
Label.new(
|
59
|
+
**attrs,
|
60
|
+
data: data_merge({slot: "label"}, attrs[:data])
|
61
|
+
)
|
62
|
+
) do
|
63
|
+
text
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def description(text = nil, **attrs)
|
68
|
+
text ||= field_description
|
69
|
+
|
70
|
+
return unless text
|
71
|
+
|
72
|
+
div(
|
73
|
+
data: {slot: "description"},
|
74
|
+
class: merge(DESCRIPTION, attrs[:class])
|
75
|
+
) { text }
|
76
|
+
end
|
77
|
+
|
78
|
+
alias :original_input :input
|
79
|
+
|
80
|
+
def input(**attrs)
|
81
|
+
render(
|
82
|
+
Input.new(
|
83
|
+
name:,
|
84
|
+
**field_attrs,
|
85
|
+
**attrs,
|
86
|
+
data: {slot: "control", **data_merge(field_attrs[:data], attrs[:data])}
|
87
|
+
)
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
def errors(error_messages = nil, **attrs)
|
92
|
+
error_messages ||= field_error_messages
|
93
|
+
|
94
|
+
return unless error_messages&.any?
|
95
|
+
|
96
|
+
ul(
|
97
|
+
**attrs,
|
98
|
+
data: {slot: "error"},
|
99
|
+
class: merge([ERROR, attrs[:class]])
|
100
|
+
) do |msg|
|
101
|
+
error_messages.each do |msg|
|
102
|
+
li { msg }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def control(**override_attrs)
|
108
|
+
case as
|
109
|
+
when :string
|
110
|
+
input(**override_attrs)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def default_field
|
117
|
+
label
|
118
|
+
description
|
119
|
+
control
|
120
|
+
errors
|
121
|
+
end
|
36
122
|
end
|
37
123
|
end
|
@@ -2,13 +2,12 @@ module NitroKit
|
|
2
2
|
class FieldGroup < Component
|
3
3
|
FIELD_GROUP_BASE = "space-y-6"
|
4
4
|
|
5
|
-
def initialize(**attrs)
|
6
|
-
@attrs = attrs
|
7
|
-
@class_list = merge([FIELD_GROUP_BASE, attrs[:class]])
|
8
|
-
end
|
9
|
-
|
10
5
|
def view_template(&block)
|
11
|
-
div(
|
6
|
+
div(
|
7
|
+
**attrs,
|
8
|
+
class: merge([FIELD_GROUP_BASE, attrs[:class]]),
|
9
|
+
&block
|
10
|
+
)
|
12
11
|
end
|
13
12
|
end
|
14
13
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module NitroKit
|
2
|
+
INPUT = [
|
3
|
+
"rounded-md border bg-background border-border text-base px-3 py-2",
|
4
|
+
"focus:outline-none ring-ring ring-offset-2 ring-offset-background focus-visible:ring-2",
|
5
|
+
""
|
6
|
+
].freeze
|
7
|
+
|
8
|
+
class Input < Component
|
9
|
+
def view_template
|
10
|
+
input(
|
11
|
+
**attrs,
|
12
|
+
class: merge(INPUT, attrs[:class])
|
13
|
+
)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -19,7 +19,7 @@ module NitroKit
|
|
19
19
|
)
|
20
20
|
|
21
21
|
def view_template
|
22
|
-
div(class: merge(
|
22
|
+
div(class: merge("inline-flex items-center gap-2", attrs[:class])) do
|
23
23
|
label(class: "grid grid-cols-1 place-items-center shrink-0") do
|
24
24
|
input(
|
25
25
|
**attrs,
|
@@ -29,7 +29,7 @@ module NitroKit
|
|
29
29
|
id:,
|
30
30
|
class: class_names(
|
31
31
|
"peer row-start-1 col-start-1",
|
32
|
-
"appearance-none size-5 shadow rounded-full border text-foreground bg-background",
|
32
|
+
"appearance-none size-5 shadow-sm rounded-full border text-foreground bg-background",
|
33
33
|
"[&[aria-checked='true']]:bg-primary",
|
34
34
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
35
35
|
)
|
@@ -15,7 +15,7 @@ module NitroKit
|
|
15
15
|
].freeze
|
16
16
|
|
17
17
|
HANDLE = [
|
18
|
-
"pointer-events-none inline-block rounded-full shadow ring-0",
|
18
|
+
"pointer-events-none inline-block rounded-full shadow-sm ring-0",
|
19
19
|
"transition translate-x-[3px] duration-200 ease-in-out"
|
20
20
|
].freeze
|
21
21
|
|
@@ -48,7 +48,7 @@ module NitroKit
|
|
48
48
|
**attrs,
|
49
49
|
type: "button",
|
50
50
|
class: merge([BUTTON, SIZE[size], attrs[:class]]),
|
51
|
-
data: data_merge(attrs[:data], {controller: "nk--switch", action: "nk--switch#
|
51
|
+
data: data_merge(attrs[:data], {controller: "nk--switch", action: "nk--switch#toggle"}),
|
52
52
|
role: "switch",
|
53
53
|
aria: {checked: checked.to_s}
|
54
54
|
) do
|
@@ -5,16 +5,25 @@ module ApplicationHelper
|
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
-
def title(text)
|
9
|
-
|
8
|
+
def title(text = nil, **attrs, &block)
|
9
|
+
text = capture(&block) if block_given?
|
10
|
+
tag.h1(**attrs, class: class_names("text-3xl font-semibold mb-6", attrs[:class])) { text }
|
10
11
|
end
|
11
12
|
|
12
|
-
def lead(text)
|
13
|
-
|
13
|
+
def lead(text = nil, &block)
|
14
|
+
text = capture(&block) if block_given?
|
15
|
+
tag.div(class: "text-lg text-gray-600 dark:text-gray-400 mb-6") do
|
16
|
+
text
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
def section(**attrs)
|
17
|
-
tag.div(
|
21
|
+
tag.div(
|
22
|
+
**attrs,
|
23
|
+
class: class_names("mt-8 space-y-4", attrs[:class])
|
24
|
+
) do
|
25
|
+
yield
|
26
|
+
end
|
18
27
|
end
|
19
28
|
|
20
29
|
def section_title(text)
|
@@ -26,41 +35,52 @@ module ApplicationHelper
|
|
26
35
|
.div(
|
27
36
|
**attrs,
|
28
37
|
class: class_names(
|
29
|
-
[
|
38
|
+
[
|
39
|
+
"flex flex-wrap gap-2 justify-center items-center min-h-[200px] py-12 p-5 w-full rounded border overflow-scroll",
|
40
|
+
attrs[:class]
|
41
|
+
]
|
30
42
|
)
|
31
43
|
) do
|
32
44
|
yield
|
33
45
|
end
|
34
46
|
end
|
35
47
|
|
36
|
-
def code_example(str)
|
48
|
+
def code_example(str = nil, language: :erb, toolbar: true, &block)
|
49
|
+
if block_given?
|
50
|
+
str = capture(&block)
|
51
|
+
.gsub(/{#/, "<%")
|
52
|
+
.gsub(/#}/, "%>")
|
53
|
+
end
|
54
|
+
|
55
|
+
lexer = Rouge::Lexer.find(language)
|
37
56
|
formatter = Rouge::Formatters::HTML.new
|
38
|
-
lexer = Rouge::Lexers::ERB.new
|
39
57
|
|
40
58
|
tag
|
41
59
|
.div(
|
42
|
-
class: "bg-[#f7f8fa] dark:bg-[#161b22] divide-y border rounded overflow-hidden",
|
60
|
+
class: "bg-[#f7f8fa] dark:bg-[#161b22] divide-y border rounded-sm overflow-hidden",
|
43
61
|
data: {controller: "copy-to-clipboard"}
|
44
62
|
) do
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
63
|
+
if toolbar
|
64
|
+
concat(
|
65
|
+
tag.div(class: "px-1 py-1 flex w-full") do
|
66
|
+
concat(
|
67
|
+
nk_ghost_button(
|
68
|
+
icon: :copy,
|
69
|
+
size: :xs,
|
70
|
+
data: {copy_to_clipboard_target: "button", action: "copy-to-clipboard#copy"}
|
71
|
+
) { "Copy" }
|
72
|
+
)
|
73
|
+
concat(
|
74
|
+
nk_ghost_button(
|
75
|
+
icon: :check,
|
76
|
+
size: :xs,
|
77
|
+
data: {copy_to_clipboard_target: "successMessage"},
|
78
|
+
class: "hidden"
|
79
|
+
) { "Copied!" }
|
80
|
+
)
|
81
|
+
end
|
82
|
+
)
|
83
|
+
end
|
64
84
|
|
65
85
|
concat(
|
66
86
|
tag
|
@@ -1,15 +1,16 @@
|
|
1
1
|
module NitroKit
|
2
2
|
module LabelHelper
|
3
|
-
def nk_label(name = nil, content_or_options = nil,
|
3
|
+
def nk_label(name = nil, content_or_options = nil, **attrs, &block)
|
4
4
|
if block_given? && content_or_options.is_a?(Hash)
|
5
|
-
|
5
|
+
attrs = content_or_options = content_or_options.symbolize_keys
|
6
6
|
else
|
7
|
-
|
8
|
-
|
7
|
+
attrs ||= {}
|
8
|
+
attrs = attrs.symbolize_keys
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
attrs[:for] = sanitize_to_id(name) unless name.blank? || attrs.has_key?("for")
|
12
|
+
|
13
|
+
render(Label.new(**attrs)) { content_or_options || name.to_s.humanize || yield }
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
data/lib/nitro_kit/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nitro_kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikkel Malmberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.13.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.13.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: phlex-rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,6 +74,7 @@ files:
|
|
74
74
|
- app/components/nitro_kit/fieldset.rb
|
75
75
|
- app/components/nitro_kit/form_builder.rb
|
76
76
|
- app/components/nitro_kit/icon.rb
|
77
|
+
- app/components/nitro_kit/input.rb
|
77
78
|
- app/components/nitro_kit/label.rb
|
78
79
|
- app/components/nitro_kit/radio_button.rb
|
79
80
|
- app/components/nitro_kit/radio_group.rb
|