plutonium 0.15.12 → 0.15.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) 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/generators/pu/rodauth/concerns/configuration.rb +1 -0
  17. data/lib/plutonium/ui/color_mode_selector.rb +86 -0
  18. data/lib/plutonium/ui/component/kit.rb +2 -0
  19. data/lib/plutonium/ui/component/methods.rb +2 -0
  20. data/lib/plutonium/ui/dyna_frame/host.rb +2 -2
  21. data/lib/plutonium/ui/layout/base.rb +135 -0
  22. data/lib/plutonium/ui/layout/header.rb +121 -0
  23. data/lib/plutonium/ui/layout/resource_layout.rb +26 -0
  24. data/lib/plutonium/ui/layout/rodauth_layout.rb +34 -0
  25. data/lib/plutonium/ui/layout/sidebar.rb +56 -0
  26. data/lib/plutonium/ui/table/resource.rb +1 -1
  27. data/lib/plutonium/version.rb +1 -1
  28. data/lib/plutonium.rb +2 -0
  29. data/lib/rodauth/features/case_insensitive_login.rb +21 -0
  30. data/lib/rodauth/plugins.rb +1 -0
  31. data/package-lock.json +2 -2
  32. data/package.json +1 -1
  33. data/src/js/controllers/header_controller.js +184 -0
  34. data/src/js/controllers/register_controllers.js +4 -2
  35. data/src/js/controllers/{resource_header_controller.js → sidebar_controller.js} +2 -2
  36. metadata +26 -3
@@ -94,7 +94,7 @@ module Plutonium
94
94
  end
95
95
 
96
96
  def render_footer
