iron-cms 0.8.2 → 0.8.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 053e1ac01b6555dad4cb4836c77679aa622e99502ee68bce97ddfa643ee9e074
4
- data.tar.gz: ccc7b5cff9fa76d856f5ddee5acb1bf2397dfd571715f931b4e72dcbebec18bf
3
+ metadata.gz: fa3607a886ecb036c62120d185fcd9bc82e9245948563ff1e3f74bc203a45e7c
4
+ data.tar.gz: 2799cafbf1445da0ab86935e577eea0cdbd5a6267790e161bc3ca781ff8a450b
5
5
  SHA512:
6
- metadata.gz: ffea75ba7b33b21f0cee47b5d64461bc4691a843f626a697c5a325f521c58d8202709e8992be3d3e6f5e0a7413429b88b38d9f97ccc85e50fccb712d98a87878
7
- data.tar.gz: 4e421bac5564e54a2a3a34860c81b5ab3e83b818cc899d10b7ab31fe1c2f611f637767524ca6e9a9afb001aabf01ca5b7c1a8af0937708795f8b61222b5e6b78
6
+ metadata.gz: 27bf0265abde161f09485aabcff0698eb7744502a2f38a01ca3f10b2933e34279e931ed8aa53ea3b9541543470762277805be95fde369a98f28d2e441dd7c26f
7
+ data.tar.gz: c4cdbc9b18a344848e14efbf3bea1ffd61c23d43c5b3b7993caeff7eaa47e163a646efc6369b356302a6180a4719146bfffdb226b394d3f6c6176c6006f1374d
@@ -2084,6 +2084,9 @@
2084
2084
  .cursor-default {
2085
2085
  cursor: default;
2086
2086
  }
2087
+ .cursor-grab {
2088
+ cursor: grab;
2089
+ }
2087
2090
  .cursor-pointer {
2088
2091
  cursor: pointer;
2089
2092
  }
@@ -2460,6 +2463,9 @@
2460
2463
  .p-1 {
2461
2464
  padding: calc(var(--spacing) * 1);
2462
2465
  }
2466
+ .p-1\.5 {
2467
+ padding: calc(var(--spacing) * 1.5);
2468
+ }
2463
2469
  .p-2 {
2464
2470
  padding: calc(var(--spacing) * 2);
2465
2471
  }
@@ -2502,9 +2508,6 @@
2502
2508
  .py-3 {
2503
2509
  padding-block: calc(var(--spacing) * 3);
2504
2510
  }
2505
- .py-3\.5 {
2506
- padding-block: calc(var(--spacing) * 3.5);
2507
- }
2508
2511
  .py-4 {
2509
2512
  padding-block: calc(var(--spacing) * 4);
2510
2513
  }
@@ -2995,6 +2998,16 @@
2995
2998
  background-color: transparent;
2996
2999
  }
2997
3000
  }
3001
+ .hover\:bg-red-500\/10 {
3002
+ &:hover {
3003
+ @media (hover: hover) {
3004
+ background-color: color-mix(in srgb, oklch(63.7% 0.237 25.331) 10%, transparent);
3005
+ @supports (color: color-mix(in lab, red, red)) {
3006
+ background-color: color-mix(in oklab, var(--color-red-500) 10%, transparent);
3007
+ }
3008
+ }
3009
+ }
3010
+ }
2998
3011
  .hover\:bg-stone-50 {
2999
3012
  &:hover {
3000
3013
  @media (hover: hover) {
@@ -3036,6 +3049,13 @@
3036
3049
  }
3037
3050
  }
3038
3051
  }
3052
+ .hover\:text-red-400 {
3053
+ &:hover {
3054
+ @media (hover: hover) {
3055
+ color: var(--color-red-400);
3056
+ }
3057
+ }
3058
+ }
3039
3059
  .hover\:text-red-700 {
3040
3060
  &:hover {
3041
3061
  @media (hover: hover) {
@@ -3043,6 +3063,13 @@
3043
3063
  }
3044
3064
  }
3045
3065
  }
