shadcn-ui 0.0.10 → 0.0.13

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/shadcn.css +67 -83
  3. data/app/{form_builders/shadcn_form_builder.rb → components/shadcn/form_builder.rb} +23 -4
  4. data/app/components/shadcn/select_component.rb +23 -0
  5. data/app/helpers/components/alert_helper.rb +3 -2
  6. data/app/helpers/components/badge_helper.rb +2 -2
  7. data/app/helpers/components/button_helper.rb +3 -2
  8. data/app/helpers/components/dropzone_helper.rb +5 -0
  9. data/app/helpers/components/filter_helper.rb +4 -0
  10. data/app/helpers/components/forms_helper.rb +2 -2
  11. data/app/helpers/components/input_helper.rb +3 -2
  12. data/app/helpers/components/select_helper.rb +6 -0
  13. data/app/helpers/components/sheet_helper.rb +3 -2
  14. data/app/helpers/components/table_helper.rb +61 -0
  15. data/app/helpers/components_helper.rb +2 -2
  16. data/app/javascript/controllers/ui/dialog_controller.js +3 -0
  17. data/app/javascript/controllers/ui/dropzone_controller.js +48 -0
  18. data/app/views/components/ui/_alert.html.erb +3 -3
  19. data/app/views/components/ui/_card.html.erb +1 -1
  20. data/app/views/components/ui/_dropzone.html.erb +12 -0
  21. data/app/views/components/ui/_sheet.html.erb +10 -5
  22. data/app/views/components/ui/_textarea.html.erb +2 -2
  23. data/app/views/documentation/index.html.md +1 -1
  24. data/app/views/documentation/installation.html.md +1 -1
  25. data/app/views/examples/components/accordion/code/_usage.erb +1 -1
  26. data/app/views/examples/components/accordion.html.erb +1 -1
  27. data/app/views/examples/components/card/code/_usage.erb +1 -1
  28. data/app/views/examples/components/dialog.html.erb +1 -1
  29. data/app/views/examples/components/dropdown-menu.html.erb +1 -1
  30. data/app/views/examples/components/dropzone/_usage.html.erb +20 -0
  31. data/app/views/examples/components/dropzone/code/_preview.erb +1 -0
  32. data/app/views/examples/components/dropzone/code/_usage.erb +1 -0
  33. data/app/views/examples/components/dropzone.html.erb +27 -0
  34. data/app/views/examples/components/forms/_usage.html.erb +2 -2
  35. data/app/views/examples/components/select/_usage.html.erb +22 -0
  36. data/app/views/examples/components/select/code/_preview.erb +7 -0
  37. data/app/views/examples/components/select/code/_usage.erb +5 -0
  38. data/app/views/examples/components/select.html.erb +27 -0
  39. data/app/views/examples/components/table/_usage.html.erb +23 -0
  40. data/app/views/examples/components/table/code/_preview.erb +35 -0
  41. data/app/views/examples/components/table/code/_usage.erb +12 -0
  42. data/app/views/examples/components/table.html.erb +27 -0
  43. data/app/views/layouts/shared/_components.html.erb +4 -3
  44. data/lib/components.json +25 -8
  45. data/lib/generators/shadcn-ui_generator.rb +1 -1
  46. data/lib/shadcn-ui/version.rb +1 -1
  47. data/shadcn-ui.gemspec +39 -0
  48. metadata +23 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d54c000bbd6eeb1aa3c0eedc58b9997efd3f9f06694a37b515230c46d6040d78
4
- data.tar.gz: 861723810936f97bcd326557d1a3d4147fd527e6b7118414866fd58e5ac989a8
3
+ metadata.gz: 403f7186d9ebbcca03f5f3bc13901e29db5d84bcdefa1d8648be46387822defc
4
+ data.tar.gz: eb7e79a3a62954cdbb21777e46aea6bee225a1fbde655e2e85616f2a7d357648
5
5
  SHA512:
6
- metadata.gz: 06b31b9b4bc92ab57c50ac86caaa7185420625cbbf8f3132f0679497c803aec975859095e43ee7c8880f7f1d03953db7c4c0a5bc895ddf8306583ff770e9f7d6
7
- data.tar.gz: 4a9b14a1af63e5f40bb5e5e80b992546ad9e45f6ca1d28316d2b2be91d21471062a1ebb79ead2703062358630d8691c856a7b7c962525bb8e783104069ab0748
6
+ metadata.gz: 05b4c95efea37e11f8251081572564b057ab11a77e10e97af756f5e3c9f880b0dbc68d15105dfb91af2c5c2b59723a8b0ced098b7f68f2e57e15603a8386c29f
7
+ data.tar.gz: 8e03c73187dca4d4408962a83e676c5fe0ff8a344dd27bc60fe0575a5c1014386bc7d1de29ddc31414c14264b75c6626456ce3eb715ad0200f28f90b9156d7a2
@@ -1,84 +1,64 @@
1
+ :root {
2
+ --font-sans: "Inter var";
3
+
4
+ --background: 0 0% 100%;
5
+ --foreground: 240 10% 3.9%;
6
+ --card: 0 0% 100%;
7
+ --card-foreground: 240 10% 3.9%;
8
+ --popover: 0 0% 100%;
9
+ --popover-foreground: 240 10% 3.9%;
10
+ --primary: 240 5.9% 10%;
11
+ --primary-foreground: 0 0% 98%;
12
+ --secondary: 240 4.8% 95.9%;
13
+ --secondary-foreground: 240 5.9% 10%;
14
+ --muted: 240 4.8% 95.9%;
15
+ --muted-foreground: 240 3.8% 46.1%;
16
+ --accent: 240 4.8% 95.9%;
17
+ --accent-foreground: 240 5.9% 10%;
18
+ --destructive: 0 84.2% 60.2%;
19
+ --destructive-foreground: 0 0% 98%;
20
+ --border: 240 5.9% 90%;
21
+ --input: 240 5.9% 90%;
22
+ --ring: 240 5% 64.9%;
23
+ --radius: 0.5rem;
24
+
25
+ --success: 132, 95.3%, 33.3%, 0.74;
26
+ --success-foreground: 109 55% 28%;
27
+
28
+ --info: 223 78% 42%;
29
+ --info-foreground: 225 100% 50%;
30
+
31
+ --attention: 45 90% 45%;
32
+ --attention-foreground: 60 98.4% 48.8% 0.82;
33
+ }
1
34
  @layer base {
2
- :root {
3
- --font-sans: "Inter var";
4
- --background: 0 0% 100%;
5
- --foreground: 222.2 47.4% 11.2%;
6
-
7
- --muted: 210 40% 96.1%;
8
- --muted-foreground: 215.4 16.3% 46.9%;
9
-
10
- --popover: 0 0% 100%;
11
- --popover-foreground: 222.2 47.4% 11.2%;
12
-
13
- --border: 214.3 31.8% 91.4%;
14
- --input: 214.3 31.8% 91.4%;
15
-
16
- --card: 0 0% 100%;
17
- --card-foreground: 222.2 47.4% 11.2%;
18
-
19
- --primary: 222.2 47.4% 11.2%;
20
- --primary-foreground: 210 40% 98%;
21
-
22
- --secondary: 210 40% 96.1%;
23
- --secondary-foreground: 222.2 47.4% 11.2%;
24
-
25
- --accent: 210 40% 96.1%;
26
- --accent-foreground: 222.2 47.4% 11.2%;
27
-
28
- --destructive: 0 100% 50%;
29
- --destructive-foreground: 210 40% 98%;
30
-
31
- --success: 132, 95.3%, 33.3%, 0.74;
32
- --success-foreground: 109 55% 28%;
33
-
34
- --info: 223 78% 42%;
35
- --info-foreground: 225 100% 50%;
36
-
37
- --attention: 45 90% 45%;
38
- --attention-foreground: 60 98.4% 48.8% 0.82;
39
-
40
- --ring: 215 20.2% 65.1%;
41
-
42
- --radius: 0.5rem;
43
- }
44
-
45
35
  .dark {
46
- --background: 224 71% 4%;
47
- --foreground: 213 31% 91%;
48
-
49
- --muted: 223 47% 11%;
50
- --muted-foreground: 215.4 16.3% 56.9%;
51
-
52
- --accent: 216 34% 17%;
53
- --accent-foreground: 210 40% 98%;
54
-
55
- --popover: 224 71% 4%;
56
- --popover-foreground: 215 20.2% 65.1%;
57
-
58
- --border: 216 34% 17%;
59
- --input: 216 34% 17%;
60
-
61
- --card: 224 71% 4%;
62
- --card-foreground: 213 31% 91%;
63
-
64
- --primary: 210 40% 98%;
65
- --primary-foreground: 222.2 47.4% 1.2%;
66
-
67
- --secondary: 222.2 47.4% 11.2%;
68
- --secondary-foreground: 210 40% 98%;
69
-
70
- --destructive: 0 63% 31%;
71
- --destructive-foreground: 210 40% 98%;
72
-
73
- --attention: 45, 90%, 45%, 0.8;
74
- --attention-foreground: 60 98.4% 48.8% 0.82;
36
+ --background: 240 10% 3.9%;
37
+ --foreground: 0 0% 98%;
38
+ --card: 240 10% 3.9%;
39
+ --card-foreground: 0 0% 98%;
40
+ --popover: 240 10% 3.9%;
41
+ --popover-foreground: 0 0% 98%;
42
+ --primary: 0 0% 98%;
43
+ --primary-foreground: 240 5.9% 10%;
44
+ --secondary: 240 3.7% 15.9%;
45
+ --secondary-foreground: 0 0% 98%;
46
+ --muted: 240 3.7% 15.9%;
47
+ --muted-foreground: 240 5% 64.9%;
48
+ --accent: 240 3.7% 15.9%;
49
+ --accent-foreground: 0 0% 98%;
50
+ --destructive: 0 62.8% 30.6%;
51
+ --destructive-foreground: 0 85.7% 97.3%;
52
+ --border: 240 3.7% 15.9%;
53
+ --input: 240 3.7% 15.9%;
54
+ --ring: 240 4.9% 83.9%;
55
+ --radius: 0.5rem;
75
56
 
76
57
  --success: 109 55% 28%;
77
58
  --success-foreground: 109 55% 28%;
78
59
 
79
- --ring: 216 34% 17%;
80
-
81
- --radius: 0.5rem;
60
+ --attention: 45, 90%, 45%, 0.8;
61
+ --attention-foreground: 60 98.4% 48.8% 0.82;
82
62
  }
83
63
  }
