Skip to content
Merged
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
8 changes: 8 additions & 0 deletions app/assets/stylesheets/pageflow/ui/input/color_input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
.minicolors-input-swatch {
top: 5px;
left: 5px;

.minicolors-swatch-color {
background-color: var(--placeholder-color);
}
}

&.is_default input {
Expand All @@ -22,4 +26,8 @@
.minicolors-focus input {
color: var(--ui-on-surface-color);
}

.minicolors-swatches .minicolors-swatch {
margin: 2px;
}
}
8 changes: 8 additions & 0 deletions entry_types/scrolled/config/locales/new/cards_colors.de.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
de:
pageflow_scrolled:
editor:
edit_section:
attributes:
cardSurfaceColor:
label: Kartenhintergrundfarbe
auto: "(Automatisch)"
8 changes: 8 additions & 0 deletions entry_types/scrolled/config/locales/new/cards_colors.en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
en:
pageflow_scrolled:
editor:
edit_section:
attributes:
cardSurfaceColor:
label: Cards background color
auto: "(Auto)"
1 change: 1 addition & 0 deletions entry_types/scrolled/lib/pageflow_scrolled/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def configure(config)
c.features.register('frontend_v2')
c.features.register('scrolled_entry_fragment_caching')
c.features.register('backdrop_content_elements')
c.features.register('custom_palette_colors')

