iron-cms 0.5.1 → 0.6.0

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: e0783a99d417e9bc079a93a0ea7da203807aad4ab2ad99446ebf05546d3decd4
4
- data.tar.gz: ac2aea8faf5fd1d76e0e2825ad0e98503f59a654acd6d8c1dd9c745dba0013ed
3
+ metadata.gz: 334e586c6700938ecef25a8cdbdd0d63b5006a47934024502c51c2e201bee55a
4
+ data.tar.gz: 3a0ac632ed337a7b37078bf97370195005e277f6e2167952bcc1aaad81660a98
5
5
  SHA512:
6
- metadata.gz: 515d3da7224e4842eb9c6dc00c2082a631031e478ac15f397a863c93a0fd00578bfc0daa4f9fd3da6e5911bf84104426b5c2c5104a09fcf4b913adb400e66a58
7
- data.tar.gz: af94f070a089571e535f2c2b427535010adca2b592edc3d7a0c40117b39b2bfcf5b4943ad2331d9816097d1f295ab3dd1c7acaf747676883a46760dc7b61aac1
6
+ metadata.gz: ae51fa95e78464419288997ae81ee3ce4dbee5b65ba206d201b3d1239f4052f7d2e64fd5ad01e2b405f406addca69586be97120f934a7eadf61d340b4b5ee85e
7
+ data.tar.gz: d0574e5c87be3340537962b233ab870f1522af7e470c8fe1bda75c92bf417fe1fd278f0d897fa46b8ca608dbbbdc1e77714d0ca4474b19b8a5a7d08bc2b9c253
@@ -676,6 +676,9 @@
676
676
  }
677
677
  }
678
678
  }
679
+ .collapse {
680
+ visibility: collapse;
681
+ }
679
682
  .visible {
680
683
  visibility: visible;
681
684
  }
@@ -1985,6 +1988,9 @@
1985
1988
  .justify-center {
1986
1989
  justify-content: center;
1987
1990
  }
1991
+ .gap-0\.5 {
1992
+ gap: calc(var(--spacing) * 0.5);
1993
+ }
1988
1994
  .gap-1 {
1989
1995
  gap: calc(var(--spacing) * 1);
1990
1996
  }
@@ -2334,6 +2340,9 @@
2334
2340
  .py-3 {
2335
2341
  padding-block: calc(var(--spacing) * 3);
2336
2342
  }
2343
+ .py-3\.5 {
2344
+ padding-block: calc(var(--spacing) * 3.5);
2345
+ }
2337
2346
  .py-4 {
2338
2347
  padding-block: calc(var(--spacing) * 4);
2339
2348
  }
@@ -2786,6 +2795,11 @@
2786
2795
  display: none;
2787
2796
  }
2788
2797
  }
