Property panel updates

This commit is contained in:
Conor_Mack 2020-06-01 16:31:58 +01:00
parent 91b88ecad7
commit 93ab8659ed
8 changed files with 888 additions and 903 deletions

View File

@ -1,54 +1,42 @@
export const generate_screen_css = component_arr => { export const generate_screen_css = (component_arr) => {
let styles = "" let styles = '';
for (const { _styles, _id, _children, _component } of component_arr) { for (const { _styles, _id, _children, _component } of component_arr) {
let [componentName] = _component.match(/[a-z]*$/) let [ componentName ] = _component.match(/[a-z]*$/);
Object.keys(_styles).forEach(selector => { Object.keys(_styles).forEach((selector) => {
const cssString = generate_css(_styles[selector]) const cssString = generate_css(_styles[selector]);
if (cssString) { if (cssString) {
styles += apply_class(_id, componentName, cssString, selector) styles += apply_class(_id, componentName, cssString, selector);
} }
}) });
if (_children && _children.length) { if (_children && _children.length) {
styles += generate_screen_css(_children) + "\n" styles += generate_screen_css(_children) + '\n';
} }
} }
return styles.trim() return styles.trim();
} };
export const generate_css = style => { export const generate_css = (style) => {
let cssString = Object.entries(style).reduce((str, [ key, value ]) => { let cssString = Object.entries(style).reduce((str, [ key, value ]) => {
//TODO Handle arrays and objects here also //TODO Handle arrays and objects here also
if (typeof value === "string") { if (typeof value === 'string') {
if (value) { if (value) {
return (str += `${key}: ${value};\n`) return (str += `${key}: ${value};\n`);
} }
} else if (Array.isArray(value)) { } else if (Array.isArray(value)) {
if (value.length > 0 && !value.every(v => v === "")) { if (value.length > 0 && !value.every((v) => v === '')) {
return (str += `${key}: ${value return (str += `${key}: ${value.join(' ')};\n`);
.map(generate_array_styles)
.join(" ")};\n`)
} }
} }
}, "") }, '');
return (cssString || "").trim() return (cssString || '').trim();
} };
export const generate_array_styles = item => { export const apply_class = (id, name = 'element', styles, selector) => {
let safeItem = item === "" ? 0 : item if (selector === 'normal') {
let hasPx = new RegExp("px$") return `.${name}-${id} {\n${styles}\n}`;
if (!hasPx.test(safeItem)) {
return `${safeItem}px`
} else { } else {
return safeItem let sel = selector === 'selected' ? '::selection' : `:${selector}`;
} return `.${name}-${id}${sel} {\n${styles}\n}`;
}
export const apply_class = (id, name = "element", styles, selector) => {
if (selector === "normal") {
return `.${name}-${id} {\n${styles}\n}`
} else {
let sel = selector === "selected" ? "::selection" : `:${selector}`
return `.${name}-${id}${sel} {\n${styles}\n}`
}
} }
};

View File

