kiso 0.1.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +27 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +117 -0
  5. data/Rakefile +5 -0
  6. data/app/assets/fonts/kiso/GeistMonoVF.woff2 +0 -0
  7. data/app/assets/fonts/kiso/GeistVF.woff2 +0 -0
  8. data/app/assets/fonts/kiso/OFL.txt +93 -0
  9. data/app/assets/tailwind/kiso/engine.css +32 -0
  10. data/app/helpers/kiso/component_helper.rb +47 -0
  11. data/app/helpers/kiso/icon_helper.rb +48 -0
  12. data/app/views/kiso/components/_alert.html.erb +8 -0
  13. data/app/views/kiso/components/_badge.html.erb +7 -0
  14. data/app/views/kiso/components/_button.html.erb +19 -0
  15. data/app/views/kiso/components/_card.html.erb +7 -0
  16. data/app/views/kiso/components/_empty_state.html.erb +7 -0
  17. data/app/views/kiso/components/_separator.html.erb +7 -0
  18. data/app/views/kiso/components/_stats_card.html.erb +7 -0
  19. data/app/views/kiso/components/_stats_grid.html.erb +7 -0
  20. data/app/views/kiso/components/_table.html.erb +8 -0
  21. data/app/views/kiso/components/alert/_description.html.erb +7 -0
  22. data/app/views/kiso/components/alert/_title.html.erb +7 -0
  23. data/app/views/kiso/components/card/_content.html.erb +7 -0
  24. data/app/views/kiso/components/card/_description.html.erb +7 -0
  25. data/app/views/kiso/components/card/_footer.html.erb +7 -0
  26. data/app/views/kiso/components/card/_header.html.erb +7 -0
  27. data/app/views/kiso/components/card/_title.html.erb +7 -0
  28. data/app/views/kiso/components/empty_state/_content.html.erb +7 -0
  29. data/app/views/kiso/components/empty_state/_description.html.erb +7 -0
  30. data/app/views/kiso/components/empty_state/_header.html.erb +7 -0
  31. data/app/views/kiso/components/empty_state/_media.html.erb +7 -0
  32. data/app/views/kiso/components/empty_state/_title.html.erb +7 -0
  33. data/app/views/kiso/components/stats_card/_description.html.erb +7 -0
  34. data/app/views/kiso/components/stats_card/_header.html.erb +7 -0
  35. data/app/views/kiso/components/stats_card/_label.html.erb +7 -0
  36. data/app/views/kiso/components/stats_card/_value.html.erb +7 -0
  37. data/app/views/kiso/components/table/_body.html.erb +7 -0
  38. data/app/views/kiso/components/table/_caption.html.erb +7 -0
  39. data/app/views/kiso/components/table/_cell.html.erb +7 -0
  40. data/app/views/kiso/components/table/_footer.html.erb +7 -0
  41. data/app/views/kiso/components/table/_head.html.erb +7 -0
  42. data/app/views/kiso/components/table/_header.html.erb +7 -0
  43. data/app/views/kiso/components/table/_row.html.erb +7 -0
  44. data/lib/kiso/cli/base.rb +37 -0
  45. data/lib/kiso/cli/icons.rb +6 -0
  46. data/lib/kiso/cli/main.rb +14 -0
  47. data/lib/kiso/cli/make.rb +369 -0
  48. data/lib/kiso/cli.rb +14 -0
  49. data/lib/kiso/engine.rb +26 -0
  50. data/lib/kiso/themes/alert.rb +65 -0
  51. data/lib/kiso/themes/badge.rb +66 -0
  52. data/lib/kiso/themes/button.rb +90 -0
  53. data/lib/kiso/themes/card.rb +44 -0
  54. data/lib/kiso/themes/empty_state.rb +42 -0
  55. data/lib/kiso/themes/separator.rb +17 -0
  56. data/lib/kiso/themes/stats_card.rb +57 -0
  57. data/lib/kiso/themes/table.rb +48 -0
  58. data/lib/kiso/version.rb +3 -0
  59. data/lib/kiso.rb +17 -0
  60. metadata +175 -0
