Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
connect() {
this.element
.querySelectorAll("input[type=checkbox][data-column-key]")
.forEach((checkbox) =>
this._apply(checkbox.dataset.columnKey, checkbox.checked)
);
}

toggle(event) {
const key = event.target.dataset.columnKey;
const visible = event.target.checked;
this._apply(event.target.dataset.columnKey, event.target.checked);
}

_apply(key, visible) {
const root = this.element.closest('[data-controller~="ruby-ui--data-table"]');
if (!root) return;
root
Expand Down
12 changes: 8 additions & 4 deletions gem/lib/ruby_ui/data_table/data_table_column_toggle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

module RubyUI
class DataTableColumnToggle < Base
def initialize(columns:, **attrs)
def initialize(columns:, label: "Columns", **attrs)
@columns = columns
@label = label
super(**attrs)
end

Expand All @@ -12,7 +13,7 @@ def view_template
render RubyUI::DropdownMenu.new do
render RubyUI::DropdownMenuTrigger.new do
render RubyUI::Button.new(variant: :outline, size: :sm) do
plain "Columns"
plain @label
# inline chevron-down SVG (lucide 24px, 1px stroke)
svg(
xmlns: "http://www.w3.org/2000/svg",
Expand All @@ -35,8 +36,11 @@ def view_template
label(class: "flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm cursor-pointer hover:bg-accent") do
input(
type: "checkbox",
checked: true,
class: "h-4 w-4 rounded border border-input accent-primary cursor-pointer",
checked: col.fetch(:visible, true),
class: [
"h-4 w-4 rounded border border-input accent-primary cursor-pointer",
"checked:bg-primary checked:text-primary-foreground dark:checked:bg-secondary checked:text-primary checked:border-primary"
],
data: {
column_key: col[:key].to_s,
action: "change->ruby-ui--data-table-column-visibility#toggle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
connect() {
this.element
.querySelectorAll("input[type=checkbox][data-column-key]")
.forEach((checkbox) =>
this._apply(checkbox.dataset.columnKey, checkbox.checked)
);
}

toggle(event) {
const key = event.target.dataset.columnKey;
const visible = event.target.checked;
this._apply(event.target.dataset.columnKey, event.target.checked);
}

_apply(key, visible) {
const root = this.element.closest('[data-controller~="ruby-ui--data-table"]');
if (!root) return;
root
Expand Down
20 changes: 20 additions & 0 deletions gem/test/ruby_ui/data_table_column_toggle_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,24 @@ def test_renders_dropdown_with_checkbox_per_column
assert_match(/Email/, output)
assert_match(/Salary/, output)
end

def test_renders_a_custom_trigger_label
output = phlex do
RubyUI.DataTableColumnToggle(label: "Colunas", columns: [
{key: :email, label: "Email"}
])
end
assert_match(/Colunas/, output)
end

def test_column_can_start_hidden
output = phlex do
RubyUI.DataTableColumnToggle(columns: [
{key: :email, label: "Email"},
{key: :salary, label: "Salary", visible: false}
])
end
# only the visible column renders the `checked` boolean attribute on its checkbox
assert_equal 1, output.scan(/\bchecked(?:\s|>)/).length
end
end
4 changes: 2 additions & 2 deletions mcp/data/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -1182,11 +1182,11 @@
},
{
"path": "data_table_column_toggle.rb",
"content": "# frozen_string_literal: true\n\nmodule RubyUI\n class DataTableColumnToggle < Base\n def initialize(columns:, **attrs)\n @columns = columns\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 plain \"Columns\"\n # inline chevron-down SVG (lucide 24px, 1px stroke)\n svg(\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\",\n height: \"16\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n stroke_width: \"2\",\n stroke_linecap: \"round\",\n stroke_linejoin: \"round\",\n class: \"w-4 h-4 ml-1\"\n ) do |s|\n s.polyline(points: \"6 9 12 15 18 9\")\n end\n end\n end\n render RubyUI::DropdownMenuContent.new do\n @columns.each do |col|\n label(class: \"flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm cursor-pointer hover:bg-accent\") do\n input(\n type: \"checkbox\",\n checked: true,\n class: \"h-4 w-4 rounded border border-input accent-primary cursor-pointer\",\n data: {\n column_key: col[:key].to_s,\n action: \"change->ruby-ui--data-table-column-visibility#toggle\"\n }\n )\n span { plain col[:label] }\n end\n end\n end\n end\n end\n end\n\n private\n\n def default_attrs\n {\n class: \"relative\",\n data: {controller: \"ruby-ui--data-table-column-visibility\"}\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 render RubyUI::DropdownMenu.new do\n render RubyUI::DropdownMenuTrigger.new do\n render RubyUI::Button.new(variant: :outline, size: :sm) do\n plain @label\n # inline chevron-down SVG (lucide 24px, 1px stroke)\n svg(\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\",\n height: \"16\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n stroke_width: \"2\",\n stroke_linecap: \"round\",\n stroke_linejoin: \"round\",\n class: \"w-4 h-4 ml-1\"\n ) do |s|\n s.polyline(points: \"6 9 12 15 18 9\")\n end\n end\n end\n render RubyUI::DropdownMenuContent.new do\n @columns.each do |col|\n label(class: \"flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm cursor-pointer hover:bg-accent\") do\n input(\n type: \"checkbox\",\n checked: col.fetch(:visible, true),\n class: [\n \"h-4 w-4 rounded border border-input accent-primary cursor-pointer\",\n \"checked:bg-primary checked:text-primary-foreground dark:checked:bg-secondary checked:text-primary checked:border-primary\"\n ],\n data: {\n column_key: col[:key].to_s,\n action: \"change->ruby-ui--data-table-column-visibility#toggle\"\n }\n )\n span { plain col[:label] }\n end\n end\n end\n end\n end\n end\n\n private\n\n def default_attrs\n {\n class: \"relative\",\n data: {controller: \"ruby-ui--data-table-column-visibility\"}\n }\n end\n end\nend\n"
},
{
"path": "data_table_column_visibility_controller.js",
"content": "// app/javascript/controllers/ruby_ui/data_table_column_visibility_controller.js\nimport { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n toggle(event) {\n const key = event.target.dataset.columnKey;\n const visible = event.target.checked;\n const root = this.element.closest('[data-controller~=\"ruby-ui--data-table\"]');\n if (!root) return;\n root\n .querySelectorAll(`[data-column=\"${key}\"]`)\n .forEach((el) => el.classList.toggle(\"hidden\", !visible));\n }\n}\n"
"content": "// app/javascript/controllers/ruby_ui/data_table_column_visibility_controller.js\nimport { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n connect() {\n this.element\n .querySelectorAll(\"input[type=checkbox][data-column-key]\")\n .forEach((checkbox) =>\n this._apply(checkbox.dataset.columnKey, checkbox.checked)\n );\n }\n\n toggle(event) {\n this._apply(event.target.dataset.columnKey, event.target.checked);\n }\n\n _apply(key, visible) {\n const root = this.element.closest('[data-controller~=\"ruby-ui--data-table\"]');\n if (!root) return;\n root\n .querySelectorAll(`[data-column=\"${key}\"]`)\n .forEach((el) => el.classList.toggle(\"hidden\", !visible));\n }\n}\n"
},
{
"path": "data_table_controller.js",
Expand Down