Added PreviewDesign functionality - for perfect pixel test.
This commit is contained in:
1 parent
dfcd9681bc
commit
44dc99c641
10 files changed
+421
-13
No files matched your search
Vendored
+214
-6
@@ -11480,12 +11480,206 @@ const SidebarDataOptionsStyle = qe.div`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function DesignPreview(props = {}) {
|
const PreviewButtonStyle = qe.button`
|
||||||
return /*#__PURE__*/React.createElement("span", {
|
--size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 0;
|
||||||
|
background-image: url("/scripts/dist/toolbar/images/icon-preview.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: calc(var(--size) - 0.15rem);
|
||||||
|
background-position: center center;
|
||||||
|
background-color: initial;
|
||||||
|
font-size: 1px;
|
||||||
|
color: rgba(0, 0, 0, 0);
|
||||||
|
line-height: 1;
|
||||||
|
display: block;
|
||||||
|
width: var(--size);
|
||||||
|
height: var(--size);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-image: url("/scripts/dist/toolbar/images/icon-preview-disabled.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.25;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const PreviewStyle = qe.div`
|
||||||
|
position: fixed;
|
||||||
|
top: 3rem;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
align-items: baseline;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
cursor: move;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
qe.div`
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: top;
|
||||||
|
cursor: move;
|
||||||
|
`;
|
||||||
|
|
||||||
|
let startDragPosition = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
function DesignPreview({
|
||||||
|
previewOption = {
|
||||||
|
widthDimension: 0
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
const reference = /*#__PURE__*/react.exports.createRef();
|
||||||
|
const [active, setActive] = react.exports.useState(false);
|
||||||
|
const [position, setPosition] = react.exports.useState({
|
||||||
|
x: getInitialXPosition(previewOption),
|
||||||
|
y: 0
|
||||||
|
});
|
||||||
|
const [opacity, setOpacity] = react.exports.useState(100);
|
||||||
|
const keyDownHandler = react.exports.useCallback(function (e) {
|
||||||
|
const step = e.shiftKey ? 10 : 1;
|
||||||
|
|
||||||
|
if (e.key === 'ArrowUp') {
|
||||||
|
updatePosition({
|
||||||
|
y: step * -1
|
||||||
|
}, true);
|
||||||
|
} else if (e.key === 'ArrowDown') {
|
||||||
|
updatePosition({
|
||||||
|
y: step
|
||||||
|
}, true);
|
||||||
|
} else if (e.key === 'ArrowLeft') {
|
||||||
|
updatePosition({
|
||||||
|
x: step * -1
|
||||||
|
}, true);
|
||||||
|
} else if (e.key === 'ArrowRight') {
|
||||||
|
updatePosition({
|
||||||
|
x: step
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
}, [position]);
|
||||||
|
react.exports.useEffect(() => {
|
||||||
|
document.addEventListener('keydown', keyDownHandler);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('keydown', keyDownHandler);
|
||||||
|
};
|
||||||
|
}, [keyDownHandler]);
|
||||||
|
|
||||||
|
if (!previewOption) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const disabled = !previewOption.url;
|
||||||
|
const classNames = [];
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
classNames.push('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disabled) {
|
||||||
|
classNames.push('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOpacityChange = e => {
|
||||||
|
setOpacity(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(PreviewButtonStyle, {
|
||||||
|
onClick: () => toggle(),
|
||||||
|
className: classNames.join(' '),
|
||||||
|
disabled: disabled
|
||||||
|
}), active && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("input", {
|
||||||
|
type: "range",
|
||||||
|
value: opacity,
|
||||||
|
min: "0",
|
||||||
|
max: "100",
|
||||||
|
onChange: handleOpacityChange
|
||||||
|
}), /*#__PURE__*/React.createElement(PreviewStyle, {
|
||||||
|
onMouseUp: e => stop(),
|
||||||
style: {
|
style: {
|
||||||
color: '#999'
|
opacity: opacity / 100
|
||||||
|
}
|
||||||
|
}, /*#__PURE__*/React.createElement("img", {
|
||||||
|
src: previewOption.url,
|
||||||
|
alt: "",
|
||||||
|
ref: reference,
|
||||||
|
onMouseDown: e => start(e),
|
||||||
|
draggable: false,
|
||||||
|
style: {
|
||||||
|
top: position.y + 'px',
|
||||||
|
left: position.x + 'px'
|
||||||
|
}
|
||||||
|
}))));
|
||||||
|
|
||||||
|
function start(e) {
|
||||||
|
startDragPosition.x = e.clientX;
|
||||||
|
startDragPosition.y = e.clientY;
|
||||||
|
document.body.addEventListener('mousemove', handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop(e) {
|
||||||
|
const target = reference.current;
|
||||||
|
updatePosition({
|
||||||
|
x: target.offsetLeft,
|
||||||
|
y: target.offsetTop
|
||||||
|
});
|
||||||
|
document.body.removeEventListener('mousemove', handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handler(e) {
|
||||||
|
const target = reference.current;
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
const updatedPosition = {
|
||||||
|
x: target.offsetLeft - (startDragPosition.x - e.clientX),
|
||||||
|
y: target.offsetTop - (startDragPosition.y - e.clientY)
|
||||||
|
};
|
||||||
|
target.style.left = updatedPosition.x + 'px';
|
||||||
|
target.style.top = updatedPosition.y + 'px';
|
||||||
|
startDragPosition.x = e.clientX;
|
||||||
|
startDragPosition.y = e.clientY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
setActive(!active);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePosition({
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
}, relative = false) {
|
||||||
|
x = typeof x === 'undefined' ? position.x : relative ? position.x + x : x;
|
||||||
|
y = typeof y === 'undefined' ? position.y : relative ? position.y + y : y;
|
||||||
|
setPosition({
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInitialXPosition(previewOption) {
|
||||||
|
if (!previewOption) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.innerWidth / 2 - previewOption.widthDimension / 2;
|
||||||
}
|
}
|
||||||
}, "Preview");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function DataOptions(props = {}) {
|
function DataOptions(props = {}) {
|
||||||
@@ -11493,7 +11687,8 @@ function DataOptions(props = {}) {
|
|||||||
const initialState = {
|
const initialState = {
|
||||||
dataName: 'default',
|
dataName: 'default',
|
||||||
data: {},
|
data: {},
|
||||||
dataOptions: []
|
dataOptions: [],
|
||||||
|
designPreview: []
|
||||||
};
|
};
|
||||||
const [state, setState] = react.exports.useState(initialState);
|
const [state, setState] = react.exports.useState(initialState);
|
||||||
|
|
||||||
@@ -11521,6 +11716,7 @@ function DataOptions(props = {}) {
|
|||||||
|
|
||||||
const handleBlur = async e => (await isClickOutside(e)) ? closeSidebar() : null;
|
const handleBlur = async e => (await isClickOutside(e)) ? closeSidebar() : null;
|
||||||
|
|
||||||
|
const previewOption = getDesignPreviewImage(state.dataName, state.designPreview);
|
||||||
return /*#__PURE__*/React.createElement("div", {
|
return /*#__PURE__*/React.createElement("div", {
|
||||||
style: {
|
style: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -11530,7 +11726,9 @@ function DataOptions(props = {}) {
|
|||||||
}, /*#__PURE__*/React.createElement(SidebarButtonToggleStyle, {
|
}, /*#__PURE__*/React.createElement(SidebarButtonToggleStyle, {
|
||||||
onClick: () => openSidebar(),
|
onClick: () => openSidebar(),
|
||||||
title: "Open a Sidebar with Data Options"
|
title: "Open a Sidebar with Data Options"
|
||||||
}), /*#__PURE__*/React.createElement(DesignPreview, null), /*#__PURE__*/React.createElement(SidebarStyle, {
|
}), /*#__PURE__*/React.createElement(DesignPreview, {
|
||||||
|
previewOption: previewOption
|
||||||
|
}), /*#__PURE__*/React.createElement(SidebarStyle, {
|
||||||
className: sidebarOpen ? 'active sidebar-active' : '',
|
className: sidebarOpen ? 'active sidebar-active' : '',
|
||||||
tabIndex: "0",
|
tabIndex: "0",
|
||||||
onBlur: handleBlur
|
onBlur: handleBlur
|
||||||
@@ -11577,6 +11775,16 @@ function DataOptions(props = {}) {
|
|||||||
const response = await fetch(`/data?${queryParameters}`);
|
const response = await fetch(`/data?${queryParameters}`);
|
||||||
return await response.json();
|
return await response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDesignPreviewImage(currentDataName, designPreviewOptions = []) {
|
||||||
|
const dataOptions = designPreviewOptions.filter(item => {
|
||||||
|
return item.dataSource === currentDataName;
|
||||||
|
});
|
||||||
|
dataOptions.sort((a, b) => b.widthDimension - a.widthDimension);
|
||||||
|
return dataOptions.find(item => {
|
||||||
|
return item.widthDimension === 414;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupDataOptions(rootAttributes) {
|
function setupDataOptions(rootAttributes) {
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"index.min.js","sources":["../../../node_modules/react/cjs/react.production.min.js","../../../node_modules/react/index.js","../../../node_modules/scheduler/cjs/scheduler.production.min.js","../../../node_modules/scheduler/index.js","../../../node_modules/react-dom/cjs/react-dom.production.min.js","../../../node_modules/react-dom/index.js","../../../node_modules/react-dom/client.js","../../../node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/react-is/index.js","../../../node_modules/@emotion/stylis/dist/stylis.esm.js","../../../node_modules/@emotion/unitless/dist/unitless.esm.js","../../../node_modules/@emotion/memoize/dist/emotion-memoize.esm.js","../../../node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/index.js","../../../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js","../toolbar/responsive.style.js","../toolbar/responsive-button/responsive-button.style.js","../toolbar/responsive-button/ResponsiveButton.jsx","../toolbar/responsive.jsx","../toolbar/publish.jsx","../toolbar/data-options/data-options.style.js","../toolbar/data-options/DesignPreview.jsx","../toolbar/data-options/DataOptions.jsx","../index.js"],"sourcesContent":["/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var l=Symbol.for(\"react.element\"),n=Symbol.for(\"react.portal\"),p=Symbol.for(\"react.fragment\"),q=Symbol.for(\"react.strict_mode\"),r=Symbol.for(\"react.profiler\"),t=Symbol.for(\"react.provider\"),u=Symbol.for(\"react.context\"),v=Symbol.for(\"react.forward_ref\"),w=Symbol.for(\"react.suspense\"),x=Symbol.for(\"react.memo\"),y=Symbol.for(\"react.lazy\"),z=Symbol.iterator;function A(a){if(null===a||\"object\"!==typeof a)return null;a=z&&a[z]||a[\"@@iterator\"];return\"function\"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if(\"object\"!==typeof a&&\"function\"!==typeof a&&null!=a)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,a,b,\"setState\")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,\"forceUpdate\")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=\"\"+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];c.children=f}if(a&&a.defaultProps)for(d in g=a.defaultProps,g)void 0===c[d]&&(c[d]=g[d]);return{$$typeof:l,type:a,key:k,ref:h,props:c,_owner:K.current}}\nfunction N(a,b){return{$$typeof:l,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function O(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===l}function escape(a){var b={\"=\":\"=0\",\":\":\"=2\"};return\"$\"+a.replace(/[=:]/g,function(a){return b[a]})}var P=/\\/+/g;function Q(a,b){return\"object\"===typeof a&&null!==a&&null!=a.key?escape(\"\"+a.key):b.toString(36)}\nfunction R(a,b,e,d,c){var k=typeof a;if(\"undefined\"===k||\"boolean\"===k)a=null;var h=!1;if(null===a)h=!0;else switch(k){case \"string\":case \"number\":h=!0;break;case \"object\":switch(a.$$typeof){case l:case n:h=!0}}if(h)return h=a,c=c(h),a=\"\"===d?\".\"+Q(h,0):d,I(c)?(e=\"\",null!=a&&(e=a.replace(P,\"$&/\")+\"/\"),R(c,b,e,\"\",function(a){return a})):null!=c&&(O(c)&&(c=N(c,e+(!c.key||h&&h.key===c.key?\"\":(\"\"+c.key).replace(P,\"$&/\")+\"/\")+a)),b.push(c)),1;h=0;d=\"\"===d?\".\":d+\":\";if(I(a))for(var g=0;g<a.length;g++){k=\na[g];var f=d+Q(k,g);h+=R(k,b,e,f,c)}else if(f=A(a),\"function\"===typeof f)for(a=f.call(a),g=0;!(k=a.next()).done;)k=k.value,f=d+Q(k,g++),h+=R(k,b,e,f,c);else if(\"object\"===k)throw b=String(a),Error(\"Objects are not valid as a React child (found: \"+(\"[object Object]\"===b?\"object with keys {\"+Object.keys(a).join(\", \")+\"}\":b)+\"). If you meant to render a collection of children, use an array instead.\");return h}\nfunction S(a,b,e){if(null==a)return a;var d=[],c=0;R(a,d,\"\",\"\",function(a){rLine truncated
|
{"version":3,"file":"index.min.js","sources":["../../../node_modules/react/cjs/react.production.min.js","../../../node_modules/react/index.js","../../../node_modules/scheduler/cjs/scheduler.production.min.js","../../../node_modules/scheduler/index.js","../../../node_modules/react-dom/cjs/react-dom.production.min.js","../../../node_modules/react-dom/index.js","../../../node_modules/react-dom/client.js","../../../node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/react-is/index.js","../../../node_modules/@emotion/stylis/dist/stylis.esm.js","../../../node_modules/@emotion/unitless/dist/unitless.esm.js","../../../node_modules/@emotion/memoize/dist/emotion-memoize.esm.js","../../../node_modules/@emotion/is-prop-valid/dist/emotion-is-prop-valid.esm.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/cjs/react-is.production.min.js","../../../node_modules/hoist-non-react-statics/node_modules/react-is/index.js","../../../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js","../toolbar/responsive.style.js","../toolbar/responsive-button/responsive-button.style.js","../toolbar/responsive-button/ResponsiveButton.jsx","../toolbar/responsive.jsx","../toolbar/publish.jsx","../toolbar/data-options/data-options.style.js","../toolbar/data-options/design-preview.style.js","../toolbar/data-options/DesignPreview.jsx","../toolbar/data-options/DataOptions.jsx","../index.js"],"sourcesContent":["/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var l=Symbol.for(\"react.element\"),n=Symbol.for(\"react.portal\"),p=Symbol.for(\"react.fragment\"),q=Symbol.for(\"react.strict_mode\"),r=Symbol.for(\"react.profiler\"),t=Symbol.for(\"react.provider\"),u=Symbol.for(\"react.context\"),v=Symbol.for(\"react.forward_ref\"),w=Symbol.for(\"react.suspense\"),x=Symbol.for(\"react.memo\"),y=Symbol.for(\"react.lazy\"),z=Symbol.iterator;function A(a){if(null===a||\"object\"!==typeof a)return null;a=z&&a[z]||a[\"@@iterator\"];return\"function\"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if(\"object\"!==typeof a&&\"function\"!==typeof a&&null!=a)throw Error(\"setState(...): takes an object of state variables to update or a function which returns an object of state variables.\");this.updater.enqueueSetState(this,a,b,\"setState\")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,\"forceUpdate\")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=\"\"+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];c.children=f}if(a&&a.defaultProps)for(d in g=a.defaultProps,g)void 0===c[d]&&(c[d]=g[d]);return{$$typeof:l,type:a,key:k,ref:h,props:c,_owner:K.current}}\nfunction N(a,b){return{$$typeof:l,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function O(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===l}function escape(a){var b={\"=\":\"=0\",\":\":\"=2\"};return\"$\"+a.replace(/[=:]/g,function(a){return b[a]})}var P=/\\/+/g;function Q(a,b){return\"object\"===typeof a&&null!==a&&null!=a.key?escape(\"\"+a.key):b.toString(36)}\nfunction R(a,b,e,d,c){var k=typeof a;if(\"undefined\"===k||\"boolean\"===k)a=null;var h=!1;if(null===a)h=!0;else switch(k){case \"string\":case \"number\":h=!0;break;case \"object\":switch(a.$$typeof){case l:case n:h=!0}}if(h)return h=a,c=c(h),a=\"\"===d?\".\"+Q(h,0):d,I(c)?(e=\"\",null!=a&&(e=a.replace(P,\"$&/\")+\"/\"),R(c,b,e,\"\",function(a){return a})):null!=c&&(O(c)&&(c=N(c,e+(!c.key||h&&h.key===c.key?\"\":(\"\"+c.key).replace(P,\"$&/\")+\"/\")+a)),b.push(c)),1;h=0;d=\"\"===d?\".\":d+\":\";if(I(a))for(var g=0;g<a.length;g++){k=\na[g];var f=d+Q(k,g);h+=R(k,b,e,f,c)}else if(f=A(a),\"function\"===typeof f)for(a=f.call(a),g=0;!(k=a.next()).done;)k=k.value,f=d+Q(k,g++),h+=R(k,b,e,f,c);else if(\"object\"===k)throw b=String(a),Error(\"Objects are not valid as a React child (found: \"+(\"[object Object]\"===b?\"object with keys {\"+Object.keys(a).join(\", \")+\"}\":b)+\"). If you meant to render a collection of children, use an array instead.\");return h}\nfunction S(a,b,e){if(null==a)rLine truncated
|
||||||
@@ -12,7 +12,7 @@ import {DesignPreview} from "./DesignPreview.jsx";
|
|||||||
function DataOptions(props = {}) {
|
function DataOptions(props = {}) {
|
||||||
props.rootAttributes = props.rootAttributes ?? {};
|
props.rootAttributes = props.rootAttributes ?? {};
|
||||||
|
|
||||||
const initialState = {dataName: 'default', data: {}, dataOptions: []};
|
const initialState = {dataName: 'default', data: {}, dataOptions: [], designPreview: []};
|
||||||
const [state, setState] = useState(initialState);
|
const [state, setState] = useState(initialState);
|
||||||
const updateState = (update) => setState(Object.assign({}, state, update));
|
const updateState = (update) => setState(Object.assign({}, state, update));
|
||||||
|
|
||||||
@@ -41,10 +41,12 @@ function DataOptions(props = {}) {
|
|||||||
}, [handleCloseSidebarEscEvent]);
|
}, [handleCloseSidebarEscEvent]);
|
||||||
|
|
||||||
const handleBlur = async (e) => await isClickOutside(e) ? closeSidebar() : null;
|
const handleBlur = async (e) => await isClickOutside(e) ? closeSidebar() : null;
|
||||||
|
const previewOption = getDesignPreviewImage(state.dataName, state.designPreview);
|
||||||
|
|
||||||
return <div style={{display: 'flex', gap: '1rem', alignItems: 'center'}}>
|
return <div style={{display: 'flex', gap: '1rem', alignItems: 'center'}}>
|
||||||
<SidebarButtonToggleStyle onClick={() => openSidebar()} title="Open a Sidebar with Data Options"/>
|
<SidebarButtonToggleStyle onClick={() => openSidebar()} title="Open a Sidebar with Data Options"/>
|
||||||
<DesignPreview/>
|
|
||||||
|
<DesignPreview previewOption={previewOption}/>
|
||||||
|
|
||||||
<SidebarStyle className={sidebarOpen ? 'active sidebar-active' : ''} tabIndex='0' onBlur={handleBlur}>
|
<SidebarStyle className={sidebarOpen ? 'active sidebar-active' : ''} tabIndex='0' onBlur={handleBlur}>
|
||||||
<SidebarHeaderStyle>
|
<SidebarHeaderStyle>
|
||||||
@@ -92,6 +94,18 @@ function DataOptions(props = {}) {
|
|||||||
const response = await fetch(`/data?${queryParameters}`);
|
const response = await fetch(`/data?${queryParameters}`);
|
||||||
return await response.json();
|
return await response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDesignPreviewImage(currentDataName, designPreviewOptions = []) {
|
||||||
|
const dataOptions = designPreviewOptions.filter((item) => {
|
||||||
|
return item.dataSource === currentDataName;
|
||||||
|
});
|
||||||
|
|
||||||
|
dataOptions.sort((a, b) => b.widthDimension - a.widthDimension);
|
||||||
|
|
||||||
|
return dataOptions.find((item) => {
|
||||||
|
return item.widthDimension === 414;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setupDataOptions(rootAttributes) {
|
export function setupDataOptions(rootAttributes) {
|
||||||
|
|||||||
@@ -1,5 +1,120 @@
|
|||||||
import React, {useCallback, useEffect, useState} from 'react';
|
import React, {createRef, useCallback, useEffect, useState} from 'react';
|
||||||
|
import {PreviewButtonStyle, PreviewStyle} from "./design-preview.style.js";
|
||||||
|
|
||||||
export function DesignPreview(props = {}) {
|
let startDragPosition = {x: 0, y: 0};
|
||||||
return <span style={{color: '#999'}}>Preview</span>
|
|
||||||
|
export function DesignPreview({previewOption = {widthDimension: 0}}) {
|
||||||
|
const reference = createRef();
|
||||||
|
const [active, setActive] = useState(false);
|
||||||
|
const [position, setPosition] = useState({x: getInitialXPosition(previewOption), y: 0});
|
||||||
|
const [opacity, setOpacity] = useState(100);
|
||||||
|
|
||||||
|
const keyDownHandler = useCallback(
|
||||||
|
function (e) {
|
||||||
|
const step = e.shiftKey ? 10 : 1;
|
||||||
|
if (e.key === 'ArrowUp') {
|
||||||
|
updatePosition({y: step * -1}, true)
|
||||||
|
} else if (e.key === 'ArrowDown') {
|
||||||
|
updatePosition({y: step}, true)
|
||||||
|
} else if (e.key === 'ArrowLeft') {
|
||||||
|
updatePosition({x: step * -1}, true)
|
||||||
|
} else if (e.key === 'ArrowRight') {
|
||||||
|
updatePosition({x: step}, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}, [position]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('keydown', keyDownHandler);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('keydown', keyDownHandler)
|
||||||
|
}
|
||||||
|
}, [keyDownHandler]);
|
||||||
|
|
||||||
|
if (!previewOption) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const disabled = !previewOption.url;
|
||||||
|
|
||||||
|
const classNames = [];
|
||||||
|
if (active) {
|
||||||
|
classNames.push('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disabled) {
|
||||||
|
classNames.push('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOpacityChange = (e) => {
|
||||||
|
setOpacity(e.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<PreviewButtonStyle onClick={() => toggle()} className={classNames.join(' ')} disabled={disabled}/>
|
||||||
|
|
||||||
|
{active &&
|
||||||
|
<>
|
||||||
|
<input type="range" value={opacity} min="0" max="100" onChange={handleOpacityChange}/>
|
||||||
|
<PreviewStyle onMouseUp={e => stop(e)} style={{opacity: opacity / 100}}>
|
||||||
|
<img src={previewOption.url} alt="" ref={reference}
|
||||||
|
onMouseDown={e => start(e)}
|
||||||
|
draggable={false}
|
||||||
|
style={{top: position.y + 'px', left: position.x + 'px'}}
|
||||||
|
/>
|
||||||
|
</PreviewStyle>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
|
||||||
|
function start(e) {
|
||||||
|
startDragPosition.x = e.clientX;
|
||||||
|
startDragPosition.y = e.clientY;
|
||||||
|
|
||||||
|
document.body.addEventListener('mousemove', handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop(e) {
|
||||||
|
const target = reference.current;
|
||||||
|
updatePosition({x: target.offsetLeft, y: target.offsetTop});
|
||||||
|
|
||||||
|
document.body.removeEventListener('mousemove', handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handler(e) {
|
||||||
|
const target = reference.current;
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
const updatedPosition = {
|
||||||
|
x: target.offsetLeft - (startDragPosition.x - e.clientX),
|
||||||
|
y: target.offsetTop - (startDragPosition.y - e.clientY),
|
||||||
|
};
|
||||||
|
|
||||||
|
target.style.left = updatedPosition.x + 'px';
|
||||||
|
target.style.top = updatedPosition.y + 'px';
|
||||||
|
|
||||||
|
startDragPosition.x = e.clientX;
|
||||||
|
startDragPosition.y = e.clientY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
setActive(!active);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePosition({x, y}, relative = false) {
|
||||||
|
x = typeof x === 'undefined' ? position.x : relative ? position.x + x : x;
|
||||||
|
y = typeof y === 'undefined' ? position.y : relative ? position.y + y : y;
|
||||||
|
|
||||||
|
setPosition({x, y})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInitialXPosition(previewOption) {
|
||||||
|
if (!previewOption) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return window.innerWidth / 2 - previewOption.widthDimension / 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
export const PreviewButtonStyle = styled.button`
|
||||||
|
--size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 0;
|
||||||
|
background-image: url("/scripts/dist/toolbar/images/icon-preview.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: calc(var(--size) - 0.15rem);
|
||||||
|
background-position: center center;
|
||||||
|
background-color: initial;
|
||||||
|
font-size: 1px;
|
||||||
|
color: rgba(0, 0, 0, 0);
|
||||||
|
line-height: 1;
|
||||||
|
display: block;
|
||||||
|
width: var(--size);
|
||||||
|
height: var(--size);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-image: url("/scripts/dist/toolbar/images/icon-preview-disabled.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.25;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const PreviewStyle = styled.div`
|
||||||
|
position: fixed;
|
||||||
|
top: 3rem;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
background-color: rgba(0, 0, 0, 0.1);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
align-items: baseline;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
cursor: move;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const PreviewImageStyle = styled.div`
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: top;
|
||||||
|
cursor: move;
|
||||||
|
`;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="m31.7 26.4-3.85-3.8q1.05-2.2-.625-3.45t-3.125-.3l-3.5-3.55q.75-.4 1.65-.6.9-.2 1.75-.2 3.55 0 6.025 2.475Q32.5 19.45 32.5 23q0 .8-.2 1.8t-.6 1.6Zm7.4 7.5-2.75-2.8q2.2-1.75 3.825-3.85T42.8 23q-2.6-5.5-7.525-8.75Q30.35 11 24.5 11q-2.1 0-4.1.35-2 .35-2.95.8l-3.3-3.3q1.75-.8 4.625-1.4 2.875-.6 5.475-.6 7.35 0 13.6 4.25t9.3 11.9q-1.25 3.3-3.375 6.075Q41.65 31.85 39.1 33.9Zm1.25 11.35-7.7-7.6q-1.75.7-4 1.1-2.25.4-4.65.4-7.55 0-13.825-4.275Q3.9 30.6.85 23q.9-2.55 2.75-5.15 1.85-2.6 4.3-5L1.75 6.8l2.5-2.6L42.7 42.65ZM10.8 15.7Q9 17.15 7.5 19.125 6 21.1 5.2 23q2.6 5.55 7.65 8.775Q17.9 35 24.4 35q1.35 0 2.775-.15 1.425-.15 2.225-.55l-3.2-3.2q-.4.2-1.025.3-.625.1-1.175.1-3.5 0-6-2.45T15.5 23q0-.55.075-1.15.075-.6.225-1.05Zm16.15 6.4Zm-6.85 3.45Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 825 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M24 31.5q3.55 0 6.025-2.475Q32.5 26.55 32.5 23q0-3.55-2.475-6.025Q27.55 14.5 24 14.5q-3.55 0-6.025 2.475Q15.5 19.45 15.5 23q0 3.55 2.475 6.025Q20.45 31.5 24 31.5Zm0-3.7q-2 0-3.4-1.4T19.2 23q0-2 1.4-3.4t3.4-1.4q2 0 3.4 1.4t1.4 3.4q0 2-1.4 3.4T24 27.8Zm0 11.35q-7.7 0-13.9-4.5T.85 23q3.05-7.15 9.25-11.65T24 6.85q7.7 0 13.9 4.5T47.15 23q-3.05 7.15-9.25 11.65T24 39.15ZM24 23Zm0 12q6 0 11.05-3.275Q40.1 28.45 42.75 23q-2.65-5.45-7.675-8.725Q30.05 11 24 11q-6 0-11.05 3.275Q7.9 17.55 5.2 23q2.7 5.45 7.725 8.725Q17.95 35 24 35Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 604 B |
@@ -98,6 +98,10 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
min-width: 480px;
|
||||||
|
}
|
||||||
|
.page_toolbar__right {
|
||||||
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
#preview_frame {
|
#preview_frame {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"sourceRoot":"","sources":["page--main.scss","_buttons.scss","_overlay.scss","_page--breakpoints.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;EACE;EACA;EAEA;;;ACTF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;ACtBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AFIF;EACE;EACA;EAEA;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EAHF;IAII;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKF;EADF;IAEI;;;AAKN;EAEE;EACA;EACA;;;AGxEJ;EACE;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EAEA;EAEA;;AAEA;EACE;EAEA;EACA;EACA;;;AH0DJ;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA","file":"page--main.css"}
|
{"version":3,"sourceRoot":"","sources":["page--main.scss","_buttons.scss","_overlay.scss","_page--breakpoints.scss"],"names":[],"mappings":"AAAA;EACE;EACA;;;AAGF;EACE;EACA;EAEA;;;ACTF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;ACtBJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AFIF;EACE;EACA;EAEA;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EAHF;IAII;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKF;EADF;IAEI;;;AAKN;EAEE;EACA;EACA;EACA;;AAGF;EACE;;;AG7EJ;EACE;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EAEA;EAEA;;AAEA;EACE;EAEA;EACA;EACA;;;AH+DJ;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA","file":"page--main.css"}
|
||||||
@@ -71,6 +71,11 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
min-width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__right {
|
||||||
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user