c.additional_frontend_seed_data.register(
'frontendVersion',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import {ScrolledEntry} from 'editor/models/ScrolledEntry';
import {factories} from 'pageflow/testHelpers';
import {normalizeSeed} from 'support';

describe('ScrolledEntry', () => {
describe('#getUsedSectionBackgroundColors', () => {
it('returns unique sorted list of used background colors', () => {
const entry = factories.entry(
ScrolledEntry,
{},
{
entryTypeSeed: normalizeSeed({
sections: [
{
configuration: {
backdropType: 'color',
backdropColor: '#400'}
},
{
configuration: {
backdropType: 'color',
backdropColor: '#040'
}
},
{
configuration: {
backdropType: 'color',
backdropColor: '#400'
}
},
{
configuration: {
appearance: 'cards',
cardSurfaceColor: '#500'
}
},
{
configuration: {
appearance: 'cards',
cardSurfaceColor: '#400'
}
}
]
})
}
);

const colors = entry.getUsedSectionBackgroundColors();

expect(colors).toEqual(['#400', '#500', '#040']);
});

it('ignores blank colors', () => {
const entry = factories.entry(
ScrolledEntry,
{},
{
entryTypeSeed: normalizeSeed({
sections: [
{
configuration: {
backdropType: 'color'
}
}
]
})
}
);

const colors = entry.getUsedSectionBackgroundColors();

expect(colors).toEqual([]);
});

it('ignores invisible config options', () => {
const entry = factories.entry(
ScrolledEntry,
{},
{
entryTypeSeed: normalizeSeed({
sections: [
{
configuration: {
backdropType: 'image',
backdropColor: '#400'}
},
{
configuration: {
appearance: 'shadow',
cardSurfaceColor: '#500'
}
}
]
})
}
);

const colors = entry.getUsedSectionBackgroundColors();

expect(colors).toEqual([]);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import {
ColorSelectOrCustomColorInputView
} from 'editor/views/inputs/ColorSelectOrCustomColorInputView';
import Backbone from 'backbone';

import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom/extend-expect';
import {useReactBasedBackboneViews} from 'support';
import {useFakeTranslations} from 'pageflow/testHelpers';

describe('ColorSelectOrCustomColorInputView', () => {
const {render} = useReactBasedBackboneViews();

useFakeTranslations({
'pageflow_scrolled.editor.blank': 'Auto',
'pageflow_scrolled.editor.custom_color': 'Custom Color'
});

it('loads theme palette color value', async () => {
const model = new Backbone.Model({
color: 'brand-red'
});

const inputView = new ColorSelectOrCustomColorInputView({
model,
label: 'Background Color',
customColorTranslationKey: 'pageflow_scrolled.editor.custom_color',
values: ['brand-red', 'brand-green'],
texts: ['Red', 'Green'],
propertyName: 'color'
});

const {getByRole, queryByRole} = render(inputView);

expect(getByRole('button', {name: 'Red'})).not.toBeNull();
expect(queryByRole('textbox')).toBeNull();
});

it('loads custom color value', async () => {
const model = new Backbone.Model({
color: '#ff0000'
});

const inputView = new ColorSelectOrCustomColorInputView({
model,
label: 'Background Color',
customColorTranslationKey: 'pageflow_scrolled.editor.custom_color',
values: ['brand-red', 'brand-green'],
texts: ['Red', 'Green'],
propertyName: 'color'
});

const {getByRole} = render(inputView);

expect(getByRole('button', {name: 'Custom Color'})).not.toBeNull();
expect(getByRole('textbox')).not.toBeNull();
expect(getByRole('textbox')).toHaveValue('#ff0000');
});

it('updates model when selecting theme palette color', async () => {
const model = new Backbone.Model({
color: '#ff0000'
});

const inputView = new ColorSelectOrCustomColorInputView({
model,
label: 'Background Color',
customColorTranslationKey: 'pageflow_scrolled.editor.custom_color',
values: ['brand-red', 'brand-green'],
texts: ['Red', 'Green'],
propertyName: 'color'
});

const user = userEvent.setup();
const {getByRole} = render(inputView);
await user.click(getByRole('button', {name: 'Custom Color'}));
await user.click(getByRole('option', {name: 'Red'}));

expect(model.get('color')).toBe('brand-red');
});

it('updates model when selecting custom color', async () => {
const model = new Backbone.Model({
color: 'brand-red'
});

const inputView = new ColorSelectOrCustomColorInputView({
model,
label: 'Background Color',
customColorTranslationKey: 'pageflow_scrolled.editor.custom_color',
values: ['brand-red', 'brand-green'],
texts: ['Red', 'Green'],
propertyName: 'color'
});

const user = userEvent.setup();
const {getByRole} = render(inputView);
await user.click(getByRole('button', {name: 'Red'}));
await user.click(getByRole('option', {name: 'Custom Color'}));

const input = getByRole('textbox');
await user.clear(input);
await user.type(input, '#ff0000');
await new Promise(resolve => setTimeout(resolve, 300));

expect(model.get('color')).toBe('#ff0000');
});

it('shows custom color input only when custom is selected', async () => {
const model = new Backbone.Model({
color: 'brand-red'
});

const inputView = new ColorSelectOrCustomColorInputView({
model,
label: 'Background Color',
customColorTranslationKey: 'pageflow_scrolled.editor.custom_color',
values: ['brand-red', 'brand-green'],
texts: ['Red', 'Green'],
propertyName: 'color'
});

const user = userEvent.setup();
const {getByRole, queryByRole} = render(inputView);

expect(queryByRole('textbox')).toBeNull();

await user.click(getByRole('button', {name: 'Red'}));
await user.click(getByRole('option', {name: 'Custom Color'}));

expect(getByRole('textbox')).not.toBeNull();

await user.click(getByRole('button', {name: 'Custom Color'}));
await user.click(getByRole('option', {name: 'Red'}));

expect(queryByRole('textbox')).toBeNull();
});

it('uses provided translations', async () => {
const model = new Backbone.Model();

const inputView = new ColorSelectOrCustomColorInputView({
model,
label: 'Background Color',
includeBlank: true,
blankTranslationKey: 'pageflow_scrolled.editor.blank',
customColorTranslationKey: 'pageflow_scrolled.editor.custom_color',
values: ['brand-red', 'brand-green'],
texts: ['Red', 'Green'],
propertyName: 'color'
});

const {getByText, getByRole} = render(inputView);

expect(getByText('Background Color')).not.toBeNull();

// Click the button to open the dropdown
await userEvent.click(getByRole('button'));

expect(getByRole('option', {name: 'Auto'})).not.toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {editor} from 'pageflow-scrolled/editor';
import {features} from 'pageflow/frontend';
import {SelectInputView, SliderInputView, SeparatorView, CheckBoxInputView} from 'pageflow/ui';

import {SidebarRouter} from './SidebarRouter';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,35 @@ editor.contentElementTypes.register('textBlock', {
supportedPositions: ['inline'],

configurationEditor({entry, contentElement}) {
this.listenTo(contentElement.transientState,
'change:exampleNode',
() => this.refresh());
let pendingRefresh;

this.listenTo(
contentElement.transientState,
'change:exampleNode',
() => {
// This is a terrible hack to prevent closing the minicolors
// dropdown while adjusting colors. Calling refresh is needed
// to update typography drop downs. Delay until color picker
// is closed.
if (document.activeElement &&
document.activeElement.tagName === 'INPUT' &&
document.activeElement.className === 'minicolors-input') {

if (!pendingRefresh) {
document.activeElement.addEventListener('blur', () => {
pendingRefresh = false;
this.refresh()
}, {once: true});

pendingRefresh = true;
}

return;
}

this.refresh()
}
);

this.tab('general', function() {
const exampleNode = ensureTextContent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {insertContentElement} from './insertContentElement';
import {moveContentElement} from './moveContentElement';
import {deleteContentElement} from './deleteContentElement';

import {sortColors} from './sortColors';

const typographySizeSuffixes = ['xl', 'lg', 'md', 'sm', 'xs'];

export const ScrolledEntry = Entry.extend({
Expand Down Expand Up @@ -276,6 +278,22 @@ export const ScrolledEntry = Entry.extend({
return [values, texts];
},

getUsedSectionBackgroundColors() {
const colors = new Set();

this.sections.map(section => {
if (section.configuration.get('backdropType') === 'color') {
colors.add(section.configuration.get('backdropColor'));
}

if (section.configuration.get('appearance') === 'cards') {
colors.add(section.configuration.get('cardSurfaceColor'));
}
});

return sortColors([...colors].filter(Boolean));
},

supportsSectionWidths() {
const theme = this.scrolledSeed.config.theme;

Expand Down
Loading
Loading