@@ -0,0 +1,7 @@
1
+ <%# locals: (css_classes: "", **component_options) %>
2
+ <%= content_tag :caption,
3
+ class: Kiso::Themes::TableCaption.render(class: css_classes),
4
+ data: { component: :table, table_part: :caption },
5
+ **component_options do %>
6
+ <%= yield %>
7
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <%# locals: (css_classes: "", **component_options) %>
2
+ <%= content_tag :td,
3
+ class: Kiso::Themes::TableCell.render(class: css_classes),
4
+ data: { component: :table, table_part: :cell },
5
+ **component_options do %>
6
+ <%= yield %>
7
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <%# locals: (css_classes: "", **component_options) %>
2
+ <%= content_tag :tfoot,
3
+ class: Kiso::Themes::TableFooter.render(class: css_classes),
4
+ data: { component: :table, table_part: :footer },
5
+ **component_options do %>
6
+ <%= yield %>
7
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <%# locals: (css_classes: "", **component_options) %>
2
+ <%= content_tag :th,
3
+ class: Kiso::Themes::TableHead.render(class: css_classes),
4
+ data: { component: :table, table_part: :head },
5
+ **component_options do %>
6
+ <%= yield %>
7
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <%# locals: (css_classes: "", **component_options) %>
2
+ <%= content_tag :thead,
3
+ class: Kiso::Themes::TableHeader.render(class: css_classes),
4
+ data: { component: :table, table_part: :header },
5
+ **component_options do %>
6
+ <%= yield %>
7
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <%# locals: (css_classes: "", **component_options) %>
2
+ <%= content_tag :tr,
3
+ class: Kiso::Themes::TableRow.render(class: css_classes),
4
+ data: { component: :table, table_part: :row },
5
+ **component_options do %>
6
+ <%= yield %>
7
+ <% end %>
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ class Kiso::Cli::Base < Thor
6
+ def self.exit_on_failure? = true
7
+
8
+ private
9
+
10
+ def gem_root
11
+ File.expand_path("../../..", __dir__)
12
+ end
13
+
14
+ def write_file(path, content)
15
+ full_path = File.join(gem_root, path)
16
+
17
+ if File.exist?(full_path)
18
+ say " exists #{path}", :yellow
19
+ return false
20
+ end
21
+
22
+ FileUtils.mkdir_p(File.dirname(full_path))
23
+ File.write(full_path, content)
24
+ say " create #{path}", :green
25
+ true
26
+ end
27
+
28
+ def append_to_file(path, line)
29
+ full_path = File.join(gem_root, path)
30
+ content = File.read(full_path)
31
+
32
+ unless content.include?(line)
33
+ File.write(full_path, content.rstrip + "\n#{line}\n")
34
+ say " update #{path}", :green
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "kiso/icons/commands"
4
+
5
+ # Delegate bin/kiso icons → kiso-icons gem's Commands class
6
+ Kiso::Cli::Icons = Kiso::Icons::Commands
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Kiso::Cli::Main < Kiso::Cli::Base
4
+ desc "version", "Show Kiso version"
5
+ def version
6
+ puts Kiso::VERSION
7
+ end
8
+
9
+ desc "icons SUBCOMMAND", "Manage icon sets (pin, unpin, pristine, list)"
10
+ subcommand "icons", Kiso::Cli::Icons
11
+
12
+ desc "make SUBCOMMAND", "Generate component files"
13
+ subcommand "make", Kiso::Cli::Make
14
+ end
@@ -0,0 +1,369 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Kiso::Cli::Make < Kiso::Cli::Base
4
+ desc "component NAME", "Generate a new Kiso component"
5
+ long_desc <<~DESC
6
+ Generates all files for a new component:
7
+ - Theme module (lib/kiso/themes/)
8
+ - ERB partial (app/views/kiso/components/)
9
+ - Lookbook preview + templates (test/components/previews/kiso/)
10
+ - Updates lib/kiso.rb with require
11
+ - Updates skills/kiso/references/components.md
12
+
13
+ Example:
14
+ $ bin/kiso make component alert
15
+ $ bin/kiso make component toggle_group
16
+ DESC
17
+ option :colored, type: :boolean, default: true, desc: "Include color + variant axes (compound variants)"
18
+ def component(name)
19
+ @name = name.underscore
20
+ @class_name = @name.camelize
21
+ @colored = options[:colored]
22
+
23
+ generate_theme
24
+ generate_partial
25
+ generate_preview
26
+ generate_preview_templates
27
+ update_requires
28
+ update_skill_components
29
+
30
+ say ""
31
+ say "Component '#{@name}' created!", :green
32
+ say ""
33
+ say "Next steps:", :cyan
34
+ say " 1. Edit lib/kiso/themes/#{@name}.rb — define variants"
35
+ say " 2. Edit app/views/kiso/components/_#{@name}.html.erb — build the markup"
36
+ say " 3. cd test/dummy && bin/rails tailwindcss:build"
37
+ say " 4. Open http://localhost:4001/lookbook"
38
+ end
39
+
40
+ private
41
+
42
+ def generate_theme
43
+ if @colored
44
+ write_file "lib/kiso/themes/#{@name}.rb", colored_theme_template
45
+ else
46
+ write_file "lib/kiso/themes/#{@name}.rb", simple_theme_template
47
+ end
48
+ end
49
+
50
+ def generate_partial
51
+ if @colored
52
+ write_file "app/views/kiso/components/_#{@name}.html.erb", colored_partial_template
53
+ else
54
+ write_file "app/views/kiso/components/_#{@name}.html.erb", simple_partial_template
55
+ end
56
+ end
57
+
58
+ def generate_preview
59
+ if @colored
60
+ write_file "test/components/previews/kiso/#{@name}_preview.rb", colored_preview_template
61
+ else
62
+ write_file "test/components/previews/kiso/#{@name}_preview.rb", simple_preview_template
63
+ end
64
+ end
65
+
66
+ def generate_preview_templates
67
+ write_file "test/components/previews/kiso/#{@name}_preview/playground.html.erb",
68
+ playground_template
69
+
70
+ if @colored
71
+ write_file "test/components/previews/kiso/#{@name}_preview/colors.html.erb",
72
+ colors_template
73
+ write_file "test/components/previews/kiso/#{@name}_preview/variants.html.erb",
74
+ variants_template
75
+ end
76
+
77
+ write_file "test/components/previews/kiso/#{@name}_preview/sizes.html.erb",
78
+ sizes_template
79
+ end
80
+
81
+ def update_requires
82
+ append_to_file "lib/kiso.rb", "require \"kiso/themes/#{@name}\""
83
+ end
84
+
85
+ def update_skill_components
86
+ path = File.join(gem_root, "skills/kiso/references/components.md")
87
+ return unless File.exist?(path)
88
+
89
+ content = File.read(path)
90
+ return if content.include?("### #{@class_name}")
91
+
92
+ entry = if @colored
93
+ <<~MD
94
+
95
+ ### #{@class_name}
96
+
97
+ **Locals:** `color:`, `variant:` (solid, outline, soft, subtle), `size:` (sm, md, lg), `css_classes:`, `**component_options`
98
+
99
+ **Defaults:** `color: :primary, variant: :soft, size: :md`
100
+
101
+ ```erb
102
+ <%%= kiso(:#{@name}, color: :primary, variant: :soft) { "Label" } %>
103
+ ```
104
+
105
+ **Theme module:** `Kiso::Themes::#{@class_name}` (`lib/kiso/themes/#{@name}.rb`)
106
+ MD
107
+ else
108
+ <<~MD
109
+
110
+ ### #{@class_name}
111
+
112
+ **Locals:** `variant:`, `size:` (sm, md, lg), `css_classes:`, `**component_options`
113
+
114
+ **Defaults:** `variant: :default, size: :md`
115
+
116
+ ```erb
117
+ <%%= kiso(:#{@name}) { "Label" } %>
118
+ ```
119
+
120
+ **Theme module:** `Kiso::Themes::#{@class_name}` (`lib/kiso/themes/#{@name}.rb`)
121
+ MD
122
+ end
123
+
124
+ File.write(path, content.rstrip + "\n" + entry)
125
+ say " update skills/kiso/references/components.md", :green
126
+ end
127
+
128
+ # -- Theme templates --
129
+
130
+ def colored_theme_template
131
+ <<~RUBY
132
+ module Kiso
133
+ module Themes
134
+ #{@class_name} = ClassVariants.build(
135
+ base: "",
136
+ variants: {
137
+ variant: {
138
+ solid: "",
139
+ outline: "ring ring-inset",
140
+ soft: "",
141
+ subtle: "ring ring-inset"
142
+ },
143
+ size: {
144
+ sm: "",
145
+ md: "",
146
+ lg: ""
147
+ },
148
+ color: COLORS.index_with { "" }
149
+ },
150
+ compound_variants: [
151
+ # -- solid --
152
+ { color: :primary, variant: :solid, class: "bg-primary text-primary-foreground" },
153
+ { color: :secondary, variant: :solid, class: "bg-secondary text-secondary-foreground" },
154
+ { color: :success, variant: :solid, class: "bg-success text-success-foreground" },
155
+ { color: :info, variant: :solid, class: "bg-info text-info-foreground" },
156
+ { color: :warning, variant: :solid, class: "bg-warning text-warning-foreground" },
157
+ { color: :error, variant: :solid, class: "bg-error text-error-foreground" },
158
+ { color: :neutral, variant: :solid, class: "bg-inverted text-inverted" },
159
+
160
+ # -- outline --
161
+ { color: :primary, variant: :outline, class: "text-primary ring-primary/50" },
162
+ { color: :secondary, variant: :outline, class: "text-secondary ring-secondary/50" },
163
+ { color: :success, variant: :outline, class: "text-success ring-success/50" },
164
+ { color: :info, variant: :outline, class: "text-info ring-info/50" },
165
+ { color: :warning, variant: :outline, class: "text-warning ring-warning/50" },
166
+ { color: :error, variant: :outline, class: "text-error ring-error/50" },
167
+ { color: :neutral, variant: :outline, class: "ring-accented text-foreground bg-background" },
168
+
169
+ # -- soft --
170
+ { color: :primary, variant: :soft, class: "bg-primary/10 text-primary" },
171
+ { color: :secondary, variant: :soft, class: "bg-secondary/10 text-secondary" },
172
+ { color: :success, variant: :soft, class: "bg-success/10 text-success" },
173
+ { color: :info, variant: :soft, class: "bg-info/10 text-info" },
174
+ { color: :warning, variant: :soft, class: "bg-warning/10 text-warning" },
175
+ { color: :error, variant: :soft, class: "bg-error/10 text-error" },
176
+ { color: :neutral, variant: :soft, class: "text-foreground bg-muted" },
177
+
178
+ # -- subtle --
179
+ { color: :primary, variant: :subtle, class: "bg-primary/10 text-primary ring-primary/25" },
180
+ { color: :secondary, variant: :subtle, class: "bg-secondary/10 text-secondary ring-secondary/25" },
181
+ { color: :success, variant: :subtle, class: "bg-success/10 text-success ring-success/25" },
182
+ { color: :info, variant: :subtle, class: "bg-info/10 text-info ring-info/25" },
183
+ { color: :warning, variant: :subtle, class: "bg-warning/10 text-warning ring-warning/25" },
184
+ { color: :error, variant: :subtle, class: "bg-error/10 text-error ring-error/25" },
185
+ { color: :neutral, variant: :subtle, class: "ring-accented text-foreground bg-muted" }
186
+ ],
187
+ defaults: { color: :primary, variant: :soft, size: :md }
188
+ )
189
+ end
190
+ end
191
+ RUBY
192
+ end
193
+
194
+ def simple_theme_template
195
+ <<~RUBY
196
+ module Kiso
197
+ module Themes
198
+ #{@class_name} = ClassVariants.build(
199
+ base: "",
200
+ variants: {
201
+ variant: {
202
+ default: ""
203
+ },
204
+ size: {
205
+ sm: "",
206
+ md: "",
207
+ lg: ""
208
+ }
209
+ },
210
+ defaults: { variant: :default, size: :md }
211
+ )
212
+ end
213
+ end
214
+ RUBY
215
+ end
216
+
217
+ # -- Partial templates --
218
+
219
+ def colored_partial_template
220
+ <<~ERB
221
+ <%# locals: (color: :primary, variant: :soft, size: :md, css_classes: "", **component_options) %>
222
+ <%= content_tag :div,
223
+ class: Kiso::Themes::#{@class_name}.render(color: color, variant: variant, size: size, class: css_classes),
224
+ data: { component: :#{@name} },
225
+ **component_options do %>
226
+ <%= yield %>
227
+ <% end %>
228
+ ERB
229
+ end
230
+
231
+ def simple_partial_template
232
+ <<~ERB
233
+ <%# locals: (variant: :default, size: :md, css_classes: "", **component_options) %>
234
+ <%= content_tag :div,
235
+ class: Kiso::Themes::#{@class_name}.render(variant: variant, size: size, class: css_classes),
236
+ data: { component: :#{@name} },
237
+ **component_options do %>
238
+ <%= yield %>
239
+ <% end %>
240
+ ERB
241
+ end
242
+
243
+ # -- Preview templates --
244
+
245
+ def colored_preview_template
246
+ <<~RUBY
247
+ module Kiso
248
+ # @label #{@class_name}
249
+ class #{@class_name}Preview < Lookbook::Preview
250
+ # @label Playground
251
+ # @param color select { choices: [primary, secondary, success, info, warning, error, neutral] }
252
+ # @param variant select { choices: [solid, outline, soft, subtle] }
253
+ # @param size select { choices: [sm, md, lg] }
254
+ # @param text text "#{@class_name}"
255
+ def playground(color: :primary, variant: :soft, size: :md, text: "#{@class_name}")
256
+ render_with_template(locals: {
257
+ color: color.to_sym,
258
+ variant: variant.to_sym,
259
+ size: size.to_sym,
260
+ text: text
261
+ })
262
+ end
263
+
264
+ # @label Colors
265
+ def colors
266
+ render_with_template
267
+ end
268
+
269
+ # @label Variants
270
+ def variants
271
+ render_with_template
272
+ end
273
+
274
+ # @label Sizes
275
+ def sizes
276
+ render_with_template
277
+ end
278
+ end
279
+ end
280
+ RUBY
281
+ end
282
+
283
+ def simple_preview_template
284
+ <<~RUBY
285
+ module Kiso
286
+ # @label #{@class_name}
287
+ class #{@class_name}Preview < Lookbook::Preview
288
+ # @label Playground
289
+ # @param variant select { choices: [default] }
290
+ # @param size select { choices: [sm, md, lg] }
291
+ # @param text text "#{@class_name}"
292
+ def playground(variant: :default, size: :md, text: "#{@class_name}")
293
+ render_with_template(locals: {
294
+ variant: variant.to_sym,
295
+ size: size.to_sym,
296
+ text: text
297
+ })
298
+ end
299
+
300
+ # @label Sizes
301
+ def sizes
302
+ render_with_template
303
+ end
304
+ end
305
+ end
306
+ RUBY
307
+ end
308
+
309
+ def playground_template
310
+ if @colored
311
+ <<~ERB
312
+ <div class="flex gap-4 items-center p-8">
313
+ <%%= kiso(:#{@name}, color: color, variant: variant, size: size) { text } %>
314
+ </div>
315
+ ERB
316
+ else
317
+ <<~ERB
318
+ <div class="flex gap-4 items-center p-8">
319
+ <%%= kiso(:#{@name}, variant: variant, size: size) { text } %>
320
+ </div>
321
+ ERB
322
+ end
323
+ end
324
+
325
+ def colors_template
326
+ colors = %w[primary secondary success info warning error neutral]
327
+ lines = colors.map { |c| " <%%= kiso(:#{@name}, color: :#{c}) { \"#{c.capitalize}\" } %>" }
328
+
329
+ <<~ERB
330
+ <div class="flex flex-wrap gap-3 items-center p-8">
331
+ #{lines.join("\n")}
332
+ </div>
333
+ ERB
334
+ end
335
+
336
+ def variants_template
337
+ variants = %w[solid outline soft subtle]
338
+ colors = %w[primary secondary success info warning error neutral]
339
+
340
+ sections = variants.map do |v|
341
+ lines = colors.map { |c| " <%%= kiso(:#{@name}, color: :#{c}, variant: :#{v}) { \"#{c.capitalize}\" } %>" }
342
+ <<~SECTION
343
+ <div>
344
+ <p class="text-sm text-muted-foreground mb-2">#{v.capitalize}</p>
345
+ <div class="flex flex-wrap gap-3 items-center">
346
+ #{lines.join("\n")}
347
+ </div>
348
+ </div>
349
+ SECTION
350
+ end
351
+
352
+ <<~ERB
353
+ <div class="space-y-6 p-8">
354
+ #{sections.join("\n")}
355
+ </div>
356
+ ERB
357
+ end
358
+
359
+ def sizes_template
360
+ sizes = %w[sm md lg]
361
+ lines = sizes.map { |s| " <%%= kiso(:#{@name}, size: :#{s}) { \"#{s.capitalize}\" } %>" }
362
+
363
+ <<~ERB
364
+ <div class="flex gap-4 items-center p-8">
365
+ #{lines.join("\n")}
366
+ </div>
367
+ ERB
368
+ end
369
+ end
data/lib/kiso/cli.rb ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+ require "active_support/core_ext/string/inflections"
5
+
6
+ module Kiso
7
+ module Cli
8
+ end
9
+ end
10
+
11
+ require_relative "cli/base"
12
+ require_relative "cli/icons"
13
+ require_relative "cli/make"
14
+ require_relative "cli/main"
@@ -0,0 +1,26 @@
1
+ module Kiso
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Kiso
4
+ engine_name "kiso_engine"
5
+
6
+ initializer "kiso.class_variants" do
7
+ ClassVariants.configure do |config|
8
+ merger = TailwindMerge::Merger.new
9
+ config.process_classes_with { |classes| merger.merge(classes) }
10
+ end
11
+ end
12
+
13
+ initializer "kiso.helpers" do
14
+ ActiveSupport.on_load(:action_view) do
15
+ include Kiso::ComponentHelper
16
+ include Kiso::IconHelper
17
+ end
18
+ end
19
+
20
+ initializer "kiso.lookbook", after: :load_config_initializers do
21
+ if defined?(Lookbook)
22
+ Lookbook.config.preview_paths << root.join("test/components/previews").to_s
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,65 @@
1
+ module Kiso
2
+ module Themes
3
+ Alert = ClassVariants.build(
4
+ base: "relative w-full rounded-lg px-4 py-3 text-sm " \
5
+ "grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] " \
6
+ "has-[>svg]:gap-x-3 gap-y-0.5 items-start " \
7
+ "[&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
8
+ variants: {
9
+ variant: {
10
+ solid: "",
11
+ outline: "ring ring-inset",
12
+ soft: "",
13
+ subtle: "ring ring-inset"
14
+ },
15
+ color: COLORS.index_with { "" }
16
+ },
17
+ compound_variants: [
18
+ # -- solid --
19
+ {color: :primary, variant: :solid, class: "bg-primary text-primary-foreground"},
20
+ {color: :secondary, variant: :solid, class: "bg-secondary text-secondary-foreground"},
21
+ {color: :success, variant: :solid, class: "bg-success text-success-foreground"},
22
+ {color: :info, variant: :solid, class: "bg-info text-info-foreground"},
23
+ {color: :warning, variant: :solid, class: "bg-warning text-warning-foreground"},
24
+ {color: :error, variant: :solid, class: "bg-error text-error-foreground"},
25
+ {color: :neutral, variant: :solid, class: "bg-inverted text-inverted-foreground"},
26
+
27
+ # -- outline --
28
+ {color: :primary, variant: :outline, class: "text-primary ring-primary/50"},
29
+ {color: :secondary, variant: :outline, class: "text-secondary ring-secondary/50"},
30
+ {color: :success, variant: :outline, class: "text-success ring-success/50"},
31
+ {color: :info, variant: :outline, class: "text-info ring-info/50"},
32
+ {color: :warning, variant: :outline, class: "text-warning ring-warning/50"},
33
+ {color: :error, variant: :outline, class: "text-error ring-error/50"},
34
+ {color: :neutral, variant: :outline, class: "text-foreground bg-background ring-accented"},
35
+
36
+ # -- soft --
37
+ {color: :primary, variant: :soft, class: "bg-primary/10 text-primary"},
38
+ {color: :secondary, variant: :soft, class: "bg-secondary/10 text-secondary"},
39
+ {color: :success, variant: :soft, class: "bg-success/10 text-success"},
40
+ {color: :info, variant: :soft, class: "bg-info/10 text-info"},
41
+ {color: :warning, variant: :soft, class: "bg-warning/10 text-warning"},
42
+ {color: :error, variant: :soft, class: "bg-error/10 text-error"},
43
+ {color: :neutral, variant: :soft, class: "text-foreground bg-elevated"},
44
+
45
+ # -- subtle --
46
+ {color: :primary, variant: :subtle, class: "bg-primary/10 text-primary ring-primary/25"},
47
+ {color: :secondary, variant: :subtle, class: "bg-secondary/10 text-secondary ring-secondary/25"},
48
+ {color: :success, variant: :subtle, class: "bg-success/10 text-success ring-success/25"},
49
+ {color: :info, variant: :subtle, class: "bg-info/10 text-info ring-info/25"},
50
+ {color: :warning, variant: :subtle, class: "bg-warning/10 text-warning ring-warning/25"},
51
+ {color: :error, variant: :subtle, class: "bg-error/10 text-error ring-error/25"},
52
+ {color: :neutral, variant: :subtle, class: "text-foreground bg-elevated ring-accented"}
53
+ ],
54
+ defaults: {color: :primary, variant: :soft}
55
+ )
56
+
57
+ AlertTitle = ClassVariants.build(
58
+ base: "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight"
59
+ )
60
+
61
+ AlertDescription = ClassVariants.build(
62
+ base: "col-start-2 grid justify-items-start gap-1 text-sm opacity-90 [&_p]:leading-relaxed"
63
+ )
64
+ end
65
+ end
@@ -0,0 +1,66 @@
1
+ module Kiso
2
+ module Themes
3
+ COLORS = %i[primary secondary success info warning error neutral].freeze
4
+
5
+ Badge = ClassVariants.build(
6
+ base: "inline-flex items-center justify-center font-medium whitespace-nowrap shrink-0 overflow-hidden " \
7
+ "transition-[color,box-shadow] " \
8
+ "[&>svg]:pointer-events-none [&>svg]:shrink-0 " \
9
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
10
+ variants: {
11
+ variant: {
12
+ solid: "",
13
+ outline: "ring ring-inset",
14
+ soft: "",
15
+ subtle: "ring ring-inset"
16
+ },
17
+ size: {
18
+ xs: "px-1 py-0.5 text-[8px]/3 rounded-full gap-0.5 [&>svg]:size-2.5",
19
+ sm: "px-1.5 py-0.5 text-[10px]/3 rounded-full gap-0.5 [&>svg]:size-3",
20
+ md: "px-2 py-0.5 text-xs rounded-full gap-1 [&>svg]:size-3",
21
+ lg: "px-2.5 py-1 text-sm rounded-full gap-1 [&>svg]:size-3.5",
22
+ xl: "px-2.5 py-1 text-base rounded-full gap-1.5 [&>svg]:size-4"
23
+ },
24
+ color: COLORS.index_with { "" }
25
+ },
26
+ compound_variants: [
27
+ # -- solid --
28
+ {color: :primary, variant: :solid, class: "bg-primary text-primary-foreground"},
29
+ {color: :secondary, variant: :solid, class: "bg-secondary text-secondary-foreground"},
30
+ {color: :success, variant: :solid, class: "bg-success text-success-foreground"},
31
+ {color: :info, variant: :solid, class: "bg-info text-info-foreground"},
32
+ {color: :warning, variant: :solid, class: "bg-warning text-warning-foreground"},
33
+ {color: :error, variant: :solid, class: "bg-error text-error-foreground"},
34
+ {color: :neutral, variant: :solid, class: "bg-inverted text-inverted-foreground"},
35
+
36
+ # -- outline --
37
+ {color: :primary, variant: :outline, class: "text-primary ring-primary/50"},
38
+ {color: :secondary, variant: :outline, class: "text-secondary ring-secondary/50"},
39
+ {color: :success, variant: :outline, class: "text-success ring-success/50"},
40
+ {color: :info, variant: :outline, class: "text-info ring-info/50"},
41
+ {color: :warning, variant: :outline, class: "text-warning ring-warning/50"},
42
+ {color: :error, variant: :outline, class: "text-error ring-error/50"},
43
+ {color: :neutral, variant: :outline, class: "text-foreground bg-background ring-accented"},
44
+
45
+ # -- soft --
46
+ {color: :primary, variant: :soft, class: "bg-primary/10 text-primary"},
47
+ {color: :secondary, variant: :soft, class: "bg-secondary/10 text-secondary"},
48
+ {color: :success, variant: :soft, class: "bg-success/10 text-success"},
49
+ {color: :info, variant: :soft, class: "bg-info/10 text-info"},
50
+ {color: :warning, variant: :soft, class: "bg-warning/10 text-warning"},
51
+ {color: :error, variant: :soft, class: "bg-error/10 text-error"},
52
+ {color: :neutral, variant: :soft, class: "text-foreground bg-elevated"},
53
+
54
+ # -- subtle --
55
+ {color: :primary, variant: :subtle, class: "bg-primary/10 text-primary ring-primary/25"},
56
+ {color: :secondary, variant: :subtle, class: "bg-secondary/10 text-secondary ring-secondary/25"},
57
+ {color: :success, variant: :subtle, class: "bg-success/10 text-success ring-success/25"},
58
+ {color: :info, variant: :subtle, class: "bg-info/10 text-info ring-info/25"},
59
+ {color: :warning, variant: :subtle, class: "bg-warning/10 text-warning ring-warning/25"},
60
+ {color: :error, variant: :subtle, class: "bg-error/10 text-error ring-error/25"},
61
+ {color: :neutral, variant: :subtle, class: "text-foreground bg-elevated ring-accented"}
62
+ ],
63
+ defaults: {color: :primary, variant: :soft, size: :md}
64
+ )
65
+ end
66
+ end