nitro_kit 0.1.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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -0
- data/README.md +28 -1
- data/Rakefile +6 -4
- data/app/components/nitro_kit/accordion.rb +69 -33
- data/app/components/nitro_kit/alert.rb +69 -0
- data/app/components/nitro_kit/avatar.rb +52 -0
- data/app/components/nitro_kit/badge.rb +47 -23
- data/app/components/nitro_kit/button.rb +97 -65
- data/app/components/nitro_kit/button_group.rb +18 -13
- data/app/components/nitro_kit/card.rb +49 -9
- data/app/components/nitro_kit/checkbox.rb +59 -41
- data/app/components/nitro_kit/checkbox_group.rb +38 -0
- data/app/components/nitro_kit/combobox.rb +138 -0
- data/app/components/nitro_kit/component.rb +46 -17
- data/app/components/nitro_kit/datepicker.rb +9 -0
- data/app/components/nitro_kit/dialog.rb +95 -0
- data/app/components/nitro_kit/dropdown.rb +116 -73
- data/app/components/nitro_kit/field.rb +281 -30
- data/app/components/nitro_kit/field_group.rb +10 -5
- data/app/components/nitro_kit/fieldset.rb +42 -7
- data/app/components/nitro_kit/form_builder.rb +45 -22
- data/app/components/nitro_kit/icon.rb +29 -8
- data/app/components/nitro_kit/input.rb +26 -0
- data/app/components/nitro_kit/label.rb +18 -5
- data/app/components/nitro_kit/pagination.rb +98 -0
- data/app/components/nitro_kit/radio_button.rb +28 -27
- data/app/components/nitro_kit/radio_button_group.rb +53 -0
- data/app/components/nitro_kit/select.rb +72 -0
- data/app/components/nitro_kit/switch.rb +49 -39
- data/app/components/nitro_kit/table.rb +56 -0
- data/app/components/nitro_kit/tabs.rb +98 -0
- data/app/components/nitro_kit/textarea.rb +26 -0
- data/app/components/nitro_kit/toast.rb +104 -0
- data/app/components/nitro_kit/tooltip.rb +53 -0
- data/app/helpers/nitro_kit/accordion_helper.rb +3 -1
- data/app/helpers/nitro_kit/alert_helper.rb +11 -0
- data/app/helpers/nitro_kit/avatar_helper.rb +9 -0
- data/app/helpers/nitro_kit/badge_helper.rb +3 -5
- data/app/helpers/nitro_kit/button_group_helper.rb +2 -0
- data/app/helpers/nitro_kit/button_helper.rb +37 -28
- data/app/helpers/nitro_kit/card_helper.rb +2 -0
- data/app/helpers/nitro_kit/checkbox_helper.rb +19 -16
- data/app/helpers/nitro_kit/combobox_helper.rb +9 -0
- data/app/helpers/nitro_kit/datepicker_helper.rb +9 -0
- data/app/helpers/nitro_kit/dialog_helper.rb +9 -0
- data/app/helpers/nitro_kit/dropdown_helper.rb +3 -1
- data/app/helpers/nitro_kit/field_group_helper.rb +9 -0
- data/app/helpers/nitro_kit/field_helper.rb +4 -2
- data/app/helpers/nitro_kit/fieldset_helper.rb +9 -0
- data/app/helpers/nitro_kit/form_helper.rb +13 -0
- data/app/helpers/nitro_kit/icon_helper.rb +3 -1
- data/app/helpers/nitro_kit/input_helper.rb +35 -0
- data/app/helpers/nitro_kit/label_helper.rb +12 -8
- data/app/helpers/nitro_kit/pagination_helper.rb +42 -0
- data/app/helpers/nitro_kit/radio_button_helper.rb +15 -12
- data/app/helpers/nitro_kit/select_helper.rb +24 -0
- data/app/helpers/nitro_kit/switch_helper.rb +4 -10
- data/app/helpers/nitro_kit/table_helper.rb +9 -0
- data/app/helpers/nitro_kit/tabs_helper.rb +9 -0
- data/app/helpers/nitro_kit/textarea_helper.rb +9 -0
- data/app/helpers/nitro_kit/toast_helper.rb +36 -0
- data/app/helpers/nitro_kit/tooltip_helper.rb +9 -0
- data/lib/generators/nitro_kit/add_generator.rb +38 -41
- data/lib/generators/nitro_kit/install_generator.rb +2 -1
- data/lib/nitro_kit/engine.rb +4 -0
- data/lib/nitro_kit/schema_builder.rb +90 -16
- data/lib/nitro_kit/version.rb +1 -1
- data/lib/nitro_kit.rb +39 -1
- data/lib/tasks/nitro_kit_tasks.rake +4 -0
- metadata +40 -12
- data/app/components/nitro_kit/radio_group.rb +0 -35
- data/app/helpers/application_helper.rb +0 -89
- data/lib/nitro_kit/railtie.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d58e573f0c99860c6ede6591c772db3d2399c754a1cb2c25b65632c42ca8a00
|
4
|
+
data.tar.gz: 4796fae213b057ed86d3bcc693c504c7323abe020bcfa920713ea7d9a2e4438a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2865c2a1a86d6cf786eff5a699ce98aabea646c44349ecb387369ee7ba3aaab1b928f28ea1fded788bc95ffeb06926aac017a4fe292e70bbc0e1ecfa7d0dc30f
|
7
|
+
data.tar.gz: 2f8f3fc20b0be34cc8fc07f01fba9ace962dad39926332a50bf65bec062b7d96398bdc790b708fb6c027f2193b542641c5127fd6920f417d359a448a82bff782
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright Mikkel Malmberg
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
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
|
data/Rakefile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
1
|
+
require "bundler/setup"
|
3
2
|
|
4
|
-
|
3
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
4
|
+
load "rails/tasks/engine.rake"
|
5
5
|
|
6
|
-
|
6
|
+
load "rails/tasks/statistics.rake"
|
7
|
+
|
8
|
+
require "bundler/gem_tasks"
|
@@ -1,27 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module NitroKit
|
2
4
|
class Accordion < Component
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
].freeze
|
11
|
-
|
12
|
-
CONTENT = [
|
13
|
-
"overflow-hidden transition-all duration-200",
|
14
|
-
"[&[aria-hidden='true']]:h-0 [&[aria-hidden='false']]:h-auto"
|
15
|
-
].freeze
|
16
|
-
|
17
|
-
ARROW = "transition-transform duration-200 text-muted-foreground group-hover/accordion-trigger:text-primary"
|
5
|
+
def initialize(**attrs)
|
6
|
+
super(
|
7
|
+
attrs,
|
8
|
+
class: item_class,
|
9
|
+
data: {controller: "nk--accordion"}
|
10
|
+
)
|
11
|
+
end
|
18
12
|
|
19
13
|
def view_template
|
20
|
-
div(
|
21
|
-
**attrs,
|
22
|
-
class: merge([ITEM, class_list]),
|
23
|
-
data: { controller: "nk--accordion" }
|
24
|
-
) do
|
14
|
+
div(**attrs) do
|
25
15
|
yield
|
26
16
|
end
|
27
17
|
end
|
@@ -34,27 +24,73 @@ module NitroKit
|
|
34
24
|
|
35
25
|
def trigger(text = nil, **attrs)
|
36
26
|
button(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
27
|
+
**mattr(
|
28
|
+
attrs,
|
29
|
+
type: "button",
|
30
|
+
class: trigger_class,
|
31
|
+
data: {
|
32
|
+
action: "nk--accordion#toggle",
|
33
|
+
nk__accordion_target: "trigger"
|
34
|
+
},
|
35
|
+
aria: {expanded: "false"}
|
36
|
+
)
|
44
37
|
) do
|
45
|
-
|
46
|
-
|
38
|
+
block_given? ? yield : plain(text)
|
39
|
+
chevron_icon
|
47
40
|
end
|
48
41
|
end
|
49
42
|
|
50
43
|
def content(**attrs)
|
51
44
|
div(
|
52
|
-
|
53
|
-
|
54
|
-
|
45
|
+
**mattr(
|
46
|
+
attrs,
|
47
|
+
class: content_class,
|
48
|
+
data: {
|
49
|
+
nk__accordion_target: "content"
|
50
|
+
},
|
51
|
+
aria: {hidden: "true"}
|
52
|
+
)
|
55
53
|
) do
|
56
54
|
div(class: "pb-4") { yield }
|
57
55
|
end
|
58
56
|
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def item_class
|
61
|
+
"divide-y"
|
62
|
+
end
|
63
|
+
|
64
|
+
def trigger_class
|
65
|
+
[
|
66
|
+
"flex w-full items-center justify-between py-4 font-medium cursor-pointer",
|
67
|
+
"group/accordion-trigger hover:underline transition-colors",
|
68
|
+
"[&[aria-expanded='true']>svg]:rotate-180",
|
69
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
70
|
+
]
|
71
|
+
end
|
72
|
+
|
73
|
+
def content_class
|
74
|
+
[
|
75
|
+
"overflow-hidden transition-all duration-200",
|
76
|
+
"[&[aria-hidden='true']]:h-0 [&[aria-hidden='false']]:h-auto"
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
def arrow_class
|
81
|
+
"transition-transform duration-200 text-muted-foreground group-hover/accordion-trigger:text-primary"
|
82
|
+
end
|
83
|
+
|
84
|
+
def chevron_icon
|
85
|
+
svg(
|
86
|
+
class: "transition-transform duration-200 size-4 self-center place-self-end mr-2 pointer-events-none text-muted-foreground group-hover/accordion-trigger:text-primary",
|
87
|
+
viewbox: "0 0 24 24",
|
88
|
+
fill: "none",
|
89
|
+
stroke: "currentColor",
|
90
|
+
stroke_width: 1
|
91
|
+
) do |svg|
|
92
|
+
svg.path(d: "m6 9 6 6 6-6")
|
93
|
+
end
|
94
|
+
end
|
59
95
|
end
|
60
|
-
end
|
96
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NitroKit
|
4
|
+
class Alert < Component
|
5
|
+
VARIANTS = %i[default warning error success]
|
6
|
+
|
7
|
+
def initialize(variant: :default, **attrs)
|
8
|
+
@variant = variant
|
9
|
+
|
10
|
+
super(
|
11
|
+
attrs,
|
12
|
+
role: "alert",
|
13
|
+
class: [base_class, variant_class]
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :variant
|
18
|
+
|
19
|
+
def view_template
|
20
|
+
div(**attrs) do
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def title(text = nil, **attrs, &block)
|
26
|
+
h5(**mattr(attrs, class: title_class)) do
|
27
|
+
text_or_block(text, &block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def description(text = nil, **attrs, &block)
|
32
|
+
div(**mattr(attrs, class: description_class)) do
|
33
|
+
text_or_block(text, &block)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def base_class
|
40
|
+
[
|
41
|
+
"relative border w-full rounded-md p-5 text-sm space-y-2",
|
42
|
+
"[&>svg~*]:pl-8 [&>svg]:absolute [&>svg]:top-5 [&>svg]:left-5"
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
46
|
+
def variant_class
|
47
|
+
case variant
|
48
|
+
when :default
|
49
|
+
"border-border bg-background text-foreground"
|
50
|
+
when :warning
|
51
|
+
"bg-yellow-300/20 dark:bg-yellow-300/20 text-yellow-900 dark:text-yellow-100 border-yellow-500/80 dark:border-yellow-400/50"
|
52
|
+
when :success
|
53
|
+
"bg-green-300/20 dark:bg-green-300/20 text-green-900 dark:text-green-100 border-green-500/80 dark:border-green-400/50"
|
54
|
+
when :error
|
55
|
+
"bg-red-300/20 dark:bg-red-300/20 text-red-900 dark:text-red-100 border-red-400/80 dark:border-red-400/50"
|
56
|
+
else
|
57
|
+
raise ArgumentError, "Invalid variant: #{variant}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def title_class
|
62
|
+
"font-medium text-lg leading-5"
|
63
|
+
end
|
64
|
+
|
65
|
+
def description_class
|
66
|
+
""
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NitroKit
|
4
|
+
class Avatar < Component
|
5
|
+
include ActionView::Helpers::AssetUrlHelper
|
6
|
+
|
7
|
+
def initialize(src_arg = nil, src: nil, size: :md, **attrs)
|
8
|
+
@src = src_arg || src
|
9
|
+
@size = size
|
10
|
+
|
11
|
+
super(
|
12
|
+
attrs,
|
13
|
+
class: [container_class, size_classes]
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :src, :size
|
18
|
+
|
19
|
+
def view_template(&block)
|
20
|
+
div(**attrs) do
|
21
|
+
image
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def image
|
26
|
+
helpers.image_tag(src, class: image_class)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def size_classes
|
32
|
+
case size
|
33
|
+
when :sm
|
34
|
+
"size-8"
|
35
|
+
when :md
|
36
|
+
"size-12"
|
37
|
+
when :lg
|
38
|
+
"size-16"
|
39
|
+
else
|
40
|
+
raise ArgumentError, "Invalid size: #{size}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def container_class
|
45
|
+
"inline-flex overflow-hidden rounded-full"
|
46
|
+
end
|
47
|
+
|
48
|
+
def image_class
|
49
|
+
"block size-full bg-muted"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,34 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module NitroKit
|
2
4
|
class Badge < Component
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@attrs = attrs
|
17
|
-
|
18
|
-
@class_list = merge(
|
19
|
-
[
|
20
|
-
BASE,
|
21
|
-
VARIANTS[variant],
|
22
|
-
SIZES[size],
|
23
|
-
attrs[:class]
|
5
|
+
VARIANTS = %i[default outline]
|
6
|
+
|
7
|
+
def initialize(text = nil, variant: :default, size: :md, **attrs)
|
8
|
+
@text = text
|
9
|
+
@variant = variant
|
10
|
+
@size = size
|
11
|
+
|
12
|
+
super(
|
13
|
+
attrs,
|
14
|
+
class: [
|
15
|
+
base_class,
|
16
|
+
variant_class,
|
17
|
+
size_class
|
24
18
|
]
|
25
19
|
)
|
26
20
|
end
|
27
21
|
|
28
|
-
attr_reader :
|
22
|
+
attr_reader :text, :variant, :size
|
29
23
|
|
30
24
|
def view_template(&block)
|
31
|
-
span(**attrs
|
25
|
+
span(**attrs) do
|
26
|
+
text_or_block(text, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def base_class
|
33
|
+
"inline-flex items-center gap-x-1.5 rounded-md font-medium"
|
34
|
+
end
|
35
|
+
|
36
|
+
def variant_class
|
37
|
+
case variant
|
38
|
+
when :default
|
39
|
+
"bg-zinc-200 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300"
|
40
|
+
when :outline
|
41
|
+
"border"
|
42
|
+
else
|
43
|
+
raise ArgumentError, "Invalid variant: #{variant}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def size_class
|
48
|
+
case size
|
49
|
+
when :sm
|
50
|
+
"text-xs px-1.5 py-0.5"
|
51
|
+
when :md
|
52
|
+
"text-sm px-2 py-0.5"
|
53
|
+
else
|
54
|
+
raise ArgumentError, "Invalid size: #{size}"
|
55
|
+
end
|
32
56
|
end
|
33
57
|
end
|
34
58
|
end
|
@@ -1,89 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module NitroKit
|
2
4
|
class Button < Component
|
3
|
-
|
4
|
-
"inline-flex items-center cursor-pointer shrink-0 justify-center rounded-md border gap-2 font-medium",
|
5
|
-
# Disabled
|
6
|
-
"disabled:opacity-70 disabled:pointer-events-none",
|
7
|
-
# Focus
|
8
|
-
"focus:outline-none focus:ring-[3px] focus:ring-offset-2 focus:ring-ring ring-offset-background",
|
9
|
-
# Icon
|
10
|
-
"[&_svg]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
11
|
-
# If icon only, make square
|
12
|
-
"[&_svg:first-child:last-child]:-mx-2"
|
13
|
-
].freeze
|
14
|
-
|
15
|
-
VARIANTS = {
|
16
|
-
default: [
|
17
|
-
"bg-background text-foreground",
|
18
|
-
"hover:bg-zinc-50 dark:hover:bg-zinc-900"
|
19
|
-
],
|
20
|
-
primary: [
|
21
|
-
"bg-primary text-white dark:text-zinc-950 border-primary",
|
22
|
-
"hover:bg-primary/90 dark:hover:bg-primary/90"
|
23
|
-
],
|
24
|
-
destructive: [
|
25
|
-
"bg-destructive text-white border-destructive",
|
26
|
-
"hover:bg-destructive/90 dark:hover:bg-destructive/90",
|
27
|
-
"disabled:text-white/80"
|
28
|
-
],
|
29
|
-
ghost: [
|
30
|
-
"bg-transparent text-foreground border-transparent",
|
31
|
-
"hover:bg-zinc-50 dark:hover:bg-zinc-900",
|
32
|
-
"disabled:text-muted-foreground"
|
33
|
-
]
|
34
|
-
}.freeze
|
35
|
-
|
36
|
-
SIZES = {
|
37
|
-
base: "px-4 h-9",
|
38
|
-
sm: "px-2.5 h-7 text-sm",
|
39
|
-
xs: "px-1.5 h-6 text-xs"
|
40
|
-
}
|
5
|
+
VARIANTS = %i[default primary destructive ghost]
|
41
6
|
|
42
7
|
def initialize(
|
8
|
+
text = nil,
|
43
9
|
href: nil,
|
10
|
+
variant: :default,
|
11
|
+
size: :md,
|
44
12
|
icon: nil,
|
45
13
|
icon_right: nil,
|
46
|
-
size: :base,
|
47
|
-
type: :button,
|
48
|
-
variant: :default,
|
49
14
|
**attrs
|
50
15
|
)
|
16
|
+
@text = text
|
51
17
|
@href = href
|
52
18
|
@icon = icon
|
53
19
|
@icon_right = icon_right
|
54
20
|
@size = size
|
55
|
-
@type = type
|
56
21
|
@variant = variant
|
57
|
-
@attrs = attrs
|
58
22
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
23
|
+
super(
|
24
|
+
attrs,
|
25
|
+
class: [
|
26
|
+
base_class,
|
27
|
+
variant_class,
|
28
|
+
size_class
|
65
29
|
]
|
66
30
|
)
|
67
31
|
end
|
68
32
|
|
69
33
|
attr_reader(
|
70
|
-
:
|
34
|
+
:text,
|
71
35
|
:href,
|
72
36
|
:icon,
|
73
37
|
:icon_right,
|
74
38
|
:size,
|
75
|
-
:
|
76
|
-
:variant,
|
77
|
-
:attrs
|
39
|
+
:variant
|
78
40
|
)
|
79
41
|
|
80
42
|
def view_template(&block)
|
81
43
|
if href
|
82
|
-
a(href:, **attrs
|
44
|
+
a(href:, **attrs) do
|
83
45
|
contents(&block)
|
84
46
|
end
|
85
47
|
else
|
86
|
-
button(type
|
48
|
+
button(type: :button, **attrs) do
|
87
49
|
contents(&block)
|
88
50
|
end
|
89
51
|
end
|
@@ -91,19 +53,89 @@ module NitroKit
|
|
91
53
|
|
92
54
|
private
|
93
55
|
|
94
|
-
def contents
|
95
|
-
|
96
|
-
|
56
|
+
def contents(&block)
|
57
|
+
has_content = text.present? || block_given?
|
58
|
+
|
59
|
+
if !has_content
|
60
|
+
return render(Icon.new(icon))
|
61
|
+
end
|
62
|
+
|
63
|
+
render(Icon.new(icon)) if icon
|
64
|
+
|
65
|
+
if block_given?
|
66
|
+
yield
|
67
|
+
else
|
68
|
+
span { plain(text) }
|
69
|
+
end
|
70
|
+
|
71
|
+
render(Icon.new(icon_right)) if icon_right
|
72
|
+
end
|
73
|
+
|
74
|
+
def base_class
|
75
|
+
[
|
76
|
+
"inline-flex items-center cursor-pointer shrink-0 justify-center rounded-md border gap-2 font-medium select-none",
|
77
|
+
# Disabled
|
78
|
+
"disabled:opacity-70 disabled:pointer-events-none",
|
79
|
+
# Focus
|
80
|
+
"focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-offset-2 focus-visible:ring-ring ring-offset-background",
|
81
|
+
# Icon
|
82
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0"
|
83
|
+
]
|
84
|
+
end
|
97
85
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
86
|
+
def variant_class
|
87
|
+
case variant
|
88
|
+
when :default
|
89
|
+
[
|
90
|
+
"bg-background text-foreground border-border",
|
91
|
+
"hover:bg-zinc-50 dark:hover:bg-zinc-900"
|
92
|
+
]
|
93
|
+
when :primary
|
94
|
+
[
|
95
|
+
"bg-primary text-white dark:text-zinc-950 border-primary",
|
96
|
+
"hover:bg-primary/90 dark:hover:bg-primary/90"
|
97
|
+
]
|
98
|
+
when :destructive
|
99
|
+
[
|
100
|
+
"bg-destructive text-white border-destructive",
|
101
|
+
"hover:bg-destructive/90 dark:hover:bg-destructive/90",
|
102
|
+
"disabled:text-white/80"
|
103
|
+
]
|
104
|
+
when :ghost
|
105
|
+
[
|
106
|
+
"bg-transparent text-foreground border-transparent",
|
107
|
+
"hover:bg-zinc-200/50 dark:hover:bg-zinc-900",
|
108
|
+
"disabled:text-muted-foreground"
|
109
|
+
]
|
110
|
+
else
|
111
|
+
raise ArgumentError, "Unknown variant `#{variant}'"
|
102
112
|
end
|
113
|
+
end
|
103
114
|
|
104
|
-
|
105
|
-
|
106
|
-
|
115
|
+
def size_class
|
116
|
+
case size
|
117
|
+
when :xs
|
118
|
+
"px-1.5 h-6 text-xs [&_svg]:size-3"
|
119
|
+
when :sm
|
120
|
+
[
|
121
|
+
"px-2.5 h-7 text-sm [&_svg]:size-3",
|
122
|
+
"[&_svg:first-child:last-child]:-mx-1"
|
123
|
+
]
|
124
|
+
when :md
|
125
|
+
[
|
126
|
+
"px-4 h-10 text-base [&_svg]:size-4",
|
127
|
+
# If icon only, make square
|
128
|
+
"[&_svg:first-child:last-child]:-mx-2"
|
129
|
+
]
|
130
|
+
when :lg
|
131
|
+
[
|
132
|
+
"px-5 h-11 text-lg [&_svg]:size-5",
|
133
|
+
# If icon only, make square
|
134
|
+
"[&_svg:first-child:last-child]:-mx-2"
|
135
|
+
]
|
136
|
+
else
|
137
|
+
raise ArgumentError, "Unknown size `#{size}'"
|
138
|
+
end
|
107
139
|
end
|
108
140
|
end
|
109
141
|
end
|
@@ -1,19 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module NitroKit
|
2
4
|
class ButtonGroup < Component
|
3
|
-
def
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
]
|
14
|
-
),
|
15
|
-
&block
|
5
|
+
def initialize(**attrs)
|
6
|
+
super(
|
7
|
+
attrs,
|
8
|
+
class: [
|
9
|
+
"flex -space-x-px isolate",
|
10
|
+
# Remove rounded corners from middle buttons
|
11
|
+
"[&>*:not(:first-child):not(:last-child)]:rounded-none [&>*:first-child:not(:last-child)]:rounded-r-none [&>*:last-child:not(:first-child)]:rounded-l-none",
|
12
|
+
# Put focused button on top
|
13
|
+
"[&>*]:focus:z-10"
|
14
|
+
]
|
16
15
|
)
|
17
16
|
end
|
17
|
+
|
18
|
+
def view_template
|
19
|
+
div(**attrs) do
|
20
|
+
yield
|
21
|
+
end
|
22
|
+
end
|
18
23
|
end
|
19
24
|
end
|