Skip to content

Commit 3bbc906

Browse files
authored
Merge pull request #2350 from tf/content-el-defaults
Content element defaults
2 parents 59799de + 61a7f37 commit 3bbc906

21 files changed

Lines changed: 754 additions & 8 deletions

File tree

entry_types/scrolled/config/locales/de.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,9 @@ de:
616616
mute: Ausblenden
617617
play: Weiterspielen
618618
turnDown: Leiser weiterspielen
619+
autoplay:
620+
inline_help: Automatisch abspielen, wenn das Element in den sichtbaren Bereich gescrollt wird.
621+
label: Autoplay
619622
id:
620623
label: Audio
621624
playerControlVariant:
@@ -1457,24 +1460,46 @@ de:
14571460
edit_defaults:
14581461
back: Erscheinungsbild
14591462
sections_info: Änderungen an diesen Einstellungen haben keine Auswirkungen auf existierende Abschnitte.
1463+
content_elements_info: |-
1464+
Änderungen an diesen Einstellungen haben keine Auswirkungen auf existierende Elemente.
1465+
Einstellungen können später für einzelne Elemente überschrieben werden.
1466+
all_elements: Alle Elemente
14601467
tabs:
14611468
sections: Neue Abschnitte
1469+
content_elements: Neue Elemente
14621470
attributes:
14631471
defaultSectionLayout:
14641472
label: Vordergrund-Positionierung
1473+
inline_help: |-
1474+
Standardposition der scrollenden Vordergrund-Ebene
1475+
neuer Abschnitte in Desktop-Darstellung.
14651476
values:
14661477
center: Mitte
14671478
centerRagged: Zentriert
14681479
left: Links
14691480
right: Rechts
1481+
defaultSectionAppearance:
1482+
label: Abblendung
1483+
inline_help: Standard-Erscheinung neuer Abschnitte.
1484+
values:
1485+
cards: Karte
1486+
shadow: Schatten
1487+
transparent: Keine
14701488
topPaddingVisualization:
14711489
label: Abstand oben
14721490
defaultSectionPaddingTop:
14731491
label: Abstand oben
1492+
inline_help: Standardabstand oberhalb des Inhalts neuer Abschnitte.
14741493
bottomPaddingVisualization:
14751494
label: Abstand unten
14761495
defaultSectionPaddingBottom:
14771496
label: Abstand unten
1497+
inline_help: Standardabstand unterhalb des Inhalts neuer Abschnitte.
1498+
defaultContentElementFullWidthInPhoneLayout:
1499+
label: Volle Breite im Phone-Layout
1500+
inline_help: |-
1501+
Standardmäßig Elemente auf kleineren Bildschirmen
1502+
die gesamte Breite des Viewports nutzen lassen.
14781503
typography_sizes:
14791504
xl: Sehr groß
14801505
lg: Groß

entry_types/scrolled/config/locales/en.yml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,14 +601,17 @@ en:
601601
mute: Mute
602602
play: Keep playing
603603
turnDown: Keep playing at lower volume
604+
autoplay:
605+
inline_help: Start playing automatically when the element is scrolled into view.
606+
label: Autoplay
604607
id:
605608
label: Audio
606609
playerControlVariant:
607610
inline_help: Choose the style of player controls.
608-
label: Waveform Style
611+
label: Player Controls
609612
values:
610613
classic: Classic
611-
waveform: Waveform (Fein)
614+
waveform: Waveform (Fine)
612615
waveformBars: Waveform (Bars)
613616
waveformLines: Waveform (Lines)
614617
posterId:
@@ -1440,24 +1443,46 @@ en:
14401443
edit_defaults:
14411444
back: Appearance
14421445
sections_info: Changes to these settings have no effect on existing sections.
1446+
content_elements_info: |-
1447+
Changes to these settings have no effect on existing elements.
1448+
Settings can later be changed for individual elements.
1449+
all_elements: All elements
14431450
tabs:
14441451
sections: New sections
1452+
content_elements: New elements
14451453
attributes:
14461454
defaultSectionLayout:
14471455
label: Content alignment
1456+
inline_help: |-
1457+
Default position of the scrolling foreground layer of
1458+
new sections on desktop devices.
14481459
values:
14491460
center: Centered
14501461
centerRagged: Centered (Ragged)
14511462
left: Left
14521463
right: Right
1464+
defaultSectionAppearance:
1465+
label: Text background
1466+
inline_help: Default appearance of new sections.
1467+
values:
1468+
cards: Card
1469+
shadow: Shadow
1470+
transparent: Transparent
14531471
topPaddingVisualization:
14541472
label: Top padding
14551473
defaultSectionPaddingTop:
14561474
label: Top padding
1475+
inline_help: Default vertical spacing above the content of new sections.
14571476
bottomPaddingVisualization:
14581477
label: Bottom padding
14591478
defaultSectionPaddingBottom:
14601479
label: Bottom padding
1480+
inline_help: Default vertical spacing below the content of new sections.
1481+
defaultContentElementFullWidthInPhoneLayout:
1482+
label: Full width in phone layout
1483+
inline_help: |-
1484+
By default, make elements span the full width of the
1485+
viewport on smaller screens.
14611486
typography_sizes:
14621487
xl: Very large
14631488
lg: Large

