diff --git a/docs/app/components/shared/components_list.rb b/docs/app/components/shared/components_list.rb
index eae5c84d..28112700 100644
--- a/docs/app/components/shared/components_list.rb
+++ b/docs/app/components/shared/components_list.rb
@@ -30,6 +30,7 @@ def components
{name: "Date Picker", path: docs_date_picker_path},
{name: "Dialog / Modal", path: docs_dialog_path},
{name: "Dropdown Menu", path: docs_dropdown_menu_path},
+ {name: "Empty", path: docs_empty_path},
{name: "Form", path: docs_form_path},
{name: "Hover Card", path: docs_hover_card_path},
{name: "Input", path: docs_input_path},
diff --git a/docs/app/controllers/docs_controller.rb b/docs/app/controllers/docs_controller.rb
index d5e8473d..6b9d5a83 100644
--- a/docs/app/controllers/docs_controller.rb
+++ b/docs/app/controllers/docs_controller.rb
@@ -146,6 +146,10 @@ def dropdown_menu
render Views::Docs::DropdownMenu.new
end
+ def empty
+ render Views::Docs::Empty.new
+ end
+
def form
render Views::Docs::Form.new
end
diff --git a/docs/app/lib/site_files.rb b/docs/app/lib/site_files.rb
index b0984020..7eda2dfa 100644
--- a/docs/app/lib/site_files.rb
+++ b/docs/app/lib/site_files.rb
@@ -103,6 +103,7 @@ class SiteFiles
{title: "Date Picker", path: "/docs/date_picker", description: "Date picker component with input."},
{title: "Dialog", path: "/docs/dialog", description: "Modal window that renders background content inert."},
{title: "Dropdown Menu", path: "/docs/dropdown_menu", description: "Button-triggered menu for actions or functions."},
+ {title: "Empty", path: "/docs/empty", description: "Empty state for when there is no data or content."},
{title: "Form", path: "/docs/form", description: "Form fields with built-in client-side validations."},
{title: "Hover Card", path: "/docs/hover_card", description: "Preview content exposed behind a link or trigger."},
{title: "Input", path: "/docs/input", description: "Styled input field primitive."},
diff --git a/docs/app/views/docs/empty.rb b/docs/app/views/docs/empty.rb
new file mode 100644
index 00000000..c69b3f43
--- /dev/null
+++ b/docs/app/views/docs/empty.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+class Views::Docs::Empty < Views::Base
+ def view_template
+ component = "Empty"
+
+ div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do
+ render Docs::Header.new(title: "Empty", description: "Use the empty component to display a state when there is no data or content.")
+
+ Heading(level: 2) { "Usage" }
+
+ render Docs::VisualCodeExample.new(title: "Default", context: self) do
+ <<~RUBY
+ Empty do
+ EmptyHeader do
+ EmptyMedia(variant: :icon) do
+ svg(xmlns: "http://www.w3.org/2000/svg", fill: "none", viewbox: "0 0 24 24", stroke_width: "1.5", stroke: "currentColor", class: "size-6") do |s|
+ s.path(stroke_linecap: "round", stroke_linejoin: "round", d: "M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 48.64 48.64 0 0 0-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0 0 11.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155")
+ end
+ end
+ EmptyTitle { "No messages yet" }
+ EmptyDescription { "Start a conversation to see your messages here." }
+ end
+ end
+ RUBY
+ end
+
+ render Docs::VisualCodeExample.new(title: "With action", context: self) do
+ <<~RUBY
+ Empty do
+ EmptyHeader do
+ EmptyMedia(variant: :icon) do
+ svg(xmlns: "http://www.w3.org/2000/svg", fill: "none", viewbox: "0 0 24 24", stroke_width: "1.5", stroke: "currentColor", class: "size-6") do |s|
+ s.path(stroke_linecap: "round", stroke_linejoin: "round", d: "M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z")
+ end
+ end
+ EmptyTitle { "No projects" }
+ EmptyDescription { "Get started by creating your first project." }
+ end
+ EmptyContent do
+ Button { "Create project" }
+ end
+ end
+ RUBY
+ end
+
+ render Docs::VisualCodeExample.new(title: "Default media", context: self) do
+ <<~RUBY
+ Empty(class: "border-none") do
+ EmptyHeader do
+ EmptyMedia(variant: :default) do
+ Avatar(size: :lg) do
+ AvatarFallback { "RU" }
+ end
+ end
+ EmptyTitle { "No team members" }
+ EmptyDescription { "Invite your team to start collaborating." }
+ end
+ end
+ RUBY
+ end
+
+ render Components::ComponentSetup::Tabs.new(component_name: component)
+
+ # components
+ render Docs::ComponentsTable.new(component_files(component))
+ end
+ end
+end
diff --git a/docs/config/routes.rb b/docs/config/routes.rb
index 59702c7f..d739ebe2 100644
--- a/docs/config/routes.rb
+++ b/docs/config/routes.rb
@@ -47,6 +47,7 @@
get "date_picker", to: "docs#date_picker", as: :docs_date_picker
get "dialog", to: "docs#dialog", as: :docs_dialog
get "dropdown_menu", to: "docs#dropdown_menu", as: :docs_dropdown_menu
+ get "empty", to: "docs#empty", as: :docs_empty
get "form", to: "docs#form", as: :docs_form
get "hover_card", to: "docs#hover_card", as: :docs_hover_card
get "input", to: "docs#input", as: :docs_input
diff --git a/docs/public/llms-full.txt b/docs/public/llms-full.txt
index 3bd2e280..4ab58847 100644
--- a/docs/public/llms-full.txt
+++ b/docs/public/llms-full.txt
@@ -203,6 +203,11 @@ This file expands the curated /llms.txt map into a compact reference that can be
- URL: https://rubyui.com/docs/dropdown_menu
- Summary: Button-triggered menu for actions or functions.
+### Empty
+
+- URL: https://rubyui.com/docs/empty
+- Summary: Empty state for when there is no data or content.
+
### Form
- URL: https://rubyui.com/docs/form
diff --git a/docs/public/llms.txt b/docs/public/llms.txt
index 722ad3ac..f2269efb 100644
--- a/docs/public/llms.txt
+++ b/docs/public/llms.txt
@@ -45,6 +45,7 @@ Use the core docs first for installation, theming, dark mode, and customization
- [Date Picker](https://rubyui.com/docs/date_picker): Date picker component with input.
- [Dialog](https://rubyui.com/docs/dialog): Modal window that renders background content inert.
- [Dropdown Menu](https://rubyui.com/docs/dropdown_menu): Button-triggered menu for actions or functions.
+- [Empty](https://rubyui.com/docs/empty): Empty state for when there is no data or content.
- [Form](https://rubyui.com/docs/form): Form fields with built-in client-side validations.
- [Hover Card](https://rubyui.com/docs/hover_card): Preview content exposed behind a link or trigger.
- [Input](https://rubyui.com/docs/input): Styled input field primitive.
diff --git a/docs/public/sitemap.xml b/docs/public/sitemap.xml
index e3f5c942..518381a2 100644
--- a/docs/public/sitemap.xml
+++ b/docs/public/sitemap.xml
@@ -180,6 +180,11 @@
monthly
0.7
+
+ https://rubyui.com/docs/empty
+ monthly
+ 0.7
+
https://rubyui.com/docs/form
monthly
diff --git a/gem/lib/ruby_ui/empty/empty.rb b/gem/lib/ruby_ui/empty/empty.rb
new file mode 100644
index 00000000..1c315f8f
--- /dev/null
+++ b/gem/lib/ruby_ui/empty/empty.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module RubyUI
+ class Empty < Base
+ def view_template(&)
+ div(**attrs, &)
+ end
+
+ private
+
+ def default_attrs
+ {
+ data: {slot: "empty"},
+ class: "flex w-full min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded-3xl border border-dashed p-12 text-center text-balance"
+ }
+ end
+ end
+end
diff --git a/gem/lib/ruby_ui/empty/empty_content.rb b/gem/lib/ruby_ui/empty/empty_content.rb
new file mode 100644
index 00000000..eae0b46d
--- /dev/null
+++ b/gem/lib/ruby_ui/empty/empty_content.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module RubyUI
+ class EmptyContent < Base
+ def view_template(&)
+ div(**attrs, &)
+ end
+
+ private
+
+ def default_attrs
+ {
+ data: {slot: "empty-content"},
+ class: "flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance"
+ }
+ end
+ end
+end
diff --git a/gem/lib/ruby_ui/empty/empty_description.rb b/gem/lib/ruby_ui/empty/empty_description.rb
new file mode 100644
index 00000000..147bcafb
--- /dev/null
+++ b/gem/lib/ruby_ui/empty/empty_description.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module RubyUI
+ class EmptyDescription < Base
+ def view_template(&)
+ div(**attrs, &)
+ end
+
+ private
+
+ def default_attrs
+ {
+ data: {slot: "empty-description"},
+ class: "text-sm leading-relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary"
+ }
+ end
+ end
+end
diff --git a/gem/lib/ruby_ui/empty/empty_docs.rb b/gem/lib/ruby_ui/empty/empty_docs.rb
new file mode 100644
index 00000000..c69b3f43
--- /dev/null
+++ b/gem/lib/ruby_ui/empty/empty_docs.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+class Views::Docs::Empty < Views::Base
+ def view_template
+ component = "Empty"
+
+ div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do
+ render Docs::Header.new(title: "Empty", description: "Use the empty component to display a state when there is no data or content.")
+
+ Heading(level: 2) { "Usage" }
+
+ render Docs::VisualCodeExample.new(title: "Default", context: self) do
+ <<~RUBY
+ Empty do
+ EmptyHeader do
+ EmptyMedia(variant: :icon) do
+ svg(xmlns: "http://www.w3.org/2000/svg", fill: "none", viewbox: "0 0 24 24", stroke_width: "1.5", stroke: "currentColor", class: "size-6") do |s|
+ s.path(stroke_linecap: "round", stroke_linejoin: "round", d: "M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 48.64 48.64 0 0 0-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0 0 11.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155")
+ end
+ end
+ EmptyTitle { "No messages yet" }
+ EmptyDescription { "Start a conversation to see your messages here." }
+ end
+ end
+ RUBY
+ end
+
+ render Docs::VisualCodeExample.new(title: "With action", context: self) do
+ <<~RUBY
+ Empty do
+ EmptyHeader do
+ EmptyMedia(variant: :icon) do
+ svg(xmlns: "http://www.w3.org/2000/svg", fill: "none", viewbox: "0 0 24 24", stroke_width: "1.5", stroke: "currentColor", class: "size-6") do |s|
+ s.path(stroke_linecap: "round", stroke_linejoin: "round", d: "M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z")
+ end
+ end
+ EmptyTitle { "No projects" }
+ EmptyDescription { "Get started by creating your first project." }
+ end
+ EmptyContent do
+ Button { "Create project" }
+ end
+ end
+ RUBY
+ end
+
+ render Docs::VisualCodeExample.new(title: "Default media", context: self) do
+ <<~RUBY
+ Empty(class: "border-none") do
+ EmptyHeader do
+ EmptyMedia(variant: :default) do
+ Avatar(size: :lg) do
+ AvatarFallback { "RU" }
+ end
+ end
+ EmptyTitle { "No team members" }
+ EmptyDescription { "Invite your team to start collaborating." }
+ end
+ end
+ RUBY
+ end
+
+ render Components::ComponentSetup::Tabs.new(component_name: component)
+
+ # components
+ render Docs::ComponentsTable.new(component_files(component))
+ end
+ end
+end
diff --git a/gem/lib/ruby_ui/empty/empty_header.rb b/gem/lib/ruby_ui/empty/empty_header.rb
new file mode 100644
index 00000000..8207b0cc
--- /dev/null
+++ b/gem/lib/ruby_ui/empty/empty_header.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module RubyUI
+ class EmptyHeader < Base
+ def view_template(&)
+ div(**attrs, &)
+ end
+
+ private
+
+ def default_attrs
+ {
+ data: {slot: "empty-header"},
+ class: "flex max-w-sm flex-col items-center gap-2"
+ }
+ end
+ end
+end
diff --git a/gem/lib/ruby_ui/empty/empty_media.rb b/gem/lib/ruby_ui/empty/empty_media.rb
new file mode 100644
index 00000000..231d110b
--- /dev/null
+++ b/gem/lib/ruby_ui/empty/empty_media.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module RubyUI
+ class EmptyMedia < Base
+ VARIANTS = {
+ default: "bg-transparent",
+ icon: "size-10 rounded-xl bg-muted text-foreground [&_svg:not([class*='size-'])]:size-5"
+ }
+
+ def initialize(variant: :default, **attrs)
+ @variant = variant
+ super(**attrs)
+ end
+
+ def view_template(&)
+ div(**attrs, &)
+ end
+
+ private
+
+ def default_attrs
+ {
+ data: {slot: "empty-icon", variant: @variant},
+ class: [
+ "mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
+ VARIANTS[@variant]
+ ]
+ }
+ end
+ end
+end
diff --git a/gem/lib/ruby_ui/empty/empty_title.rb b/gem/lib/ruby_ui/empty/empty_title.rb
new file mode 100644
index 00000000..26570c1b
--- /dev/null
+++ b/gem/lib/ruby_ui/empty/empty_title.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module RubyUI
+ class EmptyTitle < Base
+ def view_template(&)
+ div(**attrs, &)
+ end
+
+ private
+
+ def default_attrs
+ {
+ data: {slot: "empty-title"},
+ class: "text-lg font-medium tracking-tight"
+ }
+ end
+ end
+end
diff --git a/gem/test/ruby_ui/empty_test.rb b/gem/test/ruby_ui/empty_test.rb
new file mode 100644
index 00000000..75205f50
--- /dev/null
+++ b/gem/test/ruby_ui/empty_test.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require "test_helper"
+
+class RubyUI::EmptyTest < ComponentTest
+ def test_renders_full_structure
+ output = phlex do
+ RubyUI.Empty do
+ RubyUI.EmptyHeader do
+ RubyUI.EmptyMedia(variant: :icon) { "icon" }
+ RubyUI.EmptyTitle { "Nothing here" }
+ RubyUI.EmptyDescription { "No content yet." }
+ end
+ RubyUI.EmptyContent { "action" }
+ end
+ end
+
+ assert_match(/data-slot="empty"/, output)
+ assert_match(/data-slot="empty-header"/, output)
+ assert_match(/data-slot="empty-icon"/, output)
+ assert_match(/data-slot="empty-title"/, output)
+ assert_match(/data-slot="empty-description"/, output)
+ assert_match(/data-slot="empty-content"/, output)
+ assert_match(/Nothing here/, output)
+ end
+
+ def test_media_default_variant
+ output = phlex { RubyUI.EmptyMedia { "x" } }
+
+ assert_match(/data-variant="default"/, output)
+ end
+
+ def test_media_icon_variant
+ output = phlex { RubyUI.EmptyMedia(variant: :icon) { "x" } }
+
+ assert_match(/data-variant="icon"/, output)
+ assert_match(/bg-muted/, output)
+ end
+end
diff --git a/mcp/data/registry.json b/mcp/data/registry.json
index 4922db45..aff6f5a4 100644
--- a/mcp/data/registry.json
+++ b/mcp/data/registry.json
@@ -1435,6 +1435,60 @@
}
]
},
+ "empty": {
+ "name": "Empty",
+ "description": "Use the empty component to display a state when there is no data or content.",
+ "files": [
+ {
+ "path": "empty.rb",
+ "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class Empty < Base\n def view_template(&)\n div(**attrs, &)\n end\n\n private\n\n def default_attrs\n {\n data: {slot: \"empty\"},\n class: \"flex w-full min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded-3xl border border-dashed p-12 text-center text-balance\"\n }\n end\n end\nend\n"
+ },
+ {
+ "path": "empty_content.rb",
+ "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class EmptyContent < Base\n def view_template(&)\n div(**attrs, &)\n end\n\n private\n\n def default_attrs\n {\n data: {slot: \"empty-content\"},\n class: \"flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance\"\n }\n end\n end\nend\n"
+ },
+ {
+ "path": "empty_description.rb",
+ "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class EmptyDescription < Base\n def view_template(&)\n div(**attrs, &)\n end\n\n private\n\n def default_attrs\n {\n data: {slot: \"empty-description\"},\n class: \"text-sm leading-relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\"\n }\n end\n end\nend\n"
+ },
+ {
+ "path": "empty_header.rb",
+ "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class EmptyHeader < Base\n def view_template(&)\n div(**attrs, &)\n end\n\n private\n\n def default_attrs\n {\n data: {slot: \"empty-header\"},\n class: \"flex max-w-sm flex-col items-center gap-2\"\n }\n end\n end\nend\n"
+ },
+ {
+ "path": "empty_media.rb",
+ "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class EmptyMedia < Base\n VARIANTS = {\n default: \"bg-transparent\",\n icon: \"size-10 rounded-xl bg-muted text-foreground [&_svg:not([class*='size-'])]:size-5\"\n }\n\n def initialize(variant: :default, **attrs)\n @variant = variant\n super(**attrs)\n end\n\n def view_template(&)\n div(**attrs, &)\n end\n\n private\n\n def default_attrs\n {\n data: {slot: \"empty-icon\", variant: @variant},\n class: [\n \"mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n VARIANTS[@variant]\n ]\n }\n end\n end\nend\n"
+ },
+ {
+ "path": "empty_title.rb",
+ "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class EmptyTitle < Base\n def view_template(&)\n div(**attrs, &)\n end\n\n private\n\n def default_attrs\n {\n data: {slot: \"empty-title\"},\n class: \"text-lg font-medium tracking-tight\"\n }\n end\n end\nend\n"
+ }
+ ],
+ "dependencies": {
+ "components": [],
+ "js_packages": [],
+ "gems": []
+ },
+ "install_command": "rails g ruby_ui:component Empty",
+ "docs_markdown": "# Empty\n\nUse the empty component to display a state when there is no data or content.\n\n## Usage\n\n### Default\n\n```ruby\nEmpty do\n EmptyHeader do\n EmptyMedia(variant: :icon) do\n svg(xmlns: \"http://www.w3.org/2000/svg\", fill: \"none\", viewbox: \"0 0 24 24\", stroke_width: \"1.5\", stroke: \"currentColor\", class: \"size-6\") do |s|\n s.path(stroke_linecap: \"round\", stroke_linejoin: \"round\", d: \"M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 48.64 48.64 0 0 0-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0 0 11.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155\")\n end\n end\n EmptyTitle { \"No messages yet\" }\n EmptyDescription { \"Start a conversation to see your messages here.\" }\n end\nend\n```\n\n### With action\n\n```ruby\nEmpty do\n EmptyHeader do\n EmptyMedia(variant: :icon) do\n svg(xmlns: \"http://www.w3.org/2000/svg\", fill: \"none\", viewbox: \"0 0 24 24\", stroke_width: \"1.5\", stroke: \"currentColor\", class: \"size-6\") do |s|\n s.path(stroke_linecap: \"round\", stroke_linejoin: \"round\", d: \"M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z\")\n end\n end\n EmptyTitle { \"No projects\" }\n EmptyDescription { \"Get started by creating your first project.\" }\n end\n EmptyContent do\n Button { \"Create project\" }\n end\nend\n```\n\n### Default media\n\n```ruby\nEmpty(class: \"border-none\") do\n EmptyHeader do\n EmptyMedia(variant: :default) do\n Avatar(size: :lg) do\n AvatarFallback { \"RU\" }\n end\n end\n EmptyTitle { \"No team members\" }\n EmptyDescription { \"Invite your team to start collaborating.\" }\n end\nend\n```",
+ "examples": [
+ {
+ "title": "Default",
+ "code": "Empty do\n EmptyHeader do\n EmptyMedia(variant: :icon) do\n svg(xmlns: \"http://www.w3.org/2000/svg\", fill: \"none\", viewbox: \"0 0 24 24\", stroke_width: \"1.5\", stroke: \"currentColor\", class: \"size-6\") do |s|\n s.path(stroke_linecap: \"round\", stroke_linejoin: \"round\", d: \"M20.25 8.511c.884.284 1.5 1.128 1.5 2.097v4.286c0 1.136-.847 2.1-1.98 2.193-.34.027-.68.052-1.02.072v3.091l-3-3c-1.354 0-2.694-.055-4.02-.163a2.115 2.115 0 0 1-.825-.242m9.345-8.334a2.126 2.126 0 0 0-.476-.095 48.64 48.64 0 0 0-8.048 0c-1.131.094-1.976 1.057-1.976 2.192v4.286c0 .837.46 1.58 1.155 1.951m9.345-8.334V6.637c0-1.621-1.152-3.026-2.76-3.235A48.455 48.455 0 0 0 11.25 3c-2.115 0-4.198.137-6.24.402-1.608.209-2.76 1.614-2.76 3.235v6.226c0 1.621 1.152 3.026 2.76 3.235.577.075 1.157.14 1.74.194V21l4.155-4.155\")\n end\n end\n EmptyTitle { \"No messages yet\" }\n EmptyDescription { \"Start a conversation to see your messages here.\" }\n end\nend\n",
+ "language": "ruby"
+ },
+ {
+ "title": "With action",
+ "code": "Empty do\n EmptyHeader do\n EmptyMedia(variant: :icon) do\n svg(xmlns: \"http://www.w3.org/2000/svg\", fill: \"none\", viewbox: \"0 0 24 24\", stroke_width: \"1.5\", stroke: \"currentColor\", class: \"size-6\") do |s|\n s.path(stroke_linecap: \"round\", stroke_linejoin: \"round\", d: \"M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z\")\n end\n end\n EmptyTitle { \"No projects\" }\n EmptyDescription { \"Get started by creating your first project.\" }\n end\n EmptyContent do\n Button { \"Create project\" }\n end\nend\n",
+ "language": "ruby"
+ },
+ {
+ "title": "Default media",
+ "code": "Empty(class: \"border-none\") do\n EmptyHeader do\n EmptyMedia(variant: :default) do\n Avatar(size: :lg) do\n AvatarFallback { \"RU\" }\n end\n end\n EmptyTitle { \"No team members\" }\n EmptyDescription { \"Invite your team to start collaborating.\" }\n end\nend\n",
+ "language": "ruby"
+ }
+ ]
+ },
"form": {
"name": "Form",
"description": "Building forms with built-in client-side validations.",