plutonium 0.15.13 → 0.15.14

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/plutonium.css +1 -1
  3. data/app/assets/plutonium.js +155 -4
  4. data/app/assets/plutonium.js.map +4 -4
  5. data/app/assets/plutonium.min.js +8 -8
  6. data/app/assets/plutonium.min.js.map +4 -4
  7. data/app/views/components/resource_header/resource_header_component.rb +1 -1
  8. data/app/views/components/resource_layout/resource_layout_component.html.erb +6 -2
  9. data/app/views/layouts/resource.html.erb +1 -14
  10. data/app/views/layouts/rodauth.html.erb +2 -18
  11. data/app/views/plutonium/_resource_header.html.erb +4 -2
  12. data/app/views/plutonium/_resource_sidebar.html.erb +1 -1
  13. data/docs/public/templates/plutonium.rb +6 -12
  14. data/lib/generators/pu/gem/standard/standard_generator.rb +14 -1
  15. data/lib/generators/pu/lib/plutonium_generators/concerns/actions.rb +1 -1
  16. data/lib/plutonium/ui/color_mode_selector.rb +86 -0
  17. data/lib/plutonium/ui/component/kit.rb +2 -0
  18. data/lib/plutonium/ui/component/methods.rb +2 -0
  19. data/lib/plutonium/ui/dyna_frame/host.rb +2 -2
  20. data/lib/plutonium/ui/layout/base.rb +135 -0
  21. data/lib/plutonium/ui/layout/header.rb +121 -0
  22. data/lib/plutonium/ui/layout/resource_layout.rb +26 -0
  23. data/lib/plutonium/ui/layout/rodauth_layout.rb +34 -0
  24. data/lib/plutonium/ui/layout/sidebar.rb +56 -0
  25. data/lib/plutonium/ui/table/resource.rb +1 -1
  26. data/lib/plutonium/version.rb +1 -1
  27. data/lib/plutonium.rb +1 -1
  28. data/lib/rodauth/features/case_insensitive_login.rb +10 -4
  29. data/package-lock.json +2 -2
  30. data/package.json +1 -1
  31. data/src/js/controllers/header_controller.js +184 -0
  32. data/src/js/controllers/register_controllers.js +4 -2
  33. data/src/js/controllers/{resource_header_controller.js → sidebar_controller.js} +2 -2
  34. metadata +25 -4
  35. /data/lib/rodauth/{loader.rb → plugins.rb} +0 -0
@@ -2648,10 +2648,153 @@
2648
2648
  }
2649
2649
  };
2650
2650
 
