diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index 19987764e5..8877ccef69 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -285,6 +285,7 @@ export const getFrontendStore = () => { _id: uuid(), _component: definition.component, _styles: { normal: {}, hover: {}, active: {} }, + _transition: "", _instanceName: `New ${definition.name}`, ...cloneDeep(props), ...extras, @@ -487,6 +488,15 @@ export const getFrontendStore = () => { selected._styles = { normal: {}, hover: {}, active: {} } await store.actions.preview.saveSelected() }, + updateTransition: async transition => { + const selected = get(selectedComponent) + if (transition == null || transition === "") { + selected._transition = "" + } else { + selected._transition = transition + } + await store.actions.preview.saveSelected() + }, updateProp: async (name, value) => { let component = get(selectedComponent) if (!name || !component) { diff --git a/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js b/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js index 182736a1d5..c4085e483c 100644 --- a/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js +++ b/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js @@ -14,6 +14,7 @@ export class Component extends BaseStructure { active: {}, selected: {}, }, + _transition: "", _instanceName: "", _children: [], } @@ -39,6 +40,11 @@ export class Component extends BaseStructure { return this } + transition(transition) { + this._json._transition = transition + return this + } + // Shorthand for custom props "type" type(type) { this._json.type = type diff --git a/packages/builder/src/components/design/NavigationPanel/NewScreenModal.svelte b/packages/builder/src/components/design/NavigationPanel/NewScreenModal.svelte index 379144367f..b924aa4b32 100644 --- a/packages/builder/src/components/design/NavigationPanel/NewScreenModal.svelte +++ b/packages/builder/src/components/design/NavigationPanel/NewScreenModal.svelte @@ -1,11 +1,8 @@ -
-
+
+
-
+
{#if groups.length > 0} {#each groups as groupName}
+ {#if componentDefinition?.transitionable} +
+ +
+ {/if}
diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte index 6291917cd0..9980b6712a 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertiesPanel.svelte @@ -24,29 +24,9 @@ const onStyleChanged = store.actions.components.updateStyle const onCustomStyleChanged = store.actions.components.updateCustomStyle + const onUpdateTransition = store.actions.components.updateTransition const onResetStyles = store.actions.components.resetStyles - function walkProps(component, action) { - action(component) - if (component.children) { - for (let child of component.children) { - walkProps(child, action) - } - } - } - - function flattenComponents(props) { - const components = [] - props.forEach(comp => - walkProps(comp, c => { - if ("_component" in c) { - components.push(c) - } - }) - ) - return components - } - function setAssetProps(name, value) { const selectedAsset = get(currentAsset) store.update(state => { @@ -62,10 +42,6 @@ }) store.actions.preview.saveSelected() } - - function getProps(obj, keys) { - return keys.map((key, i) => [key, obj[key], obj.props._id + i]) - } {:else if selectedCategory.value === 'settings'} {#key screenDefinition?._id} -
- -
+
{/key} - - diff --git a/packages/client/src/sdk.js b/packages/client/src/sdk.js index 1a3a4177a8..7eef69441d 100644 --- a/packages/client/src/sdk.js +++ b/packages/client/src/sdk.js @@ -7,6 +7,7 @@ import { builderStore, } from "./store" import { styleable } from "./utils/styleable" +import transition from "./utils/transition" import { linkable } from "./utils/linkable" import Provider from "./components/Provider.svelte" import { ActionTypes } from "./constants" @@ -19,6 +20,7 @@ export default { screenStore, builderStore, styleable, + transition, linkable, Provider, ActionTypes, diff --git a/packages/client/src/store/notification.js b/packages/client/src/store/notification.js index 64757569ed..d69a39080e 100644 --- a/packages/client/src/store/notification.js +++ b/packages/client/src/store/notification.js @@ -1,42 +1,33 @@ -import { writable, derived } from "svelte/store" -import { generate } from "shortid" +import { writable } from "svelte/store" const NOTIFICATION_TIMEOUT = 3000 const createNotificationStore = () => { - const _notifications = writable([]) - let block = false - - const send = (message, type = "default") => { - if (block) { - return - } - _notifications.update(state => { - return [...state, { id: generate(), type, message }] - }) - } - - const blockNotifications = (timeout = 1000) => { - block = true - setTimeout(() => (block = false), timeout) - } - - const notifications = derived(_notifications, ($_notifications, set) => { - set($_notifications) - if ($_notifications.length > 0) { - const timeout = setTimeout(() => { - _notifications.update(state => { - state.shift() - return state - }) - set($_notifications) - }, NOTIFICATION_TIMEOUT) - return () => { - clearTimeout(timeout) - } + const timeoutIds = new Set() + const _notifications = writable([], () => { + return () => { + // clear all the timers + timeoutIds.forEach(timeoutId => { + clearTimeout(timeoutId) + }) + _notifications.set([]) } }) - const { subscribe } = notifications + + const send = (message, type = "default") => { + let _id = id() + _notifications.update(state => { + return [...state, { id: _id, type, message }] + }) + const timeoutId = setTimeout(() => { + _notifications.update(state => { + return state.filter(({ id }) => id !== _id) + }) + }, NOTIFICATION_TIMEOUT) + timeoutIds.add(timeoutId) + } + + const { subscribe } = _notifications return { subscribe, @@ -45,8 +36,16 @@ const createNotificationStore = () => { warning: msg => send(msg, "warning"), info: msg => send(msg, "info"), success: msg => send(msg, "success"), - blockNotifications, } } +function id() { + return ( + "_" + + Math.random() + .toString(36) + .substr(2, 9) + ) +} + export const notificationStore = createNotificationStore() diff --git a/packages/client/src/utils/transition.js b/packages/client/src/utils/transition.js new file mode 100644 index 0000000000..3814c1fc65 --- /dev/null +++ b/packages/client/src/utils/transition.js @@ -0,0 +1,16 @@ +import { fade, blur, scale, fly } from "svelte/transition" + +// Default options +const transitions = new Map([ + ["fade", { tn: fade, opt: {} }], + ["blur", { tn: blur, opt: {} }], + // This one seems to not result in any effect + // ["slide", { tn: slide, opt: {} }], + ["scale", { tn: scale, opt: {} }], + ["fly", { tn: fly, opt: { y: 80 } }], +]) + +export default function transition(node, { type, options = {} }) { + const { tn, opt } = transitions.get(type) || { tn: () => {}, opt: {} } + return tn(node, { ...opt, ...options }) +} diff --git a/packages/server/src/constants/screens.js b/packages/server/src/constants/screens.js index 54c1271efc..54dcc2551d 100644 --- a/packages/server/src/constants/screens.js +++ b/packages/server/src/constants/screens.js @@ -21,6 +21,7 @@ exports.createHomeScreen = () => ({ active: {}, selected: {}, }, + _transition: "fade", type: "div", _children: [ { @@ -69,6 +70,7 @@ exports.createLoginScreen = app => ({ active: {}, selected: {}, }, + _transition: "fade", type: "div", _children: [ { diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json index 14b20dd9ad..b69181b683 100644 --- a/packages/standard-components/manifest.json +++ b/packages/standard-components/manifest.json @@ -5,6 +5,7 @@ "icon": "ri-layout-column-line", "hasChildren": true, "styleable": true, + "transitionable": true, "settings": [ { "type": "select", diff --git a/packages/standard-components/src/Container.svelte b/packages/standard-components/src/Container.svelte index 22139d7d7e..8f49ba0ca9 100644 --- a/packages/standard-components/src/Container.svelte +++ b/packages/standard-components/src/Container.svelte @@ -1,62 +1,62 @@ {#if type === 'div'} -
+
{:else if type === 'header'} -
+
{:else if type === 'main'} -
+
{:else if type === 'footer'} -