Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
}
}

ul {
&:not(:last-child) ul {
border-bottom: solid 1px var(--ui-on-surface-color-lighter);
padding-bottom: 1px;
margin-bottom: 1px;
Expand Down
3 changes: 3 additions & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1959,6 +1959,9 @@ de:
feature_name: "'Titel und Bild'-Lade-Ansicht"
widget_type_name: Titel und Bild
ui:
color_picker:
hue: "Farbton"
opacity: "Deckkraft"
configuration_editor:
tabs:
consent_bar: Consent-Leiste
Expand Down
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1946,6 +1946,9 @@ en:
feature_name: "'Title and image' loading view"
widget_type_name: Title and Image
ui:
color_picker:
hue: "Hue"
opacity: "Opacity"
configuration_editor:
tabs:
consent_bar: Consent bar
Expand Down
9 changes: 8 additions & 1 deletion entry_types/scrolled/config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ de:
turnDown: Leiser weiterspielen
hideControlBar:
inline_help: Für kurze Videos, bei denen der Benutzer nicht an bestimmte Stellen springen will.
inline_help_disabled: Für Videos mit Wiedergabe-Modus "Loop" sind die Controls immer ausgeblendet.
inline_help_disabled: Für Videos mit Wiedergabe-Modus "Loop" oder kreisförmigem Zuschnitt sind die Controls immer ausgeblendet.
label: Controls ausblenden
id:
label: Video
Expand Down Expand Up @@ -1427,6 +1427,11 @@ de:
lg: L
xl: XL
xxl: XXL
contentElementBoxShadow:
sm: S
md: M
lg: L
xl: XL
content_element_text_inline_file_rights_attributes:
showTextInlineFileRightsBackdrop:
label: "Abblendung hinter Rechteangabe"
Expand Down Expand Up @@ -1467,6 +1472,8 @@ de:
remove: "Stil entfernen"
marginTop: "Abstand oben"
marginBottom: "Abstand unten"
boxShadow: "Schatten"
outlineColor: "Umrandung"
image_modifier_list_input:
add: "Stil hinzufügen..."
remove: "Stil entfernen"
Expand Down
9 changes: 8 additions & 1 deletion entry_types/scrolled/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ en:
turnDown: Keep playing at lower volume
hideControlBar:
inline_help: For short videos where there is no need to seek.
inline_help_disabled: Controls are always hidden for videos with playback mode "Loop".
inline_help_disabled: Controls are always hidden for videos with playback mode "Loop" or circle crop.
label: Hide controls
id:
label: Video
Expand Down Expand Up @@ -1411,6 +1411,11 @@ en:
lg: L
xl: XL
xxl: XXL
contentElementBoxShadow:
sm: S
md: M
lg: L
xl: XL
content_element_text_inline_file_rights_attributes:
showTextInlineFileRightsBackdrop:
label: "Backdrop behind inline file rights"
Expand Down Expand Up @@ -1451,6 +1456,8 @@ en:
remove: "Remove style"
marginTop: "Margin top"
marginBottom: "Margin bottom"
boxShadow: "Box shadow"
outlineColor: "Outline"
image_modifier_list_input:
add: "Add style..."
remove: "Remove style"
Expand Down
19 changes: 18 additions & 1 deletion entry_types/scrolled/lib/pageflow_scrolled/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ def configure(config)
'xxl' => '16em'
}

box_shadow_scale = {
'sm' => '0 1px 3px 0 rgb(0 0 0 / 0.2), 0 1px 2px -1px rgb(0 0 0 / 0.15)',
'md' => '0 4px 6px -1px rgb(0 0 0 / 0.2), 0 2px 4px -2px rgb(0 0 0 / 0.15)',
'lg' => '0 10px 15px -3px rgb(0 0 0 / 0.2), 0 4px 6px -4px rgb(0 0 0 / 0.12)',
'xl' => '0 20px 25px -5px rgb(0 0 0 / 0.2), 0 8px 10px -6px rgb(0 0 0 / 0.12)'
}

c.themes.register_options_transform(
ThemeOptionsDefaultScale.new(
prefix: 'section_padding_top',
Expand All @@ -51,12 +58,22 @@ def configure(config)
)
)

c.themes.register_options_transform(
ThemeOptionsDefaultScale.new(
prefix: 'content_element_box_shadow',
values: box_shadow_scale
)
)

c.themes.register_default_options(
properties: {
root: {
'section_default_padding_top' => 'max(10em, 20svh)',
'section_default_padding_bottom' => 'max(10em, 20svh)',
'content_element_margin_style_default' => '2em'
'content_element_margin_style_default' => '2em',
'content_element_box_shadow_style_default' => '0 4px 6px -1px rgb(0 0 0 / 0.2), 0 2px 4px -2px rgb(0 0 0 / 0.15)',
'box_shadow_clip_margin_bottom' => '3rem',
'outline_color' => '#a0a0a080'
},
cards_appearance_section: {
'section_default_padding_top' => 'max(10em, 20svh)',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';

import {ExternalLinkList} from 'contentElements/externalLinkList/frontend/ExternalLinkList';

import {renderInContentElement} from 'pageflow-scrolled/testHelpers';
import '@testing-library/jest-dom/extend-expect'

describe('ExternalLinkList box styles', () => {
it('sets box shadow custom property from configuration', () => {
const {container} = renderInContentElement(
<ExternalLinkList configuration={{boxShadow: 'md', links: []}}
sectionProps={{}} />
);

const list = container.querySelector('ul');
expect(list.style.getPropertyValue('--content-element-box-shadow'))
.toEqual('var(--theme-content-element-box-shadow-md)');
});

it('sets outline color custom property from configuration', () => {
const {container} = renderInContentElement(
<ExternalLinkList configuration={{outlineColor: '#ff0000', links: []}}
sectionProps={{}} />
);

const list = container.querySelector('ul');
expect(list.style.getPropertyValue('--content-element-box-outline-color'))
.toEqual('#ff0000');
});

it('does not set custom properties when not configured', () => {
const {container} = renderInContentElement(
<ExternalLinkList configuration={{links: []}}
sectionProps={{}} />
);

const list = container.querySelector('ul');
expect(list.style.getPropertyValue('--content-element-box-shadow')).toEqual('');
expect(list.style.getPropertyValue('--content-element-box-outline-color')).toEqual('');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('InlineImage', () => {
});

const contentElement = getContentElement();
expect(contentElement.getFitViewportAspectRatio()).toEqual('1');
expect(contentElement.getFitViewportAspectRatio()).toEqual('square');
});

it('applies circle border radius', () => {
Expand All @@ -57,6 +57,28 @@ describe('InlineImage', () => {
expect(contentElement.getBoxBorderRadius()).toEqual('circle');
});

it('applies box shadow on circle box', () => {
const {getContentElement} = renderContentElement({
typeName: 'inlineImage',
configuration: {
id: 100,
boxShadow: 'md',
imageModifiers: [
{name: 'crop', value: 'circle'}
]
},
imageFiles: [{
permaId: 100,
width: 200,
height: 100
}]
});

const contentElement = getContentElement();
expect(contentElement.getBoxBorderRadius()).toEqual('circle');
expect(contentElement.hasBoxShadow('md')).toBe(true);
});

it('overrides rounded styles', () => {
const {getContentElement} = renderContentElement({
typeName: 'inlineImage',
Expand Down Expand Up @@ -100,6 +122,28 @@ describe('InlineImage', () => {
expect(contentElement.getFitViewportAspectRatio()).toEqual('square');
});

it('applies box shadow on outer box with rounded styles', () => {
const {getContentElement} = renderContentElement({
typeName: 'inlineImage',
configuration: {
id: 100,
boxShadow: 'lg',
imageModifiers: [
{name: 'rounded', value: 'md'}
]
},
imageFiles: [{
permaId: 100,
width: 200,
height: 100
}]
});

const contentElement = getContentElement();
expect(contentElement.getBoxBorderRadius()).toEqual('md');
expect(contentElement.hasBoxShadow('lg')).toBe(true);
});

it('applies rounded styles independently', () => {
const {getContentElement} = renderContentElement({
typeName: 'inlineImage',
Expand Down Expand Up @@ -154,7 +198,7 @@ describe('InlineImage', () => {
});

const contentElement = getContentElement();
expect(contentElement.getFitViewportAspectRatio()).toEqual('1');
expect(contentElement.getFitViewportAspectRatio()).toEqual('square');
expect(contentElement.getBoxBorderRadius()).toEqual('circle');
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {StylesCollection} from 'editor/collections/StylesCollection';
import {Style} from 'editor/models/Style';

import Backbone from 'backbone';
import {useFakeTranslations} from 'pageflow/testHelpers';
import {features} from 'pageflow/frontend';

describe('StylesCollection', () => {
const exampleTypes = {
Expand Down Expand Up @@ -37,8 +37,6 @@ describe('StylesCollection', () => {
}
};

beforeEach(() => features.enabledFeatureNames = []);

describe('#getUnusedStyles', () => {
useFakeTranslations({
'pageflow_scrolled.editor.backdrop_effects.blur.label': 'Blur',
Expand All @@ -63,23 +61,6 @@ describe('StylesCollection', () => {
expect(unusedStyles.findWhere({name: 'brightness'}).get('hidden')).toEqual(true);
});

it('does not include decoration styles by default', () => {
const styles = new StylesCollection([], {types: exampleTypes});

const unusedStyles = styles.getUnusedStyles();

expect(unusedStyles.pluck('name')).not.toContain('frame');
});

it('includes decoration styles if feature is enabled', () => {
const styles = new StylesCollection([], {types: exampleTypes});
features.enable('frontend', ['decoration_effects']);

const unusedStyles = styles.getUnusedStyles();

expect(unusedStyles.pluck('name')).toContain('frame');
});

it('selecting an unused style adds it to the collection', () => {
const styles = new StylesCollection([], {types: exampleTypes});

Expand Down Expand Up @@ -422,9 +403,71 @@ describe('StylesCollection', () => {
});
});

describe('conditional styles', () => {
it('hides unused style when condition is not met', () => {
const bindingModel = new Backbone.Model({posterId: null});
const types = {
boxShadow: {
label: 'Box shadow',
kind: 'decoration',
inputType: 'slider',
values: ['sm', 'md', 'lg'],
texts: ['S', 'M', 'L'],
defaultValue: 'md',
binding: 'posterId',
when: posterId => !!posterId
}
};

const styles = new StylesCollection([], {types, bindingModel});
const unusedStyles = styles.getUnusedStyles();

expect(unusedStyles.findWhere({name: 'boxShadow'}).get('hidden')).toEqual(true);
});

it('shows unused style when condition becomes met', () => {
const bindingModel = new Backbone.Model({posterId: null});
const types = {
boxShadow: {
label: 'Box shadow',
kind: 'decoration',
inputType: 'slider',
values: ['sm', 'md', 'lg'],
texts: ['S', 'M', 'L'],
defaultValue: 'md',
binding: 'posterId',
when: posterId => !!posterId
}
};

const styles = new StylesCollection([], {types, bindingModel});
const unusedStyles = styles.getUnusedStyles();

bindingModel.set('posterId', 5);

expect(unusedStyles.findWhere({name: 'boxShadow'}).get('hidden')).toEqual(false);
});

it('does not hide unused style without condition', () => {
const bindingModel = new Backbone.Model();
const types = {
outlineColor: {
label: 'Outline',
kind: 'decoration',
inputType: 'color'
}
};

const styles = new StylesCollection([], {types, bindingModel});
const unusedStyles = styles.getUnusedStyles();

expect(unusedStyles.findWhere({name: 'outlineColor'}).get('hidden')).toEqual(false);
});
});

describe('with effect types', () => {
it('creates collection with effect style types', () => {
const styles = new StylesCollection([{name: 'blur', value: 50}], {types: Style.effectTypes});
const styles = new StylesCollection([{name: 'blur', value: 50}], {types: Style.getEffectTypes()});

expect(styles.pluck('name')).toEqual(['blur']);
expect(styles.first().minValue()).toEqual(0);
Expand Down
Loading
Loading