@ -1,321 +1,288 @@
import { cloneDeep, values } from "lodash/fp" import { cloneDeep, values } from 'lodash/fp';
import { backendUiStore } from "builderStore" import { backendUiStore } from 'builderStore';
import * as backendStoreActions from "./backend" import * as backendStoreActions from './backend';
import { writable, get } from "svelte/store" import { writable, get } from 'svelte/store';
import api from "../api" import api from '../api';
import { DEFAULT_PAGES_OBJECT } from "../../constants" import { DEFAULT_PAGES_OBJECT } from '../../constants';
import { getExactComponent } from "components/userInterface/pagesParsing/searchComponents" import { getExactComponent } from 'components/userInterface/pagesParsing/searchComponents';
import { rename } from "components/userInterface/pagesParsing/renameScreen" import { rename } from 'components/userInterface/pagesParsing/renameScreen';
import { import { createProps, makePropsSafe, getBuiltin } from 'components/userInterface/pagesParsing/createProps';
createProps, import { fetchComponentLibDefinitions } from '../loadComponentLibraries';
makePropsSafe, import { buildCodeForScreens } from '../buildCodeForScreens';
getBuiltin, import { generate_screen_css } from '../generate_css';
} from "components/userInterface/pagesParsing/createProps" import { insertCodeMetadata } from '../insertCodeMetadata';
import { fetchComponentLibDefinitions } from "../loadComponentLibraries" import { uuid } from '../uuid';
import { buildCodeForScreens } from "../buildCodeForScreens"
import { generate_screen_css } from "../generate_css"
import { insertCodeMetadata } from "../insertCodeMetadata"
import { uuid } from "../uuid"
export const getStore = () => { export const getStore = () => {
const initial = { const initial = {
apps: [], apps: [],
appname: "", appname: '',
pages: DEFAULT_PAGES_OBJECT, pages: DEFAULT_PAGES_OBJECT,
mainUi: {}, mainUi: {},
unauthenticatedUi: {}, unauthenticatedUi: {},
components: [], components: [],
currentPreviewItem: null, currentPreviewItem: null,
currentComponentInfo: null, currentComponentInfo: null,
currentFrontEndType: "none", currentFrontEndType: 'none',
currentPageName: "", currentPageName: '',
currentComponentProps: null, currentComponentProps: null,
errors: [], errors: [],
hasAppPackage: false, hasAppPackage: false,
libraries: null, libraries: null,
appId: "", appId: ''
} };
const store = writable(initial) const store = writable(initial);
store.setPackage = setPackage(store, initial) store.setPackage = setPackage(store, initial);
store.createDatabaseForApp = backendStoreActions.createDatabaseForApp(store) store.createDatabaseForApp = backendStoreActions.createDatabaseForApp(store);
store.saveScreen = saveScreen(store) store.saveScreen = saveScreen(store);
store.renameScreen = renameScreen(store) store.renameScreen = renameScreen(store);
store.deleteScreen = deleteScreen(store) store.deleteScreen = deleteScreen(store);
store.setCurrentScreen = setCurrentScreen(store) store.setCurrentScreen = setCurrentScreen(store);
store.setCurrentPage = setCurrentPage(store) store.setCurrentPage = setCurrentPage(store);
store.createScreen = createScreen(store) store.createScreen = createScreen(store);
store.addStylesheet = addStylesheet(store) store.addStylesheet = addStylesheet(store);
store.removeStylesheet = removeStylesheet(store) store.removeStylesheet = removeStylesheet(store);
store.savePage = savePage(store) store.savePage = savePage(store);
store.addChildComponent = addChildComponent(store) store.addChildComponent = addChildComponent(store);
store.selectComponent = selectComponent(store) store.selectComponent = selectComponent(store);
store.setComponentProp = setComponentProp(store) store.setComponentProp = setComponentProp(store);
store.setComponentStyle = setComponentStyle(store) store.setComponentStyle = setComponentStyle(store);
store.setComponentCode = setComponentCode(store) store.setComponentCode = setComponentCode(store);
store.setScreenType = setScreenType(store) store.setScreenType = setScreenType(store);
store.deleteComponent = deleteComponent(store) store.deleteComponent = deleteComponent(store);
store.moveUpComponent = moveUpComponent(store) store.moveUpComponent = moveUpComponent(store);
store.moveDownComponent = moveDownComponent(store) store.moveDownComponent = moveDownComponent(store);
store.copyComponent = copyComponent(store) store.copyComponent = copyComponent(store);
store.getPathToComponent = getPathToComponent(store) store.getPathToComponent = getPathToComponent(store);
store.addTemplatedComponent = addTemplatedComponent(store) store.addTemplatedComponent = addTemplatedComponent(store);
store.setMetadataProp = setMetadataProp(store) store.setMetadataProp = setMetadataProp(store);
return store return store;
} };
export default getStore export default getStore;
const setPackage = (store, initial) => async pkg => { const setPackage = (store, initial) => async (pkg) => {
const [ main_screens, unauth_screens ] = await Promise.all([ const [ main_screens, unauth_screens ] = await Promise.all([
api api.get(`/_builder/api/${pkg.application._id}/pages/main/screens`).then((r) => r.json()),
.get(`/_builder/api/${pkg.application._id}/pages/main/screens`) api.get(`/_builder/api/${pkg.application._id}/pages/unauthenticated/screens`).then((r) => r.json())
.then(r => r.json()), ]);
api
.get(`/_builder/api/${pkg.application._id}/pages/unauthenticated/screens`)
.then(r => r.json()),
])
pkg.pages = { pkg.pages = {
main: { main: {
...pkg.pages.main, ...pkg.pages.main,
_screens: Object.values(main_screens), _screens: Object.values(main_screens)
}, },
unauthenticated: { unauthenticated: {
...pkg.pages.unauthenticated, ...pkg.pages.unauthenticated,
_screens: Object.values(unauth_screens), _screens: Object.values(unauth_screens)
},
} }
};
initial.libraries = pkg.application.componentLibraries initial.libraries = pkg.application.componentLibraries;
initial.components = await fetchComponentLibDefinitions(pkg.application._id) initial.components = await fetchComponentLibDefinitions(pkg.application._id);
initial.appname = pkg.application.name initial.appname = pkg.application.name;
initial.appId = pkg.application._id initial.appId = pkg.application._id;
initial.pages = pkg.pages initial.pages = pkg.pages;
initial.hasAppPackage = true initial.hasAppPackage = true;
initial.screens = values(pkg.screens) initial.screens = values(pkg.screens);
initial.builtins = [getBuiltin("##builtin/screenslot")] initial.builtins = [ getBuiltin('##builtin/screenslot') ];
initial.appInstances = pkg.application.instances initial.appInstances = pkg.application.instances;
initial.appId = pkg.application._id initial.appId = pkg.application._id;
store.set(initial) store.set(initial);
return initial return initial;
} };
const saveScreen = store => screen => { const saveScreen = (store) => (screen) => {
store.update(state => { store.update((state) => {
return _saveScreen(store, state, screen) return _saveScreen(store, state, screen);
}) });
} };
const _saveScreen = async (store, s, screen) => { const _saveScreen = async (store, s, screen) => {
const currentPageScreens = s.pages[s.currentPageName]._screens const currentPageScreens = s.pages[s.currentPageName]._screens;
await api await api.post(`/_builder/api/${s.appId}/pages/${s.currentPageName}/screen`, screen).then(() => {
.post(`/_builder/api/${s.appId}/pages/${s.currentPageName}/screen`, screen) if (currentPageScreens.includes(screen)) return;
.then(() => {
if (currentPageScreens.includes(screen)) return
const screens = [...currentPageScreens, screen] const screens = [ ...currentPageScreens, screen ];
store.update(innerState => { store.update((innerState) => {
innerState.pages[s.currentPageName]._screens = screens innerState.pages[s.currentPageName]._screens = screens;
innerState.screens = screens innerState.screens = screens;
innerState.currentPreviewItem = screen innerState.currentPreviewItem = screen;
const safeProps = makePropsSafe( const safeProps = makePropsSafe(innerState.components[screen.props._component], screen.props);
innerState.components[screen.props._component], innerState.currentComponentInfo = safeProps;
screen.props screen.props = safeProps;
)
innerState.currentComponentInfo = safeProps
screen.props = safeProps
_savePage(innerState) _savePage(innerState);
return innerState return innerState;
}) });
}) });
return s return s;
} };
const _saveScreenApi = (screen, s) => { const _saveScreenApi = (screen, s) => {
api api.post(`/_builder/api/${s.appId}/pages/${s.currentPageName}/screen`, screen).then(() => _savePage(s));
.post(`/_builder/api/${s.appId}/pages/${s.currentPageName}/screen`, screen) };
.then(() => _savePage(s))
}
const createScreen = store => (screenName, route, layoutComponentName) => { const createScreen = (store) => (screenName, route, layoutComponentName) => {
store.update(state => { store.update((state) => {
const rootComponent = state.components[layoutComponentName] const rootComponent = state.components[layoutComponentName];
const newScreen = { const newScreen = {
name: screenName || "", name: screenName || '',
description: "", description: '',
url: "", url: '',
_css: "", _css: '',
uiFunctions: "", uiFunctions: '',
props: createProps(rootComponent).props, props: createProps(rootComponent).props
} };
newScreen.route = route newScreen.route = route;
state.currentPreviewItem = newScreen state.currentPreviewItem = newScreen;
state.currentComponentInfo = newScreen.props state.currentComponentInfo = newScreen.props;
state.currentFrontEndType = "screen" state.currentFrontEndType = 'screen';
_saveScreen(store, state, newScreen) _saveScreen(store, state, newScreen);
return state return state;
}) });
} };
const setCurrentScreen = store => screenName => { const setCurrentScreen = (store) => (screenName) => {
store.update(s => { store.update((s) => {
const screen = getExactComponent(s.screens, screenName) const screen = getExactComponent(s.screens, screenName);
screen._css = generate_screen_css([screen.props]) screen._css = generate_screen_css([ screen.props ]);
s.currentPreviewItem = screen s.currentPreviewItem = screen;
s.currentFrontEndType = "screen" s.currentFrontEndType = 'screen';
s.currentView = "detail" s.currentView = 'detail';
const safeProps = makePropsSafe( const safeProps = makePropsSafe(s.components[screen.props._component], screen.props);
s.components[screen.props._component], screen.props = safeProps;
screen.props s.currentComponentInfo = safeProps;
) setCurrentPageFunctions(s);
screen.props = safeProps return s;
s.currentComponentInfo = safeProps });
setCurrentPageFunctions(s) };
return s
})
}
const deleteScreen = store => name => { const deleteScreen = (store) => (name) => {
store.update(s => { store.update((s) => {
const components = s.components.filter(c => c.name !== name) const components = s.components.filter((c) => c.name !== name);
const screens = s.screens.filter(c => c.name !== name) const screens = s.screens.filter((c) => c.name !== name);
s.components = components s.components = components;
s.screens = screens s.screens = screens;
if (s.currentPreviewItem.name === name) { if (s.currentPreviewItem.name === name) {
s.currentPreviewItem = null s.currentPreviewItem = null;
s.currentFrontEndType = "" s.currentFrontEndType = '';
} }
api.delete(`/_builder/api/${s.appId}/screen/${name}`) api.delete(`/_builder/api/${s.appId}/screen/${name}`);
return s return s;
}) });
} };
const renameScreen = store => (oldname, newname) => { const renameScreen = (store) => (oldname, newname) => {
store.update(s => { store.update((s) => {
const { screens, pages, error, changedScreens } = rename( const { screens, pages, error, changedScreens } = rename(s.pages, s.screens, oldname, newname);
s.pages,
s.screens,
oldname,
newname
)
if (error) { if (error) {
// should really do something with this // should really do something with this
return s return s;
} }
s.screens = screens s.screens = screens;
s.pages = pages s.pages = pages;
if (s.currentPreviewItem.name === oldname) if (s.currentPreviewItem.name === oldname) s.currentPreviewItem.name = newname;
s.currentPreviewItem.name = newname
const saveAllChanged = async () => { const saveAllChanged = async () => {
for (let screenName of changedScreens) { for (let screenName of changedScreens) {
const changedScreen = getExactComponent(screens, screenName) const changedScreen = getExactComponent(screens, screenName);
await api.post(`/_builder/api/${s.appId}/screen`, changedScreen) await api.post(`/_builder/api/${s.appId}/screen`, changedScreen);
}
} }
};
api api
.patch(`/_builder/api/${s.appId}/screen`, { .patch(`/_builder/api/${s.appId}/screen`, {
oldname, oldname,
newname, newname
}) })
.then(() => saveAllChanged()) .then(() => saveAllChanged())
.then(() => { .then(() => {
_savePage(s) _savePage(s);
}) });
return s return s;
}) });
};
const savePage = (store) => async (page) => {
store.update((state) => {
if (state.currentFrontEndType !== 'page' || !state.currentPageName) {
return state;
} }
const savePage = store => async page => { state.pages[state.currentPageName] = page;
store.update(state => { _savePage(state);
if (state.currentFrontEndType !== "page" || !state.currentPageName) { return state;
return state });
} };
state.pages[state.currentPageName] = page const addStylesheet = (store) => (stylesheet) => {
_savePage(state) store.update((s) => {
return state s.pages.stylesheets.push(stylesheet);
}) _savePage(s);
} return s;
});
};
const addStylesheet = store => stylesheet => { const removeStylesheet = (store) => (stylesheet) => {
store.update(s => { store.update((state) => {
s.pages.stylesheets.push(stylesheet) state.pages.stylesheets = state.pages.stylesheets.filter((s) => s !== stylesheet);
_savePage(s) _savePage(state);
return s return state;
}) });
} };
const removeStylesheet = store => stylesheet => { const _savePage = async (s) => {
store.update(state => { const page = s.pages[s.currentPageName];
state.pages.stylesheets = state.pages.stylesheets.filter(
s => s !== stylesheet
)
_savePage(state)
return state
})
}
const _savePage = async s => {
const page = s.pages[s.currentPageName]
await api.post(`/_builder/api/${s.appId}/pages/${s.currentPageName}`, { await api.post(`/_builder/api/${s.appId}/pages/${s.currentPageName}`, {
page: { componentLibraries: s.pages.componentLibraries, ...page }, page: { componentLibraries: s.pages.componentLibraries, ...page },
uiFunctions: s.currentPageFunctions, uiFunctions: s.currentPageFunctions,
screens: page._screens, screens: page._screens
}) });
} };
const setCurrentPage = store => pageName => { const setCurrentPage = (store) => (pageName) => {
store.update(state => { store.update((state) => {
const current_screens = state.pages[pageName]._screens const current_screens = state.pages[pageName]._screens;
const currentPage = state.pages[pageName] const currentPage = state.pages[pageName];
state.currentFrontEndType = "page" state.currentFrontEndType = 'page';
state.currentPageName = pageName state.currentPageName = pageName;
state.screens = Array.isArray(current_screens) state.screens = Array.isArray(current_screens) ? current_screens : Object.values(current_screens);
? current_screens const safeProps = makePropsSafe(state.components[currentPage.props._component], currentPage.props);
: Object.values(current_screens) state.currentComponentInfo = safeProps;
const safeProps = makePropsSafe( currentPage.props = safeProps;
state.components[currentPage.props._component], state.currentPreviewItem = state.pages[pageName];
currentPage.props state.currentPreviewItem._css = generate_screen_css([ state.currentPreviewItem.props ]);
)
state.currentComponentInfo = safeProps
currentPage.props = safeProps
state.currentPreviewItem = state.pages[pageName]
state.currentPreviewItem._css = generate_screen_css([
state.currentPreviewItem.props,
])
for (let screen of state.screens) { for (let screen of state.screens) {
screen._css = generate_screen_css([screen.props]) screen._css = generate_screen_css([ screen.props ]);
} }
setCurrentPageFunctions(state) setCurrentPageFunctions(state);
return state return state;
}) });
} };
// const getComponentDefinition = (components, name) => components.find(c => c.name === name) // const getComponentDefinition = (components, name) => components.find(c => c.name === name)
@ -323,288 +290,267 @@ const setCurrentPage = store => pageName => {
* @param {string} componentToAdd - name of the component to add to the application * @param {string} componentToAdd - name of the component to add to the application
* @param {string} presetName - name of the component preset if defined * @param {string} presetName - name of the component preset if defined
*/ */
const addChildComponent = store => (componentToAdd, presetName) => { const addChildComponent = (store) => (componentToAdd, presetName) => {
store.update(state => { store.update((state) => {
function findSlot(component_array) { function findSlot(component_array) {
for (let i = 0; i < component_array.length; i += 1) { for (let i = 0; i < component_array.length; i += 1) {
if (component_array[i]._component === "##builtin/screenslot") { if (component_array[i]._component === '##builtin/screenslot') {
return true return true;
} }
if (component_array[i]._children) findSlot(component_array[i]) if (component_array[i]._children) findSlot(component_array[i]);
} }
return false return false;
} }
if ( if (componentToAdd.startsWith('##') && findSlot(state.pages[state.currentPageName].props._children)) {
componentToAdd.startsWith("##") && return state;
findSlot(state.pages[state.currentPageName].props._children)
) {
return state
} }
const component = componentToAdd.startsWith("##") const component = componentToAdd.startsWith('##')
? getBuiltin(componentToAdd) ? getBuiltin(componentToAdd)
: state.components[componentToAdd] : state.components[componentToAdd];
const presetProps = presetName ? component.presets[presetName] : {} const presetProps = presetName ? component.presets[presetName] : {};
const instanceId = get(backendUiStore).selectedDatabase._id const instanceId = get(backendUiStore).selectedDatabase._id;
const newComponent = createProps( const newComponent = createProps(
component, component,
{ {
...presetProps, ...presetProps,
_instanceId: instanceId, _instanceId: instanceId
}, },
state state
) );
state.currentComponentInfo._children = state.currentComponentInfo._children.concat( state.currentComponentInfo._children = state.currentComponentInfo._children.concat(newComponent.props);
newComponent.props
)
state.currentFrontEndType === "page" state.currentFrontEndType === 'page' ? _savePage(state) : _saveScreenApi(state.currentPreviewItem, state);
? _savePage(state)
: _saveScreenApi(state.currentPreviewItem, state)
state.currentView = "component" state.currentView = 'component';
state.currentComponentInfo = newComponent.props state.currentComponentInfo = newComponent.props;
return state return state;
}) });
} };
/** /**
* @param {string} props - props to add, as child of current component * @param {string} props - props to add, as child of current component
*/ */
const addTemplatedComponent = store => props => { const addTemplatedComponent = (store) => (props) => {
store.update(state => { store.update((state) => {
walkProps(props, p => { walkProps(props, (p) => {
p._id = uuid() p._id = uuid();
}) });
state.currentComponentInfo._children = state.currentComponentInfo._children.concat( state.currentComponentInfo._children = state.currentComponentInfo._children.concat(props);
props state.currentPreviewItem._css = generate_screen_css([ state.currentPreviewItem.props ]);
)
state.currentPreviewItem._css = generate_screen_css([
state.currentPreviewItem.props,
])
setCurrentPageFunctions(state) setCurrentPageFunctions(state);
_saveCurrentPreviewItem(state) _saveCurrentPreviewItem(state);
return state return state;
}) });
} };
const selectComponent = store => component => { const selectComponent = (store) => (component) => {
store.update(state => { store.update((state) => {
const componentDef = component._component.startsWith("##") const componentDef = component._component.startsWith('##') ? component : state.components[component._component];
? component state.currentComponentInfo = makePropsSafe(componentDef, component);
: state.components[component._component] state.currentView = 'component';
state.currentComponentInfo = makePropsSafe(componentDef, component) return state;
state.currentView = "component" });
return state };
})
}
const setComponentProp = store => (name, value) => { const setComponentProp = (store) => (name, value) => {
store.update(state => { store.update((state) => {
const current_component = state.currentComponentInfo const current_component = state.currentComponentInfo;
state.currentComponentInfo[name] = value state.currentComponentInfo[name] = value;
_saveCurrentPreviewItem(state) _saveCurrentPreviewItem(state);
state.currentComponentInfo = current_component state.currentComponentInfo = current_component;
return state return state;
}) });
} };
const setComponentStyle = store => (type, name, value) => { const setComponentStyle = (store) => (type, name, value) => {
store.update(state => { store.update((state) => {
if (!state.currentComponentInfo._styles) { if (!state.currentComponentInfo._styles) {
state.currentComponentInfo._styles = {} state.currentComponentInfo._styles = {};
} }
state.currentComponentInfo._styles[type][name] = value state.currentComponentInfo._styles[type][name] = value;
state.currentPreviewItem._css = generate_screen_css([ state.currentPreviewItem._css = generate_screen_css([ state.currentPreviewItem.props ]);
state.currentPreviewItem.props,
])
// save without messing with the store // save without messing with the store
_saveCurrentPreviewItem(state) _saveCurrentPreviewItem(state);
return state return state;
}) });
} };
const setComponentCode = store => code => { const setComponentCode = (store) => (code) => {
store.update(state => { store.update((state) => {
state.currentComponentInfo._code = code state.currentComponentInfo._code = code;
setCurrentPageFunctions(state) setCurrentPageFunctions(state);
// save without messing with the store // save without messing with the store
_saveScreenApi(state.currentPreviewItem, state) _saveScreenApi(state.currentPreviewItem, state);
return state return state;
}) });
} };
const setCurrentPageFunctions = s => { const setCurrentPageFunctions = (s) => {
s.currentPageFunctions = buildPageCode(s.screens, s.pages[s.currentPageName]) s.currentPageFunctions = buildPageCode(s.screens, s.pages[s.currentPageName]);
insertCodeMetadata(s.currentPreviewItem.props) insertCodeMetadata(s.currentPreviewItem.props);
} };
const buildPageCode = (screens, page) => buildCodeForScreens([page, ...screens]) const buildPageCode = (screens, page) => buildCodeForScreens([ page, ...screens ]);
const setScreenType = store => type => { const setScreenType = (store) => (type) => {
store.update(state => { store.update((state) => {
state.currentFrontEndType = type state.currentFrontEndType = type;
const pageOrScreen = const pageOrScreen =
type === "page" type === 'page' ? state.pages[state.currentPageName] : state.pages[state.currentPageName]._screens[0];
? state.pages[state.currentPageName]
: state.pages[state.currentPageName]._screens[0]
state.currentComponentInfo = pageOrScreen ? pageOrScreen.props : null state.currentComponentInfo = pageOrScreen ? pageOrScreen.props : null;
state.currentPreviewItem = pageOrScreen state.currentPreviewItem = pageOrScreen;
return state return state;
}) });
} };
const deleteComponent = store => componentName => { const deleteComponent = (store) => (componentName) => {
store.update(state => { store.update((state) => {
const parent = getParent(state.currentPreviewItem.props, componentName) const parent = getParent(state.currentPreviewItem.props, componentName);
if (parent) { if (parent) {
parent._children = parent._children.filter( parent._children = parent._children.filter((component) => component !== componentName);
component => component !== componentName
)
} }
_saveCurrentPreviewItem(state) _saveCurrentPreviewItem(state);
return state return state;
}) });
} };
const moveUpComponent = store => component => { const moveUpComponent = (store) => (component) => {
store.update(s => { store.update((s) => {
const parent = getParent(s.currentPreviewItem.props, component) const parent = getParent(s.currentPreviewItem.props, component);
if (parent) { if (parent) {
const currentIndex = parent._children.indexOf(component) const currentIndex = parent._children.indexOf(component);
if (currentIndex === 0) return s if (currentIndex === 0) return s;
const newChildren = parent._children.filter(c => c !== component) const newChildren = parent._children.filter((c) => c !== component);
newChildren.splice(currentIndex - 1, 0, component) newChildren.splice(currentIndex - 1, 0, component);
parent._children = newChildren parent._children = newChildren;
} }
s.currentComponentInfo = component s.currentComponentInfo = component;
_saveCurrentPreviewItem(s) _saveCurrentPreviewItem(s);
return s return s;
}) });
} };
const moveDownComponent = store => component => { const moveDownComponent = (store) => (component) => {
store.update(s => { store.update((s) => {
const parent = getParent(s.currentPreviewItem.props, component) const parent = getParent(s.currentPreviewItem.props, component);
if (parent) { if (parent) {
const currentIndex = parent._children.indexOf(component) const currentIndex = parent._children.indexOf(component);
if (currentIndex === parent._children.length - 1) return s if (currentIndex === parent._children.length - 1) return s;
const newChildren = parent._children.filter(c => c !== component) const newChildren = parent._children.filter((c) => c !== component);
newChildren.splice(currentIndex + 1, 0, component) newChildren.splice(currentIndex + 1, 0, component);
parent._children = newChildren parent._children = newChildren;
} }
s.currentComponentInfo = component s.currentComponentInfo = component;
_saveCurrentPreviewItem(s) _saveCurrentPreviewItem(s);
return s return s;
}) });
} };
const copyComponent = store => component => { const copyComponent = (store) => (component) => {
store.update(s => { store.update((s) => {
const parent = getParent(s.currentPreviewItem.props, component) const parent = getParent(s.currentPreviewItem.props, component);
const copiedComponent = cloneDeep(component) const copiedComponent = cloneDeep(component);
walkProps(copiedComponent, p => { walkProps(copiedComponent, (p) => {
p._id = uuid() p._id = uuid();
}) });
parent._children = [...parent._children, copiedComponent] parent._children = [ ...parent._children, copiedComponent ];
s.curren s.curren;
_saveCurrentPreviewItem(s) _saveCurrentPreviewItem(s);
s.currentComponentInfo = copiedComponent s.currentComponentInfo = copiedComponent;
return s return s;
}) });
} };
const getPathToComponent = store => component => { const getPathToComponent = (store) => (component) => {
// Gets all the components to needed to construct a path. // Gets all the components to needed to construct a path.
const tempStore = get(store) const tempStore = get(store);
let pathComponents = [] let pathComponents = [];
let parent = component let parent = component;
let root = false let root = false;
while (!root) { while (!root) {
parent = getParent(tempStore.currentPreviewItem.props, parent) parent = getParent(tempStore.currentPreviewItem.props, parent);
if (!parent) { if (!parent) {
root = true root = true;
} else { } else {
pathComponents.push(parent) pathComponents.push(parent);
} }
} }
// Remove root entry since it's the screen or page layout. // Remove root entry since it's the screen or page layout.
// Reverse array since we need the correct order of the IDs // Reverse array since we need the correct order of the IDs
const reversedComponents = pathComponents.reverse().slice(1) const reversedComponents = pathComponents.reverse().slice(1);
// Add component // Add component
const allComponents = [...reversedComponents, component] const allComponents = [ ...reversedComponents, component ];
// Map IDs // Map IDs
const IdList = allComponents.map(c => c._id) const IdList = allComponents.map((c) => c._id);
// Construct ID Path: // Construct ID Path:
const path = IdList.join("/") const path = IdList.join('/');
return path return path;
} };
const getParent = (rootProps, child) => { const getParent = (rootProps, child) => {
let parent let parent;
walkProps(rootProps, (p, breakWalk) => { walkProps(rootProps, (p, breakWalk) => {
if (p._children && p._children.includes(child)) { if (p._children && p._children.includes(child)) {
parent = p parent = p;
breakWalk() breakWalk();
}
})
return parent
} }
});
return parent;
};
const walkProps = (props, action, cancelToken = null) => { const walkProps = (props, action, cancelToken = null) => {
cancelToken = cancelToken || { cancelled: false } cancelToken = cancelToken || { cancelled: false };
action(props, () => { action(props, () => {
cancelToken.cancelled = true cancelToken.cancelled = true;
}) });
if (props._children) { if (props._children) {
for (let child of props._children) { for (let child of props._children) {
if (cancelToken.cancelled) return if (cancelToken.cancelled) return;
walkProps(child, action, cancelToken) walkProps(child, action, cancelToken);
}
} }
} }
};
const setMetadataProp = store => (name, prop) => { const setMetadataProp = (store) => (name, prop) => {
store.update(s => { store.update((s) => {
s.currentPreviewItem[name] = prop s.currentPreviewItem[name] = prop;
return s return s;
}) });
} };
const _saveCurrentPreviewItem = s => const _saveCurrentPreviewItem = (s) =>
s.currentFrontEndType === "page" s.currentFrontEndType === 'page' ? _savePage(s) : _saveScreenApi(s.currentPreviewItem, s);
? _savePage(s)
: _saveScreenApi(s.currentPreviewItem, s)

View File

@ -1,14 +1,17 @@
<script> <script>
import {onMount} from "svelte"
import { buildStyle } from "../../helpers.js" import { buildStyle } from "../../helpers.js"
export let value = "" export let value = ""
export let textAlign = "left" export let textAlign = "left"
export let width = "160px" export let width = "160px"
export let placeholder = "" export let placeholder = ""
let centerPlaceholder = textAlign === "center"
let style = buildStyle({ width, textAlign }) let style = buildStyle({ width, textAlign })
</script> </script>
<input type="text" {placeholder} {style} on:change bind:value /> <input class:centerPlaceholder type="text" {placeholder} {style} on:change bind:value />
<style> <style>
input { input {
@ -24,10 +27,13 @@
border: 1px solid var(--grey); border: 1px solid var(--grey);
border-radius: 2px; border-radius: 2px;
outline: none; outline: none;
float: right;
} }
input::placeholder { input::placeholder {
text-align: left;
}
.centerPlaceholder::placeholder {
text-align: center; text-align: center;
} }
</style> </style>

View File

@ -5,40 +5,41 @@
export let meta = [] export let meta = []
export let label = "" export let label = ""
export let value = ["0", "0", "0", "0"] export let value = ["0", "0", "0", "0"]
export let type = "number" export let suffix = ""
export let onChange = () => {} export let onChange = () => {}
function handleChange(val, idx) { function handleChange(val, idx) {
value.splice(idx, 1, val) value.splice(idx, 1, suffix ? val + suffix : val)
value = value value = value
console.log("IDX",idx) let _value = value.map(v => (!v.endsWith(suffix) ? v + suffix : v))
let _value = value.map(v => !/px$/.test(v) ? `${v}px` : v)
onChange(_value) onChange(_value)
} }
$: displayValues = value.map(v => v.toString().replace(/px$/, "")) $: displayValues = value
? value.map(v => v.replace(new RegExp(`${suffix}$`), ""))
: []
</script> </script>
<div class="input-container"> <div class="input-container">
<div class="label">{label}</div> <div class="label">{label}</div>
<div class="inputs"> <div class="inputs-group">
{#each meta as { placeholder }, i} {#each meta as m, i}
<Input
<Input width="32px" textAlign="center" placeholder={placeholder || ""} value={!displayValues || displayValues[i] === 0 ? '' : displayValues[i]} on:change={e => handleChange(e.target.value || 0, i)} /> width="32px"
textAlign="center"
placeholder={m.placeholder || ''}
value={!displayValues || displayValues[i] === '0' ? '' : displayValues[i]}
on:change={e => handleChange(e.target.value || 0, i)} />
{/each} {/each}
</div> </div>
</div> </div>
<style> <style>
.label { .label {
flex: 0; flex: 0;
} }
.inputs { .inputs-group {
flex: 1; flex: 1;
} }
</style> </style>

View File

@ -3,7 +3,7 @@
export let value = "" export let value = ""
export let text = "" export let text = ""
export let icon = "" export let icon = ""
export let padding = "8px 2px;" export let padding = "8px 5px;"
export let onClick = value => {} export let onClick = value => {}
export let selected = false export let selected = false
export let fontWeight = "" export let fontWeight = ""

View File

@ -28,9 +28,9 @@
onChange(val) onChange(val)
} }
const checkSelected = val => isMultiSelect ? value.includes(val) : value === val const checkSelected = val =>
isMultiSelect ? value.includes(val) : value === val
$: console.log("VALUE",value)
</script> </script>
<div class="flatbutton-group"> <div class="flatbutton-group">