3066
+ .hover\:text-stone-300 {
3067
+ &:hover {
3068
+ @media (hover: hover) {
3069
+ color: var(--color-stone-300);
3070
+ }
3071
+ }
3072
+ }
3046
3073
  .hover\:text-stone-500 {
3047
3074
  &:hover {
3048
3075
  @media (hover: hover) {
@@ -5191,6 +5218,14 @@
5191
5218
  [data-sortable-list-target~="item"].dragging {
5192
5219
  opacity: 0%;
5193
5220
  }
5221
+ [data-sortable-list-target~="handle"] {
5222
+ position: relative;
5223
+ &::before {
5224
+ content: "";
5225
+ position: absolute;
5226
+ inset: calc(var(--spacing) * -2);
5227
+ }
5228
+ }
5194
5229
  }
5195
5230
  }
5196
5231
  @layer base {
@@ -65,6 +65,15 @@
65
65
  [data-sortable-list-target~="item"].dragging {
66
66
  @apply opacity-0;
67
67
  }
68
+
69
+ [data-sortable-list-target~="handle"] {
70
+ @apply relative;
71
+
72
+ &::before {
73
+ content: "";
74
+ @apply absolute -inset-2;
75
+ }
76
+ }
68
77
  }
69
78
  }
70
79
 
@@ -41,6 +41,8 @@ module Iron
41
41
  end
42
42
 
43
43
  def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
44
+ return super if options.delete(:unstyled)
45
+
44
46
  @template.content_tag(:div, class: "group/checkbox checkbox") do
45
47
  super(method, options, checked_value, unchecked_value) +
46
48
  @template.icon("check")
@@ -2,16 +2,14 @@ import { Controller } from "@hotwired/stimulus";
2
2
  import { Lexorank } from "lib/lexorank";
3
3
 