2798
+ .group-open\:hidden {
2799
+ &:is(:where(.group):is([open], :popover-open, :open) *) {
2800
+ display: none;
2801
+ }
2802
+ }
2789
2803
  .group-open\:rotate-180 {
2790
2804
  &:is(:where(.group):is([open], :popover-open, :open) *) {
2791
2805
  rotate: 180deg;
@@ -0,0 +1,62 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ /**
4
+ * Persists element state to localStorage automatically.
5
+ *
6
+ * Listens for changes and saves the element's property value to localStorage.
7
+ * Use with `Iron.preference.apply(id, property)` to restore state on page load.
8
+ *
9
+ * @example Basic usage (auto-detects event and property)
10
+ * <details id="my-panel" data-controller="local-preference">
11
+ * ...
12
+ * </details>
13
+ * <script>Iron.preference.apply("my-panel", "open")</script>
14
+ *
15
+ * @example With custom property
16
+ * <input id="my-input" data-controller="local-preference" data-local-preference-property-value="value">
17
+ *
18
+ * @example With key prefix (useful for scoping)
19
+ * <details id="panel" data-controller="local-preference" data-local-preference-key-prefix-value="settings:">
20
+ *
21
+ * @values {string} [property] - Element property to persist. Auto-detected if not set:
22
+ * - "open" for <details>
23
+ * - "checked" for checkbox/radio inputs
24
+ * - "value" for other inputs, selects, textareas
25
+ * @values {string} [keyPrefix=""] - Prefix for the localStorage key
26
+ */
27
+ export default class extends Controller {
28
+ static values = {
29
+ property: String,
30
+ keyPrefix: { type: String, default: "" }
31
+ }
32
+
33
+ connect() {
34
+ this.element.addEventListener(this.event, this.save)
35
+ }
36
+
37
+ disconnect() {
38
+ this.element.removeEventListener(this.event, this.save)
39
+ }
40
+
41
+ save = () => {
42
+ const key = this.keyPrefixValue + this.element.id
43
+ localStorage.setItem(Iron.preference.storageKey(key), this.element[this.property])
44
+ }
45
+
46
+ get event() {
47
+ const el = this.element
48
+ if (el.tagName === "DETAILS") return "toggle"
49
+ if (el.tagName === "TEXTAREA") return "input"
50
+ if (el.tagName === "INPUT" && el.type !== "checkbox" && el.type !== "radio") return "input"
51
+ return "change"
52
+ }
53
+
54
+ get property() {
55
+ if (this.hasPropertyValue) return this.propertyValue
56
+
57
+ const el = this.element
58
+ if (el.tagName === "DETAILS") return "open"
59
+ if (el.type === "checkbox" || el.type === "radio") return "checked"
60
+ return "value"
61
+ }
62
+ }
@@ -56,5 +56,21 @@ module Iron
56
56
 
57
57
  rows
58
58
  end
59
+
60
+ def title
61
+ text_types = %w[Iron::Fields::TextField Iron::Fields::TextArea Iron::Fields::RichTextArea]
62
+
63
+ text_field = fields.find { |f| text_types.include?(f.type) }
64
+ return nil unless text_field
65
+
66
+ content = case text_field
67
+ when Fields::RichTextArea
68
+ text_field.rich_text&.to_plain_text
69
+ else
70
+ text_field.value
71
+ end
72
+
73
+ content&.truncate(300)
74
+ end
59
75
  end
60
76
  end
@@ -60,7 +60,7 @@ module Iron
60
60
  Gem::Package::TarReader.new(tar_io) do |tar|
61
61
  tar.each do |entry|
62
62
  if entry.file? && entry.full_name.end_with?(".csv")
63
- @csv_files[entry.full_name] = entry.read
63
+ @csv_files[entry.full_name] = entry.read.force_encoding("UTF-8")
64
64
  end
65
65
  end
66
66
  end
@@ -3,6 +3,7 @@
3
3
  <% block = field %>
4
4
 
5
5
  <% if block.block_list.present? %>
6
+ <% disclosure_id = dom_id(block, :disclosure) %>
6
7
 
7
8
  <div
8
9
  class="has-[>_.destroy:checked]:hidden flex items-start space-x-1"
@@ -11,22 +12,31 @@
11
12
  <%= builder.check_box :_destroy, class: "destroy hidden", data: { destroy: "" } %>
12
13
  <button
13
14
  type="button"
14
- class="handle button-ghost button-sm"
15
+ class="handle button-ghost button-sm py-3.5"
15
16
  data-sortable-list-target="handle"
16
17
  >
17
18
  <%= icon "grip-vertical" %>
18
19
  </button>
19
- <details class="group grow border border-stone-800 rounded-lg" open>
20
+ <details
21
+ id="<%= disclosure_id %>"
22
+ class="group grow border border-stone-800 rounded-lg"
23
+ data-controller="local-preference"
24
+ <%= "open" if block.new_record? %>
25
+ >
20
26
  <summary
21
- class="
22
- relative flex items-center justify-between px-4 py-3 cursor-pointer
23
- transition-all hover:bg-stone-800/50 rounded-t-lg select-none
24
- "
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"
25
28
  >
26
- <span class="font-medium text-base/6 sm:text-sm/5">
27
- <%= block.definition.name %>
28
- </span>
29
- <div class="flex items-center gap-2">
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>
33
+ <% if block.title.present? %>
34
+ <span class="text-stone-400 text-sm line-clamp-1 group-open:hidden">
35
+ <%= block.title %>
36
+ </span>
37
+ <% end %>
38
+ </div>
39
+ <div class="flex items-center gap-2 shrink-0">
30
40
  <%= builder.label :_destroy, class: "button-secondary button-sm" do %>
31
41
  <%= icon "trash" %>
32
42
  <% end %>
@@ -51,6 +61,9 @@
51
61
  <% end %>
52
62
  </div>
53
63
  </details>
64
+ <% unless block.new_record? %>
65
+ <script>Iron.preference.apply("<%= disclosure_id %>", "open")</script>
66
+ <% end %>
54
67
  </div>
55
68
 
56
69
  <% else %>
@@ -1,6 +1,20 @@
1
1
  <!DOCTYPE html>
2
2
  <html class="h-full bg-stone-50 text-stone-950 antialiased dark:bg-stone-900 dark:text-white">
3
3
  <head>
4
+ <script>
5
+ window.Iron = {
6
+ preference: {
7
+ storageKey: (k) => `iron:preference:${k}`,
8
+ apply: (id, property) => {
9
+ const el = document.getElementById(id)
10
+ if (!el) return
11
+ const raw = localStorage.getItem(Iron.preference.storageKey(id))
12
+ if (raw === null) return
13
+ el[property] = raw === "true" ? true : raw === "false" ? false : raw
14
+ }
15
+ }
16
+ }
17
+ </script>
4
18
  <title><%= content_for(:title).present? ? "#{content_for(:title)} | Iron CMS" : "Iron CMS" %></title>
5
19
  <%= csrf_meta_tags %>
6
20
  <%= csp_meta_tag %>
data/lib/iron/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Iron
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
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.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Massimo De Marchi
@@ -242,6 +242,7 @@ files:
242
242
  - app/javascript/iron/controllers/handle_controller.js
243
243
  - app/javascript/iron/controllers/icon_picker_controller.js
244
244
  - app/javascript/iron/controllers/index.js
245
+ - app/javascript/iron/controllers/local_preference_controller.js
245
246
  - app/javascript/iron/controllers/sortable_list_controller.js
246
247
  - app/javascript/iron/controllers/toggle_controller.js
247
248
  - app/javascript/iron/lib/lexorank.js