entry_types/scrolled/doc/creating_content_element_types.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,57 @@ pageflow_scrolled:
379379
inline_help: "..."
380380
```
381381

382+
## Defaults Inputs
383+
384+
Content element types can contribute inputs to the entry defaults
385+
settings. These inputs allow editors to configure default values that
386+
are applied when creating new content elements of that type.
387+
388+
To define defaults inputs, provide a `defaultsInputs` function when
389+
registering your content element type:
390+
391+
```javascript
392+
import {editor} from 'pageflow-scrolled/editor';
393+
import {CheckBoxInputView} from 'pageflow/ui';
394+
395+
editor.contentElementTypes.register('inlineImage', {
396+
configurationEditor({entry}) {
397+
// ...
398+
},
399+
400+
defaultsInputs() {
401+
this.input('enableFullscreen', CheckBoxInputView);
402+
}
403+
});
404+
```
405+
406+
The `defaultsInputs` function is called in a similar context as the
407+
`this.tab` callback in `configurationEditor`. Property names are
408+
automatically prefixed with `default-{typeName}-` when stored in the
409+
entry metadata configuration.
410+
411+
For translations, Pageflow first looks for keys under a `defaults`
412+
namespace, then falls back to normal attribute translations:
413+
414+
```
415+
pageflow_scrolled:
416+
editor:
417+
content_elements:
418+
inlineImage:
419+
defaults:
420+
attributes:
421+
enableFullscreen:
422+
label: "..."
423+
inline_help: "..."
424+
attributes:
425+
enableFullscreen:
426+
label: "..."
427+
inline_help: "..."
428+
```
429+
430+
If the `defaults.attributes` translation is not found, the normal
431+
`attributes` translation is used as a fallback.
432+
382433
## Using Palette Colors
383434

384435
[Palette

entry_types/scrolled/package/spec/editor/api/ContentElementTypeRegistry-spec.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,114 @@ describe('ContentElementTypeRegistry', () => {
146146
});
147147
});
148148

149+
describe('#getDefaultsInputsMapping', () => {
150+
it('returns empty object for type without defaultsInputs', () => {
151+
const registry = new ContentElementTypeRegistry({features: new Features()});
152+
registry.register('textBlock', {});
153+
154+
const mapping = registry.getDefaultsInputsMapping('textBlock');
155+
156+
expect(mapping).toEqual({});
157+
});
158+
159+
it('returns mapping from metadata keys to property names', () => {
160+
const registry = new ContentElementTypeRegistry({features: new Features()});
161+
registry.register('inlineImage', {
162+
defaultsInputs() {
163+
this.input('enableFullscreen');
164+
this.input('autoplay');
165+
}
166+
});
167+
168+
const mapping = registry.getDefaultsInputsMapping('inlineImage');
169+
170+
expect(mapping).toEqual({
171+
'default-inlineImage-enableFullscreen': 'enableFullscreen',
172+
'default-inlineImage-autoplay': 'autoplay'
173+
});
174+
});
175+
});
176+
177+
describe('#createDefaultsInputContext', () => {
178+
it('prefixes property names passed to input', () => {
179+
const registry = new ContentElementTypeRegistry({features: new Features()});
180+
const tabView = {
181+
input: jest.fn(),
182+
view: jest.fn()
183+
};
184+
185+
const context = registry.createDefaultsInputContext(tabView, 'inlineImage');
186+
context.input('enableFullscreen', 'CheckBoxInputView', {some: 'option'});
187+
188+
expect(tabView.input).toHaveBeenCalledWith(
189+
'default-inlineImage-enableFullscreen',
190+
'CheckBoxInputView',
191+
expect.objectContaining({some: 'option'})
192+
);
193+
});
194+
195+
it('adds attributeTranslationKeyPrefixes with fallback to normal attributes', () => {
196+
const registry = new ContentElementTypeRegistry({features: new Features()});
197+
const tabView = {
198+
input: jest.fn(),
199+
view: jest.fn()
200+
};
201+
202+
const context = registry.createDefaultsInputContext(tabView, 'inlineImage');
203+
context.input('enableFullscreen', 'CheckBoxInputView');
204+
205+
expect(tabView.input).toHaveBeenCalledWith(
206+
expect.anything(),
207+
expect.anything(),
208+
expect.objectContaining({
209+
attributeTranslationKeyPrefixes: [
210+
'pageflow_scrolled.editor.content_elements.inlineImage.defaults.attributes',
211+
'pageflow_scrolled.editor.content_elements.inlineImage.attributes'
212+
],
213+
attributeTranslationPropertyName: 'enableFullscreen'
214+
})
215+
);
216+
});
217+
218+
it('preserves existing attributeTranslationKeyPrefixes', () => {
219+
const registry = new ContentElementTypeRegistry({features: new Features()});
220+
const tabView = {
221+
input: jest.fn(),
222+
view: jest.fn()
223+
};
224+
225+
const context = registry.createDefaultsInputContext(tabView, 'inlineImage');
226+
context.input('enableFullscreen', 'CheckBoxInputView', {
227+
attributeTranslationKeyPrefixes: ['custom.prefix']
228+
});
229+
230+
expect(tabView.input).toHaveBeenCalledWith(
231+
expect.anything(),
232+
expect.anything(),
233+
expect.objectContaining({
234+
attributeTranslationKeyPrefixes: [
235+
'pageflow_scrolled.editor.content_elements.inlineImage.defaults.attributes',
236+
'pageflow_scrolled.editor.content_elements.inlineImage.attributes',
237+
'custom.prefix'
238+
]
239+
})
240+
);
241+
});
242+
243+
it('passes through view calls', () => {
244+
const registry = new ContentElementTypeRegistry({features: new Features()});
245+
const tabView = {
246+
input: jest.fn(),
247+
view: jest.fn()
248+
};
249+
250+
const context = registry.createDefaultsInputContext(tabView, 'inlineImage');
251+
context.view('SomeView', {some: 'option'});
252+
253+
expect(tabView.view).toHaveBeenCalledWith('SomeView', {some: 'option'});
254+
});
255+
});
256+
149257
describe('#toArray', () => {
150258
it('returns array of with options passed to register', () => {
151259
const registry = new ContentElementTypeRegistry({features: new Features()});

entry_types/scrolled/package/spec/editor/models/Chapter-spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ describe('Chapter', () => {
5959
expect(section.configuration.get('layout')).toEqual('right');
6060
});
6161

62+
it('uses default appearance from entry metadata configuration', () => {
63+
const {entry} = testContext;
64+
65+
entry.metadata.configuration.set('defaultSectionAppearance', 'cards');
66+
const section = entry.chapters.first().addSection();
67+
68+
expect(section.configuration.get('appearance')).toEqual('cards');
69+
});
70+
6271
it('handles sparse positions correctly', () => {
6372
const {entry} = testContext;
6473

0 commit comments

Comments
 (0)