97
- div(class: "sticky dyna:static bottom-[-2px] mt-1 p-4 pb-6 w-full z-50 bg-gray-50 dark:bg-gray-900") {
97
+ div(class: "lg:sticky lg:dyna:static bottom-[-2px] mt-1 p-4 pb-6 w-full z-30 bg-gray-50 dark:bg-gray-900") {
98
98
  TableInfo(pagy_instance)
99
99
  TablePagination(pagy_instance)
100
100
  }
@@ -1,5 +1,5 @@
1
1
  module Plutonium
2
- VERSION = "0.15.12"
2
+ VERSION = "0.15.14"
3
3
  NEXT_MAJOR_VERSION = VERSION.split(".").tap { |v|
4
4
  v[1] = v[1].to_i + 1
5
5
  v[2] = 0
data/lib/plutonium.rb CHANGED
@@ -10,6 +10,7 @@ require "phlexi-form"
10
10
  require "phlexi-table"
11
11
 
12
12
  require_relative "plutonium/configuration"
13
+ require_relative "rodauth/plugins" if defined?(Rodauth)
13
14
 
14
15
  # Plutonium module
15
16
  #
@@ -25,6 +26,7 @@ module Plutonium
25
26
  Loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false).tap do |loader|
26
27
  loader.ignore("#{__dir__}/generators")
27
28
  loader.ignore("#{__dir__}/plutonium/railtie.rb")
29
+ loader.ignore("#{__dir__}/rodauth")
28
30
  loader.inflector.inflect("ui" => "UI")
29
31
  loader.inflector.inflect("workflow_dsl" => "WorkflowDSL")
30
32
  loader.enable_reloading if defined?(Rails.env) && Rails.env.development?
@@ -0,0 +1,21 @@
1
+ require "rodauth"
2
+
3
+ # A plugin to enable case insensitive logins on Rodauth.
4
+ # It does that by downcasing any login inputs.
5
+ # Should not be enabled on existing installations unless logins are downcased in the database.
6
+ # See https://github.com/jeremyevans/rodauth/discussions/451
7
+ module Rodauth
8
+ Feature.define(:case_insensitive_login, :CaseInsensitiveLogin) do
9
+ def param(key)
10
+ if [login_param, login_confirm_param].include?(key)
11
+ super.downcase
12
+ else
13
+ super
14
+ end
15
+ end
16
+
17
+ def account_from_login(login)
18
+ super(login.downcase)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1 @@
1
+ require_relative "features/case_insensitive_login"
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@radioactive-labs/plutonium",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@radioactive-labs/plutonium",
9
- "version": "0.1.6",
9
+ "version": "0.1.8",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@hotwired/stimulus": "^3.2.2",
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radioactive-labs/plutonium",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Core assets for the Plutonium gem",
5
5
  "type": "module",
6
6
  "main": "src/js/core.js",
@@ -0,0 +1,184 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ static targets = ["open", "close"]
5
+ static outlets = ["sidebar"]
6
+ static values = {
7
+ placement: { type: String, default: "left" },
8
+ bodyScrolling: { type: Boolean, default: false },
9
+ backdrop: { type: Boolean, default: true },
10
+ edge: { type: Boolean, default: false },
11
+ edgeOffset: { type: String, default: "bottom-[60px]" }
12
+ }
13
+ static classes = {
14
+ backdrop: "bg-gray-900/50 dark:bg-gray-900/80 fixed inset-0 z-30"
15
+ }
16
+
17
+ initialize() {
18
+ this.visible = false
19
+ this.handleEscapeKey = this.handleEscapeKey.bind(this)
20
+ }
21
+
22
+ connect() {
23
+ document.addEventListener("keydown", this.handleEscapeKey)
24
+ }
25
+
26
+ sidebarOutletConnected() {
27
+ this.#setupDrawer(this.sidebarOutlet.element)
28
+ }
29
+
30
+ disconnect() {
31
+ this.#removeBackdrop()
32
+ document.removeEventListener("keydown", this.handleEscapeKey)
33
+ if (!this.bodyScrollingValue) {
34
+ document.body.classList.remove("overflow-hidden")
35
+ }
36
+ }
37
+
38
+ #setupDrawer(drawerElement) {
39
+ drawerElement.setAttribute("aria-hidden", "true")
40
+ drawerElement.classList.add("transition-transform")
41
+
42
+ // Add base placement classes
43
+ this.#getPlacementClasses(this.placementValue).base.forEach(className => {
44
+ drawerElement.classList.add(className)
45
+ })
46
+ }
47
+
48
+ toggleDrawer() {
49
+ this.visible ? this.hideDrawer() : this.showDrawer()
50
+ }
51
+
52
+ showDrawer() {
53
+ if (this.edgeValue) {
54
+ this.#toggleEdgePlacementClasses(`${this.placementValue}-edge`, true)
55
+ } else {
56
+ this.#togglePlacementClasses(this.placementValue, true)
57
+ }
58
+
59
+ // Toggle visibility and ARIA attributes of icons
60
+ this.openTarget.classList.add("hidden")
61
+ this.openTarget.setAttribute("aria-hidden", "true")
62
+
63
+ this.closeTarget.classList.remove("hidden")
64
+ this.closeTarget.setAttribute("aria-hidden", "false")
65
+
66
+ // Rest of the method stays same...
67
+ this.sidebarOutlet.element.setAttribute("aria-modal", "true")
68
+ this.sidebarOutlet.element.setAttribute("role", "dialog")
69
+ this.sidebarOutlet.element.removeAttribute("aria-hidden")
70
+
71
+ if (!this.bodyScrollingValue) {
72
+ document.body.classList.add("overflow-hidden")
73
+ }
74
+
75
+ if (this.backdropValue) {
76
+ this.#createBackdrop()
77
+ }
78
+
79
+ this.visible = true
80
+ this.dispatch("show")
81
+ }
82
+
83
+ hideDrawer() {
84
+ if (this.edgeValue) {
85
+ this.#toggleEdgePlacementClasses(`${this.placementValue}-edge`, false)
86
+ } else {
87
+ this.#togglePlacementClasses(this.placementValue, false)
88
+ }
89
+
90
+ // Toggle visibility and ARIA attributes of icons
91
+ this.openTarget.classList.remove("hidden")
92
+ this.openTarget.setAttribute("aria-hidden", "false")
93
+
94
+ this.closeTarget.classList.add("hidden")
95
+ this.closeTarget.setAttribute("aria-hidden", "true")
96
+
97
+ // Rest of the method stays same...
98
+ this.sidebarOutlet.element.setAttribute("aria-hidden", "true")
99
+ this.sidebarOutlet.element.removeAttribute("aria-modal")
100
+ this.sidebarOutlet.element.removeAttribute("role")
101
+
102
+ if (!this.bodyScrollingValue) {
103
+ document.body.classList.remove("overflow-hidden")
104
+ }
105
+
106
+ if (this.backdropValue) {
107
+ this.#removeBackdrop()
108
+ }
109
+
110
+ this.visible = false
111
+ this.dispatch("hide")
112
+ }
113
+
114
+ handleEscapeKey(event) {
115
+ if (event.key === "Escape" && this.visible) {
116
+ this.hideDrawer()
117
+ }
118
+ }
119
+
120
+ #createBackdrop() {
121
+ if (!this.visible) {
122
+ const backdrop = document.createElement("div")
123
+ backdrop.setAttribute("data-drawer-backdrop", "")
124
+ backdrop.classList.add(...this.constructor.classes.backdrop.split(" "))
125
+ backdrop.addEventListener("click", () => this.hideDrawer())
126
+ document.body.appendChild(backdrop)
127
+ }
128
+ }
129
+
130
+ #removeBackdrop() {
131
+ const backdrop = document.querySelector("[data-drawer-backdrop]")
132
+ if (backdrop) {
133
+ backdrop.remove()
134
+ }
135
+ }
136
+
137
+ #getPlacementClasses(placement) {
138
+ const placements = {
139
+ top: {
140
+ base: ["top-0", "left-0", "right-0"],
141
+ active: ["transform-none"],
142
+ inactive: ["-translate-y-full"]
143
+ },
144
+ right: {
145
+ base: ["right-0", "top-0"],
146
+ active: ["transform-none"],
147
+ inactive: ["translate-x-full"]
148
+ },
149
+ bottom: {
150
+ base: ["bottom-0", "left-0", "right-0"],
151
+ active: ["transform-none"],
152
+ inactive: ["translate-y-full"]
153
+ },
154
+ left: {
155
+ base: ["left-0", "top-0"],
156
+ active: ["transform-none"],
157
+ inactive: ["-translate-x-full"]
158
+ },
159
+ "bottom-edge": {
160
+ base: ["left-0", "top-0"],
161
+ active: ["transform-none"],
162
+ inactive: ["translate-y-full", this.edgeOffsetValue]
163
+ }
164
+ }
165
+
166
+ return placements[placement] || placements.left
167
+ }
168
+
169
+ #togglePlacementClasses(placement, show) {
170
+ const classes = this.#getPlacementClasses(placement)
171
+
172
+ if (show) {
173
+ classes.active.forEach(c => this.sidebarOutlet.element.classList.add(c))
174
+ classes.inactive.forEach(c => this.sidebarOutlet.element.classList.remove(c))
175
+ } else {
176
+ classes.active.forEach(c => this.sidebarOutlet.element.classList.remove(c))
177
+ classes.inactive.forEach(c => this.sidebarOutlet.element.classList.add(c))
178
+ }
179
+ }
180
+
181
+ #toggleEdgePlacementClasses(placement, show) {
182
+ this.#togglePlacementClasses(placement, show)
183
+ }
184
+ }
@@ -5,9 +5,10 @@ import NavGridMenuController from "./nav_grid_menu_controller.js"
5
5
  import NavUserSectionController from "./nav_user_section_controller.js"
