nitro_kit 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Rubygems](https://img.shields.io/gem/v/nitro_kit.svg)](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
|