Skip to content

Commit 5f6107a

Browse files
committed
Add configurable section paddings feature
Editors can now customize top and bottom padding for individual sections, with separate portrait orientation settings. This provides better control over section spacing and improves layout flexibility across different screen orientations. REDMINE-20979
1 parent 1da5c19 commit 5f6107a

File tree

15 files changed

+319
-2
lines changed

15 files changed

+319
-2
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
de:
2+
pageflow:
3+
section_paddings:
4+
feature_name: "Abschnittsinnenabstände"
5+
pageflow_scrolled:
6+
editor:
7+
section_paddings_input:
8+
auto: (Automatisch)
9+
edit_section:
10+
attributes:
11+
sectionPaddings:
12+
label: Innenabstände oben/unten
13+
edit_section_paddings:
14+
tabs:
15+
sectionPaddings: Innenabstände
16+
portrait: Hochkant
17+
attributes:
18+
paddingTop:
19+
blank: (Standard)
20+
label: Oben
21+
paddingBottom:
22+
blank: (Standard)
23+
label: Unten
24+
portraitPaddingTop:
25+
blank: (Standard)
26+
label: Oben (Hochkant)
27+
portraitPaddingBottom:
28+
blank: (Standard)
29+
label: Unten (Hochkant)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
en:

entry_types/scrolled/lib/pageflow_scrolled/plugin.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def configure(config)
5151
c.features.register('custom_palette_colors')
5252
c.features.register('decoration_effects')
5353
c.features.register('backdrop_size')
54+
c.features.register('section_paddings')
5455

