Skip to content

Commit

Permalink
Merge pull request #28 from techdivision/feature/data-attributes
Browse files Browse the repository at this point in the history
TASK: Add option to set other attributes (SEE #26)
  • Loading branch information
anianweber authored Mar 21, 2022
2 parents e27002d + 1ec1789 commit 965f9c3
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 51 deletions.
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ This package allows you to add different styles based on your css-classes for th
You can define the classes in you yaml configuration.
Styles can be applied both on block- and element level.

It is also possible to set a different attribute (for usage with placeholders for example).


**Demo:**

Expand All @@ -29,6 +31,8 @@ Styles can be applied both on block- and element level.
In most projects there are requirements that you cannot achieve with tags alone, and you need classes under editorial control -
e.g. if you want to highlight some text with font size but don't use a headline for SEO reasons
or want to add an icon, adjust the font color, ...
Or you want to add data-attributes to an element for use in combination with js ...


## Getting started

Expand Down Expand Up @@ -63,6 +67,13 @@ TechDivision:
'big':
label: 'Large'
cssClass: 'my-class-size-large'
'dataAttribute':
label: 'Inline data attribute'
options:
'data':
label: 'Inline data'
attribute: 'data-attribute'
attributeValue: 'my-custom-attribute-value'
BlockStyles:
presets:
'indent':
Expand All @@ -74,12 +85,19 @@ TechDivision:
'secondary':
label: '4 rem'
cssClass: 'my-class-indent-4'
'dataAttribute':
label: 'Block data attribute'
options:
'data':
label: 'Block data'
attribute: 'data-attribute'
attributeValue: 'my-custom-attribute-value'
```
Example: [Configuration/Settings.yaml](Configuration/Settings.yaml)
**What values are allowed for cssClass?**
**What values are allowed for `cssClass` and/or `attributeValue`?**
- **Not null** Using an empty class (cssClass: null) to unset the value might cause errors during rendering in the backend. The select boxes of this package contain an "x" button for resetting the value.
- Although you can add **multiple classes** by separating them with a whitespace. e.g. `btn btn-primary`, it is **highly recommended** to use only **one and unique** class across all Inline- or BlockStyles. See [known issues](#konwn-issues) for more details.

Expand All @@ -94,10 +112,12 @@ Example: [Configuration/Settings.yaml](Configuration/Settings.yaml)
inline:
editorOptions:
inlineStyling:
dataAttribute: true
fontColor: true
fontSize: true
blockStyling:
indent: true
dataAttribute: true
```

Example: [Configuration/NodeTypes.Override.BaseMixins.yaml](Configuration/NodeTypes.Override.BaseMixins.yaml)
Expand Down
16 changes: 8 additions & 8 deletions Resources/Private/JavaScript/CkStyles/src/BlockStyleCommand.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Originally taken from https://raw.githubusercontent.com/ckeditor/ckeditor5/master/packages/ckeditor5-basic-styles/src/attributecommand.js and adjusted
import { Command } from 'ckeditor5-exports';
import {Command} from 'ckeditor5-exports';

/**
* Set a key-value block style; e.g. "fontColor=red".
Expand Down Expand Up @@ -37,11 +37,11 @@ export default class BlockStyleCommand extends Command {
refresh() {
const model = this.editor.model;
const doc = model.document;
const blocksToChange = Array.from( doc.selection.getSelectedBlocks() );
const blocksToChange = Array.from(doc.selection.getSelectedBlocks());

this.value = this._getValueFromBlockNode();
for ( const block of blocksToChange ) {
if(model.schema.checkAttribute(block, this.attributeKey)) {
for (const block of blocksToChange) {
if (model.schema.checkAttribute(block, this.attributeKey)) {
this.isEnabled = true;
}
}
Expand All @@ -60,9 +60,9 @@ export default class BlockStyleCommand extends Command {
const doc = model.document;
const selection = doc.selection;
const value = options.value;
const blocksToChange = Array.from( selection.getSelectedBlocks() );
model.change( writer => {
for ( const block of blocksToChange ) {
const blocksToChange = Array.from(selection.getSelectedBlocks());
model.change(writer => {
for (const block of blocksToChange) {
if (value) {
writer.setAttribute(this.attributeKey, value, block);
} else {
Expand All @@ -82,7 +82,7 @@ export default class BlockStyleCommand extends Command {
const model = this.editor.model;
const schema = model.schema;
const selection = model.document.selection;
const blocks = Array.from( selection.getSelectedBlocks() );
const blocks = Array.from(selection.getSelectedBlocks());

for (const block of blocks) {
if (schema.checkAttribute(block, this.attributeKey)) {
Expand Down
16 changes: 8 additions & 8 deletions Resources/Private/JavaScript/CkStyles/src/BlockStyleEditing.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ export default (presetIdentifier, presetConfiguration) =>

schema.extend(
'$block',
{ allowAttributes: modelAttributeKey}
{allowAttributes: modelAttributeKey}
);

// https://ckeditor.com/docs/ckeditor5/latest/features/remove-format.html
schema.setAttributeProperties(
modelAttributeKey,
{ isFormatting: true }
{isFormatting: true}
);

// Model configuration
Expand All @@ -34,13 +34,13 @@ export default (presetIdentifier, presetConfiguration) =>

// View configuration
optionIdentifiers.forEach(optionIdentifier => {
const option = presetConfiguration.options[optionIdentifier];
// split the cssClass configuration to allow for multiple classes
const classes = option.cssClass.split(' ');
const options = presetConfiguration.options[optionIdentifier];
const attribute = options.attribute || 'class';
const attributeValues = (attribute === options.attribute) ? options.attributeValue : (options.cssClass).split(' ');

config.view[optionIdentifier] = {
key: 'class',
value: classes
key: attribute,
value: attributeValues
}
});

Expand All @@ -49,4 +49,4 @@ export default (presetIdentifier, presetConfiguration) =>

this.editor.commands.add(`blockStyles:${presetIdentifier}`, new BlockStyleCommand(this.editor, modelAttributeKey));
}
}
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Originally taken from https://raw.githubusercontent.com/ckeditor/ckeditor5/master/packages/ckeditor5-basic-styles/src/attributecommand.js and adjusted
import { Command } from 'ckeditor5-exports';
import {Command} from 'ckeditor5-exports';

/**
* Set a key-value inline style; e.g. "fontColor=red".
Expand Down
10 changes: 5 additions & 5 deletions Resources/Private/JavaScript/CkStyles/src/InlineStylesEditing.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ export default (presetIdentifier, presetConfiguration) =>

// View configuration
optionIdentifiers.forEach(optionIdentifier => {
const option = presetConfiguration.options[optionIdentifier];
// split the cssClass configuration to allow for multiple classes
const classes = option.cssClass.split(' ');
const options = presetConfiguration.options[optionIdentifier];
const {attribute} = options;
const classes = options.attributeValue || options.cssClass;

config.view[optionIdentifier] = {
name: 'span',
classes: classes
attributes: {[attribute ? attribute : 'class']: classes}
}
});

Expand All @@ -49,4 +49,4 @@ export default (presetIdentifier, presetConfiguration) =>

this.editor.commands.add(`inlineStyles:${presetIdentifier}`, new InlineStylesCommand(this.editor, modelAttributeKey));
}
}
};
15 changes: 13 additions & 2 deletions Resources/Private/JavaScript/CkStyles/src/PresetType.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import PropTypes from 'prop-types';

function attributeValueOrCssClass(props, propName, componentName) {
if (props[propName] && typeof props[propName] !== 'string') {
return new Error(`Prop '${propName}' must be a string.`);
}
if (!props.attributeValue && !props.cssClass) {
return new Error(`Either prop 'attributeValue' or 'cssClass' must be supplied to ${componentName}.`);
}
}

export default PropTypes.shape({
label: PropTypes.string.isRequired,

// keys are the option values
options: PropTypes.objectOf(PropTypes.shape({
label: PropTypes.string.isRequired,
cssClass: PropTypes.string.isRequired
}))
attribute: PropTypes.string,
attributeValue: attributeValueOrCssClass,
cssClass: attributeValueOrCssClass,
})),
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { PureComponent } from 'react';
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import { SelectBox } from '@neos-project/react-ui-components';
import { connect } from 'react-redux';
import { $transform } from 'plow-js';
import {SelectBox} from '@neos-project/react-ui-components';
import {connect} from 'react-redux';
import {$transform} from 'plow-js';
import PresetType from '../PresetType';

import {selectors} from '@neos-project/neos-ui-redux-store';
Expand Down Expand Up @@ -54,7 +54,7 @@ export default class BlockStyleSelector extends PureComponent {
handleOnSelect(optionIdentifier) {
CkEditorApi.executeCommand(
`blockStyles:${this.props.presetIdentifier}`,
{ value: optionIdentifier }
{value: optionIdentifier}
);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import { SelectBox } from '@neos-project/react-ui-components';
import {SelectBox} from '@neos-project/react-ui-components';
import {connect} from 'react-redux';
import {$transform} from 'plow-js';
import PresetType from '../PresetType';
Expand Down Expand Up @@ -54,7 +54,7 @@ export default class InlineStyleSelector extends PureComponent {
handleOnSelect(optionIdentifier) {
CkEditorApi.executeCommand(
`inlineStyles:${this.props.presetIdentifier}`,
{ value: optionIdentifier }
{value: optionIdentifier}
);
}
}
14 changes: 7 additions & 7 deletions Resources/Private/JavaScript/CkStyles/src/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ manifest('TechDivision.CkStyles:Styles', {}, (globalRegistry, {frontendConfigura
const blockStyleConfiguration = frontendConfiguration['TechDivision.CkStyles:BlockStyles'];

// Block style
if(blockStyleConfiguration) {
if (blockStyleConfiguration) {

Object.keys(blockStyleConfiguration.presets).forEach(presetIdentifier => {

Expand All @@ -33,9 +33,9 @@ manifest('TechDivision.CkStyles:Styles', {}, (globalRegistry, {frontendConfigura
richtextToolbar.set(`blockStyles_${presetIdentifier}`, {
component: BlockStyleSelector,
// Display only if the preset is activated in NodeType.yaml for this node property
isVisible: function(editorOptions, formattingUnderCursor) {
isVisible: function (editorOptions, formattingUnderCursor) {
var isVisible = false;
if(editorOptions['blockStyling'] !== undefined && editorOptions['blockStyling'][presetIdentifier] !== undefined) {
if (editorOptions['blockStyling'] !== undefined && editorOptions['blockStyling'][presetIdentifier] !== undefined) {
isVisible = editorOptions['blockStyling'][presetIdentifier];
}
return isVisible;
Expand All @@ -48,7 +48,7 @@ manifest('TechDivision.CkStyles:Styles', {}, (globalRegistry, {frontendConfigura
}

//Inline Style
if(inlineStyleConfiguration) {
if (inlineStyleConfiguration) {

Object.keys(inlineStyleConfiguration.presets).forEach((presetIdentifier) => {

Expand All @@ -63,16 +63,16 @@ manifest('TechDivision.CkStyles:Styles', {}, (globalRegistry, {frontendConfigura
richtextToolbar.set(`inlineStyles_${presetIdentifier}`, {
component: InlineStyleSelector,
// Display only if the preset is activated in NodeType.yaml for this node property
isVisible: function(editorOptions, formattingUnderCursor) {
isVisible: function (editorOptions, formattingUnderCursor) {
var isVisible = false;
if(editorOptions['inlineStyling'] !== undefined && editorOptions['inlineStyling'][presetIdentifier] !== undefined) {
if (editorOptions['inlineStyling'] !== undefined && editorOptions['inlineStyling'][presetIdentifier] !== undefined) {
isVisible = editorOptions['inlineStyling'][presetIdentifier];
}
return isVisible;
},
presetIdentifier: presetIdentifier,
presetConfiguration: inlineStylePresetConfiguration
});
})
});
}
});
34 changes: 24 additions & 10 deletions Resources/Public/JavaScript/CkStyles/Plugin.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Resources/Public/JavaScript/CkStyles/Plugin.js.map

Large diffs are not rendered by default.

0 comments on commit 965f9c3

Please sign in to comment.