shadcn-ui 0.0.8 → 0.0.12

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/{form_builders/shadcn_form_builder.rb → components/shadcn/form_builder.rb} +11 -3
  3. data/app/components/shadcn/select_component.rb +23 -0
  4. data/app/helpers/components/alert_helper.rb +3 -2
  5. data/app/helpers/components/button_helper.rb +1 -0
  6. data/app/helpers/components/dropzone_helper.rb +5 -0
  7. data/app/helpers/components/forms_helper.rb +2 -2
  8. data/app/helpers/components/select_helper.rb +6 -0
  9. data/app/helpers/components/sheet_helper.rb +3 -2
  10. data/app/helpers/components/table_helper.rb +61 -0
  11. data/app/helpers/components_helper.rb +2 -2
  12. data/app/javascript/controllers/ui/dropzone_controller.js +48 -0
  13. data/app/views/components/ui/_alert.html.erb +3 -3
  14. data/app/views/components/ui/_dropzone.html.erb +12 -0
  15. data/app/views/components/ui/_sheet.html.erb +10 -5
  16. data/app/views/documentation/index.html.md +1 -1
  17. data/app/views/documentation/installation.html.md +1 -1
  18. data/app/views/examples/components/accordion/code/_usage.erb +1 -1
  19. data/app/views/examples/components/accordion.html.erb +1 -1
  20. data/app/views/examples/components/card/code/_usage.erb +1 -1
  21. data/app/views/examples/components/dialog.html.erb +1 -1
  22. data/app/views/examples/components/dropzone/_usage.html.erb +20 -0
  23. data/app/views/examples/components/dropzone/code/_preview.erb +1 -0
  24. data/app/views/examples/components/dropzone/code/_usage.erb +1 -0
  25. data/app/views/examples/components/dropzone.html.erb +27 -0
  26. data/app/views/examples/components/forms/_usage.html.erb +2 -2
  27. data/app/views/examples/components/select/_usage.html.erb +22 -0
  28. data/app/views/examples/components/select/code/_preview.erb +7 -0
  29. data/app/views/examples/components/select/code/_usage.erb +5 -0
  30. data/app/views/examples/components/select.html.erb +27 -0
  31. data/app/views/examples/components/table/_usage.html.erb +23 -0
  32. data/app/views/examples/components/table/code/_preview.erb +35 -0
  33. data/app/views/examples/components/table/code/_usage.erb +12 -0
  34. data/app/views/examples/components/table.html.erb +27 -0
  35. data/app/views/layouts/shared/_components.html.erb +4 -3
  36. data/lib/components.json +25 -8
  37. data/lib/generators/shadcn-ui_generator.rb +1 -1
  38. data/lib/shadcn-ui/version.rb +1 -1
  39. metadata +22 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1a6d106b3e241c5c7a418478bde0b7c4e4e50ce27c0999a1963d7a40b543dd2
4
- data.tar.gz: 47a2ff41f7186f01c3cdef384b2b602b39868fbd9f2c2f15f7a3d8c2e0d3a72c
3
+ metadata.gz: d36b644105b526361e08e906fb9404b89f4099f4f860afdc229bebe36a4b1996
4
+ data.tar.gz: ad0edad68914c4d1eee78f8b468b5f28cbead6ebd22fbd58f174ef7b5f00d77a
5
5
  SHA512:
6
- metadata.gz: 0b040f697a8b80b085a5d4a595bb20ed7b78b9f26d90082831977feb7acb80389787c8b23983f2094cde67212f5bf0a682f206c79171231d5b023ca22e11716e
7
- data.tar.gz: 1e44cfd6682738fc2df66f886ba9d2c6de2b044c6828f43ff9e2b67aef0f37f62a01087f78bd4158911083eee8cb45ef59f18ad64e0044d824b7b6075ccb6966
6
+ metadata.gz: d2d42f118d6048f572eab0597f8958be014e653ae2a0d020843308c96b2be4777798e91d54b648333caf67f516494b480edf7993639b64fbdaf5661ceb4389b6
7
+ data.tar.gz: cd3967406dcf715fd6604bf25f20e2e7f1c719feefa27b239f982be71ecc811118f74fd7351d59f230f6a0e8269a1be378b9760ee6ebb82fb6f8d6609503eee8
@@ -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}",
@@ -40,4 +41,11 @@ class ShadcnFormBuilder < ActionView::Helpers::FormBuilder
40
41
  def submit(value = nil, options = {})
41
42
  @template.render_button(value, **options)
42
43
  end
44
+
45
+ private
46
+
47
+ def label_for(object, method)
48
+ return method.capitalize if object.nil?
49
+ object.class.human_attribute_name(method)
50
+ end
43
51
  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
@@ -14,6 +14,7 @@ module Components::ButtonHelper
14
14
  " hover:bg-accent hover:text-accent-foreground "
15
15
  end
16
16
  button_classes << " #{varianet_classes} #{options[:class]}"
17
+ button_classes = tw(button_classes)
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
@@ -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
@@ -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 "
@@ -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>
@@ -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"
@@ -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>
@@ -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.8"
2
+ VERSION = "0.0.12"
3
3
  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.8
4
+ version: 0.0.12
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: 2023-09-04 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
@@ -379,7 +397,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
379
397
  - !ruby/object:Gem::Version
380
398
  version: '0'
381
399
  requirements: []
382
- rubygems_version: 3.4.10
400
+ rubygems_version: 3.4.18
383
401
  signing_key:
384
402
  specification_version: 4
385
403
  summary: Provides the shadcn-ui component library to a Ruby on Rails application.