]*data-slot="dropdown-menu"[^>]*class="contents"/, output)
+ end
end
diff --git a/gem/test/ruby_ui/data_table_toolbar_test.rb b/gem/test/ruby_ui/data_table_toolbar_test.rb
index e78b9f9d9..17ae288f5 100644
--- a/gem/test/ruby_ui/data_table_toolbar_test.rb
+++ b/gem/test/ruby_ui/data_table_toolbar_test.rb
@@ -8,4 +8,9 @@ def test_renders_div_with_flex_layout_and_children
assert_match(/
]*class="[^"]*flex[^"]*"/, output)
assert_match(/INNER/, output)
end
+
+ def test_leaves_24px_before_the_table
+ output = phlex { RubyUI.DataTableToolbar { "INNER" } }
+ assert_match(/
]*class="[^"]*\bmb-6\b[^"]*"/, output)
+ end
end
diff --git a/mcp/data/registry/components/data_table.json b/mcp/data/registry/components/data_table.json
index d763f01d6..861359fde 100644
--- a/mcp/data/registry/components/data_table.json
+++ b/mcp/data/registry/components/data_table.json
@@ -12,7 +12,7 @@
},
{
"path": "data_table_column_toggle.rb",
- "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class DataTableColumnToggle < Base\n def initialize(columns:, label: \"Columns\", **attrs)\n @columns = columns\n @label = label\n super(**attrs)\n end\n\n def view_template\n div(**attrs) do\n render RubyUI::DropdownMenu.new do\n render RubyUI::DropdownMenuTrigger.new do\n render RubyUI::Button.new(variant: :outline, size: :sm) do\n columns_icon\n plain @label\n chevron_down_icon\n end\n end\n render RubyUI::DropdownMenuContent.new(align: :end, class: \"w-32\") do\n @columns.each do |col|\n render RubyUI::DropdownMenuCheckboxItem.new(\n checked: col.fetch(:visible, true),\n class: \"capitalize\",\n data: {column_key: col[:key].to_s}\n ) { plain col[:label] }\n end\n end\n end\n end\n end\n\n private\n\n # lucide columns-3, as shadcn's trigger (data-icon tightens the button's padding)\n def columns_icon\n svg(xmlns: \"http://www.w3.org/2000/svg\", viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\",\n stroke_width: \"2\", stroke_linecap: \"round\", stroke_linejoin: \"round\", aria_hidden: \"true\",\n data: {icon: \"inline-start\"}) do |s|\n s.rect(width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\")\n s.path(d: \"M9 3v18\")\n s.path(d: \"M15 3v18\")\n end\n end\n\n # lucide chevron-down\n def chevron_down_icon\n svg(xmlns: \"http://www.w3.org/2000/svg\", viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\",\n stroke_width: \"2\", stroke_linecap: \"round\", stroke_linejoin: \"round\", aria_hidden: \"true\",\n data: {icon: \"inline-end\"}) do |s|\n s.path(d: \"m6 9 6 6 6-6\")\n end\n end\n\n def default_attrs\n {\n class: \"relative\",\n data: {\n controller: \"ruby-ui--data-table-column-visibility\",\n action: \"ruby-ui--dropdown-menu:change->ruby-ui--data-table-column-visibility#toggle\"\n }\n }\n end\n end\nend\n"
+ "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class DataTableColumnToggle < Base\n def initialize(columns:, label: \"Columns\", **attrs)\n @columns = columns\n @label = label\n super(**attrs)\n end\n\n def view_template\n div(**attrs) do\n # Both wrappers are display: contents so the button is a flex item of\n # the toolbar, as shadcn's trigger (inline-flex blockifies to flex).\n render RubyUI::DropdownMenu.new(class: \"contents\") do\n render RubyUI::DropdownMenuTrigger.new do\n render RubyUI::Button.new(variant: :outline, size: :sm) do\n columns_icon\n plain @label\n chevron_down_icon\n end\n end\n render RubyUI::DropdownMenuContent.new(align: :end, class: \"w-32\") do\n @columns.each do |col|\n render RubyUI::DropdownMenuCheckboxItem.new(\n checked: col.fetch(:visible, true),\n class: \"capitalize\",\n data: {column_key: col[:key].to_s}\n ) { plain col[:label] }\n end\n end\n end\n end\n end\n\n private\n\n # lucide columns-3, as shadcn's trigger (data-icon tightens the button's padding)\n def columns_icon\n svg(xmlns: \"http://www.w3.org/2000/svg\", viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\",\n stroke_width: \"2\", stroke_linecap: \"round\", stroke_linejoin: \"round\", aria_hidden: \"true\",\n data: {icon: \"inline-start\"}) do |s|\n s.rect(width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\")\n s.path(d: \"M9 3v18\")\n s.path(d: \"M15 3v18\")\n end\n end\n\n # lucide chevron-down\n def chevron_down_icon\n svg(xmlns: \"http://www.w3.org/2000/svg\", viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\",\n stroke_width: \"2\", stroke_linecap: \"round\", stroke_linejoin: \"round\", aria_hidden: \"true\",\n data: {icon: \"inline-end\"}) do |s|\n s.path(d: \"m6 9 6 6 6-6\")\n end\n end\n\n def default_attrs\n {\n class: \"contents\",\n data: {\n controller: \"ruby-ui--data-table-column-visibility\",\n action: \"ruby-ui--dropdown-menu:change->ruby-ui--data-table-column-visibility#toggle\"\n }\n }\n end\n end\nend\n"
},
{
"path": "data_table_column_visibility_controller.js",
@@ -84,7 +84,7 @@
},
{
"path": "data_table_toolbar.rb",
- "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class DataTableToolbar < Base\n def view_template(&)\n div(**attrs, &)\n end\n\n private\n\n def default_attrs\n {class: \"flex items-center justify-between gap-2\"}\n end\n end\nend\n"
+ "content": "# frozen_string_literal: true\n\nmodule RubyUI\n class DataTableToolbar < Base\n def view_template(&)\n div(**attrs, &)\n end\n\n private\n\n def default_attrs\n # mb-6 overrides DataTable's space-y-4 (zero specificity) below the\n # toolbar: the dashboard-01 block puts 24px (gap-6) between the toolbar\n # and the table, 16px between the table and the pagination.\n {class: \"mb-6 flex items-center justify-between gap-2\"}\n end\n end\nend\n"
}
],
"dependencies": {