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.
- checksums.yaml +4 -4
- data/app/{form_builders/shadcn_form_builder.rb → components/shadcn/form_builder.rb} +11 -3
- data/app/components/shadcn/select_component.rb +23 -0
- data/app/helpers/components/alert_helper.rb +3 -2
- data/app/helpers/components/button_helper.rb +1 -0
- data/app/helpers/components/dropzone_helper.rb +5 -0
- data/app/helpers/components/forms_helper.rb +2 -2
- data/app/helpers/components/select_helper.rb +6 -0
- data/app/helpers/components/sheet_helper.rb +3 -2
- data/app/helpers/components/table_helper.rb +61 -0
- data/app/helpers/components_helper.rb +2 -2
- data/app/javascript/controllers/ui/dropzone_controller.js +48 -0
- data/app/views/components/ui/_alert.html.erb +3 -3
- data/app/views/components/ui/_dropzone.html.erb +12 -0
- data/app/views/components/ui/_sheet.html.erb +10 -5
- data/app/views/documentation/index.html.md +1 -1
- data/app/views/documentation/installation.html.md +1 -1
- data/app/views/examples/components/accordion/code/_usage.erb +1 -1
- data/app/views/examples/components/accordion.html.erb +1 -1
- data/app/views/examples/components/card/code/_usage.erb +1 -1
- data/app/views/examples/components/dialog.html.erb +1 -1
- data/app/views/examples/components/dropzone/_usage.html.erb +20 -0
- data/app/views/examples/components/dropzone/code/_preview.erb +1 -0
- data/app/views/examples/components/dropzone/code/_usage.erb +1 -0
- data/app/views/examples/components/dropzone.html.erb +27 -0
- data/app/views/examples/components/forms/_usage.html.erb +2 -2
- data/app/views/examples/components/select/_usage.html.erb +22 -0
- data/app/views/examples/components/select/code/_preview.erb +7 -0
- data/app/views/examples/components/select/code/_usage.erb +5 -0
- data/app/views/examples/components/select.html.erb +27 -0
- data/app/views/examples/components/table/_usage.html.erb +23 -0
- data/app/views/examples/components/table/code/_preview.erb +35 -0
- data/app/views/examples/components/table/code/_usage.erb +12 -0
- data/app/views/examples/components/table.html.erb +27 -0
- data/app/views/layouts/shared/_components.html.erb +4 -3
- data/lib/components.json +25 -8
- data/lib/generators/shadcn-ui_generator.rb +1 -1
- data/lib/shadcn-ui/version.rb +1 -1
- metadata +22 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d36b644105b526361e08e906fb9404b89f4099f4f860afdc229bebe36a4b1996
|
4
|
+
data.tar.gz: ad0edad68914c4d1eee78f8b468b5f28cbead6ebd22fbd58f174ef7b5f00d77a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2d42f118d6048f572eab0597f8958be014e653ae2a0d020843308c96b2be4777798e91d54b648333caf67f516494b480edf7993639b64fbdaf5661ceb4389b6
|
7
|
+
data.tar.gz: cd3967406dcf715fd6604bf25f20e2e7f1c719feefa27b239f982be71ecc811118f74fd7351d59f230f6a0e8269a1be378b9760ee6ebb82fb6f8d6609503eee8
|
@@ -1,12 +1,13 @@
|
|
1
|
-
class
|
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
|
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
|
-
|
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
|
-
|
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
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module Components::FormsHelper
|
2
2
|
def render_form_with(**opts)
|
3
|
-
form_with(**opts.merge(builder:
|
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:
|
9
|
+
form_for(obj, **opts.merge(builder: Shadcn::FormBuilder), html: opts) do |form|
|
10
10
|
yield form
|
11
11
|
end
|
12
12
|
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
|
-
|
24
|
-
|
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
|
-
|
65
|
-
|
66
|
-
|
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="
|
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
|
-
|
12
|
-
|
13
|
-
|
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](/
|
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](
|
120
|
+
[installing components via the generator](/docs/generators) and rendering them into your
|
121
121
|
views.
|
122
122
|
|
123
123
|
# Manual Installation
|
@@ -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
|
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>
|
@@ -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
|
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/
|
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>
|
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,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,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("
|
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
|
-
|
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
|
-
|
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/
|
25
|
-
"app/views/components/ui/
|
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/
|
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/
|
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
|
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
|
|
data/lib/shadcn-ui/version.rb
CHANGED
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.
|
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-
|
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.
|
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.
|