diff --git a/README.md b/README.md index e700f1a..535ac9d 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,7 @@ Gem implements [Lookbook](https://lookbook.build) documentation for all componen ```ruby config.lookbook.preview_paths = [TurboMaterial::Engine.root.join('lib/lookbook')] +config.lookbook.preview_controller = 'TurboMaterial::LookbookController' ``` Or extend your existing config for `lookbook.preview_paths` with same value. diff --git a/app/assets/javascripts/turbo_material/material_data_table_controller.js b/app/assets/javascripts/turbo_material/material_data_table_controller.js new file mode 100644 index 0000000..3067977 --- /dev/null +++ b/app/assets/javascripts/turbo_material/material_data_table_controller.js @@ -0,0 +1,56 @@ +import { Controller } from "@hotwired/stimulus"; +import { Turbo } from "@hotwired/turbo-rails"; +import { put } from "@rails/request.js"; + +export default class extends Controller { + dataTable = undefined; + static values = { url: String, selectUrl: String, queryString: String, body: String, selectionType: String }; + + connect() { + this.dataTable = mdc.dataTable.MDCDataTable.attachTo(this.element); + this.dataTable.listen('MDCDataTable:sorted', this.sort.bind(this)); + this.dataTable.listen('MDCDataTable:rowSelectionChanged', this.select.bind(this)); + this.dataTable.listen('MDCDataTable:selectedAll', this.selectAll.bind(this)); + this.dataTable.listen('MDCDataTable:unselectedAll', this.unselectAll.bind(this)); + } + + sort(event) { + let params = new URLSearchParams(this.queryStringValue); + params.delete("order"); + params.delete("reverse"); + params.append("order", event.detail.columnId); + params.append("reverse", event.detail.sortValue === "descending" ? "true" : "false"); + let frame = this.element.querySelector('turbo-frame#pupils-table-data'); + Turbo.visit(`${this.urlValue}?${params.toString()}`); + // , { action: 'advance', frame: this.bodyValue } + // FIXME: get this back as soon as https://github.com/hotwired/turbo/issues/489 is fixed + } + + select(event) { + put(`${this.selectUrlValue || this.urlValue}/${event.detail.rowId}/select`, { + body: { + type: this.selectionTypeValue, + selected: event.detail.selected, + }, + responseKind: "turbo-stream", + }); + } + + selectAll(event, selected = true) { + let params = new URLSearchParams(this.queryStringValue); + put(`${this.selectUrlValue || this.urlValue}/select_all?${params.toString()}`, { + body: { + type: this.selectionTypeValue, + selected: selected, + }, + responseKind: "turbo-stream", + }); + } + + unselectAll(event) { + this.selectAll(event, false); + } + + disconnect() { + } +} diff --git a/app/controllers/turbo_material/lookbook_controller.rb b/app/controllers/turbo_material/lookbook_controller.rb new file mode 100644 index 0000000..b2e3096 --- /dev/null +++ b/app/controllers/turbo_material/lookbook_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module TurboMaterial + class LookbookController < Lookbook::PreviewController + layout 'turbo_material/lookbook' + end +end diff --git a/app/helpers/turbo_material/data_table_helper.rb b/app/helpers/turbo_material/data_table_helper.rb new file mode 100644 index 0000000..9ce9231 --- /dev/null +++ b/app/helpers/turbo_material/data_table_helper.rb @@ -0,0 +1,7 @@ +module TurboMaterial + module DataTableHelper + def material_data_table(kwargs = {}) + render "components/material_data_table", **kwargs + end + end +end diff --git a/app/views/common/_form.html.erb b/app/views/common/_form.html.erb new file mode 100644 index 0000000..605c525 --- /dev/null +++ b/app/views/common/_form.html.erb @@ -0,0 +1,7 @@ +
+
+ <%= form_with(url: '/', method: :get, html: { novalidate: true }) do |form| %> + <%= public_send local_assigns.delete(:helper_name).to_sym, **local_assigns.merge(form: form) %> + <%- end -%> +
+
diff --git a/app/views/common/_menu_contents.html.erb b/app/views/common/_menu_contents.html.erb new file mode 100644 index 0000000..ba684df --- /dev/null +++ b/app/views/common/_menu_contents.html.erb @@ -0,0 +1,13 @@ + diff --git a/app/views/common/_standalone.html.erb b/app/views/common/_standalone.html.erb new file mode 100644 index 0000000..8d665d5 --- /dev/null +++ b/app/views/common/_standalone.html.erb @@ -0,0 +1 @@ +<%= public_send local_assigns.delete(:helper_name).to_sym, **local_assigns %> diff --git a/app/views/components/_material_data_table.html.erb b/app/views/components/_material_data_table.html.erb new file mode 100644 index 0000000..6b8ef74 --- /dev/null +++ b/app/views/components/_material_data_table.html.erb @@ -0,0 +1,132 @@ +<%# locals: (name:, table_body:, url:, table_params:, records:, pagy:, table_headers_partial:, table_contents_partial:) %> +
+
+ + + + + <%= render partial: table_headers_partial %> + + + + <%= render partial: table_contents_partial, locals: { records: records } %> + +
+
+ +
+ + + +
+
+
+
+
+
+
+
+
+
+ Rows per page +
+ + <%= form_with(url: url, method: :get, data: { + turbo_frame: table_body, + turbo_action: 'advance', + controller: 'live-form', + action: 'input->live-form#submit submit-now->live-form#submitNow' }, autocomplete: 'off') do |form| %> + <% params.keys.select { |k| k.starts_with?('ransack') }.each do |key| -%> + <%= form.hidden_field key, value: params[key] %> + <%- end -%> +
+ <%= form.hidden_field :per_page, value: pagy.items %> +
+ + <%= pagy.items %> + + + + + + + + + + + + + +
+ +
+
    +
  • + + + 10 + +
  • +
  • + + + 20 + +
  • +
  • + + + 100 + +
  • +
+
+
+
+ <%- end -%> + +
+
+ <%= pagy.from %>‑<%= pagy.to %> of <%= pagy.count %> +
+ <%= button_to url, method: :get, params: table_params.merge(page: 1), + data: { 'first-page' => "true", turbo_frame: table_body, turbo_action: 'advance' }, + disabled: pagy.page == 1, class: "mdc-icon-button material-icons mdc-data-table__pagination-button" do %> +
first_page
+ <% end %> + <%= button_to url, method: :get, params: table_params.merge(page: pagy.prev), + data: { 'prev-page' => "true", turbo_frame: table_body, turbo_action: 'advance' }, + disabled: pagy.prev.nil?, class: "mdc-icon-button material-icons mdc-data-table__pagination-button" do %> +
chevron_left
+ <% end %> + <%= button_to url, method: :get, params: table_params.merge(page: pagy.next), + data: { 'next-page' => "true", turbo_frame: table_body, turbo_action: 'advance' }, + disabled: pagy.next.nil?, class: "mdc-icon-button material-icons mdc-data-table__pagination-button" do %> +
chevron_right
+ <% end %> + <%= button_to url, method: :get, params: table_params.merge(page: pagy.last), + data: { 'last-page' => "true", turbo_frame: table_body, turbo_action: 'advance' }, + disabled: pagy.page == pagy.last, class: "mdc-icon-button material-icons mdc-data-table__pagination-button" do %> +
last_page
+ <% end %> +
+
+
+
diff --git a/app/views/layouts/turbo_material/lookbook.html.erb b/app/views/layouts/turbo_material/lookbook.html.erb new file mode 100644 index 0000000..a7aa72a --- /dev/null +++ b/app/views/layouts/turbo_material/lookbook.html.erb @@ -0,0 +1,20 @@ + + + + Turbo material + <%= csrf_meta_tags %> + <%= csp_meta_tag %> + + + + <%= stylesheet_link_tag "turbo_material/tailwind", "data-turbo-track": "reload" %> + <%= javascript_importmap_tags %> + <%= javascript_import_module_tag "turbo_material/application" %> + <%= stylesheet_link_tag "turbo_material/application", media: "all" %> + + + +<%= yield %> + + + diff --git a/lib/turbo_material/engine.rb b/lib/turbo_material/engine.rb index 84f1e30..ea2fdee 100644 --- a/lib/turbo_material/engine.rb +++ b/lib/turbo_material/engine.rb @@ -11,6 +11,7 @@ class Engine < ::Rails::Engine helper TurboMaterial::CheckboxHelper helper TurboMaterial::ChipsInputHelper helper TurboMaterial::ChipsSelectHelper + helper TurboMaterial::DataTableHelper helper TurboMaterial::MenuButtonHelper helper TurboMaterial::ModalHelper helper TurboMaterial::RadioHelper diff --git a/lib/turbo_material/version.rb b/lib/turbo_material/version.rb index e03808d..d3bfa64 100644 --- a/lib/turbo_material/version.rb +++ b/lib/turbo_material/version.rb @@ -1,3 +1,3 @@ module TurboMaterial - VERSION = "0.2.1" + VERSION = "0.2.2" end