5556
c.additional_frontend_seed_data.register(
5657
'frontendVersion',

entry_types/scrolled/package/spec/frontend/features/sectionPadding-spec.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import {renderEntry, useInlineEditingPageObjects} from 'support/pageObjects';
22

3+
import '@testing-library/jest-dom/extend-expect';
4+
5+
import {usePortraitOrientation} from 'frontend/usePortraitOrientation';
6+
jest.mock('frontend/usePortraitOrientation');
7+
38
describe('section padding', () => {
49
useInlineEditingPageObjects();
510

@@ -55,4 +60,73 @@ describe('section padding', () => {
5560

5661
expect(getSectionByPermaId(6).hasBottomPadding()).toBe(true);
5762
});
63+
64+
it('supports setting custom foreground padding', () => {
65+
const {getSectionByPermaId} = renderEntry({
66+
seed: {
67+
sections: [{
68+
id: 5,
69+
permaId: 6,
70+
configuration: {
71+
paddingTop: 'lg',
72+
paddingBottom: 'md'
73+
}
74+
}],
75+
contentElements: [{sectionId: 5}]
76+
}
77+
});
78+
79+
expect(getSectionByPermaId(6).el).toHaveStyle({
80+
'--foreground-padding-top': 'var(--theme-section-padding-top-lg)',
81+
'--foreground-padding-bottom': 'var(--theme-section-padding-bottom-md)',
82+
});
83+
});
84+
85+
it('supports portrait custom foreground padding', () => {
86+
usePortraitOrientation.mockReturnValue(true);
87+
88+
const {getSectionByPermaId} = renderEntry({
89+
seed: {
90+
sections: [{
91+
id: 5,
92+
permaId: 6,
93+
configuration: {
94+
paddingTop: 'lg',
95+
paddingBottom: 'md',
96+
portraitPaddingTop: 'sm',
97+
portraitPaddingBottom: 'xs'
98+
}
99+
}],
100+
contentElements: [{sectionId: 5}]
101+
}
102+
});
103+
104+
expect(getSectionByPermaId(6).el).toHaveStyle({
105+
'--foreground-padding-top': 'var(--theme-section-padding-top-sm)',
106+
'--foreground-padding-bottom': 'var(--theme-section-padding-bottom-xs)',
107+
});
108+
});
109+
110+
it('falls back to default padding if portrait padding not configured', () => {
111+
usePortraitOrientation.mockReturnValue(true);
112+
113+
const {getSectionByPermaId} = renderEntry({
114+
seed: {
115+
sections: [{
116+
id: 5,
117+
permaId: 6,
118+
configuration: {
119+
paddingTop: 'lg',
120+
paddingBottom: 'md'
121+
}
122+
}],
123+
contentElements: [{sectionId: 5}]
124+
}
125+
});
126+
127+
expect(getSectionByPermaId(6).el).toHaveStyle({
128+
'--foreground-padding-top': 'var(--theme-section-padding-top-lg)',
129+
'--foreground-padding-bottom': 'var(--theme-section-padding-bottom-md)',
130+
});
131+
});
58132
});

entry_types/scrolled/package/src/editor/controllers/SideBarController.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {editor} from 'pageflow-scrolled/editor';
55
import {EditChapterView} from '../views/EditChapterView';
66
import {EditSectionView} from '../views/EditSectionView';
77
import {EditSectionTransitionView} from '../views/EditSectionTransitionView';
8+
import {EditSectionPaddingsView} from '../views/EditSectionPaddingsView';
89
import {EditContentElementView} from '../views/EditContentElementView';
910

1011
export const SideBarController = Marionette.Controller.extend({
@@ -37,6 +38,14 @@ export const SideBarController = Marionette.Controller.extend({
3738
}));
3839
},
3940

41+
sectionPaddings: function(id, tab) {
42+
this.region.show(new EditSectionPaddingsView({
43+
entry: this.entry,
44+
model: this.entry.sections.get(id),
45+
editor
46+
}));
47+
},
48+
4049
contentElement: function(id, tab) {
4150
this.region.show(new EditContentElementView({
4251
entry: this.entry,

entry_types/scrolled/package/src/editor/routers/SideBarRouter.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const SideBarRouter = Marionette.AppRouter.extend({
44
appRoutes: {
55
'scrolled/chapters/:id': 'chapter',
66
'scrolled/sections/:id/transition': 'sectionTransition',
7+
'scrolled/sections/:id/paddings': 'sectionPaddings',
78
'scrolled/sections/:id': 'section',
89
'scrolled/content_elements/:id': 'contentElement'
910
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import {EditConfigurationView} from 'pageflow/editor';
2+
import {SelectInputView} from 'pageflow/ui';
3+
4+
import styles from './EditSectionPaddingsView.module.css';
5+
6+
export const EditSectionPaddingsView = EditConfigurationView.extend({
7+
translationKeyPrefix: 'pageflow_scrolled.editor.edit_section_paddings',
8+
hideDestroyButton: true,
9+
10+
className: styles.view,
11+
12+
goBackPath() {
13+
return `/scrolled/sections/` + this.model.get('id')
14+
},
15+
16+
configure: function(configurationEditor) {
17+
const entry = this.options.entry;
18+
19+
const [paddingTopValues, paddingTopTexts] = entry.getScale('sectionPaddingTop');
20+
const [paddingBottomValues, paddingBottomTexts] = entry.getScale('sectionPaddingBottom');
21+
22+
configurationEditor.tab('sectionPaddings', function() {
23+
this.input('paddingTop', SelectInputView, {
24+
includeBlank: true,
25+
values: paddingTopValues,
26+
texts: paddingTopTexts
27+
});
28+
29+
this.input('paddingBottom', SelectInputView, {
30+
includeBlank: true,
31+
values: paddingBottomValues,
32+
texts: paddingBottomTexts
33+
});
34+
});
35+
configurationEditor.tab('portrait', function() {
36+
this.input('portraitPaddingTop', SelectInputView, {
37+
includeBlank: true,
38+
values: paddingTopValues,
39+
texts: paddingTopTexts
40+
});
41+
42+
this.input('portraitPaddingBottom', SelectInputView, {
43+
includeBlank: true,
44+
values: paddingBottomValues,
45+
texts: paddingBottomTexts
46+
});
47+
});
48+
}
49+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.view :global(.tabs_view-headers) li:nth-child(2) {
2+
margin-left: 5px;
3+
}
4+
5+
.view :global(.tabs_view-headers) li:nth-child(2)::before {
6+
content: "›";
7+
margin-left: -15px;
8+
margin-right: 10px;
9+
font-weight: normal;
10+
}

entry_types/scrolled/package/src/editor/views/EditSectionTransitionView.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {normalizeSectionConfigurationData} from '../../entryState';
55

66
export const EditSectionTransitionView = EditConfigurationView.extend({
77
translationKeyPrefix: 'pageflow_scrolled.editor.edit_section_transition',
8+
hideDestroyButton: true,
89

910
configure: function(configurationEditor) {
1011
const entry = this.options.entry;

entry_types/scrolled/package/src/editor/views/EditSectionView.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from 'pageflow/ui';
88
import {BackdropContentElementInputView} from './inputs/BackdropContentElementInputView';
99
import {EffectListInputView} from './inputs/EffectListInputView';
10+
import {SectionPaddingsInputView} from './inputs/SectionPaddingsInputView';
1011
import {InlineFileRightsMenuItem} from '../models/InlineFileRightsMenuItem'
1112
import I18n from 'i18n-js';
1213
import {features} from 'pageflow/frontend';
@@ -126,6 +127,13 @@ export const EditSectionView = EditConfigurationView.extend({
126127
this.input('layout', SelectInputView, {
127128
values: ['left', 'right', 'center', 'centerRagged']
128129
});
130+
131+
if (features.isEnabled('section_paddings')) {
132+
this.input('sectionPaddings', SectionPaddingsInputView, {
133+
entry
134+
});
135+
}
136+
129137
if (entry.supportsSectionWidths()) {
130138
this.input('width', SelectInputView, {
131139
values: ['wide', 'narrow']

0 commit comments

Comments
 (0)