katalyst-content 3.0.0.alpha.1 → 3.0.0.alpha.2

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/README.md +8 -3
  3. data/app/assets/stylesheets/katalyst/content/_editor.scss +4 -0
  4. data/app/assets/stylesheets/katalyst/content/_frontend.scss +1 -0
  5. data/app/assets/stylesheets/katalyst/content/editor/editor.css +200 -0
  6. data/app/assets/stylesheets/katalyst/content/editor.css +4 -196
  7. data/app/assets/stylesheets/katalyst/content/frontend/frontend.css +46 -0
  8. data/app/assets/stylesheets/katalyst/content/frontend.css +1 -0
  9. data/app/components/katalyst/content/editor/item_component.html.erb +6 -4
  10. data/app/helpers/katalyst/content/frontend_helper.rb +40 -24
  11. data/app/models/concerns/katalyst/content/has_tree.rb +16 -3
  12. data/app/models/katalyst/content/item.rb +15 -7
  13. data/app/views/katalyst/content/asides/_aside.html+form.erb +2 -2
  14. data/app/views/katalyst/content/asides/_aside.html.erb +5 -7
  15. data/app/views/katalyst/content/columns/_column.html+form.erb +2 -2
  16. data/app/views/katalyst/content/columns/_column.html.erb +3 -3
  17. data/app/views/katalyst/content/contents/_content.html+form.erb +2 -2
  18. data/app/views/katalyst/content/contents/_content.html.erb +2 -2
  19. data/app/views/katalyst/content/figures/_figure.html+form.erb +2 -2
  20. data/app/views/katalyst/content/figures/_figure.html.erb +1 -1
  21. data/app/views/katalyst/content/groups/_group.html+form.erb +2 -2
  22. data/app/views/katalyst/content/groups/_group.html.erb +1 -3
  23. data/app/views/katalyst/content/items/_item.html+form.erb +2 -2
  24. data/app/views/katalyst/content/sections/_section.html+form.erb +2 -2
  25. data/app/views/katalyst/content/sections/_section.html.erb +3 -5
  26. data/app/views/katalyst/content/tables/_table.html+form.erb +2 -2
  27. data/db/migrate/20250321045027_rename_background_to_theme.rb +7 -0
  28. data/lib/katalyst/content/config.rb +4 -1
  29. data/spec/factories/katalyst/content/items.rb +1 -1
  30. metadata +11 -7
  31. data/app/assets/stylesheets/katalyst/_content.scss +0 -4
  32. data/app/assets/stylesheets/katalyst/content.css +0 -4
  33. /data/app/assets/stylesheets/katalyst/content/{icons.css → editor/icons.css} +0 -0
  34. /data/app/assets/stylesheets/katalyst/content/{status-bar.css → editor/status-bar.css} +0 -0
  35. /data/app/assets/stylesheets/katalyst/content/{table.css → editor/table.css} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bab70f2b26e14144e5828cc4410cda794d1cfba6883066b3552b5b3830f35005
4
- data.tar.gz: 45e4723a3dcec7ca357fc79442edafebc8c15af038cd42e5c43a32d1bd78ab6c
3
+ metadata.gz: 67bf34ad36a47a0d138ca8c63b1fed487fbd974a0cd498a4cec98da235a28e72
4
+ data.tar.gz: 249030bf322465c73e0786f88899cfcb03847049fe756b9747d2209645ccfbcc
5
5
  SHA512:
6
- metadata.gz: 7d772c1165b1fccf409ff89bf26bd656ff17d3f96e9e949b2524c114dbe89a12820a40ba249a298f5fee849b235aae3d7b63340647b975314809b72a3b5d22ca
7
- data.tar.gz: 67af0d40bb65869f7ba2382d9a958184e83191be5a1b437c2f92985f9b608a8fdc577674f38d95486a70654c5104634a49c08e55b03a952c308997ae449e5397
6
+ metadata.gz: e65e5172a28aa4f2bf988828a2d47a00778d6114ed6cb1da4ea5c8f0b5961e937cb6f5c1bb9f1001be614ab6e8bea0f1207b0448e95e63af0e898757b43b0374
7
+ data.tar.gz: 2721e291497463fe0ee78d6446cde29abd85468961cda125e8713d5e754747fa6f33f797723a5d465911281decf1eca500d0ccd818fea5f972ced62f415cd532
data/README.md CHANGED
@@ -33,17 +33,22 @@ import content from "@katalyst/content";
33
33
  application.load(content);
34
34
  ```
35
35
 
36
- Import the styles as css:
36
+ Import the editor styles as css:
37
37
 
38
38
  ```css
