nanoui 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +189 -199
- data/lib/generators/nanoui/component_generator.rb +0 -52
- data/lib/generators/nanoui/install_generator.rb +0 -18
- data/lib/generators/nanoui/templates/css/components/alert.css +1 -1
- data/lib/generators/nanoui/templates/css/components/button.css +36 -7
- data/lib/generators/nanoui/templates/css/components/card.css +2 -1
- data/lib/generators/nanoui/templates/css/components/dialog.css +1 -1
- data/lib/generators/nanoui/templates/css/components/input.css +62 -8
- data/lib/generators/nanoui/templates/css/components/label.css +2 -1
- data/lib/generators/nanoui/templates/css/components/select.css +12 -7
- data/lib/nanoui/version.rb +1 -1
- metadata +1 -22
- data/lib/generators/nanoui/templates/css/nanoui.css +0 -33
- data/lib/generators/nanoui/templates/css/nanoui.install.css +0 -15
- data/lib/generators/nanoui/templates/views/components/_accordion.html.erb +0 -40
- data/lib/generators/nanoui/templates/views/components/_alert.html.erb +0 -33
- data/lib/generators/nanoui/templates/views/components/_badge.html.erb +0 -18
- data/lib/generators/nanoui/templates/views/components/_button.html.erb +0 -27
- data/lib/generators/nanoui/templates/views/components/_card.html.erb +0 -43
- data/lib/generators/nanoui/templates/views/components/_checkbox.html.erb +0 -36
- data/lib/generators/nanoui/templates/views/components/_dialog.html.erb +0 -65
- data/lib/generators/nanoui/templates/views/components/_dropdown.html.erb +0 -29
- data/lib/generators/nanoui/templates/views/components/_input.html.erb +0 -42
- data/lib/generators/nanoui/templates/views/components/_label.html.erb +0 -20
- data/lib/generators/nanoui/templates/views/components/_progress.html.erb +0 -29
- data/lib/generators/nanoui/templates/views/components/_radio_group.html.erb +0 -46
- data/lib/generators/nanoui/templates/views/components/_select.html.erb +0 -67
- data/lib/generators/nanoui/templates/views/components/_switch.html.erb +0 -32
- data/lib/generators/nanoui/templates/views/components/_table.html.erb +0 -41
- data/lib/generators/nanoui/templates/views/components/_tabs.html.erb +0 -46
- data/lib/generators/nanoui/templates/views/components/_toast.html.erb +0 -33
- data/lib/generators/nanoui/templates/views/components/_toast_container.html.erb +0 -17
- data/lib/generators/nanoui/templates/views/components/_tooltip.html.erb +0 -28
|
@@ -23,7 +23,6 @@ module Nanoui
|
|
|
23
23
|
accordion
|
|
24
24
|
progress
|
|
25
25
|
].freeze
|
|
26
|
-
COMPONENT_IMPORT_PATTERN = /^\s*@import "components\/_?([^\"]+)\.css";\s*\n?/
|
|
27
26
|
|
|
28
27
|
argument :components, type: :array, default: [], banner: "component [component] ..."
|
|
29
28
|
|
|
@@ -38,12 +37,6 @@ module Nanoui
|
|
|
38
37
|
}.freeze
|
|
39
38
|
|
|
40
39
|
STIMULUS_COMPONENTS = %w[dialog dropdown tooltip toast tabs accordion switch].freeze
|
|
41
|
-
PARTIAL_TEMPLATES = COMPONENT_ORDER.each_with_object({}) do |name, partials|
|
|
42
|
-
partials[name] = [name]
|
|
43
|
-
end.merge(
|
|
44
|
-
"radio" => %w[radio_group],
|
|
45
|
-
"toast" => %w[toast toast_container]
|
|
46
|
-
).freeze
|
|
47
40
|
|
|
48
41
|
def resolve_components
|
|
49
42
|
@resolved = if options[:all]
|
|
@@ -72,34 +65,6 @@ module Nanoui
|
|
|
72
65
|
end
|
|
73
66
|
end
|
|
74
67
|
|
|
75
|
-
def copy_partials
|
|
76
|
-
@resolved.each do |name|
|
|
77
|
-
PARTIAL_TEMPLATES.fetch(name, [name]).each do |partial_name|
|
|
78
|
-
source = "views/components/_#{partial_name}.html.erb"
|
|
79
|
-
next unless File.exist?(File.join(self.class.source_root, source))
|
|
80
|
-
|
|
81
|
-
copy_file source, "app/views/components/_#{partial_name}.html.erb"
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def update_nanoui_css
|
|
87
|
-
nanoui_css = "app/assets/stylesheets/nanoui/nanoui.css"
|
|
88
|
-
return unless File.exist?(nanoui_css)
|
|
89
|
-
|
|
90
|
-
content = File.read(nanoui_css)
|
|
91
|
-
content_without_component_imports = content.gsub(COMPONENT_IMPORT_PATTERN, "")
|
|
92
|
-
component_section = ["/* Components */", component_imports].reject(&:empty?).join("\n")
|
|
93
|
-
|
|
94
|
-
updated_content = if content_without_component_imports.include?("/* Components */")
|
|
95
|
-
content_without_component_imports.sub("/* Components */", component_section)
|
|
96
|
-
else
|
|
97
|
-
"#{content_without_component_imports.rstrip}\n\n#{component_section}\n"
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
File.write(nanoui_css, updated_content)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
68
|
def print_summary
|
|
104
69
|
say ""
|
|
105
70
|
say "NanoUI components installed:", :green
|
|
@@ -110,23 +75,6 @@ module Nanoui
|
|
|
110
75
|
end
|
|
111
76
|
say ""
|
|
112
77
|
end
|
|
113
|
-
|
|
114
|
-
private
|
|
115
|
-
|
|
116
|
-
def component_imports
|
|
117
|
-
installed_components.map { |name| "@import \"components/#{name}.css\";" }.join("\n")
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def installed_components
|
|
121
|
-
component_dir = "app/assets/stylesheets/nanoui/components"
|
|
122
|
-
names = Dir.glob(File.join(component_dir, "*.css")).map do |path|
|
|
123
|
-
File.basename(path, ".css").delete_prefix("_")
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
names.uniq.sort_by do |name|
|
|
127
|
-
[COMPONENT_ORDER.index(name) || COMPONENT_ORDER.length, name]
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
78
|
end
|
|
131
79
|
end
|
|
132
80
|
end
|
|
@@ -3,34 +3,16 @@ module Nanoui
|
|
|
3
3
|
class InstallGenerator < Rails::Generators::Base
|
|
4
4
|
source_root File.expand_path("templates", __dir__)
|
|
5
5
|
|
|
6
|
-
APPLICATION_IMPORT = '@import "nanoui/nanoui.css";'.freeze
|
|
7
|
-
LEADING_CSS_HEADER_PATTERN = /\A((?:\s|\/\*.*?\*\/\s*)*(?:@charset\s+[^;]+;\s*)?(?:@import\s+[^;]+;\s*)*)/m.freeze
|
|
8
|
-
|
|
9
6
|
desc "Install NanoUI foundation (base styles, fonts)"
|
|
10
7
|
|
|
11
8
|
def copy_base
|
|
12
9
|
directory "css/base", "app/assets/stylesheets/nanoui/base"
|
|
13
10
|
end
|
|
14
11
|
|
|
15
|
-
def copy_entry_point
|
|
16
|
-
copy_file "css/nanoui.install.css", "app/assets/stylesheets/nanoui/nanoui.css"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
12
|
def copy_fonts
|
|
20
13
|
directory "css/fonts", "app/assets/stylesheets/nanoui/fonts"
|
|
21
14
|
end
|
|
22
15
|
|
|
23
|
-
def add_import_to_application_css
|
|
24
|
-
application_css = "app/assets/stylesheets/application.css"
|
|
25
|
-
return unless File.exist?(application_css)
|
|
26
|
-
|
|
27
|
-
content = File.read(application_css)
|
|
28
|
-
return if content.include?(APPLICATION_IMPORT)
|
|
29
|
-
|
|
30
|
-
updated_content = content.sub(LEADING_CSS_HEADER_PATTERN, "\\1#{APPLICATION_IMPORT}\n")
|
|
31
|
-
File.write(application_css, updated_content)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
16
|
def print_instructions
|
|
35
17
|
say ""
|
|
36
18
|
say "NanoUI installed!", :green
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
.nano-btn
|
|
1
|
+
.nano-btn,
|
|
2
|
+
button,
|
|
3
|
+
input[type="submit"],
|
|
4
|
+
input[type="button"],
|
|
5
|
+
input[type="reset"] {
|
|
2
6
|
display: inline-flex;
|
|
3
7
|
align-items: center;
|
|
4
8
|
justify-content: center;
|
|
@@ -13,15 +17,34 @@
|
|
|
13
17
|
transition: background-color var(--duration-fast) var(--ease-default),
|
|
14
18
|
color var(--duration-fast) var(--ease-default);
|
|
15
19
|
padding: var(--space-2-5) var(--space-4);
|
|
20
|
+
background-color: hsl(var(--color-primary));
|
|
21
|
+
color: hsl(var(--color-primary-foreground));
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
.nano-btn:
|
|
24
|
+
.nano-btn:hover,
|
|
25
|
+
button:hover,
|
|
26
|
+
input[type="submit"]:hover,
|
|
27
|
+
input[type="button"]:hover,
|
|
28
|
+
input[type="reset"]:hover {
|
|
29
|
+
background-color: hsl(var(--color-primary) / 0.9);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.nano-btn:focus-visible,
|
|
33
|
+
button:focus-visible,
|
|
34
|
+
input[type="submit"]:focus-visible,
|
|
35
|
+
input[type="button"]:focus-visible,
|
|
36
|
+
input[type="reset"]:focus-visible {
|
|
19
37
|
outline: 2px solid hsl(var(--color-ring));
|
|
20
38
|
outline-offset: 2px;
|
|
21
39
|
}
|
|
22
40
|
|
|
23
41
|
.nano-btn:disabled,
|
|
24
|
-
.nano-btn[aria-disabled="true"]
|
|
42
|
+
.nano-btn[aria-disabled="true"],
|
|
43
|
+
button:disabled,
|
|
44
|
+
button[aria-disabled="true"],
|
|
45
|
+
input[type="submit"]:disabled,
|
|
46
|
+
input[type="button"]:disabled,
|
|
47
|
+
input[type="reset"]:disabled {
|
|
25
48
|
pointer-events: none;
|
|
26
49
|
opacity: 0.5;
|
|
27
50
|
}
|
|
@@ -38,10 +61,11 @@
|
|
|
38
61
|
.nano-btn--secondary {
|
|
39
62
|
background-color: hsl(var(--color-secondary));
|
|
40
63
|
color: hsl(var(--color-secondary-foreground));
|
|
64
|
+
border: 1px solid hsl(var(--color-border));
|
|
41
65
|
}
|
|
42
66
|
|
|
43
67
|
.nano-btn--secondary:hover {
|
|
44
|
-
background-color: hsl(var(--color-
|
|
68
|
+
background-color: hsl(var(--color-muted-foreground) / 0.15);
|
|
45
69
|
}
|
|
46
70
|
|
|
47
71
|
.nano-btn--destructive {
|
|
@@ -75,13 +99,14 @@
|
|
|
75
99
|
.nano-btn--link {
|
|
76
100
|
background-color: transparent;
|
|
77
101
|
color: hsl(var(--color-primary));
|
|
78
|
-
text-decoration: underline;
|
|
102
|
+
text-decoration: underline dashed;
|
|
79
103
|
text-underline-offset: 4px;
|
|
80
104
|
padding: 0;
|
|
81
105
|
}
|
|
82
106
|
|
|
83
107
|
.nano-btn--link:hover {
|
|
84
|
-
|
|
108
|
+
background-color: transparent;
|
|
109
|
+
text-decoration-style: solid;
|
|
85
110
|
}
|
|
86
111
|
|
|
87
112
|
.nano-btn--sm {
|
|
@@ -109,7 +134,11 @@
|
|
|
109
134
|
to { transform: rotate(360deg); }
|
|
110
135
|
}
|
|
111
136
|
|
|
112
|
-
.nano-btn svg
|
|
137
|
+
.nano-btn svg,
|
|
138
|
+
button svg,
|
|
139
|
+
input[type="submit"] svg,
|
|
140
|
+
input[type="button"] svg,
|
|
141
|
+
input[type="reset"] svg {
|
|
113
142
|
width: 1em;
|
|
114
143
|
height: 1em;
|
|
115
144
|
flex-shrink: 0;
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
|
|
34
34
|
.nano-card__description {
|
|
35
35
|
font-size: var(--text-sm);
|
|
36
|
-
color: hsl(var(--color-
|
|
36
|
+
color: hsl(var(--color-foreground));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.nano-card__content {
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
.nano-card__footer {
|
|
44
44
|
display: flex;
|
|
45
45
|
align-items: center;
|
|
46
|
+
gap: var(--space-2);
|
|
46
47
|
padding: var(--space-6);
|
|
47
48
|
padding-top: 0;
|
|
48
49
|
}
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
gap: var(--space-1-5);
|
|
59
59
|
padding: var(--space-6);
|
|
60
60
|
padding-bottom: 0;
|
|
61
|
+
padding-right: var(--space-12);
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
.nano-dialog__title {
|
|
@@ -82,7 +83,6 @@
|
|
|
82
83
|
justify-content: flex-end;
|
|
83
84
|
gap: var(--space-2);
|
|
84
85
|
padding: var(--space-6);
|
|
85
|
-
padding-top: 0;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
.nano-dialog__close {
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
.nano-input
|
|
1
|
+
.nano-input,
|
|
2
|
+
input[type="text"],
|
|
3
|
+
input[type="email"],
|
|
4
|
+
input[type="password"],
|
|
5
|
+
input[type="search"],
|
|
6
|
+
input[type="tel"],
|
|
7
|
+
input[type="url"],
|
|
8
|
+
input[type="number"],
|
|
9
|
+
input[type="date"],
|
|
10
|
+
input[type="datetime-local"],
|
|
11
|
+
input[type="month"],
|
|
12
|
+
input[type="week"],
|
|
13
|
+
input[type="time"],
|
|
14
|
+
textarea {
|
|
2
15
|
display: block;
|
|
3
16
|
width: 100%;
|
|
4
17
|
padding: var(--space-2) var(--space-3);
|
|
@@ -13,17 +26,56 @@
|
|
|
13
26
|
box-shadow var(--duration-fast) var(--ease-default);
|
|
14
27
|
}
|
|
15
28
|
|
|
16
|
-
.nano-input::placeholder
|
|
29
|
+
.nano-input::placeholder,
|
|
30
|
+
input[type="text"]::placeholder,
|
|
31
|
+
input[type="email"]::placeholder,
|
|
32
|
+
input[type="password"]::placeholder,
|
|
33
|
+
input[type="search"]::placeholder,
|
|
34
|
+
input[type="tel"]::placeholder,
|
|
35
|
+
input[type="url"]::placeholder,
|
|
36
|
+
input[type="number"]::placeholder,
|
|
37
|
+
input[type="date"]::placeholder,
|
|
38
|
+
input[type="datetime-local"]::placeholder,
|
|
39
|
+
input[type="month"]::placeholder,
|
|
40
|
+
input[type="week"]::placeholder,
|
|
41
|
+
input[type="time"]::placeholder,
|
|
42
|
+
textarea::placeholder {
|
|
17
43
|
color: hsl(var(--color-muted-foreground));
|
|
18
44
|
}
|
|
19
45
|
|
|
20
|
-
.nano-input:focus
|
|
21
|
-
|
|
46
|
+
.nano-input:focus,
|
|
47
|
+
input[type="text"]:focus,
|
|
48
|
+
input[type="email"]:focus,
|
|
49
|
+
input[type="password"]:focus,
|
|
50
|
+
input[type="search"]:focus,
|
|
51
|
+
input[type="tel"]:focus,
|
|
52
|
+
input[type="url"]:focus,
|
|
53
|
+
input[type="number"]:focus,
|
|
54
|
+
input[type="date"]:focus,
|
|
55
|
+
input[type="datetime-local"]:focus,
|
|
56
|
+
input[type="month"]:focus,
|
|
57
|
+
input[type="week"]:focus,
|
|
58
|
+
input[type="time"]:focus,
|
|
59
|
+
textarea:focus {
|
|
22
60
|
border-color: hsl(var(--color-input-focus));
|
|
23
|
-
|
|
61
|
+
outline: 2px solid hsl(var(--color-input-focus));
|
|
62
|
+
outline-offset: -1px;
|
|
24
63
|
}
|
|
25
64
|
|
|
26
|
-
.nano-input:disabled
|
|
65
|
+
.nano-input:disabled,
|
|
66
|
+
input[type="text"]:disabled,
|
|
67
|
+
input[type="email"]:disabled,
|
|
68
|
+
input[type="password"]:disabled,
|
|
69
|
+
input[type="search"]:disabled,
|
|
70
|
+
input[type="tel"]:disabled,
|
|
71
|
+
input[type="url"]:disabled,
|
|
72
|
+
input[type="number"]:disabled,
|
|
73
|
+
input[type="date"]:disabled,
|
|
74
|
+
input[type="datetime-local"]:disabled,
|
|
75
|
+
input[type="month"]:disabled,
|
|
76
|
+
input[type="week"]:disabled,
|
|
77
|
+
input[type="time"]:disabled,
|
|
78
|
+
textarea:disabled {
|
|
27
79
|
opacity: 0.5;
|
|
28
80
|
cursor: not-allowed;
|
|
29
81
|
}
|
|
@@ -36,10 +88,12 @@
|
|
|
36
88
|
.nano-input--error:focus,
|
|
37
89
|
.nano-input[aria-invalid="true"]:focus {
|
|
38
90
|
border-color: hsl(var(--color-destructive));
|
|
39
|
-
|
|
91
|
+
outline: 2px solid hsl(var(--color-destructive));
|
|
92
|
+
outline-offset: -1px;
|
|
40
93
|
}
|
|
41
94
|
|
|
42
|
-
textarea.nano-input
|
|
95
|
+
textarea.nano-input,
|
|
96
|
+
textarea {
|
|
43
97
|
min-height: 5rem;
|
|
44
98
|
resize: vertical;
|
|
45
99
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
.nano-select
|
|
1
|
+
.nano-select,
|
|
2
|
+
select {
|
|
2
3
|
display: block;
|
|
3
4
|
width: 100%;
|
|
4
5
|
padding: var(--space-2) var(--space-8) var(--space-2) var(--space-3);
|
|
@@ -18,13 +19,15 @@
|
|
|
18
19
|
box-shadow var(--duration-fast) var(--ease-default);
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
.nano-select:focus
|
|
22
|
-
|
|
22
|
+
.nano-select:focus,
|
|
23
|
+
select:focus {
|
|
23
24
|
border-color: hsl(var(--color-input-focus));
|
|
24
|
-
|
|
25
|
+
outline: 2px solid hsl(var(--color-input-focus));
|
|
26
|
+
outline-offset: -1px;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
.nano-select:disabled
|
|
29
|
+
.nano-select:disabled,
|
|
30
|
+
select:disabled {
|
|
28
31
|
opacity: 0.5;
|
|
29
32
|
cursor: not-allowed;
|
|
30
33
|
}
|
|
@@ -37,9 +40,11 @@
|
|
|
37
40
|
.nano-select--error:focus,
|
|
38
41
|
.nano-select[aria-invalid="true"]:focus {
|
|
39
42
|
border-color: hsl(var(--color-destructive));
|
|
40
|
-
|
|
43
|
+
outline: 2px solid hsl(var(--color-destructive));
|
|
44
|
+
outline-offset: -1px;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
.dark .nano-select
|
|
47
|
+
.dark .nano-select,
|
|
48
|
+
.dark select {
|
|
44
49
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
45
50
|
}
|
data/lib/nanoui/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nanoui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Denis Omerovic
|
|
@@ -79,8 +79,6 @@ files:
|
|
|
79
79
|
- lib/generators/nanoui/templates/css/components/toast.css
|
|
80
80
|
- lib/generators/nanoui/templates/css/components/tooltip.css
|
|
81
81
|
- lib/generators/nanoui/templates/css/fonts/inter-variable.ttf
|
|
82
|
-
- lib/generators/nanoui/templates/css/nanoui.css
|
|
83
|
-
- lib/generators/nanoui/templates/css/nanoui.install.css
|
|
84
82
|
- lib/generators/nanoui/templates/js/controllers/accordion_controller.js
|
|
85
83
|
- lib/generators/nanoui/templates/js/controllers/dialog_controller.js
|
|
86
84
|
- lib/generators/nanoui/templates/js/controllers/dropdown_controller.js
|
|
@@ -88,25 +86,6 @@ files:
|
|
|
88
86
|
- lib/generators/nanoui/templates/js/controllers/tabs_controller.js
|
|
89
87
|
- lib/generators/nanoui/templates/js/controllers/toast_controller.js
|
|
90
88
|
- lib/generators/nanoui/templates/js/controllers/tooltip_controller.js
|
|
91
|
-
- lib/generators/nanoui/templates/views/components/_accordion.html.erb
|
|
92
|
-
- lib/generators/nanoui/templates/views/components/_alert.html.erb
|
|
93
|
-
- lib/generators/nanoui/templates/views/components/_badge.html.erb
|
|
94
|
-
- lib/generators/nanoui/templates/views/components/_button.html.erb
|
|
95
|
-
- lib/generators/nanoui/templates/views/components/_card.html.erb
|
|
96
|
-
- lib/generators/nanoui/templates/views/components/_checkbox.html.erb
|
|
97
|
-
- lib/generators/nanoui/templates/views/components/_dialog.html.erb
|
|
98
|
-
- lib/generators/nanoui/templates/views/components/_dropdown.html.erb
|
|
99
|
-
- lib/generators/nanoui/templates/views/components/_input.html.erb
|
|
100
|
-
- lib/generators/nanoui/templates/views/components/_label.html.erb
|
|
101
|
-
- lib/generators/nanoui/templates/views/components/_progress.html.erb
|
|
102
|
-
- lib/generators/nanoui/templates/views/components/_radio_group.html.erb
|
|
103
|
-
- lib/generators/nanoui/templates/views/components/_select.html.erb
|
|
104
|
-
- lib/generators/nanoui/templates/views/components/_switch.html.erb
|
|
105
|
-
- lib/generators/nanoui/templates/views/components/_table.html.erb
|
|
106
|
-
- lib/generators/nanoui/templates/views/components/_tabs.html.erb
|
|
107
|
-
- lib/generators/nanoui/templates/views/components/_toast.html.erb
|
|
108
|
-
- lib/generators/nanoui/templates/views/components/_toast_container.html.erb
|
|
109
|
-
- lib/generators/nanoui/templates/views/components/_tooltip.html.erb
|
|
110
89
|
- lib/nanoui.rb
|
|
111
90
|
- lib/nanoui/version.rb
|
|
112
91
|
homepage: https://github.com/chille1987/nanoui
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/* NanoUI — Vanilla CSS + Stimulus Component Library */
|
|
2
|
-
|
|
3
|
-
/* Base */
|
|
4
|
-
@import "base/01_reset.css";
|
|
5
|
-
@import "base/02_fonts.css";
|
|
6
|
-
@import "base/03_colors.css";
|
|
7
|
-
@import "base/04_typography.css";
|
|
8
|
-
@import "base/05_spacing.css";
|
|
9
|
-
@import "base/06_radius.css";
|
|
10
|
-
@import "base/07_shadows.css";
|
|
11
|
-
@import "base/08_transitions.css";
|
|
12
|
-
@import "base/09_z-index.css";
|
|
13
|
-
@import "base/10_globals.css";
|
|
14
|
-
|
|
15
|
-
/* Components */
|
|
16
|
-
@import "components/button.css";
|
|
17
|
-
@import "components/input.css";
|
|
18
|
-
@import "components/label.css";
|
|
19
|
-
@import "components/card.css";
|
|
20
|
-
@import "components/checkbox.css";
|
|
21
|
-
@import "components/radio.css";
|
|
22
|
-
@import "components/switch.css";
|
|
23
|
-
@import "components/select.css";
|
|
24
|
-
@import "components/badge.css";
|
|
25
|
-
@import "components/alert.css";
|
|
26
|
-
@import "components/dialog.css";
|
|
27
|
-
@import "components/dropdown.css";
|
|
28
|
-
@import "components/tooltip.css";
|
|
29
|
-
@import "components/toast.css";
|
|
30
|
-
@import "components/table.css";
|
|
31
|
-
@import "components/tabs.css";
|
|
32
|
-
@import "components/accordion.css";
|
|
33
|
-
@import "components/progress.css";
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/* NanoUI — Vanilla CSS + Stimulus Component Library */
|
|
2
|
-
|
|
3
|
-
/* Base */
|
|
4
|
-
@import "base/01_reset.css";
|
|
5
|
-
@import "base/02_fonts.css";
|
|
6
|
-
@import "base/03_colors.css";
|
|
7
|
-
@import "base/04_typography.css";
|
|
8
|
-
@import "base/05_spacing.css";
|
|
9
|
-
@import "base/06_radius.css";
|
|
10
|
-
@import "base/07_shadows.css";
|
|
11
|
-
@import "base/08_transitions.css";
|
|
12
|
-
@import "base/09_z-index.css";
|
|
13
|
-
@import "base/10_globals.css";
|
|
14
|
-
|
|
15
|
-
/* Components */
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
<%# NanoUI Accordion (native <details>/<summary> with Stimulus)
|
|
2
|
-
Options: items (array of {title:, content:, open:}), single (false), class
|
|
3
|
-
Usage:
|
|
4
|
-
render "components/accordion", single: true, items: [
|
|
5
|
-
{ title: "Is it free?", content: "Yes, MIT licensed.", open: true },
|
|
6
|
-
{ title: "Build step?", content: "No, vanilla CSS." },
|
|
7
|
-
{ title: "Dark mode?", content: "Add .dark class to html." }
|
|
8
|
-
]
|
|
9
|
-
%>
|
|
10
|
-
<%
|
|
11
|
-
items = local_assigns.fetch(:items, [])
|
|
12
|
-
single = local_assigns.fetch(:single, false)
|
|
13
|
-
classes = local_assigns.fetch(:class, "")
|
|
14
|
-
|
|
15
|
-
css = "nano-accordion"
|
|
16
|
-
css += " #{classes}" if classes.present?
|
|
17
|
-
%>
|
|
18
|
-
|
|
19
|
-
<div class="<%= css.strip %>"
|
|
20
|
-
data-controller="nanoui-accordion"
|
|
21
|
-
data-nanoui-accordion-single-value="<%= single %>">
|
|
22
|
-
<% items.each do |item| %>
|
|
23
|
-
<details class="nano-accordion__item"
|
|
24
|
-
data-nanoui-accordion-target="item"
|
|
25
|
-
data-action="toggle->nanoui-accordion#toggle"
|
|
26
|
-
<%= "open" if item[:open] %>>
|
|
27
|
-
<summary class="nano-accordion__trigger">
|
|
28
|
-
<span><%= item[:title] %></span>
|
|
29
|
-
<svg class="nano-accordion__icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
|
30
|
-
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
31
|
-
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
32
|
-
<path d="m6 9 6 6 6-6"/>
|
|
33
|
-
</svg>
|
|
34
|
-
</summary>
|
|
35
|
-
<div class="nano-accordion__content">
|
|
36
|
-
<p><%= item[:content] %></p>
|
|
37
|
-
</div>
|
|
38
|
-
</details>
|
|
39
|
-
<% end %>
|
|
40
|
-
</div>
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
<%# NanoUI Alert
|
|
2
|
-
Variants: default, destructive, success, warning
|
|
3
|
-
Options: variant, title, icon, class
|
|
4
|
-
Usage:
|
|
5
|
-
render "components/alert", variant: "success", title: "Saved!" do
|
|
6
|
-
"Your changes have been saved."
|
|
7
|
-
end
|
|
8
|
-
%>
|
|
9
|
-
<%
|
|
10
|
-
variant = local_assigns.fetch(:variant, nil)
|
|
11
|
-
title = local_assigns.fetch(:title, nil)
|
|
12
|
-
icon = local_assigns.fetch(:icon, nil)
|
|
13
|
-
classes = local_assigns.fetch(:class, "")
|
|
14
|
-
|
|
15
|
-
css = ["nano-alert"]
|
|
16
|
-
css << "nano-alert--#{variant}" if variant
|
|
17
|
-
css << classes if classes.present?
|
|
18
|
-
%>
|
|
19
|
-
|
|
20
|
-
<div class="<%= css.join(" ").strip %>" role="alert">
|
|
21
|
-
<% if icon %>
|
|
22
|
-
<div class="nano-alert__icon">
|
|
23
|
-
<%= icon %>
|
|
24
|
-
</div>
|
|
25
|
-
<% end %>
|
|
26
|
-
|
|
27
|
-
<div class="nano-alert__content">
|
|
28
|
-
<% if title %>
|
|
29
|
-
<p class="nano-alert__title"><%= title %></p>
|
|
30
|
-
<% end %>
|
|
31
|
-
<p class="nano-alert__description"><%= yield %></p>
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<%# NanoUI Badge
|
|
2
|
-
Variants: primary (default), secondary, destructive, outline, success, warning
|
|
3
|
-
Options: variant, class, html
|
|
4
|
-
Usage:
|
|
5
|
-
render "components/badge", variant: "success" do "Active" end
|
|
6
|
-
%>
|
|
7
|
-
<%
|
|
8
|
-
variant = local_assigns.fetch(:variant, "primary")
|
|
9
|
-
classes = local_assigns.fetch(:class, "")
|
|
10
|
-
html = local_assigns.fetch(:html, {}).symbolize_keys
|
|
11
|
-
|
|
12
|
-
css = "nano-badge nano-badge--#{variant}"
|
|
13
|
-
css += " #{classes}" if classes.present?
|
|
14
|
-
%>
|
|
15
|
-
|
|
16
|
-
<%= content_tag(:span, { class: css.strip }.merge(html)) do %>
|
|
17
|
-
<%= yield %>
|
|
18
|
-
<% end %>
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
<%# NanoUI Button
|
|
2
|
-
Variants: primary (default), secondary, destructive, outline, ghost, link
|
|
3
|
-
Sizes: sm, md (default), lg, icon
|
|
4
|
-
Options: tag (:button), href (auto-switches to :a), class, html (extra attrs)
|
|
5
|
-
Usage:
|
|
6
|
-
render "components/button", variant: "primary" do "Save" end
|
|
7
|
-
render "components/button", variant: "outline", size: "sm" do "Cancel" end
|
|
8
|
-
render "components/button", href: "/about" do "Learn More" end
|
|
9
|
-
%>
|
|
10
|
-
<%
|
|
11
|
-
variant = local_assigns.fetch(:variant, "primary")
|
|
12
|
-
size = local_assigns.fetch(:size, nil)
|
|
13
|
-
tag = local_assigns.fetch(:tag, :button)
|
|
14
|
-
href = local_assigns.fetch(:href, nil)
|
|
15
|
-
classes = local_assigns.fetch(:class, "")
|
|
16
|
-
html = local_assigns.fetch(:html, {}).symbolize_keys
|
|
17
|
-
|
|
18
|
-
css = ["nano-btn", "nano-btn--#{variant}"]
|
|
19
|
-
css << "nano-btn--#{size}" if size
|
|
20
|
-
css << classes if classes.present?
|
|
21
|
-
tag = :a if href
|
|
22
|
-
html[:type] = "button" if tag == :button && !html.key?(:type)
|
|
23
|
-
%>
|
|
24
|
-
|
|
25
|
-
<%= content_tag(tag, href: href, class: css.join(" ").strip, **html) do %>
|
|
26
|
-
<%= yield %>
|
|
27
|
-
<% end %>
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
<%# NanoUI Card
|
|
2
|
-
Variants: default, elevated, bordered
|
|
3
|
-
Options: variant, tag (:article), title, description, footer, class, html
|
|
4
|
-
Usage:
|
|
5
|
-
render "components/card",
|
|
6
|
-
title: "My Card",
|
|
7
|
-
description: "Subtitle",
|
|
8
|
-
footer: render("components/button", variant: "primary") { "Save" } do
|
|
9
|
-
"Card body content"
|
|
10
|
-
end
|
|
11
|
-
%>
|
|
12
|
-
<%
|
|
13
|
-
variant = local_assigns.fetch(:variant, nil)
|
|
14
|
-
tag = local_assigns.fetch(:tag, :article)
|
|
15
|
-
title = local_assigns.fetch(:title, nil)
|
|
16
|
-
desc = local_assigns.fetch(:description, nil)
|
|
17
|
-
footer = local_assigns.fetch(:footer, nil)
|
|
18
|
-
classes = local_assigns.fetch(:class, "")
|
|
19
|
-
html = local_assigns.fetch(:html, {}).symbolize_keys
|
|
20
|
-
|
|
21
|
-
css = ["nano-card"]
|
|
22
|
-
css << "nano-card--#{variant}" if variant
|
|
23
|
-
css << classes if classes.present?
|
|
24
|
-
%>
|
|
25
|
-
|
|
26
|
-
<%= content_tag(tag, class: css.join(" ").strip, **html) do %>
|
|
27
|
-
<% if title || desc %>
|
|
28
|
-
<div class="nano-card__header">
|
|
29
|
-
<% if title %><h3 class="nano-card__title"><%= title %></h3><% end %>
|
|
30
|
-
<% if desc %><p class="nano-card__description"><%= desc %></p><% end %>
|
|
31
|
-
</div>
|
|
32
|
-
<% end %>
|
|
33
|
-
|
|
34
|
-
<div class="nano-card__content">
|
|
35
|
-
<%= yield %>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
<% if footer %>
|
|
39
|
-
<div class="nano-card__footer">
|
|
40
|
-
<%= footer %>
|
|
41
|
-
</div>
|
|
42
|
-
<% end %>
|
|
43
|
-
<% end %>
|