6
6
  import NavUserLinkController from "./nav_user_link_controller.js"
7
7
  import NavUserController from "./nav_user_controller.js"
8
- import ResourceHeaderController from "./resource_header_controller.js"
8
+ import HeaderController from "./header_controller.js"
9
9
  import SidebarMenuItemController from "./sidebar_menu_item_controller.js"
10
10
  import SidebarMenuController from "./sidebar_menu_controller.js"
11
+ import SidebarController from "./sidebar_controller.js"
11
12
  import HasManyPanelController from "./has_many_panel_controller.js"
12
13
  import NestedResourceFormFieldsController from "./nested_resource_form_fields_controller.js"
13
14
  import ToolbarController from "./toolbar_controller.js"
@@ -29,9 +30,10 @@ export default function (application) {
29
30
  application.register("nav-user-section", NavUserSectionController)
30
31
  application.register("nav-user-link", NavUserLinkController)
31
32
  application.register("nav-user", NavUserController)
32
- application.register("resource-header", ResourceHeaderController)
33
+ application.register("header", HeaderController)
33
34
  application.register("sidebar-menu-item", SidebarMenuItemController)
34
35
  application.register("sidebar-menu", SidebarMenuController)
36
+ application.register("sidebar", SidebarController)
35
37
  application.register("has-many-panel", HasManyPanelController)
36
38
  application.register("nested-resource-form-fields", NestedResourceFormFieldsController)
37
39
  application.register("toolbar", ToolbarController)
@@ -1,8 +1,8 @@
1
1
  import { Controller } from "@hotwired/stimulus"
2
2
 
3
- // Connects to data-controller="resource-header"
3
+ // Connects to data-controller="sidebar"
4
4
  export default class extends Controller {
5
5
  connect() {
6
- console.log(`resource-header connected: ${this.element}`)
6
+ console.log(`sidebar connected: ${this.element}`)
7
7
  }
8
8
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plutonium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.12
4
+ version: 0.15.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-10 00:00:00.000000000 Z
11
+ date: 2024-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -268,6 +268,20 @@ dependencies:
268
268
  - - ">="
269
269
  - !ruby/object:Gem::Version
270
270
  version: '0'
271
+ - !ruby/object:Gem::Dependency
272
+ name: phlex-slotable
273
+ requirement: !ruby/object:Gem::Requirement
274
+ requirements:
275
+ - - ">="
276
+ - !ruby/object:Gem::Version
277
+ version: '0'
278
+ type: :runtime
279
+ prerelease: false
280
+ version_requirements: !ruby/object:Gem::Requirement
281
+ requirements:
282
+ - - ">="
283
+ - !ruby/object:Gem::Version
284
+ version: '0'
271
285
  - !ruby/object:Gem::Dependency
272
286
  name: rake
273
287
  requirement: !ruby/object:Gem::Requirement
@@ -1364,6 +1378,7 @@ files:
1364
1378
  - lib/plutonium/ui/action_button.rb
1365
1379
  - lib/plutonium/ui/block.rb
1366
1380
  - lib/plutonium/ui/breadcrumbs.rb
1381
+ - lib/plutonium/ui/color_mode_selector.rb
1367
1382
  - lib/plutonium/ui/component/base.rb
1368
1383
  - lib/plutonium/ui/component/behaviour.rb
1369
1384
  - lib/plutonium/ui/component/kit.rb
@@ -1382,6 +1397,11 @@ files:
1382
1397
  - lib/plutonium/ui/form/resource.rb
1383
1398
  - lib/plutonium/ui/form/theme.rb
1384
1399
  - lib/plutonium/ui/frame_navigator_panel.rb
1400
+ - lib/plutonium/ui/layout/base.rb
1401
+ - lib/plutonium/ui/layout/header.rb
1402
+ - lib/plutonium/ui/layout/resource_layout.rb
1403
+ - lib/plutonium/ui/layout/rodauth_layout.rb
1404
+ - lib/plutonium/ui/layout/sidebar.rb
1385
1405
  - lib/plutonium/ui/page/base.rb
1386
1406
  - lib/plutonium/ui/page/edit.rb
1387
1407
  - lib/plutonium/ui/page/index.rb
@@ -1401,6 +1421,8 @@ files:
1401
1421
  - lib/plutonium/ui/table/resource.rb
1402
1422
  - lib/plutonium/ui/table/theme.rb
1403
1423
  - lib/plutonium/version.rb
1424
+ - lib/rodauth/features/case_insensitive_login.rb
1425
+ - lib/rodauth/plugins.rb
1404
1426
  - lib/tasks/create_rodauth_admin.rake
1405
1427
  - package-lock.json
1406
1428
  - package.json
@@ -1418,6 +1440,7 @@ files:
1418
1440
  - src/js/controllers/form_controller.js
1419
1441
  - src/js/controllers/frame_navigator_controller.js
1420
1442
  - src/js/controllers/has_many_panel_controller.js
1443
+ - src/js/controllers/header_controller.js
1421
1444
  - src/js/controllers/interactive_action_form_controller.js
1422
1445
  - src/js/controllers/nav_grid_menu_controller.js
1423
1446
  - src/js/controllers/nav_grid_menu_item_controller.js
@@ -1429,8 +1452,8 @@ files:
1429
1452
  - src/js/controllers/resource_collapse_controller.js
1430
1453
  - src/js/controllers/resource_dismiss_controller.js
1431
1454
  - src/js/controllers/resource_drop_down_controller.js
1432
- - src/js/controllers/resource_header_controller.js
1433
1455
  - src/js/controllers/resource_layout_controller.js
1456
+ - src/js/controllers/sidebar_controller.js
1434
1457
  - src/js/controllers/sidebar_menu_controller.js
1435
1458
  - src/js/controllers/sidebar_menu_item_controller.js
1436
1459
  - src/js/controllers/table_controller.js