From 4bdf8030d7a4d39d3a48b56ed6c8cddc311b3ff7 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 17 May 2021 07:03:56 +0300 Subject: [PATCH 1/5] Add a clear button to the box size widget --- src/Widgets/Size.jsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Widgets/Size.jsx b/src/Widgets/Size.jsx index 1d5a6b2..24a2e1a 100644 --- a/src/Widgets/Size.jsx +++ b/src/Widgets/Size.jsx @@ -6,8 +6,10 @@ import React from 'react'; -import { FormFieldWrapper } from '@plone/volto/components'; +import { FormFieldWrapper, Icon } from '@plone/volto/components'; import ImageSizeWidget from '@plone/volto/components/manage/Blocks/Image/ImageSizeWidget'; +import { Button } from 'semantic-ui-react'; +import clearSVG from '@plone/volto/icons/clear.svg'; // TODO: copy the styles from Volto's stylesheet @@ -21,6 +23,18 @@ const SizeWidget = (props) => { data={{ size: value }} block={id} /> + + + ); From 3b8ed26a82c31ff430301adceea1174e92464a77 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 24 May 2021 16:41:34 +0300 Subject: [PATCH 2/5] Add hidden toggle --- src/StyleWrapper/StyleWrapperView.jsx | 19 ++++++++++++++++++- src/StyleWrapper/schema.js | 7 ++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/StyleWrapper/StyleWrapperView.jsx b/src/StyleWrapper/StyleWrapperView.jsx index 26acd3a..f41fab1 100644 --- a/src/StyleWrapper/StyleWrapperView.jsx +++ b/src/StyleWrapper/StyleWrapperView.jsx @@ -4,12 +4,27 @@ import cx from 'classnames'; import config from '@plone/volto/registry'; import { withCachedImages } from '@eeacms/volto-block-style/hocs'; +const getLineHeight = (fontSize) => { + switch (fontSize) { + case 'large': + return '110%'; + case 'x-large': + return '130%'; + default: + return; + } +}; + export function getInlineStyles(data, props = {}) { + // console.log('props', props); return { + ...(data.hidden && props.mode !== 'edit' ? { display: 'none' } : {}), ...(data.backgroundColor ? { backgroundColor: data.backgroundColor } : {}), ...(data.textColor ? { color: data.textColor } : {}), ...(data.textAlign ? { textAlign: data.textAlign } : {}), - ...(data.fontSize ? { fontSize: data.fontSize } : {}), + ...(data.fontSize + ? { fontSize: data.fontSize, lineHeight: getLineHeight(data.fontSize) } + : {}), ...(data.isScreenHeight && props.screen.screenHeight ? { minHeight: ( @@ -36,6 +51,7 @@ const StyleWrapperView = (props) => { customId, isDropCap, isScreenHeight, + hidden = false, } = styleData; const containerType = data['@type']; const backgroundImage = styleData.backgroundImage; @@ -51,6 +67,7 @@ const StyleWrapperView = (props) => { size || customClass || isDropCap || + hidden || customId; const attrs = { diff --git a/src/StyleWrapper/schema.js b/src/StyleWrapper/schema.js index 15749ce..07452cf 100644 --- a/src/StyleWrapper/schema.js +++ b/src/StyleWrapper/schema.js @@ -11,7 +11,7 @@ export const StyleSchema = () => ({ { id: 'standard', title: 'Standard', - fields: ['textAlign', 'fontSize', 'align', 'size', 'isDropCap'], + fields: ['textAlign', 'fontSize', 'align', 'size', 'isDropCap', 'hidden'], }, { id: 'advanced', @@ -91,6 +91,11 @@ export const StyleSchema = () => ({ description: 'First letter is styled as a drop cop', type: 'boolean', }, + hidden: { + title: 'Hidden', + description: 'Hide this block', + type: 'boolean', + }, }, required: [], }); From 2adffd58a99af59bb42d72c54f2a05be3b9b2ea1 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Thu, 29 Jul 2021 15:36:39 +0300 Subject: [PATCH 3/5] Separate block wrapping; don't apply multiple times --- src/index.js | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/index.js b/src/index.js index a0108ae..a25d56f 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,40 @@ import SimpleColorPicker from './Widgets/SimpleColorPicker'; import './styles.less'; +/** + * Given a block's config object, it wrapps the view and edit in style wrappers + */ +export const applyStyleWrapperToBlock = (blockConfig) => { + const BaseEditComponent = blockConfig.edit; + let EditComponent = BaseEditComponent; + if (!EditComponent._styleWrapped) { + EditComponent = (props) => ( + + + + ); + EditComponent.displayName = ``; + EditComponent._styleWrapped = true; + } + + const BaseViewComponent = blockConfig.view; + let ViewComponent = BaseViewComponent; + if (ViewComponent._styleWrapped) { + ViewComponent = (props) => ( + + + + ); + ViewComponent.displayName = ``; + ViewComponent._styleWrapped = true; + } + return { + ...blockConfig, + view: ViewComponent, + edit: EditComponent, + }; +}; + const applyConfig = (config) => { const { settings } = config; const whitelist = settings.pluggableStylesBlocksWhitelist; @@ -23,21 +57,7 @@ const applyConfig = (config) => { (whitelist ? whitelist.includes(name) : true), ); okBlocks.forEach((name) => { - const EditComponent = blocksConfig[name].edit; - const ViewComponent = blocksConfig[name].view; - blocksConfig[name].edit = (props) => ( - - - - ); - blocksConfig[name].edit.displayName = 'EditBlockWithStyleWrapper'; - - blocksConfig[name].view = (props) => ( - - - - ); - blocksConfig[name].view.displayName = 'ViewBlockWithStyleWrapper'; + blocksConfig[name] = applyStyleWrapperToBlock(blocksConfig[name]); }); config.widgets.widget.style_select = StyleSelectWidget; From 15ebf8925e1ea099b759a47da6e567a0a79c9621 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Thu, 29 Jul 2021 16:31:58 +0300 Subject: [PATCH 4/5] Add extra controls --- src/StyleWrapper/StyleWrapperView.jsx | 15 + src/StyleWrapper/schema.js | 31 ++ src/Widgets/Slider.jsx | 458 ++++++++++++++++++++++++++ src/Widgets/range.css.js | 174 ++++++++++ src/index.js | 2 + 5 files changed, 680 insertions(+) create mode 100644 src/Widgets/Slider.jsx create mode 100644 src/Widgets/range.css.js diff --git a/src/StyleWrapper/StyleWrapperView.jsx b/src/StyleWrapper/StyleWrapperView.jsx index 93bdd42..d60109b 100644 --- a/src/StyleWrapper/StyleWrapperView.jsx +++ b/src/StyleWrapper/StyleWrapperView.jsx @@ -34,6 +34,21 @@ export function getInlineStyles(data, props = {}) { ).toPixel(), } : {}), + ...(data.shadowDepth && + { + // TODO: calculate proper shadow CSS + // shadowColor: data.shadowColor || '#000', + // shadowOffset: { + // width: 0, + // height: data.shadowDepth, + // }, + // shadowOpacity: (data.shadowDepth * 100) / 24 / 100, + // shadowRadius: 1 + (data.shadowDepth * 100) / 16, + // elevation: data.shadowDepth, + }), + ...(data.borderRadius && { + borderRadius: data.borderRadius, + }), // fill in more }; } diff --git a/src/StyleWrapper/schema.js b/src/StyleWrapper/schema.js index 07452cf..5fce8d2 100644 --- a/src/StyleWrapper/schema.js +++ b/src/StyleWrapper/schema.js @@ -13,6 +13,11 @@ export const StyleSchema = () => ({ title: 'Standard', fields: ['textAlign', 'fontSize', 'align', 'size', 'isDropCap', 'hidden'], }, + { + id: 'decorations', + title: 'Decorations', + fields: ['shadowDepth', 'shadowColor', 'borderRadius'], + }, { id: 'advanced', title: 'Advanced', @@ -96,6 +101,32 @@ export const StyleSchema = () => ({ description: 'Hide this block', type: 'boolean', }, + shadowDepth: { + widget: 'slider', + title: 'Shadow depth', + settings: { + min: 0, + max: 24, + step: 1, + start: 0, + }, + }, + shadowColor: { + title: 'Shadow color', + type: 'color', + widget: 'style_simple_color', + available_colors: config.settings.available_colors, + }, + borderRadius: { + widget: 'slider', + title: 'Rounded Corner', + settings: { + min: 0, + max: 24, + step: 1, + start: 0, + }, + }, }, required: [], }); diff --git a/src/Widgets/Slider.jsx b/src/Widgets/Slider.jsx new file mode 100644 index 0000000..df20c56 --- /dev/null +++ b/src/Widgets/Slider.jsx @@ -0,0 +1,458 @@ +// Copied from MIT-licensed https://github.com/iozbeyli/react-semantic-ui-range + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; + +import ReactDOM from 'react-dom'; +import { FormFieldWrapper } from '@plone/volto/components'; +// import { withParentSize } from '@visx/responsive'; + +import styles from './range.css.js'; + +export class Slider extends Component { + constructor(props) { + super(props); + let value = this.props.value + ? this.props.value + : props.multiple + ? [...props.settings.start] + : props.settings.start; + this.state = { + value: value, + position: props.multiple ? [] : 0, + numberOfKnobs: props.multiple ? value.length : 1, + offset: 10, + precision: 0, + mouseDown: false, + }; + this.determinePosition = this.determinePosition.bind(this); + this.rangeMouseUp = this.rangeMouseUp.bind(this); + this.refresh = this.refresh.bind(this); + } + + componentDidMount() { + this.determinePrecision(); + const value = this.props.value ? this.props.value : this.state.value; + this.setValuesAndPositions(value, false); + window.addEventListener('mouseup', this.rangeMouseUp); + window.addEventListener('resize', this.refresh); + } + + refresh() { + const value = this.props.value ? this.props.value : this.state.value; + this.setValuesAndPositions(value, false); + } + + UNSAFE_componentWillReceiveProps(nextProps) { + const isValueUnset = + nextProps.value === null || nextProps.value === undefined; + + if (!isValueUnset && nextProps.value !== this.state.value) { + if (this.props.multiple) { + const different = this.isDifferentArrays( + nextProps.value, + this.state.value, + ); + if (different) { + this.setValuesAndPositions(nextProps.value, true); + } + } else { + this.setValuesAndPositions(nextProps.value, true); + } + } + } + + componentWillUnmount() { + this.inner = undefined; + this.innerLeft = undefined; + this.innerRight = undefined; + window.removeEventListener('mouseup', this.rangeMouseUp); + window.removeEventListener('resize', this.refresh); + } + + setValuesAndPositions(value, triggeredByUser) { + if (this.props.multiple) { + const positions = [...this.state.position]; + value.forEach((val, i) => { + this.setValue(val, triggeredByUser, i); + positions[i] = this.determinePosition(val); + }); + this.setState({ + position: positions, + }); + } else { + this.setValue(value, triggeredByUser); + this.setState({ + position: this.determinePosition(value), + }); + } + } + + isDifferentArrays(a, b) { + let different = false; + a.some((val, i) => { + if (val !== b[i]) { + different = true; + return true; + } + return false; + }); + return different; + } + + determinePosition(value) { + const trackLeft = ReactDOM.findDOMNode(this.track).getBoundingClientRect() + .left; + const innerLeft = ReactDOM.findDOMNode(this.inner).getBoundingClientRect() + .left; + const ratio = + (value - this.props.settings.min) / + (this.props.settings.max - this.props.settings.min); + const position = + Math.round(ratio * this.inner.offsetWidth) + + trackLeft - + innerLeft - + this.state.offset; + return position; + } + + determinePrecision() { + let split = String(this.props.settings.step).split('.'); + let decimalPlaces; + if (split.length === 2) { + decimalPlaces = split[1].length; + } else { + decimalPlaces = 0; + } + this.setState({ + precision: Math.pow(10, decimalPlaces), + }); + } + + determineValue(startPos, endPos, currentPos) { + let ratio = (currentPos - startPos) / (endPos - startPos); + let range = this.props.settings.max - this.props.settings.min; + let difference = + Math.round((ratio * range) / this.props.settings.step) * + this.props.settings.step; + // Use precision to avoid ugly Javascript floating point rounding issues + // (like 35 * .01 = 0.35000000000000003) + difference = + Math.round(difference * this.state.precision) / this.state.precision; + return difference + this.props.settings.min; + } + + determineKnob(position, value) { + if (!this.props.multiple) { + return 0; + } + if (position <= this.state.position[0]) { + return 0; + } + if (position >= this.state.position[this.state.numberOfKnobs - 1]) { + return this.state.numberOfKnobs - 1; + } + let index = 0; + + for (let i = 0; i < this.state.numberOfKnobs - 1; i++) { + if ( + position >= this.state.position[i] && + position < this.state.position[i + 1] + ) { + const distanceToSecond = Math.abs( + position - this.state.position[i + 1], + ); + const distanceToFirst = Math.abs(position - this.state.position[i]); + if (distanceToSecond <= distanceToFirst) { + return i + 1; + } else { + return i; + } + } + } + return index; + } + + setValue(value, triggeredByUser, knobIndex) { + if (typeof triggeredByUser === 'undefined') { + triggeredByUser = true; + } + const currentValue = this.props.multiple + ? this.state.value[knobIndex] + : this.state.value; + if (currentValue !== value) { + let newValue = []; + if (this.props.multiple) { + newValue = [...this.state.value]; + newValue[knobIndex] = value; + this.setState({ + value: newValue, + }); + } else { + newValue = value; + this.setState({ + value: value, + }); + } + if (this.props.settings.onChange) { + this.props.settings.onChange(newValue, { + triggeredByUser: triggeredByUser, + }); + } + } + } + + setValuePosition(value, triggeredByUser, knobIndex) { + if (this.props.multiple) { + const positions = [...this.state.position]; + positions[knobIndex] = this.determinePosition(value); + this.setValue(value, triggeredByUser, knobIndex); + this.setState({ + position: positions, + }); + } else { + this.setValue(value, triggeredByUser); + this.setState({ + position: this.determinePosition(value), + }); + } + } + + setPosition(position, knobIndex) { + if (this.props.multiple) { + const newPosition = [...this.state.position]; + newPosition[knobIndex] = position; + this.setState({ + position: newPosition, + }); + } else { + this.setState({ + position: position, + }); + } + } + + rangeMouseDown(isTouch, e) { + e.stopPropagation(); + if (!this.props.disabled) { + if (!isTouch) { + e.preventDefault(); + } + + this.setState({ + mouseDown: true, + }); + let innerBoundingClientRect = ReactDOM.findDOMNode( + this.inner, + ).getBoundingClientRect(); + this.innerLeft = innerBoundingClientRect.left; + this.innerRight = this.innerLeft + this.inner.offsetWidth; + this.rangeMouse(isTouch, e); + } + } + + rangeMouse(isTouch, e) { + let pageX; + let event = isTouch ? e.touches[0] : e; + if (event.pageX) { + pageX = event.pageX; + } else { + console.log('PageX undefined'); + } + let value = this.determineValue(this.innerLeft, this.innerRight, pageX); + if (pageX >= this.innerLeft && pageX <= this.innerRight) { + if ( + value >= this.props.settings.min && + value <= this.props.settings.max + ) { + const position = pageX - this.innerLeft - this.state.offset; + const knobIndex = this.props.multiple + ? this.determineKnob(position) + : undefined; + if (this.props.discrete) { + this.setValuePosition(value, false, knobIndex); + } else { + this.setPosition(position, knobIndex); + this.setValue(value, undefined, knobIndex); + } + } + } + } + + rangeMouseMove(isTouch, e) { + e.stopPropagation(); + if (!isTouch) { + e.preventDefault(); + } + if (this.state.mouseDown) { + this.rangeMouse(isTouch, e); + } + } + + rangeMouseUp() { + this.setState({ + mouseDown: false, + }); + } + + render() { + return ( +
+
this.rangeMouseDown(false, event)} + onMouseMove={(event) => this.rangeMouseMove(false, event)} + onMouseUp={(event) => this.rangeMouseUp(false, event)} + onTouchEnd={(event) => this.rangeMouseUp(true, event)} + onTouchMove={(event) => this.rangeMouseMove(true, event)} + onTouchStart={(event) => this.rangeMouseDown(true, event)} + style={{ + ...styles.range, + ...(this.props.disabled ? styles.disabled : {}), + ...(this.props.style ? this.props.style : {}), + }} + > +
{ + this.inner = inner; + }} + style={{ + ...styles.inner, + ...(this.props.style + ? this.props.style.inner + ? this.props.style.inner + : {} + : {}), + }} + > +
{ + this.track = track; + }} + style={{ + ...styles.track, + ...(this.props.inverted ? styles.invertedTrack : {}), + ...(this.props.style + ? this.props.style.track + ? this.props.style.track + : {} + : {}), + }} + /> +
{ + this.trackFill = trackFill; + }} + style={{ + ...styles.trackFill, + ...(this.props.inverted ? styles.invertedTrackFill : {}), + ...styles[ + this.props.inverted + ? 'inverted-' + this.props.color + : this.props.color + ], + ...(this.props.style + ? this.props.style.trackFill + ? this.props.style.trackFill + : {} + : {}), + ...(this.props.disabled ? styles.disabledTrackFill : {}), + ...(this.props.style + ? this.props.style.disabledTrackFill + ? this.props.style.disabledTrackFill + : {} + : {}), + ...{ width: this.state.position + this.state.offset + 'px' }, + ...(this.props.multiple && this.state.position.length > 0 + ? { + left: this.state.position[0], + width: + this.state.position[this.state.numberOfKnobs - 1] - + this.state.position[0], + } + : {}), + }} + /> + + {this.props.multiple ? ( + this.state.position.map((pos, i) => ( +
+ )) + ) : ( +
+ )} +
+
+
+ ); + } +} + +Slider.defaultProps = { + color: 'red', + settings: { + min: 0, + max: 10, + step: 1, + start: 0, + }, +}; + +Slider.propTypes = { + color: PropTypes.string, + disabled: PropTypes.bool, + discrete: PropTypes.bool, + inverted: PropTypes.bool, + multiple: PropTypes.bool, + settings: PropTypes.shape({ + min: PropTypes.number, + max: PropTypes.number, + step: PropTypes.number, + start: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.arrayOf(PropTypes.number), + ]), + onChange: PropTypes.func, + }), +}; + +const SliderWidget = (props) => { + const { id, onChange, settings = {}, ...rest } = props; + return ( + + onChange(id, value) }} + /> + + ); +}; + +export default SliderWidget; diff --git a/src/Widgets/range.css.js b/src/Widgets/range.css.js new file mode 100644 index 0000000..37bac52 --- /dev/null +++ b/src/Widgets/range.css.js @@ -0,0 +1,174 @@ +const styles = { + range: { + cursor: 'pointer', + width: '100%', + height: '20px', + }, + inner: { + margin: '0 10px 0 10px', + height: '20px', + position: 'relative', + }, + /* + .ui.range .inner:hover { + cursor: pointer; + }*/ + track: { + position: 'absolute', + width: '100%', + height: '4px', + borderRadius: '4px', + top: '9px', + left: '0', + backgroundColor: 'rgba(0,0,0,.05)', + }, + invertedTrack: { + backgroundColor: 'rgba(255,255,255,.08)', + }, + trackFill: { + position: 'absolute', + width: '0', + height: '4px', + borderRadius: '4px', + top: '9px', + left: '0', + backgroundColor: '#1b1c1d', + }, + invertedTrackFill: { + backgroundColor: '#545454', + }, + knob: { + position: 'absolute', + top: '0px', + left: '0', + height: '20px', + width: '20px', + background: '#fff linear-gradient(transparent, rgba(0, 0, 0, 0.5))', + background: '#fff -webkit-linear-gradient(transparent, rgba(0, 0, 0, 0.5))', + background: '#fff -o-linear-gradient(transparent, rgba(0, 0, 0, 0.5))', + background: '#fff -moz-linear-gradient(transparent, rgba(0, 0, 0, 0.5))', + borderRadius: '6px', + backgroundColor: '#205c90', + boxShadow: + '0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset', + }, + red: { + backgroundColor: '#DB2828', + }, + 'inverted-red': { + backgroundColor: '#FF695E', + }, + /* Orange */ + orange: { + backgroundColor: '#F2711C', + }, + 'inverted-orange': { + backgroundColor: '#FF851B', + }, + /* Yellow */ + yellow: { + backgroundColor: '#FBBD08', + }, + 'inverted-yellow': { + backgroundColor: '#FFE21F', + }, + /* Olive */ + olive: { + backgroundColor: '#B5CC18', + }, + 'inverted-olive': { + backgroundColor: '#D9E778', + }, + /* Green */ + green: { + backgroundColor: '#21BA45', + }, + 'inverted-green': { + backgroundColor: '#2ECC40', + }, + /* Teal */ + teal: { + backgroundColor: '#00B5AD', + }, + 'inverted-teal': { + backgroundColor: '#6DFFFF', + }, + /* Blue */ + blue: { + backgroundColor: '#2185D0', + }, + 'inverted-blue': { + backgroundColor: '#54C8FF', + }, + /* Violet */ + violet: { + backgroundColor: '#6435C9', + }, + 'inverted-violet': { + backgroundColor: '#A291FB', + }, + /* Purple */ + purple: { + backgroundColor: '#A333C8', + }, + 'inverted-purple': { + backgroundColor: '#DC73FF', + }, + /* Pink */ + pink: { + backgroundColor: '#E03997', + }, + 'inverted-pink': { + backgroundColor: '#FF8EDF', + }, + /* Brown */ + brown: { + backgroundColor: '#A5673F', + }, + 'inverted-brown': { + backgroundColor: '#D67C1C', + }, + /* Grey */ + grey: { + backgroundColor: '#767676', + }, + 'inverted-grey': { + backgroundColor: '#DCDDDE', + }, + /* Black */ + black: { + backgroundColor: '#1b1c1d', + }, + 'inverted-black': { + backgroundColor: '#545454', + }, + /*-------------- + Disabled +---------------*/ + disabled: { + cursor: 'not-allowed', + opacity: '.5', + }, + + /*-------------- + Disabled +---------------*/ + + disabledTrackFill: { + backgroundColor: '#ccc', + }, + + /*-------------- + Invalid-Input +---------------*/ + invalidInputTrack: { + cursor: 'not-allowed', + opacity: '.3', + background: '#ff0000', + }, + invalidInputTrackFill: { + opacity: '.0', + }, +}; + +export default styles; diff --git a/src/index.js b/src/index.js index a25d56f..f2320d5 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import { import StyleSelectWidget from './Widgets/StyleSelect'; import AlignWidget from './Widgets/Align'; import TextAlignWidget from './Widgets/TextAlign'; +import SliderWidget from './Widgets/Slider'; import SizeWidget from './Widgets/Size'; import SimpleColorPicker from './Widgets/SimpleColorPicker'; @@ -65,6 +66,7 @@ const applyConfig = (config) => { config.widgets.widget.style_text_align = TextAlignWidget; // avoid conflict for now config.widgets.widget.style_size = SizeWidget; // avoid conflict for now config.widgets.widget.style_simple_color = SimpleColorPicker; + config.widgets.widget.slider = SliderWidget; // types of blocks that natively integrate with the volto-block-style and // allow passing the style as a prop; From 177db51146d7bc25fbda365abadefb76260d992b Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Thu, 29 Jul 2021 16:29:02 +0300 Subject: [PATCH 5/5] Improve box shadow calculation --- src/StyleWrapper/StyleWrapperView.jsx | 17 +++++------------ src/index.js | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/StyleWrapper/StyleWrapperView.jsx b/src/StyleWrapper/StyleWrapperView.jsx index d60109b..3f1dab5 100644 --- a/src/StyleWrapper/StyleWrapperView.jsx +++ b/src/StyleWrapper/StyleWrapperView.jsx @@ -34,18 +34,11 @@ export function getInlineStyles(data, props = {}) { ).toPixel(), } : {}), - ...(data.shadowDepth && - { - // TODO: calculate proper shadow CSS - // shadowColor: data.shadowColor || '#000', - // shadowOffset: { - // width: 0, - // height: data.shadowDepth, - // }, - // shadowOpacity: (data.shadowDepth * 100) / 24 / 100, - // shadowRadius: 1 + (data.shadowDepth * 100) / 16, - // elevation: data.shadowDepth, - }), + ...(data.shadowDepth && { + boxShadow: `0px 0px ${data.shadowDepth}px rgba(0, 0, 0, ${ + (data.shadowDepth * 100) / 0.24 + })`, + }), ...(data.borderRadius && { borderRadius: data.borderRadius, }), diff --git a/src/index.js b/src/index.js index f2320d5..10e7b45 100644 --- a/src/index.js +++ b/src/index.js @@ -30,7 +30,7 @@ export const applyStyleWrapperToBlock = (blockConfig) => { const BaseViewComponent = blockConfig.view; let ViewComponent = BaseViewComponent; - if (ViewComponent._styleWrapped) { + if (!ViewComponent._styleWrapped) { ViewComponent = (props) => (