Skip to content
Draft
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
9 changes: 9 additions & 0 deletions package-lock.json

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

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
},
"prettier": "@wordpress/prettier-config",
"devDependencies": {
"@wordpress/eslint-plugin": "^17.8.0",
"@wordpress/icons": "^10.22.0",
"@wordpress/prettier-config": "^4.22.0",
"@wordpress/scripts": "^30.15.0",
"@wordpress/eslint-plugin": "^17.8.0",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3"
},
"dependencies": {
"tinycolor2": "^1.6.0"
}
}
8 changes: 8 additions & 0 deletions src/color-token/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* The following styles get applied inside the editor only.
*
* Replace them with your own styles or remove the file completely.
*/
.block-editor-format-toolbar__lubus-color-picker {
padding: 20px 18px;
}
180 changes: 180 additions & 0 deletions src/color-token/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/**
* External dependencies
*/
import tinycolor from 'tinycolor2';

/**
* WordPress dependencies
*/
import { brush } from '@wordpress/icons';
import { useState } from '@wordpress/element';
import { Panel, Popover } from '@wordpress/components';
import {
slice,
useAnchorRef,
applyFormat,
removeFormat,
getTextContent,
registerFormatType,
} from '@wordpress/rich-text';
import {
ColorPalette,
RichTextToolbarButton,
__unstableRichTextInputEvent,
} from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import './editor.scss';
import './style.scss';

const name = 'lubus/color';
const title = 'Color';

function InlineUI( {
value,
onChange,
onClose,
activeAttributes,
contentRef,
} ) {
const { color } = activeAttributes;

const anchorRef = useAnchorRef( {
ref: contentRef,
value,
settings: {
title,
tagName: 'span',
className: 'lubus-color-token',
},
} );

function onSetColor( newColor ) {
const colorObj = tinycolor( newColor );

const color = colorObj.toString();
const border = colorObj.darken( 20 ).toString();

if ( newColor ) {
onChange(
applyFormat( value, {
type: name,
attributes: {
style: `--lubus-color: ${ color }; --lubus-border-color: ${ border }`,
color,
border,
theme: 'minimal',
},
} )
);
} else {
onChange( removeFormat( value, name ) );
onClose(); // Close the InlineUI
}
}

return (
<Popover
position="bottom center"
anchorRef={ anchorRef }
className="block-editor-format-toolbar__lubus-color-popover"
onClose={ onClose }
>
<Panel className="block-editor-format-toolbar__lubus-color-picker">
<ColorPalette value={ color } onChange={ onSetColor } />
</Panel>
</Popover>
);
}

/**
* Format edit
*/
function EditColor( props ) {
const { value, onChange, onFocus, isActive, activeAttributes, contentRef } =
props;

const [ isSettingOpen, setIsSettingOpen ] = useState( false );

function openSettings() {
setIsSettingOpen( true );
}

function closeSettings() {
setIsSettingOpen( false );
}

function onToggle() {
const colorInput = getTextContent( slice( value ) );
const colorObj = tinycolor( colorInput );

if ( colorObj.isValid() ) {
const color = colorObj.toString();
const border = colorObj.darken( 20 ).toString();

onChange(
applyFormat( value, {
type: name,
attributes: {
style: `--lubus-color: ${ color }; --lubus-border-color: ${ border }`,
color,
border,
theme: 'minimal',
},
} )
);
} else {
openSettings();
}
}

function onClick() {
onToggle();
onFocus();
}

return (
<>
<RichTextToolbarButton
icon={ brush }
title={ title }
onClick={ () =>
!! activeAttributes.color ? openSettings() : onClick()
}
isActive={ isActive }
/>
<__unstableRichTextInputEvent
inputType="formatBold"
onInput={ onToggle }
/>

{ isSettingOpen && (
<InlineUI
value={ value }
onChange={ onChange }
onClose={ closeSettings }
activeAttributes={ activeAttributes }
contentRef={ contentRef }
/>
) }
</>
);
}

/**
* Register Richtext Color Format.
*/
registerFormatType( name, {
title,
tagName: 'span',
className: 'lubus-color-token',
edit: EditColor,
attributes: {
style: 'style',
color: 'data-color',
border: 'data-border',
theme: 'data-theme',
},
} );
21 changes: 21 additions & 0 deletions src/color-token/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* The following styles get applied both on the front of your site
* and in the editor.
*
* Replace them with your own styles or remove the file completely.
*/
.lubus-color-token {
display: inline-block;

&::before {
content: "";
background-color: var(--lubus-color);
border: 1px solid var(--lubus-border-color);
border-radius: 4px;
margin-right: 6px;
padding: 8px;
display: inherit;
position: relative;
top: 2px;
}
}
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
*/
import './marker';
import './infotip';
import './color-token';
import './font-size';
import './clear-formats';