84
64
 
@@ -104,7 +84,19 @@
104
84
  .code-sample span {
105
85
  @apply bg-zinc-950;
106
86
  }
87
+ input.error {
88
+ @apply border-red-400;
89
+ }
90
+
91
+ label.error {
92
+ @apply text-destructive;
93
+ }
94
+
95
+ input.error:focus-visible {
96
+ @apply ring-destructive;
97
+ }
107
98
  }
99
+
108
100
  input[type="range"] {
109
101
  display: inline-block;
110
102
  vertical-align: middle;
@@ -214,11 +206,3 @@ input[type="range"]::-ms-track {
214
206
  overflow: hidden;
215
207
  transition: all 0.2s;
216
208
  }
217
-
218
- input.error {
219
- @apply border-red-400;
220
- }
221
-
222
- label.error {
223
- @apply text-destructive;
224
- }
@@ -1,12 +1,13 @@
1
- class ShadcnFormBuilder < ActionView::Helpers::FormBuilder
1
+ class Shadcn::FormBuilder < ActionView::Helpers::FormBuilder
2
2
  def label(method, options = {})
3
3
  error_class = @object.errors[method].any? ? "error" : ""
4
4
  options[:class] = @template.tw("#{options[:class]} #{error_class}")
5
- @template.render_label(name: "#{object_name}[#{method}]", label: method.capitalize, **options)
5
+ @template.render_label(name: "#{object_name}[#{method}]", label: label_for(@object, method), **options)
6
6
  end
7
7
 
8
8
  def text_field(method, options = {})
9
- options[:class] << " error" if @object.errors[method].any?
9
+ error_class = @object.errors[method].any? ? "error" : ""
10
+ options[:class] = @template.tw("#{options[:class]} #{error_class}")
10
11
  @template.render_input(
11
12
  name: "#{object_name}[#{method}]",
12
13
  id: "#{object_name}_#{method}",
@@ -36,8 +37,26 @@ class ShadcnFormBuilder < ActionView::Helpers::FormBuilder
36
37
  type: "email", **options
37
38
  )
38
39
  end
39
-
40
+
41
+ def text_area(method, options = {})
42
+ error_class = @object.errors[method].any? ? "error" : ""
43
+ options[:class] = @template.tw("#{options[:class]} #{error_class}")
44
+ @template.render_textarea(
45
+ name: "#{object_name}[#{method}]",
46
+ id: "#{object_name}_#{method}",
47
+ value: @object.send(method),
48
+ type: "text", **options
49
+ )
50
+ end
51
+
40
52
  def submit(value = nil, options = {})
41
53
  @template.render_button(value, **options)
42
54
  end
55
+
56
+ private
57
+
58
+ def label_for(object, method)
59
+ return method.capitalize if object.nil?
60
+ object.class.human_attribute_name(method)
61
+ end
43
62
  end
@@ -0,0 +1,23 @@
1
+ class Shadcn::SelectComponent
2
+ include ComponentsHelper
3
+ attr_reader :name, :selected, :view_context
4
+
5
+ def initialize(name:, view_context:, selected: nil, **options, &block)
6
+ @name = name
7
+ @view_context = view_context
8
+ @selected = selected
9
+ @options = options
10
+ @content = view_context.capture(self, &block) if block
11
+ end
12
+
13
+ def option(value:, label: nil, &block)
14
+ content = label || view_context.capture(&block)
15
+ option_options = {value: value}
16
+ option_options[:selected] = "selected" if value == selected
17
+ view_context.content_tag :option, content, option_options
18
+ end
19
+
20
+ def call
21
+ view_context.content_tag :select, @content, name: name, class: tw("rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", @options[:class])
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  module Components::AlertHelper
2
- def render_alert(title:, description: nil, variant: :default, icon: true)
2
+ def render_alert(title:, description: nil, variant: :default, icon: true, &block)
3
3
  alert_classes = case variant.to_sym
4
4
  when :default
5
5
  "[&>svg]:text-foreground bg-background text-foreground"
@@ -12,6 +12,7 @@ module Components::AlertHelper
12
12
  when :attention
13
13
  "border-attention/50 text-attention dark:border-attention [&>svg]:text-attention"
14
14
  end
15
- render "components/ui/alert", title:, description:, alert_classes:, variant:, icon:
15
+ content = (capture(&block) if block) || description
16
+ render "components/ui/alert", title:, content:, alert_classes:, variant:, icon:
16
17
  end
17
18
  end
@@ -1,7 +1,7 @@
1
1
  module Components::BadgeHelper
2
2
  def render_badge(label = "", data: "", text: "", variant: :default, **options)
3
3
  badge_classes = " inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 "
4
- varianet_classes = case variant.to_sym
4
+ variant_classes = case variant.to_sym
5
5
  when :default
6
6
  ComponentsHelper::PRIMARY_CLASSES
7
7
  when :secondary
@@ -13,7 +13,7 @@ module Components::BadgeHelper
13
13
  when :ghost
14
14
  ComponentsHelper::GHOST_CLASSES
15
15
  end
16
- badge_classes << " #{varianet_classes}"
16
+ badge_classes << " #{variant_classes}"
17
17
  text = label if label.present?
18
18
 
19
19
  content_tag :div, class: badge_classes do
@@ -1,7 +1,7 @@
1
1
  module Components::ButtonHelper
2
2
  def render_button(label = "", text: nil, variant: :default, as: :button, href: nil, data: {}, **options, &block)
3
3
  button_classes = " inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 h-10 px-4 py-2 "
4
- varianet_classes = case variant.to_sym
4
+ variant_classes = case variant.to_sym
5
5
  when :default
6
6
  " bg-primary text-primary-foreground hover:bg-primary/90 "
7
7
  when :secondary
@@ -13,7 +13,8 @@ module Components::ButtonHelper
13
13
  when :ghost
14
14
  " hover:bg-accent hover:text-accent-foreground "
15
15
  end
16
- button_classes << " #{varianet_classes} #{options[:class]}"
16
+ button_classes = tw(button_classes, variant_classes, options[:class])
17
+
17
18
  text = label if label.present?
18
19
  text = capture(&block) if block
19
20
  render "components/ui/button", text:, button_classes:, as:, href:, data:, **options
@@ -0,0 +1,5 @@
1
+ module Components::DropzoneHelper
2
+ def render_dropzone
3
+ render "components/ui/dropzone"
4
+ end
5
+ end
@@ -9,4 +9,8 @@ module Components::FilterHelper
9
9
  input_class = content_for?(:filter_icon) ? "pl-1" : ""
10
10
  render "components/ui/filter", items: items, options: options, input_class: input_class, content: content
11
11
  end
12
+
13
+ def list_item(:value, :name, :selected)
14
+ "#{name}"
15
+ end
12
16
  end
@@ -1,12 +1,12 @@
1
1
  module Components::FormsHelper
2
2
  def render_form_with(**opts)
3
- form_with(**opts.merge(builder: ShadcnFormBuilder)) do |form|
3
+ form_with(**opts.merge(builder: Shadcn::FormBuilder)) do |form|
4
4
  yield form
5
5
  end
6
6
  end
7
7
 
8
8
  def render_form_for(obj, **opts)
9
- form_for(obj, **opts.merge(builder: ShadcnFormBuilder), html: opts) do |form|
9
+ form_for(obj, **opts.merge(builder: Shadcn::FormBuilder), html: opts) do |form|
10
10
  yield form
11
11
  end
12
12
  end
@@ -10,14 +10,15 @@ module Components::InputHelper
10
10
  options[:class] = tw(options[:class])
11
11
 
12
12
  options.reverse_merge!(
13
- label: (options[:lable] || false),
13
+ label: (options[:label] || false),
14
14
  required: (options[:required] || false),
15
15
  disabled: (options[:disabled] || false),
16
16
  readonly: (options[:readonly] || false),
17
17
  placeholder: (options[:placeholder] || ""),
18
18
  autocomplete: (options[:autocomplete] || ""),
19
19
  autocapitalize: (options[:autocapitalize] || nil),
20
- autocorrect: (options[:autocorrect] || nil)
20
+ autocorrect: (options[:autocorrect] || nil),
21
+ autofocus: (options[:autofocus] || nil)
21
22
  )
22
23
  render partial: "components/ui/input", locals: {
23
24
  type:,
@@ -0,0 +1,6 @@
1
+ module Components::SelectHelper
2
+ def render_select(name:, **options, &block)
3
+ component = Shadcn::SelectComponent.new(name: name, view_context: self, **options, &block)
4
+ component.call
5
+ end
6
+ end
@@ -2,6 +2,7 @@ module Components::SheetHelper
2
2
  def render_sheet(**options, &block)
3
3
  options[:direction] ||= "left"
4
4
  options[:width] ||= "w-3/4"
5
+ options[:state] ||= "closed"
5
6
 
6
7
  content_for :sheet_trigger, "", flush: true
7
8
  content_for :sheet_content, "", flush: true
@@ -20,8 +21,8 @@ module Components::SheetHelper
20
21
 
21
22
  def direction_class(direction)
22
23
  mappings = {
23
- "left": 'left-0',
24
- "right": 'right-0'
24
+ left: "left-0",
25
+ right: "right-0"
25
26
  }
26
27
 
27
28
  mappings[direction.to_sym]
@@ -0,0 +1,61 @@
1
+ module Components::TableHelper
2
+ def render_table(caption = nil, **options, &block)
3
+ content_tag :table, options.reverse_merge(
4
+ class: tw("w-full text-sm border-b", options[:class])
5
+ ) do
6
+ if caption.present?
7
+ content_tag :caption, caption, class: "mt-4 text-sm text-muted-foreground " do
8
+ capture(&block)
9
+ end
10
+ else
11
+ capture(&block)
12
+ end
13
+ end
14
+ end
15
+
16
+ def table_head(**options, &block)
17
+ content_tag :thead, options.reverse_merge(
18
+ class: tw("[&_tr]:border-b", options[:class])
19
+ ) do
20
+ content_tag :tr, class: "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted" do
21
+ capture(&block)
22
+ end
23
+ end
24
+ end
25
+
26
+ def table_header(content = nil, **options, &block)
27
+ content_tag :th, options.reverse_merge(
28
+ class: tw("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0", options[:class])
29
+ ) do
30
+ if block
31
+ capture(&block)
32
+ else
33
+ content
34
+ end
35
+ end
36
+ end
37
+
38
+ def table_body(**options, &block)
39
+ content_tag :tbody, class: options.reverse_merge(
40
+ class: tw("[&_tr:last-child]:border-0", options[:class])
41
+ ), &block
42
+ end
43
+
44
+ def table_row(**options, &block)
45
+ content_tag :tr, options.reverse_merge(
46
+ class: tw("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", options[:class])
47
+ ), &block
48
+ end
49
+
50
+ def table_column(content = nil, **options, &block)
51
+ content_tag :td, options.reverse_merge(
52
+ class: tw("p-4 align-middle [&:has([role=checkbox])]:pr-0 font-medium", options[:class])
53
+ ) do
54
+ if block
55
+ capture(&block)
56
+ else
57
+ content
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,8 +1,8 @@
1
1
  require "tailwind_merge"
2
2
 
3
3
  module ComponentsHelper
4
- def tw(classes)
5
- TailwindMerge::Merger.new.merge(classes)
4
+ def tw(*classes)
5
+ TailwindMerge::Merger.new.merge(classes.join(" "))
6
6
  end
7
7
 
8
8
  PRIMARY_CLASSES = " bg-primary text-primary-foreground hover:bg-primary/80 "
@@ -61,6 +61,9 @@ export default class UIDialog extends Controller {
61
61
  closeBy(target) {
62
62
  this.toggleClass(false);
63
63
 
64
+ if (target.getAttribute('data-ui--dialog-target') === 'modal') {
65
+ document.body.classList.remove("overflow-hidden");
66
+ }
64
67
  this.dispatch("closed", { detail: { target: target } });
65
68
  }
66
69
 
@@ -0,0 +1,48 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+
3
+ export default class extends Controller {
4
+ static targets = ["fileInput"];
5
+ connect() {
6
+ this.element.addEventListener("dragover", this.preventDragDefaults);
7
+ this.element.addEventListener("dragenter", this.preventDragDefaults);
8
+ }
9
+
10
+ disconnect() {
11
+ this.element.removeEventListener("dragover", this.preventDragDefaults);
12
+ this.element.removeEventListener("dragenter", this.preventDragDefaults);
13
+ }
14
+
15
+ preventDragDefaults(e) {
16
+ e.preventDefault();
17
+ e.stopPropagation();
18
+ }
19
+
20
+ trigger() {
21
+ this.fileInputTarget.click();
22
+ }
23
+
24
+ acceptFiles(event) {
25
+ event.preventDefault();
26
+ const files = event.dataTransfer ? event.dataTransfer.files : event.target.files;
27
+ [...files].forEach((file) => {
28
+ this.uploadFile(file);
29
+ });
30
+ }
31
+
32
+ // Implement your own file upload strategy here...
33
+ uploadFile(file) {
34
+ console.log("Received file for upload: ", file);
35
+ console.log("Implement your own file upload strategy here...");
36
+ // const formData = new FormData();
37
+ // formData.append("file", file);
38
+
39
+ // fetch("/upload", {
40
+ // method: "POST",
41
+ // body: formData,
42
+ // })
43
+ // .then((response) => response.json())
44
+ // .then((data) => {
45
+ // console.log(data);
46
+ // });
47
+ }
48
+ }
@@ -61,7 +61,7 @@
61
61
  y1="16"
62
62
  y2="16"></line>
63
63
  </svg>
64
- <% end if icon %>
65
- <h5 class="mb-1 font-medium leading-none tracking-tight"><%= title %></h5>
66
- <div class="text-sm [&_p]:leading-relaxed"><%= description %></div>
64
+ <% end if icon %>
65
+ <h5 class="mb-1 font-medium leading-none tracking-tight"><%= title %></h5>
66
+ <div class="text-sm [&_p]:leading-relaxed"><%= content %></div>
67
67
  </div>
@@ -1,4 +1,4 @@
1
- <div class="rounded-lg border bg-card text-card-foreground shadow-sm w-[350px] <%= options[:class] %>">
1
+ <div class="<%= tw("rounded-lg border bg-card text-card-foreground shadow-sm w-[350px]", options[:class]) %">
2
2
  <% if title || subtitle %>
3
3
  <div class="flex flex-col space-y-1.5 p-6">
4
4
  <% if title %>
@@ -0,0 +1,12 @@
1
+ <div class="w-full">
2
+ <div class="p-6">
3
+ <div id="dropzone" data-controller="ui--dropzone" data-action="click->ui--dropzone#trigger drop->ui--dropzone#acceptFiles">
4
+ <button
5
+ class="w-full rounded-lg bg-muted border-2 border-dashed border-gray-300 p-8 text-center hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
6
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mx-auto h-12 w-12 text-gray-400"><path d="M15.5 2H8.6c-.4 0-.8.2-1.1.5-.3.3-.5.7-.5 1.1v12.8c0 .4.2.8.5 1.1.3.3.7.5 1.1.5h9.8c.4 0 .8-.2 1.1-.5.3-.3.5-.7.5-1.1V6.5L15.5 2z" /><path d="M3 7.6v12.8c0 .4.2.8.5 1.1.3.3.7.5 1.1.5h9.8" /><path d="M15 2v5h5" /></svg>
7
+ <span class="mt-2 block text-sm font-semibold text-muted-foreground dark:text-white">Drag Files to Upload or Click Here</span>
8
+ </button>
9
+ <input type="file" class="hidden" multiple data-ui--dropzone-target="fileInput" data-action="change->ui--dropzone#acceptFiles">
10
+ </div>
11
+ </div>
12
+ </div>
@@ -5,12 +5,17 @@
5
5
 
6
6
  <div
7
7
  role="dialog"
8
- data-state="closed"
8
+ data-state="<%= options[:state]%>"
9
9
  data-ui--sheet-target="dialog"
10
- class="data-[state=closed]:hidden data-[state=open]:block fixed z-50 gap-4 bg-background p-6 shadow-lg
11
- transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500
12
- inset-y-0 <%= direction_class(options[:direction]) %> h-full <%= options[:width] %> border-l data-[state=closed]:slide-out-to-<%= options[:direction] %> data-[state=open]:slide-in-from-<%= options[:direction] %> sm:max-w-sm" tabindex="-1"
13
- style="pointer-events: auto">
10
+ class="<%= tw("data-[state=closed]:hidden data-[state=open]:block fixed z-50 gap-4 bg-background p-6 shadow-lg
11
+ transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300
12
+ data-[state=open]:duration-500 inset-y-0 h-full border-l sm:max-w-sm",
13
+ "data-[state=closed]:slide-out-to-#{options[:direction]}
14
+ data-[state=open]:slide-in-from-#{options[:direction]}",
15
+ direction_class(options[:direction]), options[:width],
16
+ options[:class]) %>"
17
+ tabindex="-1"
18
+ style="pointer-events: auto">
14
19
  <div data-ui--sheet-target="content"><%= content_for(:sheet_content) %></div>
15
20
  <button
16
21
  data-ui--sheet-target="closeButton"
@@ -1,9 +1,9 @@
1
1
  <textarea
2
- class="flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 <%= options[:class] %>"
2
+ class="<%= tw("flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", options[:class]) %>"
3
3
  placeholder="<%= options[:placeholder] %>"
4
4
  name="<%= name %>"
5
5
  id="<% id %>"
6
6
  <%= options[:disabled] ? "disabled" : "" %>
7
7
  <%= options[:required] ? "required" : "" %>
8
8
  <%= options[:readonly] ? "readonly" : "" %>
9
- <%= options[:rows] ? "rows" : "" %>></textarea>
9
+ <%= options[:rows] ? "rows" : "" %>><%= value %></textarea>
@@ -34,4 +34,4 @@ needs without any unnecessary abstraction.
34
34
 
35
35
  The gem provides a generator for you to use in your application to facilitate copying the code from
36
36
  this application to yours. It also enforces some setup for you as the component files alone in
37
- isolation won't always work. [Learn more about the generator](/documentation/generators).
37
+ isolation won't always work. [Learn more about the generator](/docs/generators).
@@ -117,7 +117,7 @@ by being at the end. And obviously feel free to inspect shadcnConfig and keep on
117
117
  ## End
118
118
 
119
119
  That's it! You are now set to start
120
- [installing components via the generator]("/documentation/generators") and rendering them into your
120
+ [installing components via the generator](/docs/generators) and rendering them into your
121
121
  views.
122
122
 
123
123
  # Manual Installation
@@ -1,5 +1,5 @@
1
1
  # Inline
2
- <%= render_accordion(title:, :description) %>
2
+ <%= render_accordion(title:, description:) %>
3
3
 
4
4
  # Description Block
5
5
  <%= render_accordion(title:) do %>
@@ -17,7 +17,7 @@
17
17
  <h2 class="font-heading scroll-m-20 border-b pb-2 text-2xl font-semibold tracking-tight first:mt-0" id="installation">Installation</h2>
18
18
 
19
19
  <%= code_sample(language: "sh") do %>
20
- rails generate shadcn-ui accodordion
20
+ rails generate shadcn-ui accordion
21
21
  <% end %>
22
22
 
23
23
  <h2 class="font-heading mt-12 scroll-m-20 border-b pb-2 mb-2 text-2xl font-semibold tracking-tight first:mt-0" id="usage"><a href="/docs/components/dialog#usage">Usage</a></h2>
@@ -1,3 +1,3 @@
1
- <%= render_card(title: nil, subtitle: nil, body: nil, footer: nil:) do %>
1
+ <%= render_card(title: nil, subtitle: nil, body: nil, footer: nil) do %>
2
2
  <!-- Optional Body Block -->
3
3
  <% end %>
@@ -16,7 +16,7 @@
16
16
  <h2 class="font-heading scroll-m-20 border-b pb-2 text-2xl font-semibold tracking-tight first:mt-0" id="installation">Installation</h2>
17
17
 
18
18
  <%= code_sample(language: "sh") do %>
19
- rails generate shadcn_ui dialog
19
+ rails generate shadcn-ui dialog
20
20
  <% end %>
21
21
 
22
22
  <h2 class="font-heading mt-12 scroll-m-20 border-b pb-2 mb-2 text-2xl font-semibold tracking-tight first:mt-0" id="usage"><a href="/docs/components/dialog#usage">Usage</a></h2>
@@ -2,7 +2,7 @@
2
2
  description: "Displays a menu to the user — such as a set of actions or functions — triggered by a button." %>
3
3
 
4
4
  <%= content_for :preview, flush: true do %>
5
- <% render_dropdown_menu do %>
5
+ <%= render_dropdown_menu do %>
6
6
  <%= dropdown_menu_trigger do %>
7
7
  <%= render_button "Open Dropdown", variant: :outline %>
8
8
  <% end %>
@@ -0,0 +1,20 @@
1
+ <p class="leading-7 [&:not(:first-child)]:mt-6">The Dropzone component introduces:</p>
2
+
3
+ <ul class="my-6 ml-6 list-disc [&>li]:mt-2 text-sm">
4
+ <li><%= code("app/helpers/components/dropzone_helper.rb") %></li>
5
+ <li><%= code("app/views/components/ui/_dropzone.html.erb") %></li>
6
+ <li><%= code("app/javascript/controllers/ui/dropzone_controller.js") %></li>
7
+ </ul>
8
+
9
+ <p class="leading-7 [&:not(:first-child)]:mt-6">
10
+ The method <%= code("render_dropzone") %> defined in <%= code("app/helpers/components/dropzone_helper.rb") %> will render the dropzone widget that is bound to the Stimulus controller.
11
+ Upon triggering the file dialog or dragging and dropping files, the controller will delegate the files individually to a function, <%= code("uploadFile") %>. It is up to you to define what to do when a a file is to be uploaded.
12
+ <p>
13
+
14
+ <p class="leading-7 [&:not(:first-child)]:mt-6">
15
+ To implement fully, edit the <%= code("uploadFile") %> function in <%= code("app/javascript/controllers/ui/dropzone_controller.js") %>. This function is called for each file that is to be uploaded. The function is passed the file object.
16
+ </p>
17
+
18
+ <p class="leading-7 [&:not(:first-child)]:mt-6">
19
+ If you try the example component, you will see that it is logging the file object to the console.
20
+ </p>
@@ -0,0 +1 @@
1
+ <%= render_dropzone %>
@@ -0,0 +1 @@
1
+ <%= render_dropzone %>
@@ -0,0 +1,27 @@
1
+ <%= render "layouts/documentation/component_header",
2
+ title: "Dropzone",
3
+ description: "A dropzone component that accepts multiple files via drag and drop." %>
4
+
5
+ <% content_for :preview, flush: true do %>
6
+ <div class="w-full flex justify-center">
7
+ <%= render_code_preview('dropzone') %>
8
+ </div>
9
+ <% end %>
10
+
11
+ <% content_for :code, flush: true do %>
12
+ <div class="w-full flex justify-center">
13
+ <%= code_partial("dropzone/preview", :erb) %>
14
+ </div>
15
+ <% end %>
16
+
17
+ <%= render_preview %>
18
+
19
+ <h2 class="font-heading scroll-m-20 border-b pb-2 text-2xl font-semibold tracking-tight first:mt-0" id="installation">Installation</h2>
20
+ <%= code_sample(language: "sh") do %>
21
+ rails generate shadcn-ui dropzone
22
+ <% end %>
23
+
24
+ <h2 class="font-heading mt-12 scroll-m-20 border-b pb-2 mb-2 text-2xl font-semibold tracking-tight first:mt-0" id="usage">Usage</h2>
25
+ <%= code_partial("dropzone/usage", :erb) %>
26
+
27
+ <%= render_usage("dropzone") %>
@@ -1,12 +1,12 @@
1
1
  <p class="leading-7 [&:not(:first-child)]:mt-6">The Forms component introduces:</p>
2
2
 
3
3
  <ul class="my-6 ml-6 list-disc [&>li]:mt-2 text-sm">
4
- <li><%= code("app/form_builders/shadcn_form_builder.rb") %></li>
4
+ <li><%= code("app/components/shadcn/form_builder.rb") %></li>
5
5
  <li><%= code("app/helpers/components/forms_helper.rb") %></li>
6
6
  </ul>
7
7
 
8
8
  <p class="leading-7 [&:not(:first-child)]:mt-6">
9
- The <code>ShadcnFormBuilder</code> is a custom form builder that extends the
9
+ The <code>Shadcn::FormBuilder</code> is a custom form builder that extends the
10
10
  <code>FormBuilder</code> class. It adds the following methods that provide the form with inputs and controls:
11
11
  <p>
12
12
 
@@ -0,0 +1,22 @@
1
+ <p class="leading-7 [&:not(:first-child)]:mt-6">The Select component introduces:</p>
2
+
3
+ <ul class="my-6 ml-6 list-disc [&>li]:mt-2 text-sm">
4
+ <li><%= code("app/helpers/components/select_helper.rb") %></li>
5
+ <li><%= code("app/components/shadcn/select_component.rb") %></li>
6
+ </ul>
7
+
8
+ <p class="leading-7 [&:not(:first-child)]:mt-6">
9
+ The select component is implemented as a component object defined in <%= code("app/components/shadcn/select_component.rb") %>.
10
+ This ruby class is initialized from the helper defined in <%= code("app/helpers/components/select_helper.rb") %>, <%= code "render_select" %>.
11
+ </p>
12
+
13
+ <p class="leading-7 [&:not(:first-child)]:mt-6">
14
+ The <%= code("render_select") %> method accepts a <%= code("name") %> keyword argument for the name of the form field.
15
+ An optional argument of <%= code "selected" %> can contain the value of the option to be selected by default.
16
+ </p>
17
+
18
+ <p class="leading-7 [&:not(:first-child)]:mt-6">
19
+ <%= code("render_select") %> yields an instance of the <%= code "Shadcn::SelectComponent" %> that can be used to build <%= code "option" %>s for the select.
20
+ <%= code "option" %> on the component instance accepts a <%= code "label" %> argument for the label text to be displayed for the option whose value will be the <%= code "value" %> on the component instance yields a new option object that accepts a <%= code "label" %> and <%= code "value" %> argument.
21
+ <%= code "option" %> also accepts a block that can be used to create the label.
22
+ </p>
@@ -0,0 +1,7 @@
1
+ <%= render_select name: "fruits", selected: "Apple" do |select| %>
2
+ <%= select.option value: "Banana" do %>
3
+ Banana
4
+ <% end %>
5
+ <%= select.option label: "Apple", value: "Apple" %>
6
+ <%= select.option label: "Strawberry", value: "Strawberry" %>
7
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <%= render_select name:, selected:, do |select| %>
2
+ <%= select.option value: do %>
3
+ <% end %>
4
+ <%= select.option label:, value: %>
5
+ <% end %>
@@ -0,0 +1,27 @@
1
+ <%= render "layouts/documentation/component_header",
2
+ title: "Select",
3
+ description: "A standard but styled select component." %>
4
+
5
+ <% content_for :preview, flush: true do %>
6
+ <div class="w-full flex justify-center">
7
+ <%= render_code_preview('select') %>
8
+ </div>
9
+ <% end %>
10
+
11
+ <% content_for :code, flush: true do %>
12
+ <div class="w-full flex justify-center">
13
+ <%= code_partial("select/preview", :erb) %>
14
+ </div>
15
+ <% end %>
16
+
17
+ <%= render_preview %>
18
+
19
+ <h2 class="font-heading scroll-m-20 border-b pb-2 text-2xl font-semibold tracking-tight first:mt-0" id="installation">Installation</h2>
20
+ <%= code_sample(language: "sh") do %>
21
+ rails generate shadcn-ui select
22
+ <% end %>
23
+
24
+ <h2 class="font-heading mt-12 scroll-m-20 border-b pb-2 mb-2 text-2xl font-semibold tracking-tight first:mt-0" id="usage">Usage</h2>
25
+ <%= code_partial("select/usage", :erb) %>
26
+
27
+ <%= render_usage("select") %>
@@ -0,0 +1,23 @@
1
+ <p class="leading-7 [&:not(:first-child)]:mt-6">The Table component introduces:</p>
2
+
3
+ <ul class="my-6 ml-6 list-disc [&>li]:mt-2 text-sm">
4
+ <li><%= code("app/helpers/components/table_helper.rb") %></li>
5
+ </ul>
6
+
7
+ <p class="leading-7 [&:not(:first-child)]:mt-6">
8
+ The table component is so far unique in that it is entirely provided by <%= code("app/helpers/components/table_helper.rb") %>. This helper introduces methods that rely on <%= code("content_tag") %> to create the markup for the table. To edit anything about the rendered table, look there.
9
+ </p>
10
+
11
+ <p class="leading-7 [&:not(:first-child)]:mt-6">
12
+ <%= code("app/helpers/components/table_helper.rb") %> introduces the following methods that can be used to create a table.
13
+
14
+ <ul class="my-6 ml-6 list-disc [&>li]:mt-2 text-md">
15
+ <li><%= code("render_table") %> accepts an optional caption as the first argument along with the block for the rest of the table components.</li>
16
+ <li><%= code("table_head") %> accepts a block for the content of the <%= code("thead") %> row.</li>
17
+ <li><%= code("table_header") %> accepts the header content inline or in a block. This will be rendered within the <%= code("thead") %> for that column.</li>
18
+ <li><%= code("table_body") %> accepts a block for the content of the <%= code("tbody") %>.</li>
19
+ <li><%= code("table_row") %> accepts a block for the content of the <%= code("tr") %>.</li>
20
+ <li><%= code("table_column") %> accepts the column content inline or in a block. This will be rendered within the <%= code("td") %> for the column.</li>
21
+ </ul>
22
+
23
+ </p>
@@ -0,0 +1,35 @@
1
+ <% @tracks = [
2
+ {title: "Total Eclipse of the Heart", artist: "Bonnie Tyler"},
3
+ {title: "I Will Always Love You", artist: "Whitney Houston"},
4
+ {title: "I Wanna Dance with Somebody", artist: "Whitney Houston"},
5
+ {title: "I Will Survive", artist: "Gloria Gaynor"},
6
+ {title: "My Heart Will Go On", artist: "Celine Dion"},
7
+ ] %>
8
+
9
+ <%= render_table do %>
10
+ <%= table_head do %>
11
+ <%= table_header "", class: "w-1" %>
12
+ <%= table_header class: "" do %>
13
+ Title
14
+ <% end %>
15
+ <%= table_header "Artist" %>
16
+ <% end %>
17
+ <%= table_body do %>
18
+ <% @tracks.each.with_index do |track, i| %>
19
+ <%= table_row do %>
20
+ <%= table_column do %>
21
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none"
22
+ stroke="currentColor" stroke-width="2" stroke-linecap="round"
23
+ stroke-linejoin="round">
24
+ <circle cx="12" cy="12" r="10"></circle>
25
+ <polygon points="10 8 16 12 10 16 10 8"></polygon>
26
+ </svg>
27
+ <% end %>
28
+ <%= table_column do %>
29
+ <%= track[:title] %>
30
+ <% end %>
31
+ <%= table_column track[:artist] %>
32
+ <% end %>
33
+ <% end %>
34
+ <% end %>
35
+ <% end %>
@@ -0,0 +1,12 @@
1
+ <%= render_table do %>
2
+ <%= table_head do %>
3
+ <%= table_header %>
4
+ <%= table_header %>
5
+ <% end %>
6
+ <%= table_body do %>
7
+ <%= table_row do %>
8
+ <%= table_column %>
9
+ <%= table_column %>
10
+ <% end %>
11
+ <% end %>
12
+ <% end %>
@@ -0,0 +1,27 @@
1
+ <%= render "layouts/documentation/component_header",
2
+ title: "Table",
3
+ description: "A simple table component for displaying data in rows and columns." %>
4
+
5
+ <% content_for :preview, flush: true do %>
6
+ <div class="w-full flex justify-center">
7
+ <%= render_code_preview('table') %>
8
+ </div>
9
+ <% end %>
10
+
11
+ <% content_for :code, flush: true do %>
12
+ <div class="w-full flex justify-center">
13
+ <%= code_partial("table/preview", :erb) %>
14
+ </div>
15
+ <% end %>
16
+
17
+ <%= render_preview %>
18
+
19
+ <h2 class="font-heading scroll-m-20 border-b pb-2 text-2xl font-semibold tracking-tight first:mt-0" id="installation">Installation</h2>
20
+ <%= code_sample(language: "sh") do %>
21
+ rails generate shadcn-ui table
22
+ <% end %>
23
+
24
+ <h2 class="font-heading mt-12 scroll-m-20 border-b pb-2 mb-2 text-2xl font-semibold tracking-tight first:mt-0" id="usage">Usage</h2>
25
+ <%= code_partial("table/usage", :erb) %>
26
+
27
+ <%= render_usage("table") %>
@@ -9,7 +9,7 @@
9
9
  <%= sidebar_link "Installation", documentation_path("installation") %>
10
10
  <%= sidebar_link "Generators", documentation_path("generators") %>
11
11
  <%= sidebar_link "Helpers", documentation_path("helpers") %>
12
- <%= sidebar_link "Stimulus", documentation_path("Javascript") %>
12
+ <%= sidebar_link "Stimulus", documentation_path("javascript") %>
13
13
  <%= sidebar_link "About", documentation_path("about") %>
14
14
  </div>
15
15
  </div>
@@ -34,6 +34,7 @@
34
34
  <%#= sidebar_link "Date Picker", "/docs/components/date-picker" %>
35
35
  <%= sidebar_link "✅ 📖 Dialog", "/docs/components/dialog" %>
36
36
  <%= sidebar_link "✅ 📖 Dropdown Menu", "/docs/components/dropdown-menu" %>
37
+ <%= sidebar_link "✅ 📖 Dropzone", "/docs/components/dropzone" %>
37
38
  <%= sidebar_link "✅ 📖 Filter", "/docs/components/filter" %>
38
39
  <%= sidebar_link "✅ 📖 Forms", "/docs/components/forms" %>
39
40
  <%= sidebar_link "✅ 📖 Hover Card", "/docs/components/hover-card" %>
@@ -45,13 +46,13 @@
45
46
  <%= sidebar_link "✅ 📖 Progress", "/docs/components/progress" %>
46
47
  <%#= sidebar_link "Radio Group", "/docs/components/radio-group" %>
47
48
  <%#= sidebar_link "Scroll Area", "/docs/components/scroll-area" %>
48
- <%#= sidebar_link "Select", "/docs/components/select" %>
49
+ <%= sidebar_link "✅ 📖 Select", "/docs/components/select" %>
49
50
  <%= sidebar_link "✅ 📖 Separator", "/docs/components/separator" %>
50
51
  <%= sidebar_link "✅ 📖 Sheet", "/docs/components/sheet" %>
51
52
  <%= sidebar_link "✅ 📖 Skeleton", "/docs/components/skeleton" %>
52
53
  <%= sidebar_link "✅ 📖 Slider", "/docs/components/slider" %>
53
54
  <%= sidebar_link "✅ 📖 Switch", "/docs/components/switch" %>
54
- <%#= sidebar_link "Table", "/docs/components/table" %>
55
+ <%= sidebar_link "✅ 📖 Table", "/docs/components/table" %>
55
56
  <%= sidebar_link "✅ 📖 Tabs", "/docs/components/tabs" %>
56
57
  <%= sidebar_link "✅ 📖 Textarea", "/docs/components/textarea" %>
57
58
  <%= sidebar_link "✅ 📖 Toast", "/docs/components/toast" %>
data/lib/components.json CHANGED
@@ -21,11 +21,10 @@
21
21
  "name": "alert-dialog",
22
22
  "type": "components:ui",
23
23
  "files": [
24
- "app/helpers/components/alert-dialog_helper.rb",
25
- "app/views/components/ui/_alert-dialog.html.erb",
26
- "app/javascript/controllers/ui/alert-dialog_controller.js"
24
+ "app/helpers/components/alert_dialog_helper.rb",
25
+ "app/views/components/ui/_alert_dialog.html.erb"
27
26
  ],
28
- "dependencies": [{ "component": "dialog" }]
27
+ "dependencies": [{ "component": "dialog" }, "app/views/components/ui/shared/_backdrop.html.erb"]
29
28
  },
30
29
  "badge": {
31
30
  "name": "badge",
@@ -102,7 +101,8 @@
102
101
  "app/helpers/components/dialog_helper.rb",
103
102
  "app/views/components/ui/_dialog.html.erb",
104
103
  "app/javascript/controllers/ui/dialog_controller.js"
105
- ]
104
+ ],
105
+ "dependencies": ["app/views/components/ui/shared/_backdrop.html.erb"]
106
106
  },