2651
- // src/js/controllers/resource_header_controller.js
2652
- var resource_header_controller_default = class extends Controller {
2651
+ // src/js/controllers/header_controller.js
2652
+ var header_controller_default = class extends Controller {
2653
+ static targets = ["open", "close"];
2654
+ static outlets = ["sidebar"];
2655
+ static values = {
2656
+ placement: { type: String, default: "left" },
2657
+ bodyScrolling: { type: Boolean, default: false },
2658
+ backdrop: { type: Boolean, default: true },
2659
+ edge: { type: Boolean, default: false },
2660
+ edgeOffset: { type: String, default: "bottom-[60px]" }
2661
+ };
2662
+ static classes = {
2663
+ backdrop: "bg-gray-900/50 dark:bg-gray-900/80 fixed inset-0 z-30"
2664
+ };
2665
+ initialize() {
2666
+ this.visible = false;
2667
+ this.handleEscapeKey = this.handleEscapeKey.bind(this);
2668
+ }
2653
2669
  connect() {
2654
- console.log(`resource-header connected: ${this.element}`);
2670
+ document.addEventListener("keydown", this.handleEscapeKey);
2671
+ }
2672
+ sidebarOutletConnected() {
2673
+ this.#setupDrawer(this.sidebarOutlet.element);
2674
+ }
2675
+ disconnect() {
2676
+ this.#removeBackdrop();
2677
+ document.removeEventListener("keydown", this.handleEscapeKey);
2678
+ if (!this.bodyScrollingValue) {
2679
+ document.body.classList.remove("overflow-hidden");
2680
+ }
2681
+ }
2682
+ #setupDrawer(drawerElement) {
2683
+ drawerElement.setAttribute("aria-hidden", "true");
2684
+ drawerElement.classList.add("transition-transform");
2685
+ this.#getPlacementClasses(this.placementValue).base.forEach((className) => {
2686
+ drawerElement.classList.add(className);
2687
+ });
2688
+ }
2689
+ toggleDrawer() {
2690
+ this.visible ? this.hideDrawer() : this.showDrawer();
2691
+ }
2692
+ showDrawer() {
2693
+ if (this.edgeValue) {
2694
+ this.#toggleEdgePlacementClasses(`${this.placementValue}-edge`, true);
2695
+ } else {
2696
+ this.#togglePlacementClasses(this.placementValue, true);
2697
+ }
2698
+ this.openTarget.classList.add("hidden");
2699
+ this.openTarget.setAttribute("aria-hidden", "true");
2700
+ this.closeTarget.classList.remove("hidden");
2701
+ this.closeTarget.setAttribute("aria-hidden", "false");
2702
+ this.sidebarOutlet.element.setAttribute("aria-modal", "true");
2703
+ this.sidebarOutlet.element.setAttribute("role", "dialog");
2704
+ this.sidebarOutlet.element.removeAttribute("aria-hidden");
2705
+ if (!this.bodyScrollingValue) {
2706
+ document.body.classList.add("overflow-hidden");
2707
+ }
2708
+ if (this.backdropValue) {
2709
+ this.#createBackdrop();
2710
+ }
2711
+ this.visible = true;
2712
+ this.dispatch("show");
2713
+ }
2714
+ hideDrawer() {
2715
+ if (this.edgeValue) {
2716
+ this.#toggleEdgePlacementClasses(`${this.placementValue}-edge`, false);
2717
+ } else {
2718
+ this.#togglePlacementClasses(this.placementValue, false);
2719
+ }
2720
+ this.openTarget.classList.remove("hidden");
2721
+ this.openTarget.setAttribute("aria-hidden", "false");
2722
+ this.closeTarget.classList.add("hidden");
2723
+ this.closeTarget.setAttribute("aria-hidden", "true");
2724
+ this.sidebarOutlet.element.setAttribute("aria-hidden", "true");
2725
+ this.sidebarOutlet.element.removeAttribute("aria-modal");
2726
+ this.sidebarOutlet.element.removeAttribute("role");
2727
+ if (!this.bodyScrollingValue) {
2728
+ document.body.classList.remove("overflow-hidden");
2729
+ }
2730
+ if (this.backdropValue) {
2731
+ this.#removeBackdrop();
2732
+ }
2733
+ this.visible = false;
2734
+ this.dispatch("hide");
2735
+ }
2736
+ handleEscapeKey(event) {
2737
+ if (event.key === "Escape" && this.visible) {
2738
+ this.hideDrawer();
2739
+ }
2740
+ }
2741
+ #createBackdrop() {
2742
+ if (!this.visible) {
2743
+ const backdrop = document.createElement("div");
2744
+ backdrop.setAttribute("data-drawer-backdrop", "");
2745
+ backdrop.classList.add(...this.constructor.classes.backdrop.split(" "));
2746
+ backdrop.addEventListener("click", () => this.hideDrawer());
2747
+ document.body.appendChild(backdrop);
2748
+ }
2749
+ }
2750
+ #removeBackdrop() {
2751
+ const backdrop = document.querySelector("[data-drawer-backdrop]");
2752
+ if (backdrop) {
2753
+ backdrop.remove();
2754
+ }
2755
+ }
2756
+ #getPlacementClasses(placement) {
2757
+ const placements2 = {
2758
+ top: {
2759
+ base: ["top-0", "left-0", "right-0"],
2760
+ active: ["transform-none"],
2761
+ inactive: ["-translate-y-full"]
2762
+ },
2763
+ right: {
2764
+ base: ["right-0", "top-0"],
2765
+ active: ["transform-none"],
2766
+ inactive: ["translate-x-full"]
2767
+ },
2768
+ bottom: {
2769
+ base: ["bottom-0", "left-0", "right-0"],
2770
+ active: ["transform-none"],
2771
+ inactive: ["translate-y-full"]
2772
+ },
2773
+ left: {
2774
+ base: ["left-0", "top-0"],
2775
+ active: ["transform-none"],
2776
+ inactive: ["-translate-x-full"]
2777
+ },
2778
+ "bottom-edge": {
2779
+ base: ["left-0", "top-0"],
2780
+ active: ["transform-none"],
2781
+ inactive: ["translate-y-full", this.edgeOffsetValue]
2782
+ }
2783
+ };
2784
+ return placements2[placement] || placements2.left;
2785
+ }
2786
+ #togglePlacementClasses(placement, show) {
2787
+ const classes = this.#getPlacementClasses(placement);
2788
+ if (show) {
2789
+ classes.active.forEach((c) => this.sidebarOutlet.element.classList.add(c));
2790
+ classes.inactive.forEach((c) => this.sidebarOutlet.element.classList.remove(c));
2791
+ } else {
2792
+ classes.active.forEach((c) => this.sidebarOutlet.element.classList.remove(c));
2793
+ classes.inactive.forEach((c) => this.sidebarOutlet.element.classList.add(c));
2794
+ }
2795
+ }
2796
+ #toggleEdgePlacementClasses(placement, show) {
2797
+ this.#togglePlacementClasses(placement, show);
2655
2798
  }
2656
2799
  };
2657
2800
 
@@ -2669,6 +2812,13 @@
2669
2812
  }
2670
2813
  };
2671
2814
 
2815
+ // src/js/controllers/sidebar_controller.js
2816
+ var sidebar_controller_default = class extends Controller {
2817
+ connect() {
2818
+ console.log(`sidebar connected: ${this.element}`);
2819
+ }
2820
+ };
2821
+
2672
2822
  // src/js/controllers/has_many_panel_controller.js
2673
2823
  var has_many_panel_controller_default = class extends Controller {
2674
2824
  connect() {
@@ -7290,9 +7440,10 @@
7290
7440
  application2.register("nav-user-section", nav_user_section_controller_default);
7291
7441
  application2.register("nav-user-link", nav_user_link_controller_default);
7292
7442
  application2.register("nav-user", nav_user_controller_default);
7293
- application2.register("resource-header", resource_header_controller_default);
7443
+ application2.register("header", header_controller_default);
7294
7444
  application2.register("sidebar-menu-item", sidebar_menu_item_controller_default);
7295
7445
  application2.register("sidebar-menu", sidebar_menu_controller_default);
7446
+ application2.register("sidebar", sidebar_controller_default);
7296
7447
  application2.register("has-many-panel", has_many_panel_controller_default);
7297
7448
  application2.register("nested-resource-form-fields", nested_resource_form_fields_controller_default);
7298
7449
  application2.register("toolbar", toolbar_controller_default);