View File

@ -144,6 +144,7 @@
width: 160px; width: 160px;
height: 32px; height: 32px;
cursor: pointer; cursor: pointer;
font-size: 12px;
} }
.bb-select-anchor { .bb-select-anchor {
@ -153,6 +154,7 @@
background-color: #f2f2f2; background-color: #f2f2f2;
border-radius: 2px; border-radius: 2px;
border: 1px solid var(--grey-dark); border: 1px solid var(--grey-dark);
align-items: center;
} }
.bb-select-anchor > span { .bb-select-anchor > span {

View File

@ -1,7 +1,7 @@
import Input from "../common/Input.svelte" import Input from '../common/Input.svelte';
import OptionSelect from "./OptionSelect.svelte" import OptionSelect from './OptionSelect.svelte';
import InputGroup from "../common/Inputs/InputGroup.svelte" import InputGroup from '../common/Inputs/InputGroup.svelte';
import FlatButtonGroup from "./FlatButtonGroup.svelte" import FlatButtonGroup from './FlatButtonGroup.svelte';
// import Colorpicker from "../common/Colorpicker.svelte" // import Colorpicker from "../common/Colorpicker.svelte"
/* /*
TODO: Allow for default values for all properties TODO: Allow for default values for all properties
@ -9,338 +9,380 @@ import FlatButtonGroup from "./FlatButtonGroup.svelte"
export const layout = [ export const layout = [
{ {
label: "Display", label: 'Display',
key: "display", key: 'display',
control: OptionSelect, control: OptionSelect,
initialValue: "Flex", initialValue: 'Flex',
options: [ options: [ { label: 'Flex', value: 'flex' }, { label: 'Inline Flex', value: 'inline-flex' } ]
{ label: "Flex", value: "flex" },
{ label: "Inline Flex", value: "inline-flex" },
],
}, },
{ {
label: "Direction", label: 'Direction',
key: "flex-direction", key: 'flex-direction',
control: FlatButtonGroup, control: FlatButtonGroup,
buttonProps: [ buttonProps: [
{ icon: "ri-arrow-right-line", padding: "4px 8px", value: "row" }, { icon: 'ri-arrow-right-line', padding: '0px 5px', value: 'row' },
{ icon: "ri-arrow-left-line", padding: "4px 8px", value: "rowReverse" }, { icon: 'ri-arrow-left-line', padding: '0px 5px', value: 'rowReverse' },
{ icon: "ri-arrow-down-line", padding: "4px 8px", value: "column" }, { icon: 'ri-arrow-down-line', padding: '0px 5px', value: 'column' },
{ {
icon: "ri-arrow-up-line", icon: 'ri-arrow-up-line',
padding: "4px 8px", padding: '0px 5px',
value: "columnReverse", value: 'columnReverse'
}, }
],
},
{
label: "Justify",
key: "justify-content",
control: OptionSelect,
initialValue: "Flex Start",
options: [
{ label: "Flex Start", value: "flex-start" },
{ label: "Flex End", value: "flex-end" },
{ label: "Center", value: "center" },
{ label: "Space Between", value: "space-between" },
{ label: "Space Around", value: "space-around" },
{ label: "Space Evenly", value: "space-evenly" },
],
},
{
label: "Align",
key: "align-items",
control: OptionSelect,
initialValue: "Flex Start",
options: [
{ label: "Flex Start", value: "flex-start" },
{ label: "Flex End", value: "flex-end" },
{ label: "Center", value: "center" },
{ label: "Baseline", value: "baseline" },
{ label: "Stretch", value: "stretch" },
],
},
{
label: "Wrap",
key: "flex-wrap",
control: OptionSelect,
options: [
{ label: "wrap", value: "wrap" },
{ label: "no wrap", value: "noWrap" },
],
},
] ]
},
{
label: 'Justify',
key: 'justify-content',
control: OptionSelect,
initialValue: 'Flex Start',
options: [
{ label: 'Flex Start', value: 'flex-start' },
{ label: 'Flex End', value: 'flex-end' },
{ label: 'Center', value: 'center' },
{ label: 'Space Between', value: 'space-between' },
{ label: 'Space Around', value: 'space-around' },
{ label: 'Space Evenly', value: 'space-evenly' }
]
},
{
label: 'Align',
key: 'align-items',
control: OptionSelect,
initialValue: 'Flex Start',
options: [
{ label: 'Flex Start', value: 'flex-start' },
{ label: 'Flex End', value: 'flex-end' },
{ label: 'Center', value: 'center' },
{ label: 'Baseline', value: 'baseline' },
{ label: 'Stretch', value: 'stretch' }
]
},
{
label: 'Wrap',
key: 'flex-wrap',
control: OptionSelect,
options: [ { label: 'wrap', value: 'wrap' }, { label: 'no wrap', value: 'noWrap' } ]
}
];
const spacingMeta = [ const spacingMeta = [ { placeholder: 'T' }, { placeholder: 'R' }, { placeholder: 'B' }, { placeholder: 'L' } ];
{ placeholder: "&#8593;" },
{ placeholder: "&#8594;" },
{ placeholder: "&#8595;" },
{ placeholder: "&#8592;" },
]
export const spacing = [ export const spacing = [
{ label: "Margin", key: "margin", control: InputGroup, meta: spacingMeta },
{ {
label: "Padding", label: 'Margin',
key: "padding", key: 'margin',
control: InputGroup, control: InputGroup,
meta: spacingMeta, meta: spacingMeta,
suffix: 'px',
defaultValue: [ '0', '0', '0', '0' ]
}, },
] {
label: 'Padding',
key: 'padding',
control: InputGroup,
meta: spacingMeta,
suffix: 'px',
defaultValue: [ '0', '0', '0', '0' ]
}
];
export const size = [ export const size = [
{ {
label: "Width", label: 'Width',
key: "width", key: 'width',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Height", label: 'Height',
key: "height", key: 'height',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Min W", label: 'Min W',
key: "min-width", key: 'min-width',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Min H", label: 'Min H',
key: "min-height", key: 'min-height',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Max W", label: 'Max W',
key: "max-width", key: 'max-width',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Max H", label: 'Max H',
key: "max-height", key: 'max-height',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, }
] ];
export const position = [ export const position = [
{ {
label: "Position", label: 'Position',
key: "position", key: 'position',
control: OptionSelect, control: OptionSelect,
initialValue: "Wrap", initialValue: 'Wrap',
options: [ options: [
{ label: "Static", value: "static" }, { label: 'Static', value: 'static' },
{ label: "Relative", value: "relative" }, { label: 'Relative', value: 'relative' },
{ label: "Fixed", value: "fixed" }, { label: 'Fixed', value: 'fixed' },
{ label: "Absolute", value: "absolute" }, { label: 'Absolute', value: 'absolute' },
{ label: "Sticky", value: "sticky" }, { label: 'Sticky', value: 'sticky' }
],
},
{
label: "Top",
key: "top",
control: Input,
placeholder: "px",
width: "48px",
textAlign: "center",
},
{
label: "Right",
key: "right",
control: Input,
placeholder: "px",
width: "48px",
textAlign: "center",
},
{
label: "Bottom",
key: "bottom",
control: Input,
placeholder: "px",
width: "48px",
textAlign: "center",
},
{
label: "Left",
key: "left",
control: Input,
placeholder: "px",
width: "48px",
textAlign: "center",
},
{
label: "Z-index",
key: "z-index",
control: Input,
placeholder: "Num",
width: "48px",
textAlign: "center",
},
] ]
},
{
label: 'Top',
key: 'top',
control: Input,
placeholder: 'px',
width: '48px',
textAlign: 'center'
},
{
label: 'Right',
key: 'right',
control: Input,
placeholder: 'px',
width: '48px',
textAlign: 'center'
},
{
label: 'Bottom',
key: 'bottom',
control: Input,
placeholder: 'px',
width: '48px',
textAlign: 'center'
},
{
label: 'Left',
key: 'left',
control: Input,
placeholder: 'px',
width: '48px',
textAlign: 'center'
},
{
label: 'Z-index',
key: 'z-index',
control: Input,
placeholder: 'num',
width: '48px',
textAlign: 'center'
}
];
export const typography = [ export const typography = [
{ {
label: "Font", label: 'Font',
key: "font-family", key: 'font-family',
control: OptionSelect, control: OptionSelect,
defaultValue: "initial", defaultValue: 'initial',
options: [ options: [
"initial", 'initial',
"Arial", 'Arial',
"Arial Black", 'Arial Black',
"Cursive", 'Cursive',
"Courier", 'Courier',
"Comic Sans MS", 'Comic Sans MS',
"Helvetica", 'Helvetica',
"Impact", 'Impact',
"Inter", 'Inter',
"Lucida Sans Unicode", 'Lucida Sans Unicode',
"Open Sans", 'Open Sans',
"Playfair", 'Playfair',
"Roboto", 'Roboto',
"Roboto Mono", 'Roboto Mono',
"Times New Roman", 'Times New Roman',
"Verdana", 'Verdana'
], ],
styleBindingProperty: "font-family", styleBindingProperty: 'font-family'
}, },
{ {
label: "Weight", label: 'Weight',
key: "font-weight", key: 'font-weight',
control: OptionSelect, control: OptionSelect,
options: ["normal", "bold", "bolder", "lighter"], options: [ 'normal', 'bold', 'bolder', 'lighter' ]
}, },
{ {
label: "size", label: 'size',
key: "font-size", key: 'font-size',
defaultValue: "", defaultValue: '',
control: Input, control: Input,
placeholder: "px", placeholder: 'px',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Line H", label: 'Line H',
key: "line-height", key: 'line-height',
control: Input, control: Input,
placeholder: "lh", placeholder: 'lh',
width: "48px", width: '48px',
textAlign: "center", textAlign: 'center'
}, },
{ {
label: "Color", label: 'Color',
key: "color", key: 'color',
control: Input, control: Input,
placeholder: "hex",
}, },
{ {
label: "align", label: 'align',
key: "text-align", key: 'text-align',
control: FlatButtonGroup, control: FlatButtonGroup,
buttonProps: [ buttonProps: [
{ icon: "ri-align-left", padding: "4px 8px", value: "left" }, { icon: 'ri-align-left', padding: '0px 5px', value: 'left' },
{ icon: "ri-align-center", padding: "4px 8px", value: "center" }, { icon: 'ri-align-center', padding: '0px 5px', value: 'center' },
{ icon: "ri-align-right", padding: "4px 8px", value: "right" }, { icon: 'ri-align-right', padding: '0px 5px', value: 'right' },
{ icon: "ri-align-justify", padding: "4px 8px", value: "justify" }, { icon: 'ri-align-justify', padding: '0px 5px', value: 'justify' }
],
},
{
label: "transform",
key: "text-transform",
control: FlatButtonGroup,
buttonProps: [
{ text: "BB", padding: "4px 8px", fontWeight: 500, value: "uppercase" },
{ text: "Bb", padding: "4px 8px", fontWeight: 500, value: "capitalize" },
{ text: "bb", padding: "4px 8px", fontWeight: 500, value: "lowercase" },
{
text: "&times;",
padding: "4px 8px",
fontWeight: 500,
value: "none",
},
],
},
{ label: "style", key: "font-style", control: Input },
] ]
},
{
label: 'transform',
key: 'text-transform',
control: FlatButtonGroup,
buttonProps: [
{ text: 'BB', padding: '0px 5px', fontWeight: 500, value: 'uppercase' },
{ text: 'Bb', padding: '0px 5px', fontWeight: 500, value: 'capitalize' },
{ text: 'bb', padding: '0px 5px', fontWeight: 500, value: 'lowercase' },
{
text: '&times;',
padding: '0px 5px',
fontWeight: 500,
value: 'none'
}
]
},
{ label: 'style', key: 'font-style', control: Input }
];
export const background = [ export const background = [
{ {
label: "Background", label: 'Background',
key: "background", key: 'background',
control: Input, control: Input,
}, },
{ label: "Image", key: "image", control: Input }, //custom {
] label: "Image",
key: "background-image",
control: Input,
placeholder: "src",
},
];
export const border = [ export const border = [
{ label: "Radius", key: "border-radius", control: Input },
{ label: "Width", key: "border-width", control: Input }, //custom
{ {
label: "Color", label: 'Radius',
key: "border-color", key: 'border-radius',
control: Input, control: Input,
width: '48px',
placeholder: 'px',
textAlign: 'center'
}, },
{ {
label: "Style", label: 'Width',
key: "border-style", key: 'border-width',
control: OptionSelect, control: Input,
options: [ width: '48px',
"none", placeholder: 'px',
"hidden", textAlign: 'center'
"dotted", }, //custom
"dashed", {
"solid", label: 'Color',
"double", key: 'border-color',
"groove", control: Input
"ridge",
"inset",
"outset",
],
}, },
] {
label: 'Style',
key: 'border-style',
control: OptionSelect,
options: [ 'none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset' ]
}
];
export const effects = [ export const effects = [
{ label: "Opacity", key: "opacity", control: Input },
{ {
label: "Rotate", label: 'Opacity',
key: "transform", key: 'opacity',
control: OptionSelect, control: Input,
options: [ width: '48px',
{ label: "None", value: "rotate(0deg)" }, textAlign: 'center',
{ label: "45 degrees", value: "rotate(45deg)" }, placeholder: '%'
{ label: "90 degrees", value: "rotate(90deg)" }, },
{ label: "135 degrees", value: "rotate(135deg)" }, {
{ label: "180 degrees", value: "rotate(180deg)" }, label: 'Rotate',
{ label: "225 degrees", value: "rotate(225deg)" }, key: 'transform',
{ label: "270 degrees", value: "rotate(270deg)" }, control: Input,
{ label: "315 degrees", value: "rotate(315deg)" }, width: '48px',
{ label: "360 degrees", value: "rotate(360deg)" }, textAlign: 'center',
], placeholder: 'deg'
}, //needs special control }, //needs special control
{ label: "Shadow", key: "box-shadow", control: Input }, {
] label: "Shadow",
key: "box-shadow",
control: InputGroup,
meta: [{ placeholder: "X" }, { placeholder: "Y" }, { placeholder: "B" }],
},
];
export const transitions = [ export const transitions = [
{ label: "Property", key: "transition-property", control: Input }, {
{ label: "Duration", key: "transition-timing-function", control: Input }, label: 'Property',
{ label: "Ease", key: "transition-ease", control: Input }, key: 'transition-property',
control: OptionSelect,
options: [
'None',
'All',
'Background Color',
'Color',
'Font Size',
'Font Weight',
'Height',
'Margin',
'Opacity',
'Padding',
'Rotate',
'Shadow',
'Width'
] ]
},
{
label: 'Duration',
key: 'transition-timing-function',
control: Input,
width: '48px',
textAlign: 'center',
placeholder: 'sec'
},
{
label: 'Ease',
key: 'transition-ease',
control: OptionSelect,
options: [ 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out' ]
}
];
export const all = { export const all = {
layout, layout,
@ -351,15 +393,15 @@ export const all = {
background, background,
border, border,
effects, effects,
transitions, transitions
} };
export function excludeProps(props, propsToExclude) { export function excludeProps(props, propsToExclude) {
const modifiedProps = {} const modifiedProps = {};
for (const prop in props) { for (const prop in props) {
if (!propsToExclude.includes(prop)) { if (!propsToExclude.includes(prop)) {
modifiedProps[prop] = props[prop] modifiedProps[prop] = props[prop];
} }
} }
return modifiedProps return modifiedProps;
} }