107
107
  "dropdown-menu": {
108
108
  "name": "dropdown-menu",
@@ -117,10 +117,28 @@
117
117
  "app/views/components/ui/shared/_menu_item.html.erb"
118
118
  ]
119
119
  },
120
+ "dropzone": {
121
+ "name": "dropzone",
122
+ "type": "components:ui",
123
+ "files": [
124
+ "app/helpers/components/dropzone_helper.rb",
125
+ "app/views/components/ui/_dropzone.html.erb",
126
+ "app/javascript/controllers/ui/dropzone_controller.js"
127
+ ]
128
+ },
129
+ "filter": {
130
+ "name": "filter",
131
+ "type": "components:ui",
132
+ "files": [
133
+ "app/helpers/components/filter_helper.rb",
134
+ "app/views/components/ui/_filter.html.erb",
135
+ "app/javascript/controllers/ui/filter_controller.js"
136
+ ]
137
+ },
120
138
  "forms": {
121
139
  "name": "forms",
122
140
  "type": "components:ui",
123
- "files": ["app/helpers/components/forms_helper.rb", "app/form_builders/shadcn_form_builder.rb"],
141
+ "files": ["app/helpers/components/forms_helper.rb", "app/components/shadcn/form_builder.rb"],
124
142
  "dependencies": [
125
143
  { "component": "input" },
126
144
  { "component": "label" },
@@ -214,8 +232,7 @@
214
232
  "type": "components:ui",
215
233
  "files": [
216
234
  "app/helpers/components/select_helper.rb",
217
- "app/views/components/ui/_select.html.erb",
218
- "app/javascript/controllers/ui/select_controller.js"
235
+ "app/components/shadcn/select_component.rb"
219
236
  ]
220
237
  },
221
238
  "separator": {
@@ -120,7 +120,7 @@ class ShadcnUiGenerator < Rails::Generators::Base
120
120
  if File.exist?(tailwind_file_path)
121
121
  true
122
122
  else
123
- abort "shadcn-ui requires Tailwind CSS. Please include tailwindcss-rails in your Gemfile and run `rails g tailwind:install` to install Tailwind CSS."
123
+ abort "shadcn-ui requires Tailwind CSS. Please include tailwindcss-rails in your Gemfile and run `rails g tailwindcss:install` to install Tailwind CSS."
124
124
  end
125
125
  end
126
126
 
@@ -1,3 +1,3 @@
1
1
  module ShadcnUi
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.13"
3
3
  end
data/shadcn-ui.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/shadcn-ui/shadcn-ui"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "shadcn-ui"
7
+ spec.version = ShadcnUi::VERSION
8
+ spec.authors = ["Avi Flombaum"]
9
+ spec.email = ["git@avi.nyc"]
10
+
11
+ spec.homepage = "https://shadcn.rails-components.com"
12
+ spec.summary = "Provides the shadcn-ui component library to a Ruby on Rails application."
13
+ spec.description = "This gem is a documentation site and gem that will copy components from the shadcn-ui library into a Ruby on Rails application."
14
+ spec.homepage = "https://github.com/aviflombaum/shadcn-rails"
15
+ spec.license = "MIT"
16
+ spec.required_ruby_version = ">= 2.6.0"
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/aviflombaum/shadcn-rails"
20
+ spec.metadata["changelog_uri"] = "https://github.com/aviflombaum/shadcn-rails/tree/main/CHANGELOG.md"
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ spec.files = Dir.chdir(__dir__) do
25
+ `git ls-files -z`.split("\x0").reject do |f|
26
+ (File.expand_path(f) == __FILE__) ||
27
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
28
+ end
29
+ end
30
+ spec.bindir = "bin"
31
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+
34
+ # Uncomment to register a new dependency of your gem
35
+ spec.add_dependency "tailwind_merge", "~> 0.7"
36
+
37
+ # For more information and examples about making a new gem, check out our
38
+ # guide at: https://bundler.io/guides/creating_gem.html
39
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shadcn-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Avi Flombaum
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-03 00:00:00.000000000 Z
11
+ date: 2024-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tailwind_merge
@@ -53,12 +53,13 @@ files:
53
53
  - app/assets/stylesheets/shadcn.css
54
54
  - app/channels/application_cable/channel.rb
55
55
  - app/channels/application_cable/connection.rb
56
+ - app/components/shadcn/form_builder.rb
57
+ - app/components/shadcn/select_component.rb
56
58
  - app/controllers/application_controller.rb
57
59
  - app/controllers/components_controller.rb
58
60
  - app/controllers/concerns/.keep
59
61
  - app/controllers/documentation_controller.rb
60
62
  - app/controllers/users_controller.rb
61
- - app/form_builders/shadcn_form_builder.rb
62
63
  - app/helpers/application_helper.rb
63
64
  - app/helpers/components/accordion_helper.rb
64
65
  - app/helpers/components/alert_dialog_helper.rb
@@ -71,6 +72,7 @@ files:
71
72
  - app/helpers/components/combobox_helper.rb
72
73
  - app/helpers/components/dialog_helper.rb
73
74
  - app/helpers/components/dropdown_menu_helper.rb
75
+ - app/helpers/components/dropzone_helper.rb
74
76
  - app/helpers/components/filter_helper.rb
75
77
  - app/helpers/components/forms_helper.rb
76
78
  - app/helpers/components/hover_card_helper.rb
@@ -79,11 +81,13 @@ files:
79
81
  - app/helpers/components/list_helper.rb
80
82
  - app/helpers/components/popover_helper.rb
81
83
  - app/helpers/components/progress_helper.rb
84
+ - app/helpers/components/select_helper.rb
82
85
  - app/helpers/components/separator_helper.rb
83
86
  - app/helpers/components/sheet_helper.rb
84
87
  - app/helpers/components/skeleton_helper.rb
85
88
  - app/helpers/components/slider_helper.rb
86
89
  - app/helpers/components/switch_helper.rb
90
+ - app/helpers/components/table_helper.rb
87
91
  - app/helpers/components/tabs_helper.rb
88
92
  - app/helpers/components/textarea_helper.rb
89
93
  - app/helpers/components/toast_helper.rb
@@ -103,6 +107,7 @@ files:
103
107
  - app/javascript/controllers/ui/collapsible_controller.js
104
108
  - app/javascript/controllers/ui/dialog_controller.js
105
109
  - app/javascript/controllers/ui/dropdown_controller.js
110
+ - app/javascript/controllers/ui/dropzone_controller.js
106
111
  - app/javascript/controllers/ui/filter_controller.js
107
112
  - app/javascript/controllers/ui/hover-card_controller.js
108
113
  - app/javascript/controllers/ui/popover_controller.js
@@ -131,6 +136,7 @@ files:
131
136
  - app/views/components/ui/_command.html.erb
132
137
  - app/views/components/ui/_dialog.html.erb
133
138
  - app/views/components/ui/_dropdown_menu.html.erb
139
+ - app/views/components/ui/_dropzone.html.erb
134
140
  - app/views/components/ui/_filter.html.erb
135
141
  - app/views/components/ui/_hover_card.html.erb
136
142
  - app/views/components/ui/_input.html.erb
@@ -215,6 +221,10 @@ files:
215
221
  - app/views/examples/components/dropdown-menu/_usage.html.erb
216
222
  - app/views/examples/components/dropdown-menu/code/_preview.erb
217
223
  - app/views/examples/components/dropdown-menu/code/_usage.erb
224
+ - app/views/examples/components/dropzone.html.erb
225
+ - app/views/examples/components/dropzone/_usage.html.erb
226
+ - app/views/examples/components/dropzone/code/_preview.erb
227
+ - app/views/examples/components/dropzone/code/_usage.erb
218
228
  - app/views/examples/components/filter.html.erb
219
229
  - app/views/examples/components/filter/_usage.html.erb
220
230
  - app/views/examples/components/filter/code/_icon.html.erb
@@ -246,6 +256,10 @@ files:
246
256
  - app/views/examples/components/progress/_usage.erb
247
257
  - app/views/examples/components/progress/code/_preview.erb
248
258
  - app/views/examples/components/progress/code/_usage.erb
259
+ - app/views/examples/components/select.html.erb
260
+ - app/views/examples/components/select/_usage.html.erb
261
+ - app/views/examples/components/select/code/_preview.erb
262
+ - app/views/examples/components/select/code/_usage.erb
249
263
  - app/views/examples/components/separator.html.erb
250
264
  - app/views/examples/components/separator/_usage.html.erb
251
265
  - app/views/examples/components/separator/code/_fancy.erb
@@ -268,6 +282,10 @@ files:
268
282
  - app/views/examples/components/switch/_usage.html.erb
269
283
  - app/views/examples/components/switch/code/_preview.erb
270
284
  - app/views/examples/components/switch/code/_usage.erb
285
+ - app/views/examples/components/table.html.erb
286
+ - app/views/examples/components/table/_usage.html.erb
287
+ - app/views/examples/components/table/code/_preview.erb
288
+ - app/views/examples/components/table/code/_usage.erb
271
289
  - app/views/examples/components/tabs.html.erb
272
290
  - app/views/examples/components/tabs/_usage.html.erb
273
291
  - app/views/examples/components/tabs/code/_account.html.erb
@@ -350,6 +368,7 @@ files:
350
368
  - public/favicon.ico
351
369
  - public/og.jpg
352
370
  - public/robots.txt
371
+ - shadcn-ui.gemspec
353
372
  - sig/shadcn-ui.rbs
354
373
  - storage/.keep
355
374
  - tmp/.keep
@@ -379,7 +398,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
379
398
  - !ruby/object:Gem::Version
380
399
  version: '0'
381
400
  requirements: []
382
- rubygems_version: 3.4.10
401
+ rubygems_version: 3.5.4
383
402
  signing_key:
384
403
  specification_version: 4
385
404
  summary: Provides the shadcn-ui component library to a Ruby on Rails application.