From 06bbc88b3e37ccef13ea70fb332b8efd9d380cd4 Mon Sep 17 00:00:00 2001 From: Conor_Mack Date: Mon, 4 May 2020 16:07:04 +0100 Subject: [PATCH] WIP: Changes for property panel --- .../userInterface/CategoryTab.svelte | 43 ++++++ .../ComponentPropertiesPanel.svelte | 129 ++++++++---------- .../ComponentSelectionList.svelte | 16 +-- .../userInterface/DesignView.svelte | 17 +++ .../userInterface/PropertyGroup.svelte | 72 ++++++++++ .../userInterface/propertyCategories.js | 77 +++++++++++ .../userInterface/temporaryPanelStructure.js | 33 +++-- 7 files changed, 289 insertions(+), 98 deletions(-) create mode 100644 packages/builder/src/components/userInterface/CategoryTab.svelte create mode 100644 packages/builder/src/components/userInterface/DesignView.svelte create mode 100644 packages/builder/src/components/userInterface/PropertyGroup.svelte create mode 100644 packages/builder/src/components/userInterface/propertyCategories.js diff --git a/packages/builder/src/components/userInterface/CategoryTab.svelte b/packages/builder/src/components/userInterface/CategoryTab.svelte new file mode 100644 index 0000000000..246c1141e8 --- /dev/null +++ b/packages/builder/src/components/userInterface/CategoryTab.svelte @@ -0,0 +1,43 @@ + + + + + diff --git a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte index c4c57c8e04..84480b2d69 100644 --- a/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte +++ b/packages/builder/src/components/userInterface/ComponentPropertiesPanel.svelte @@ -14,17 +14,33 @@ import LayoutEditor from "./LayoutEditor.svelte" import EventsEditor from "./EventsEditor" - let current_view = "props" - let codeEditor + import panelStructure from "./temporaryPanelStructure.js" + import CategoryTab from "./CategoryTab.svelte" + import DesignView from "./DesignView.svelte" + + let current_view = "design" + let codeEditor + let flattenedPanel = flattenComponents(panelStructure.categories) + let categories = [ + { name: "Design" }, + { name: "Settings" }, + { name: "Actions" }, + ] + let selectedCategory = categories[0] - $: component = $store.currentComponentInfo - $: originalName = component.name - $: name = - $store.currentView === "detail" - ? $store.currentPreviewItem.name - : component._component - $: description = component.description $: components = $store.components + $: componentInstance = $store.currentComponentInfo //contains prop values of currently selected component + $: componentDefinition = $store.components.find( + c => c.name === componentInstance._component + ) + + $: panelDefinition = flattenedPanel.find( + //use for getting controls for each component property + c => c._component === componentInstance._component + ) + + // OLD PROPS ============================================= + $: screen_props = $store.currentFrontEndType === "page" ? getProps($store.currentPreviewItem, ["name", "favicon"]) @@ -33,77 +49,47 @@ const onPropChanged = store.setComponentProp const onStyleChanged = store.setComponentStyle + //May be able to remove some of the nested components in PropsView, PropsControl and StateBindingControl tree + + 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 getProps(obj, keys) { return keys.map((k, i) => [k, obj[k], obj.props._id + i]) }
- + + (selectedCategory = category)} + {categories} + {selectedCategory} /> +
- - {#if current_view === 'props'} - {#if $store.currentView === 'detail'} - {#each screen_props as [k, v, id] (id)} -
- - store.setMetadataProp(k, target.value)} /> -
- {/each} - - {:else} - - {/if} - {:else if current_view === 'layout'} - - {:else if current_view === 'events'} - + {#if current_view === 'design'} + + {/if} - -
@@ -146,7 +132,6 @@ .root { height: 100%; - padding: 20px; display: flex; flex-direction: column; } diff --git a/packages/builder/src/components/userInterface/ComponentSelectionList.svelte b/packages/builder/src/components/userInterface/ComponentSelectionList.svelte index eb27559933..139dd65c59 100644 --- a/packages/builder/src/components/userInterface/ComponentSelectionList.svelte +++ b/packages/builder/src/components/userInterface/ComponentSelectionList.svelte @@ -2,6 +2,7 @@ import { splitName } from "./pagesParsing/splitRootComponentName.js" import components from "./temporaryPanelStructure.js" import ConfirmDialog from "components/common/ConfirmDialog.svelte" + import CategoryTab from "./CategoryTab.svelte" import { find, sortBy, @@ -85,15 +86,12 @@
- + + (selectedCategory = category)} + {selectedCategory} + {categories} /> +
+ import PropertyGroup from "./PropertyGroup.svelte" + export let panelDefinition = {} + export let componentInstance = {} + export let componentDefinition = {} + const getProperties = prop => panelDefinition.props[prop] + + $: props = !!panelDefinition.props && Object.keys(panelDefinition.props) + + +{#each props as prop} + +{/each} diff --git a/packages/builder/src/components/userInterface/PropertyGroup.svelte b/packages/builder/src/components/userInterface/PropertyGroup.svelte new file mode 100644 index 0000000000..1b424dcd28 --- /dev/null +++ b/packages/builder/src/components/userInterface/PropertyGroup.svelte @@ -0,0 +1,72 @@ + + +
(show = !show)}> +
+
+ +
+
{capitalize(title)}
+
+
+
    + {#each propertyKeys as key} + +
  • {content[key].displayName || capitalize(key)}
  • + + {/each} +
+
+
+ + diff --git a/packages/builder/src/components/userInterface/propertyCategories.js b/packages/builder/src/components/userInterface/propertyCategories.js new file mode 100644 index 0000000000..8b662d443c --- /dev/null +++ b/packages/builder/src/components/userInterface/propertyCategories.js @@ -0,0 +1,77 @@ + +/* + TODO: all strings types are really inputs and could be typed as such + TODO: Options types need option items + TODO: Allow for default values for all properties +*/ + +export const layout = { + flexDirection: { displayName: "Direction", type: "string" }, + justifyContent: { displayName: "Justify", type: "string" }, + alignItems: { displayName: "Align", type: "string" }, + flexWrap: { displayName: "Wrap", type: "options" }, +} + +export const spacing = { + padding: { type: "string" }, + margin: { type: "string" }, +} + +export const size = { + width: { type: "string" }, + height: { type: "string" }, + minWidth: { displayName: "Min W", type: "string" }, + minHeight: { displayName: "Min H", type: "string" }, + maxWidth: { displayName: "Max W", type: "string" }, + maxHeight: { displayName: "Max H", type: "string" }, + overflow: { type: "string" }, //custom +} + +export const position = { + position: { type: "options" }, +} + +export const typography = { + font: { type: "options" }, + weight: { type: "options" }, + size: { type: "string" }, + lineHeight: { displayName: "Line H", type: "string" }, + color: { type: "colour" }, + align: { type: "string" }, //custom + transform: { type: "string" }, //custom + style: { type: "string" }, //custom +} + +export const background = { + backgroundColor: { displayName: "Background Color", type: "colour" }, + image: { type: "string" }, //custom +} + +export const border = { + radius: { type: "string" }, + width: { type: "string" }, //custom + color: { type: "colour" }, + style: { type: "options" }, +} + +export const effects = { + opacity: "string", + rotate: "string", + shadow: "string", +} + +export const transitions = { + property: { type: "options" }, + duration: { type: "string" }, + ease: { type: "options" }, +} + +export function excludeProps(props, propsToExclude) { + const modifiedProps = {} + for (const prop in props) { + if (!propsToExclude.includes(prop)) { + modifiedProps[prop] = props[prop] + } + } + return modifiedProps +} diff --git a/packages/builder/src/components/userInterface/temporaryPanelStructure.js b/packages/builder/src/components/userInterface/temporaryPanelStructure.js index 5c4188d311..07facd4e28 100644 --- a/packages/builder/src/components/userInterface/temporaryPanelStructure.js +++ b/packages/builder/src/components/userInterface/temporaryPanelStructure.js @@ -1,3 +1,5 @@ +import { layout, background } from "./propertyCategories.js" + export default { categories: [ { @@ -10,7 +12,8 @@ export default { description: 'This component contains things within itself', icon: 'ri-layout-row-fill', commonProps: {}, - children: [] + children: [], + props: { layout, background }, }, { name: 'Text', @@ -24,12 +27,8 @@ export default { description: "A component for displaying heading text", icon: "ri-heading", props: { - type: { - type: "options", - options: ["h1", "h2", "h3", "h4", "h5", "h6"], - default: "h1", - }, - text: "string", + layout, + background, }, }, { @@ -82,15 +81,15 @@ export default { name: 'Button', description: 'A basic html button that is ready for styling', icon: 'ri-radio-button-fill', - commonProps: {}, - children: [] + children: [], + props: {}, }, { _component: "@budibase/standard-components/icon", name: 'Icon', description: 'A basic component for displaying icons', icon: 'ri-sun-fill', - commonProps: {}, + props: {}, children: [] }, { @@ -98,7 +97,7 @@ export default { name: 'Link', description: 'A basic link component for internal and external links', icon: 'ri-link', - commonProps: {}, + props: {}, children: [] } ] @@ -112,14 +111,14 @@ export default { name: 'Card', description: 'A basic card component that can contain content and actions.', icon: 'ri-layout-bottom-line', - commonProps: {}, + props: {}, children: [] }, { name: 'Login', description: 'A component that automatically generates a login screen for your app.', icon: 'ri-login-box-fill', - commonProps: {}, + props: {}, children: [] }, { @@ -127,7 +126,7 @@ export default { _component: "@budibase/standard-components/Navigation", description: "A component for handling the navigation within your app.", icon: "ri-navigation-fill", - commonProps: {}, + props: {}, children: [] } ] @@ -140,15 +139,15 @@ export default { name: 'Table', description: 'A component that generates a table from your data.', icon: 'ri-archive-drawer-fill', - commonProps: {}, + props: {}, children: [] }, { name: 'Form', description: 'A component that generates a form from your data.', icon: 'ri-file-edit-fill', - commonProps: {}, - component: "@budibase/materialdesign-components/Form", + props: {}, + _component: "@budibase/materialdesign-components/Form", template: { component: "@budibase/materialdesign-components/Form", description: "Form for saving a record",