4
4
  export default class extends Controller {
5
- static targets = ["item", "handle", "rank"];
5
+ static targets = ["item", "handle", "rank", "dragImage"];
6
6
 
7
7
  handleTargetConnected(handle) {
8
8
  handle.addEventListener("pointerdown", this.#onHandleTapStart);
9
- handle.addEventListener("pointerup", this.#onHandleTapEnd)
10
9
  }
11
10
 
12
11
  handleTargetDisconnected(handle) {
13
12
  handle.removeEventListener("pointerdown", this.#onHandleTapStart);
14
- handle.removeEventListener("pointerup", this.#onHandleTapEnd)
15
13
  }
16
14
 
17
15
  rankTargetConnected(rank) {
@@ -25,6 +23,29 @@ export default class extends Controller {
25
23
  this.draggedEl = event.currentTarget;
26
24
  event.dataTransfer.effectAllowed = "move";
27
25
  event.dataTransfer.setData("text/plain", "");
26
+
27
+ // Use custom drag image if specified within the item
28
+ const dragImage = this.dragImageTargets.find(t => this.draggedEl.contains(t));
29
+ if (dragImage) {
30
+ // For collapsed details elements, clone and force closed to get correct preview
31
+ if (dragImage.tagName === "DETAILS" && !dragImage.open) {
32
+ const clone = dragImage.cloneNode(true);
33
+ clone.removeAttribute("open");
34
+ clone.style.position = "absolute";
35
+ clone.style.top = "-9999px";
36
+ clone.style.width = `${dragImage.offsetWidth}px`;
37
+ document.body.appendChild(clone);
38
+
39
+ const rect = dragImage.getBoundingClientRect();
40
+ event.dataTransfer.setDragImage(clone, event.clientX - rect.left, event.clientY - rect.top);
41
+
42
+ requestAnimationFrame(() => clone.remove());
43
+ } else {
44
+ const rect = dragImage.getBoundingClientRect();
45
+ event.dataTransfer.setDragImage(dragImage, event.clientX - rect.left, event.clientY - rect.top);
46
+ }
47
+ }
48
+
28
49
  requestAnimationFrame(() => {
29
50
  this.draggedEl.classList.add("dragging");
30
51
  });
@@ -41,13 +62,22 @@ export default class extends Controller {
41
62
 
42
63
  onDragOver = (event) => {
43
64
  event.preventDefault();
65
+ event.dataTransfer.dropEffect = "move";
66
+
44
67
  const overIndex = this.itemTargets.findIndex(t => t.contains(event.target));
45
68
  const overTarget = this.itemTargets[overIndex];
46
69
  if (!overTarget || overTarget === this.draggedEl) return;
47
70
 
48
- const firstRects = new Map(this.itemTargets.map(el => [el, el.getBoundingClientRect()]));
49
-
71
+ const draggedIndex = this.itemTargets.indexOf(this.draggedEl);
50
72
  const shouldInsertBefore = this.draggedEl.getBoundingClientRect().top > overTarget.getBoundingClientRect().top;
73
+
74
+ // Skip if position unchanged
75
+ if ((shouldInsertBefore && draggedIndex === overIndex - 1) ||
76
+ (!shouldInsertBefore && draggedIndex === overIndex + 1)) {
77
+ return;
78
+ }
79
+
80
+ const firstRects = new Map(this.itemTargets.map(el => [el, el.getBoundingClientRect()]));
51
81
  this.element.insertBefore(this.draggedEl, shouldInsertBefore ? overTarget : this.itemTargets[overIndex + 1] ?? null);
52
82
 
53
83
  this.itemTargets.forEach(el => {
@@ -77,10 +107,6 @@ export default class extends Controller {
77
107
  this.#enableDraggableBehaviour();
78
108
  }
79
109
 
80
- #onHandleTapEnd = () => {
81
- this.#disableDraggableBehaviour();
82
- }
83
-
84
110
  #enableDraggableBehaviour = () => {
85
111
  this.element.addEventListener("dragover", this.onDragOver);
86
112
  this.itemTargets.forEach(this.#enableItemDraggableBehaviour);
@@ -6,41 +6,38 @@
6
6
  <% disclosure_id = dom_id(block, :disclosure) %>
7
7
 
8
8
  <div
9
- class="has-[>_.destroy:checked]:hidden flex items-start space-x-1"
9
+ class="has-[>_.destroy:checked]:hidden"
10
10
  data-sortable-list-target="item"
11
11
  >
12
- <%= builder.check_box :_destroy, class: "destroy hidden", data: { destroy: "" } %>
13
- <button
14
- type="button"
15
- class="handle button-ghost button-sm py-3.5"
16
- data-sortable-list-target="handle"
17
- >
18
- <%= icon "grip-vertical" %>
19
- </button>
12
+ <%= builder.check_box :_destroy, class: "destroy hidden", unstyled: true, data: { destroy: "" } %>
20
13
  <details
21
14
  id="<%= disclosure_id %>"
22
- class="group grow border border-stone-800 rounded-lg"
15
+ class="group border border-stone-800 rounded-lg bg-stone-900"
23
16
  data-controller="local-preference"
17
+ data-sortable-list-target="dragImage"
24
18
  <%= "open" if block.new_record? %>
25
19
  >
26
- <summary
27
- class="relative flex items-center justify-between gap-2 px-4 py-3 cursor-pointer transition-all hover:bg-stone-800/50 rounded-t-lg select-none"
28
- >
29
- <div class="flex flex-col gap-0.5 w-full min-w-0">
30
- <span class="font-medium text-sm min-w-0">
31
- <%= block.definition.name %>
32
- </span>
20
+ <summary class="flex items-center gap-2 px-3 py-3 cursor-pointer select-none rounded-t-lg transition-colors hover:bg-stone-800/50">
21
+ <button
22
+ type="button"
23
+ class="handle text-stone-500 hover:text-stone-300 transition-colors cursor-grab"
24
+ data-sortable-list-target="handle"
25
+ >
26
+ <%= icon "grip-vertical", class: "size-4" %>
27
+ </button>
28
+
29
+ <div class="flex flex-col gap-0.5 flex-1 min-w-0">
30
+ <span class="font-medium text-sm"><%= block.definition.name %></span>
33
31
  <% if block.title.present? %>
34
- <span class="text-stone-400 text-sm line-clamp-1 group-open:hidden">
35
- <%= block.title %>
36
- </span>
32
+ <span class="text-stone-400 text-sm line-clamp-1 group-open:hidden"><%= block.title %></span>
37
33
  <% end %>
38
34
  </div>
39
- <div class="flex items-center gap-2 shrink-0">
40
- <%= builder.label :_destroy, class: "button-secondary button-sm" do %>
41
- <%= icon "trash" %>
35
+
36
+ <div class="flex items-center gap-3">
37
+ <%= builder.label :_destroy, class: "p-1.5 rounded text-stone-500 hover:text-red-400 hover:bg-red-500/10 transition-colors" do %>
38
+ <%= icon "trash", class: "size-4" %>
42
39
  <% end %>
43
- <%= icon "chevron-down", class: "transition-transform group-open:rotate-180" %>
40
+ <%= icon "chevron-down", class: "size-4 text-stone-500 transition-transform group-open:rotate-180" %>
44
41
  </div>
45
42
  </summary>
46
43
 
data/lib/iron/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Iron
2
- VERSION = "0.8.2"
2
+ VERSION = "0.8.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iron-cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Massimo De Marchi