39
- @import url("/katalyst/content.css");
39
+ /** In your admin/editor */
40
+ @import url("/katalyst/content/editor.css");
41
+ /** In your frontend */
42
+ @import url("/katalyst/content/frontend.css");
40
43
  ```
41
44
 
42
45
  Or, if you're using `dartsass-rails`:
43
46
 
44
47
  ```scss
48
+ // app/assets/stylesheets/admin.scss
49
+ @use "katalyst/content/editor";
45
50
  // app/assets/stylesheets/application.scss
46
- @use "katalyst/content";
51
+ @use "katalyst/content/frontend";
47
52
  ```
48
53
 
49
54
  ## Usage
@@ -0,0 +1,4 @@
1
+ @use "editor/editor";
2
+ @use "editor/icons";
3
+ @use "editor/status-bar";
4
+ @use "editor/table";
@@ -0,0 +1 @@
1
+ @use "frontend/frontend.css";
@@ -0,0 +1,200 @@
1
+ @import url("icons.css");
2
+ @import url("status-bar.css");
3
+ @import url("table.css");
4
+
5
+ .content--editor {
6
+ --row-inset: 2rem;
7
+ --row-hover-bg: var(--color-tint, #fff0eb);
8
+ --row-padding: 0 var(--space-2xs, 0.25rem);
9
+
10
+ position: relative;
11
+ }
12
+
13
+ /* Rows */
14
+
15
+ .content--editor--item {
16
+ /* https://github.com/react-dnd/react-dnd/issues/832 */
17
+ transform: translate3d(0, 0, 0);
18
+
19
+ &:hover {
20
+ background: var(--row-hover-bg);
21
+ }
22
+
23
+ &[draggable] {
24
+ cursor: grab;
25
+ }
26
+
27
+ /* Dragged visuals */
28
+
29
+ &[data-dragging] {
30
+ box-shadow: inset 0 0 0 2px var(--color-tint, #fff0eb);
31
+
32
+ > * {
33
+ visibility: hidden;
34
+ }
35
+ }
36
+
37
+ /* Hidden items */
38
+
39
+ [data-invisible] {
40
+ color: var(--color-mid, #aaa);
41
+ }
42
+
43
+ /* row item controller */
44
+
45
+ > [data-controller] {
46
+ display: grid;
47
+ grid-template-columns: 1fr auto;
48
+ align-items: baseline;
49
+ padding: var(--row-padding);
50
+ }
51
+
52
+ /* row content */
53
+
54
+ .tree {
55
+ display: flex;
56
+ gap: var(--space-xs, 0.5rem);
57
+ align-items: baseline;
58
+
59
+ text-overflow: ellipsis;
60
+ overflow: hidden;
61
+ white-space: nowrap;
62
+ }
63
+
64
+ .actions-group {
65
+ display: flex;
66
+ gap: var(--space-3xs, 0.25em);
67
+ align-items: baseline;
68
+ }
69
+
70
+ /* Theme identifier */
71
+
72
+ .item-theme {
73
+ display: inline-flex;
74
+ background-color: var(--theme-background-color);
75
+ color: var(--theme-text-color);
76
+ aspect-ratio: 1;
77
+ padding: var(--space-3xs);
78
+ border-radius: var(--radius-s);
79
+ }
80
+
81
+ [data-content-theme="light"] {
82
+ --theme-text-color: black;
83
+ --theme-background-color: white;
84
+ }
85
+
86
+ [data-content-theme="dark"] {
87
+ --theme-text-color: white;
88
+ --theme-background-color: black;
89
+ }
90
+
91
+ /* Depth */
92
+
93
+ &[data-content-depth="1"] .tree {
94
+ padding-left: calc(var(--row-inset) * 1);
95
+ }
96
+
97
+ &[data-content-depth="2"] .tree {
98
+ padding-left: calc(var(--row-inset) * 2);
99
+ }
100
+
101
+ &[data-content-depth="3"] .tree {
102
+ padding-left: calc(var(--row-inset) * 3);
103
+ }
104
+
105
+ &[data-content-depth="4"] .tree {
106
+ padding-left: calc(var(--row-inset) * 4);
107
+ }
108
+
109
+ &[data-content-depth="5"] .tree {
110
+ padding-left: calc(var(--row-inset) * 5);
111
+ }
112
+
113
+ &[data-content-depth="6"] .tree {
114
+ padding-left: calc(var(--row-inset) * 6);
115
+ }
116
+
117
+ /* Lower opacity for buttons you can't use */
118
+
119
+ &[data-deny-de-nest] .button:has([data-icon="outdent"]),
120
+ &[data-deny-nest] .button:has([data-icon="indent"]),
121
+ &[data-deny-remove] .button:has([data-icon="remove"]),
122
+ &[data-deny-drag] .button:has([data-icon="drag"]),
123
+ &[data-deny-edit] .button:has([data-icon="edit"]) {
124
+ opacity: 0.2;
125
+ pointer-events: none;
126
+ }
127
+
128
+ &:not(:hover) .actions-group .button {
129
+ opacity: 0;
130
+ }
131
+
132
+ /* Only show 1 of the collapse / expand button */
133
+
134
+ &[data-deny-collapse] .button:has([data-icon="collapse"]),
135
+ &[data-deny-expand] .button:has([data-icon="expand"]) {
136
+ display: none !important;
137
+ pointer-events: none;
138
+ }
139
+
140
+ /* Always show the expand button when there are hidden children */
141
+
142
+ &:has([data-content-children]) .button:has([data-icon="expand"]) {
143
+ opacity: 1 !important;
144
+ }
145
+ }
146
+
147
+ /* Inline add link */
148
+
149
+ .content--editor--inline-add {
150
+ position: absolute;
151
+ left: 0;
152
+ right: 0;
153
+ top: 0;
154
+ height: 0;
155
+ z-index: 1;
156
+ outline: 1px solid var(--color-dark-glare, #555);
157
+
158
+ button {
159
+ position: absolute;
160
+ top: 0;
161
+ left: 50%;
162
+ margin: 0;
163
+ padding: 0.25rem;
164
+
165
+ animation: content--editor--pulse 200ms ease;
166
+ transform: translate(-50%, -50%) scale(1);
167
+ }
168
+
169
+ button:active {
170
+ transform: translate(-50%, -50%) scale(99%);
171
+ }
172
+
173
+ &[hidden] button {
174
+ transform: translate(-50%, -50%) scale(0);
175
+ }
176
+ }
177
+
178
+ @keyframes content--editor--pulse {
179
+ 0% {
180
+ transform: translate(-50%, -50%) scale(0);
181
+ }
182
+
183
+ 80% {
184
+ transform: translate(-50%, -50%) scale(1.1);
185
+ }
186
+
187
+ 100% {
188
+ transform: translate(-50%, -50%) scale(1);
189
+ }
190
+ }
191
+
192
+ /* New items picker */
193
+
194
+ .content--editor--new-items {
195
+ .items-list {
196
+ display: flex;
197
+ gap: var(--space-2xs, 0.25rem);
198
+ flex-wrap: wrap;
199
+ }
200
+ }
@@ -1,196 +1,4 @@
1
- .content--editor {
2
- --row-inset: 2rem;
3
- --row-hover-bg: var(--color-tint, #fff0eb);
4
- --row-padding: 0 var(--space-2xs, 0.25rem);
5
-
6
- position: relative;
7
- }
8
-
9
- /* Rows */
10
-
11
- .content--editor--item {
12
- /* https://github.com/react-dnd/react-dnd/issues/832 */
13
- transform: translate3d(0, 0, 0);
14
-
15
- &:hover {
16
- background: var(--row-hover-bg);
17
- }
18
-
19
- &[draggable] {
20
- cursor: grab;
21
- }
22
-
23
- /* Dragged visuals */
24
-
25
- &[data-dragging] {
26
- box-shadow: inset 0 0 0 2px var(--color-tint, #fff0eb);
27
-
28
- > * {
29
- visibility: hidden;
30
- }
31
- }
32
-
33
- /* Hidden items */
34
-
35
- [data-invisible] {
36
- color: var(--color-mid, #aaa);
37
- }
38
-
39
- /* row item controller */
40
-
41
- > [data-controller] {
42
- display: grid;
43
- grid-template-columns: 1fr auto;
44
- align-items: baseline;
45
- padding: var(--row-padding);
46
- }
47
-
48
- /* row content */
49
-
50
- .tree {
51
- display: flex;
52
- gap: var(--space-xs, 0.5rem);
53
- align-items: baseline;
54
-
55
- text-overflow: ellipsis;
56
- overflow: hidden;
57
- white-space: nowrap;
58
- }
59
-
60
- .actions-group {
61
- display: flex;
62
- gap: var(--space-3xs, 0.25em);
63
- align-items: baseline;
64
- }
65
-
66
- /* Theme identifier */
67
-
68
- .item-background {
69
- display: inline-flex;
70
- background-color: var(--theme-background-color);
71
- color: var(--theme-text-color);
72
- aspect-ratio: 1;
73
- padding: var(--space-3xs);
74
- border-radius: var(--radius-s);
75
- }
76
-
77
- .item-background.light {
78
- --theme-text-color: black;
79
- --theme-background-color: white;
80
- }
81
-
82
- .item-background.dark {
83
- --theme-text-color: white;
84
- --theme-background-color: black;
85
- }
86
-
87
- /* Depth */
88
-
89
- &[data-content-depth="1"] .tree {
90
- padding-left: calc(var(--row-inset) * 1);
91
- }
92
-
93
- &[data-content-depth="2"] .tree {
94
- padding-left: calc(var(--row-inset) * 2);
95
- }
96
-
97
- &[data-content-depth="3"] .tree {
98
- padding-left: calc(var(--row-inset) * 3);
99
- }
100
-
101
- &[data-content-depth="4"] .tree {
102
- padding-left: calc(var(--row-inset) * 4);
103
- }
104
-
105
- &[data-content-depth="5"] .tree {
106
- padding-left: calc(var(--row-inset) * 5);
107
- }
108
-
109
- &[data-content-depth="6"] .tree {
110
- padding-left: calc(var(--row-inset) * 6);
111
- }
112
-
113
- /* Lower opacity for buttons you can't use */
114
-
115
- &[data-deny-de-nest] .button:has([data-icon="outdent"]),
116
- &[data-deny-nest] .button:has([data-icon="indent"]),
117
- &[data-deny-remove] .button:has([data-icon="remove"]),
118
- &[data-deny-drag] .button:has([data-icon="drag"]),
119
- &[data-deny-edit] .button:has([data-icon="edit"]) {
120
- opacity: 0.2;
121
- pointer-events: none;
122
- }
123
-
124
- &:not(:hover) .actions-group .button {
125
- opacity: 0;
126
- }
127
-
128
- /* Only show 1 of the collapse / expand button */
129
-
130
- &[data-deny-collapse] .button:has([data-icon="collapse"]),
131
- &[data-deny-expand] .button:has([data-icon="expand"]) {
132
- display: none !important;
133
- pointer-events: none;
134
- }
135
-
136
- /* Always show the expand button when there are hidden children */
137
-
138
- &:has([data-content-children]) .button:has([data-icon="expand"]) {
139
- opacity: 1 !important;
140
- }
141
- }
142
-
143
- /* Inline add link */
144
-
145
- .content--editor--inline-add {
146
- position: absolute;
147
- left: 0;
148
- right: 0;
149
- top: 0;
150
- height: 0;
151
- z-index: 1;
152
- outline: 1px solid var(--color-dark-glare, #555);
153
-
154
- button {
155
- position: absolute;
156
- top: 0;
157
- left: 50%;
158
- margin: 0;
159
- padding: 0.25rem;
160
-
161
- animation: content--editor--pulse 200ms ease;
162
- transform: translate(-50%, -50%) scale(1);
163
- }
164
-
165
- button:active {
166
- transform: translate(-50%, -50%) scale(99%);
167
- }
168
-
169
- &[hidden] button {
170
- transform: translate(-50%, -50%) scale(0);
171
- }
172
- }
173
-
174
- @keyframes content--editor--pulse {
175
- 0% {
176
- transform: translate(-50%, -50%) scale(0);
177
- }
178
-
179
- 80% {
180
- transform: translate(-50%, -50%) scale(1.1);
181
- }
182
-
183
- 100% {
184
- transform: translate(-50%, -50%) scale(1);
185
- }
186
- }
187
-
188
- /* New items picker */
189
-
190
- .content--editor--new-items {
191
- .items-list {
192
- display: flex;
193
- gap: var(--space-2xs, 0.25rem);
194
- flex-wrap: wrap;
195
- }
196
- }
1
+ @import url("editor/editor.css");
2
+ @import url("editor/icons.css");
3
+ @import url("editor/status-bar.css");
4
+ @import url("editor/table.css");
@@ -0,0 +1,46 @@
1
+ /* Spacing */
2
+
3
+ .content-item {
4
+ --flow-space: var(--space-m);
5
+ margin-block: var(--block-space, var(--space-m));
6
+ }
7
+
8
+ /* Themes */
9
+
10
+ [data-content-theme] {
11
+ display: flow-root;
12
+ }
13
+
14
+ [data-content-theme] [data-content-theme] {
15
+ margin-inline: calc(-1 * var(--gutter));
16
+ padding-inline: var(--gutter);
17
+ }
18
+
19
+ [data-content-theme="light"] {
20
+ background: var(--background, var(--background-color));
21
+ color: var(--text-color);
22
+
23
+ --text-color: var(--color-dark, black);
24
+ --background: var(--color-light, black);
25
+ --link-color: var(--color-dark, black);
26
+ }
27
+
28
+ [data-content-theme="dark"] {
29
+ background: var(--background, var(--background-color));
30
+ color: var(--text-color);
31
+
32
+ --text-color: var(--color-light, white);
33
+ --background: var(--color-dark, black);
34
+ --link-color: var(--color-light, white);
35
+ }
36
+
37
+ /* Figures */
38
+
39
+ .content-item[data-content-item-type="figure"] {
40
+ margin-inline: unset;
41
+ text-align: center;
42
+
43
+ img {
44
+ margin-inline: auto;
45
+ }
46
+ }
@@ -0,0 +1 @@
1
+ @import url("frontend/frontend.css");
@@ -4,9 +4,11 @@
4
4
 
5
5
  <strong class="heading" title="<%= item.heading %>"><%= item.heading %></strong>
6
6
 
7
- <span class="item-background <%= item.background %>">
8
- <icon class="icon" data-icon="theme" role="img">&nbsp;</icon>
9
- </span>
7
+ <% if item.theme.present? %>
8
+ <span class="item-theme" data-content-theme="<%= item.theme %>">
9
+ <icon class="icon" data-icon="theme" role="img">&nbsp;</icon>
10
+ </span>
11
+ <% end %>
10
12
 
11
13
  <% unless item.visible? %>
12
14
  <icon class="icon" data-icon="hidden" title="Hidden" role="img">&nbsp;</icon>
@@ -27,7 +29,7 @@
27
29
  <icon class="icon" data-icon="indent" role="img">&nbsp;</icon>
28
30
  </button>
29
31
  <%= link_to(edit_item_link, class: "button", title: "Edit", value: "edit",
30
- data: { text_button: "", button_padding: "tight", turbo_frame: "content--editor--item-editor" }) do %>
32
+ data: { text_button: "", button_padding: "tight", turbo_frame: "content--editor--item-editor" }) do %>
31
33
  <icon class="icon" data-icon="edit" role="img">&nbsp;</icon>
32
34
  <% end %>
33
35
  <button class="button" data-button-padding="tight" data-text-button data-action="content--editor--container#remove" title="Remove">
@@ -5,6 +5,8 @@ module Katalyst
5
5
  module FrontendHelper
6
6
  include TableHelper
7
7
 
8
+ using Katalyst::HtmlAttributes::HasHtmlAttributes
9
+
8
10
  # Render all items from a content version as HTML
9
11
  # @param version [Katalyst::Content::Version] The content version to render
10
12
  # @return [ActiveSupport::SafeBuffer,String,nil] Content as HTML
@@ -14,16 +16,24 @@ module Katalyst
14
16
  capture do
15
17
  cache version do
16
18
  without_partial_path_prefix do
17
- concat render partial: version.tree.select(&:visible?)
19
+ concat(render_content_items(*version.tree.select(&:visible?), class: "flow"))
18
20
  end
19
21
  end
20
22
  end
21
23
  end
22
24
 
23
- def render_content_items(items)
24
- items = items.select(&:visible?)
25
- without_partial_path_prefix do
26
- render partial: items if items.any?
25
+ def render_content_items(*items, tag: :div, theme: nil, **)
26
+ items = items.flatten.select(&:visible?)
27
+
28
+ grouped_items = items.slice_when { |first, second| first.theme != second.theme }
29
+
30
+ grouped_items.each do |siblings|
31
+ content_theme = (siblings.first.theme if siblings.first.theme != theme)
32
+ concat(content_items_tag(tag, content_theme:, **) do
33
+ without_partial_path_prefix do
34
+ concat(render(partial: siblings))
35
+ end
36
+ end)
27
37
  end
28
38
  end
29
39
 
@@ -31,7 +41,15 @@ module Katalyst
31
41
  FrontendBuilder.new(self, item).render(...)
32
42
  end
33
43
 
34
- private
44
+ def content_items_tag(tag, content_theme:, **attributes, &)
45
+ html_attributes = {
46
+ class: "content-items",
47
+ data: {
48
+ content_theme:,
49
+ },
50
+ }.merge_html(attributes)
51
+ content_tag(tag, **html_attributes, &)
52
+ end
35
53
 
36
54
  def without_partial_path_prefix
37
55
  current = prefix_partial_path_with_controller_namespace
@@ -44,6 +62,8 @@ module Katalyst
44
62
  end
45
63
 
46
64
  class FrontendBuilder
65
+ include Katalyst::HtmlAttributes
66
+
47
67
  attr_accessor :template, :item
48
68
 
49
69
  delegate_missing_to :@template
@@ -53,32 +73,28 @@ module Katalyst
53
73
  self.item = item
54
74
  end
55
75
 
56
- def render(**, &)
57
- content_tag tag, **default_options(**) do
58
- content_tag(:div, &)
59
- end
76
+ def render(tag: :div, **, &)
77
+ update_html_attributes(**)
78
+
79
+ content_tag(tag, **html_attributes, &)
60
80
  end
61
81
 
62
82
  private
63
83
 
64
- def default_options(**options)
84
+ def default_html_attributes
65
85
  {
66
- id: item.heading&.parameterize,
67
- class: ["content-item", item.model_name.param_key, item.background, options[:class]],
68
- data: { content_index: item.index, content_depth: item.depth, **options.fetch(:data, {}) },
69
- **options.except(:class, :data, :root),
86
+ id: item.dom_id,
87
+ class: ["content-item", wrapper_class],
88
+ data: {
89
+ content_index: item.index,
90
+ content_depth: item.depth,
91
+ content_item_type: item.item_type,
92
+ },
70
93
  }
71
94
  end
72
95
 
73
- def tag
74
- case item
75
- when Figure
76
- :figure
77
- when Section
78
- :section
79
- else
80
- :div
81
- end
96
+ def wrapper_class
97
+ "wrapper" if item.depth.zero?
82
98
  end
83
99
  end
84
100
  end
@@ -20,9 +20,7 @@ module Katalyst
20
20
 
21
21
  def add(node)
22
22
  if node.depth == depth
23
- node.parent = current
24
- children << node
25
- self
23
+ add_sibling(node)
26
24
  elsif node.depth > depth
27
25
  push(children.last)
28
26
  add(node)
@@ -32,6 +30,21 @@ module Katalyst
32
30
  end
33
31
  end
34
32
 
33
+ def add_sibling(node)
34
+ node.parent = current
35
+
36
+ previous = children.last
37
+
38
+ children << node
39
+
40
+ if previous
41
+ previous.next_sibling = node
42
+ node.previous_sibling = previous
43
+ end
44
+
45
+ self
46
+ end
47
+
35
48
  private
36
49
 
37
50
  attr_writer :current, :depth, :children
@@ -16,12 +16,12 @@ module Katalyst
16
16
 
17
17
  validates :heading, presence: true
18
18
  validates :heading_style, inclusion: { in: config.heading_styles }
19
- validates :background, presence: true, inclusion: { in: config.backgrounds }, if: :validate_background?
19
+ validates :theme, inclusion: { in: config.themes, allow_blank: true }
20
20
 
21
21
  after_initialize :initialize_tree
22
22
  before_validation :set_defaults
23
23
 
24
- attr_accessor :parent, :children, :index, :depth
24
+ attr_accessor :parent, :children, :index, :depth, :previous_sibling, :next_sibling
25
25
 
26
26
  def self.permitted_params
27
27
  %i[
@@ -30,7 +30,7 @@ module Katalyst
30
30
  type
31
31
  heading
32
32
  heading_style
33
- background
33
+ theme
34
34
  visible
35
35
  ]
36
36
  end
@@ -51,6 +51,18 @@ module Katalyst
51
51
  is_a? Layout
52
52
  end
53
53
 
54
+ def dom_id
55
+ heading&.parameterize
56
+ end
57
+
58
+ def item_type
59
+ model_name.param_key
60
+ end
61
+
62
+ def theme
63
+ super.presence || parent&.theme
64
+ end
65
+
54
66
  private
55
67
 
56
68
  def initialize_tree
@@ -61,10 +73,6 @@ module Katalyst
61
73
  def set_defaults
62
74
  self.heading_style = "none" if heading_style.blank?
63
75
  end
64
-
65
- def validate_background?
66
- true
67
- end
68
76
  end
69
77
  end
70
78
  end
@@ -13,8 +13,8 @@
13
13
  </div>
14
14
 
15
15
  <div class="field">
16
- <%= form.label :background %>
17
- <%= form.select :background, Katalyst::Content.config.backgrounds %>
16
+ <%= form.label :theme %>
17
+ <%= form.select :theme, Katalyst::Content.config.themes %>
18
18
  </div>
19
19
 
20
20
  <div class="field">
@@ -1,16 +1,14 @@
1
- <%= content_item_tag aside do %>
1
+ <%= content_item_tag(aside, data: { aside_reverse: ("" if aside.reverse) }) do %>
2
2
  <%= tag.h3 aside.heading, class: aside.heading_style_class if aside.show_heading? %>
3
3
 
4
4
  <% if aside.children.any? %>
5
5
  <% items = aside.children.select(&:visible?) %>
6
6
  <% last = items.pop %>
7
- <div role="aside-container" <%= "class=reverse" if aside.reverse %>>
8
- <div>
9
- <%= render_content_items items %>
7
+ <div class="sidebar">
8
+ <div class="aside--main">
9
+ <%= render_content_items(*items, theme: aside.theme, class: "flow") %>
10
10
  </div>
11
- <aside>
12
- <%= render_content_items [last] %>
13
- </aside>
11
+ <%= render_content_items(last, tag: :aside, class: "aside--sidebar", theme: aside.theme) %>
14
12
  </div>
15
13
  <% end %>
16
14
  <% end %>
@@ -13,8 +13,8 @@
13
13
  </div>
14
14
 
15
15
  <div class="field">
16
- <%= form.label :background %>
17
- <%= form.select :background, Katalyst::Content.config.backgrounds %>
16
+ <%= form.label :theme %>
17
+ <%= form.select :theme, Katalyst::Content.config.themes %>
18
18
  </div>
19
19
 
20
20
  <div class="field">
@@ -6,13 +6,13 @@
6
6
  <div class="columns-container">
7
7
  <div class="column">
8
8
  <% if items.any? %>
9
- <%= render_content_items items %>
9
+ <%= render_content_items(*items, theme: column.theme, class: "flow") %>
10
10
  <% elsif last %>
11
- <%= render_content_items [last] %>
11
+ <%= render_content_items(last, theme: column.theme) %>
12
12
  <% end %>
13
13
  </div>
14
14
  <div class="column">
15
- <%= render_content_items [last] if last && items.any? %>
15
+ <%= render_content_items(last, theme: column.theme) if last && items.any? %>
16
16
  </div>
17
17
  </div>
18
18
  <% end %>
@@ -13,8 +13,8 @@
13
13
  </div>
14
14
 
15
15
  <div class="field">
16
- <%= form.label :background %>
17
- <%= form.select :background, Katalyst::Content.config.backgrounds %>
16
+ <%= form.label :theme %>
17
+ <%= form.select :theme, Katalyst::Content.config.themes %>
18
18
  </div>
19
19
 
20
20
  <div class="field">
@@ -1,5 +1,5 @@
1
- <%= content_item_tag content do %>
2
- <%= tag.h3 content.heading, class: content.heading_style_class if content.show_heading? %>
1
+ <%= content_item_tag(content, class: "flow") do %>
2
+ <%= tag.h3(content.heading, class: content.heading_style_class) if content.show_heading? %>
3
3
 
4
4
  <%= content.content %>
5
5
  <% end %>
@@ -18,8 +18,8 @@
18
18
  </div>
19
19
 
20
20
  <div class="field">
21
- <%= form.label :background %>
22
- <%= form.select :background, Katalyst::Content.config.backgrounds %>
21
+ <%= form.label :theme %>
22
+ <%= form.select :theme, Katalyst::Content.config.themes %>
23
23
  </div>
24
24
 
25
25
  <div class="field">
@@ -1,4 +1,4 @@
1
- <%= content_item_tag figure do %>
1
+ <%= content_item_tag(figure, tag: :figure) do %>
2
2
  <%= image_tag figure.image, alt: figure.alt %>
3
3
  <%= tag.figcaption figure.caption if figure.caption.present? %>
4
4
  <% end %>
@@ -13,8 +13,8 @@
13
13
  </div>
14
14
 
15
15
  <div class="field">
16
- <%= form.label :background %>
17
- <%= form.select :background, Katalyst::Content.config.backgrounds %>
16
+ <%= form.label :theme %>
17
+ <%= form.select :theme, Katalyst::Content.config.themes %>
18
18
  </div>
19
19
 
20
20
  <div class="field">
@@ -1,7 +1,5 @@
1
1
  <%= content_item_tag group do %>
2
2
  <%= tag.h3 group.heading, class: group.heading_style_class if group.show_heading? %>
3
3
 
4
- <div>
5
- <%= render_content_items group.children %>
6
- </div>
4
+ <%= render_content_items(*group.children, theme: group.theme, class: "flow") %>
7
5
  <% end %>
@@ -13,8 +13,8 @@
13
13
  </div>
14
14
 
15
15
  <div class="field">
16
- <%= form.label :background %>
17
- <%= form.select :background, Katalyst::Content.config.backgrounds %>
16
+ <%= form.label :theme %>
17
+ <%= form.select :theme, Katalyst::Content.config.themes %>
18
18
  </div>
19
19
 
20
20
  <div class="field">
@@ -13,8 +13,8 @@
13
13
  </div>
14
14
 
15
15
  <div class="field">
16
- <%= form.label :background %>
17
- <%= form.select :background, Katalyst::Content.config.backgrounds %>
16
+ <%= form.label :theme %>
17
+ <%= form.select :theme, Katalyst::Content.config.themes %>
18
18
  </div>
19
19
 
20
20
  <div class="field">
@@ -1,7 +1,5 @@
1
- <%= content_item_tag section do %>
2
- <%= tag.h2 section.heading, class: section.heading_style_class if section.show_heading? %>
1
+ <%= content_item_tag(section, tag: :section, class: "flow") do %>
2
+ <%= tag.h2(section.heading, class: section.heading_style_class) if section.show_heading? %>
3
3
 
4
- <div>
5
- <%= render_content_items section.children %>
6
- </div>
4
+ <%= render_content_items(*section.children, theme: section.theme, class: "flow") %>
7
5
  <% end %>
@@ -14,8 +14,8 @@
14
14
  </div>
15
15
 
16
16
  <div class="field">
17
- <%= form.label :background %>
18
- <%= form.select :background, Katalyst::Content.config.backgrounds %>
17
+ <%= form.label :theme %>
18
+ <%= form.select :theme, Katalyst::Content.config.themes %>
19
19
  </div>
20
20
 
21
21
  <div class="field">
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RenameBackgroundToTheme < ActiveRecord::Migration[8.0]
4
+ def change
5
+ rename_column :katalyst_content_items, :background, :theme
6
+ end
7
+ end
@@ -7,7 +7,10 @@ module Katalyst
7
7
  class Config
8
8
  include ActiveSupport::Configurable
9
9
 
10
- config_accessor(:backgrounds) { %w[light dark] }
10
+ config_accessor(:themes) { %w[light dark] }
11
+ alias_method :backgrounds, :themes
12
+ alias_method :backgrounds=, :themes=
13
+
11
14
  config_accessor(:heading_styles) { %w[none default] }
12
15
  config_accessor(:items) do
13
16
  %w[
@@ -4,7 +4,7 @@ FactoryBot.define do
4
4
  trait :content_item_defaults do
5
5
  heading { Faker::Lorem.word }
6
6
  heading_style { "default" }
7
- background { Katalyst::Content.config.backgrounds.sample }
7
+ theme { Katalyst::Content.config.themes.sample }
8
8
  depth { 0 }
9
9
  end
10
10
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katalyst-content
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.alpha.1
4
+ version: 3.0.0.alpha.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katalyst Interactive
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-18 00:00:00.000000000 Z
10
+ date: 2025-03-21 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activerecord
@@ -93,12 +93,15 @@ files:
93
93
  - app/assets/images/katalyst/content/icons/section.svg
94
94
  - app/assets/images/katalyst/content/icons/table.svg
95
95
  - app/assets/images/katalyst/content/icons/theme.svg
96
- - app/assets/stylesheets/katalyst/_content.scss
97
- - app/assets/stylesheets/katalyst/content.css
96
+ - app/assets/stylesheets/katalyst/content/_editor.scss
97
+ - app/assets/stylesheets/katalyst/content/_frontend.scss
98
98
  - app/assets/stylesheets/katalyst/content/editor.css
99
- - app/assets/stylesheets/katalyst/content/icons.css
100
- - app/assets/stylesheets/katalyst/content/status-bar.css
101
- - app/assets/stylesheets/katalyst/content/table.css
99
+ - app/assets/stylesheets/katalyst/content/editor/editor.css
100
+ - app/assets/stylesheets/katalyst/content/editor/icons.css
101
+ - app/assets/stylesheets/katalyst/content/editor/status-bar.css
102
+ - app/assets/stylesheets/katalyst/content/editor/table.css
103
+ - app/assets/stylesheets/katalyst/content/frontend.css
104
+ - app/assets/stylesheets/katalyst/content/frontend/frontend.css
102
105
  - app/components/katalyst/content/editor/base_component.rb
103
106
  - app/components/katalyst/content/editor/errors_component.html.erb
104
107
  - app/components/katalyst/content/editor/errors_component.rb
@@ -185,6 +188,7 @@ files:
185
188
  - db/migrate/20220926061535_add_fields_for_figure_to_katalyst_content_items.rb
186
189
  - db/migrate/20230515151440_change_katalyst_content_items_show_heading_column.rb
187
190
  - db/migrate/20240826042004_add_style_to_content_items.rb
191
+ - db/migrate/20250321045027_rename_background_to_theme.rb
188
192
  - lib/katalyst/content.rb
189
193
  - lib/katalyst/content/config.rb
190
194
  - lib/katalyst/content/engine.rb
@@ -1,4 +0,0 @@
1
- @use "content/editor";
2
- @use "content/icons";
3
- @use "content/status-bar";
4
- @use "content/table";
@@ -1,4 +0,0 @@
1
- @import url("content/editor.css");
2
- @import url("content/icons.css");
3
- @import url("content/status-bar.css");
4
- @import url("content/table.css");