From 21b2706cea8f8cb8ce674f34fa3748e9de604825 Mon Sep 17 00:00:00 2001 From: Gerard Burns Date: Fri, 25 Nov 2022 10:02:43 +0000 Subject: [PATCH] Skeleton Loading States (#8719) * Loading Skeletons * PR Feedback --- packages/bbui/src/Skeleton/Skeleton.svelte | 56 +++++++++++++++++++ packages/bbui/src/Table/Table.svelte | 20 +++++-- packages/bbui/src/index.js | 1 + packages/client/manifest.json | 23 ++++++-- .../src/components/BlockComponent.svelte | 1 + .../client/src/components/Component.svelte | 16 +++++- packages/client/src/components/Router.svelte | 4 ++ .../src/components/app/DataProvider.svelte | 46 +++++++-------- .../client/src/components/app/Repeater.svelte | 13 +++-- .../client/src/components/app/Skeleton.svelte | 31 ++++++++++ .../app/forms/AttachmentField.svelte | 36 +++++++----- .../src/components/app/forms/Field.svelte | 7 +++ .../src/components/app/table/Table.svelte | 14 ++++- 13 files changed, 207 insertions(+), 61 deletions(-) create mode 100644 packages/bbui/src/Skeleton/Skeleton.svelte create mode 100644 packages/client/src/components/app/Skeleton.svelte diff --git a/packages/bbui/src/Skeleton/Skeleton.svelte b/packages/bbui/src/Skeleton/Skeleton.svelte new file mode 100644 index 0000000000..e12d37b057 --- /dev/null +++ b/packages/bbui/src/Skeleton/Skeleton.svelte @@ -0,0 +1,56 @@ +
+
+ +
+
+ + diff --git a/packages/bbui/src/Table/Table.svelte b/packages/bbui/src/Table/Table.svelte index 7745c3c407..d6be0e8c9b 100644 --- a/packages/bbui/src/Table/Table.svelte +++ b/packages/bbui/src/Table/Table.svelte @@ -71,7 +71,8 @@ visibleRowCount, rowCount, totalRowCount, - rowHeight + rowHeight, + loading ) $: sortedRows = sortRows(rows, sortColumn, sortOrder) $: gridStyle = getGridStyle(fields, schema, showEditColumn) @@ -120,8 +121,12 @@ visibleRowCount, rowCount, totalRowCount, - rowHeight + rowHeight, + loading ) => { + if (loading) { + return `height: ${headerHeight + visibleRowCount * rowHeight}px;` + } if (!rowCount || !visibleRowCount || totalRowCount <= rowCount) { return "" } @@ -277,9 +282,11 @@ bind:offsetHeight={height} style={`--row-height: ${rowHeight}px; --header-height: ${headerHeight}px;`} > - {#if !loaded} + {#if loading}
- + + +
{:else}
@@ -438,9 +445,10 @@ /* Loading */ .loading { - display: grid; - place-items: center; + display: flex; + align-items: center; min-height: 100px; + justify-content: center; } /* Table */ diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index 538a62188f..601c4dcbca 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -4,6 +4,7 @@ import "./bbui.css" import "@spectrum-css/icon/dist/index-vars.css" // Components +export { default as Skeleton } from "./Skeleton/Skeleton.svelte" export { default as Input } from "./Form/Input.svelte" export { default as Stepper } from "./Form/Stepper.svelte" export { default as TextArea } from "./Form/TextArea.svelte" diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 8ded099d80..1f29012197 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -284,7 +284,7 @@ "editable": true, "size": { "width": 105, - "height": 35 + "height": 32 }, "settings": [ { @@ -683,7 +683,7 @@ "editable": true, "size": { "width": 400, - "height": 30 + "height": 24 }, "settings": [ { @@ -808,7 +808,7 @@ "editable": true, "size": { "width": 400, - "height": 40 + "height": 32 }, "settings": [ { @@ -2447,6 +2447,7 @@ ] }, "stringfield": { + "skeleton": false, "name": "Text Field", "icon": "Text", "styles": [ @@ -2455,7 +2456,7 @@ "editable": true, "size": { "width": 400, - "height": 50 + "height": 32 }, "settings": [ { @@ -2538,6 +2539,7 @@ ] }, "numberfield": { + "skeleton": false, "name": "Number Field", "icon": "123", "styles": [ @@ -2652,6 +2654,7 @@ ] }, "optionsfield": { + "skeleton": false, "name": "Options Picker", "icon": "Menu", "styles": [ @@ -2820,6 +2823,7 @@ ] }, "multifieldselect": { + "skeleton": false, "name": "Multi-select Picker", "icon": "ViewList", "styles": [ @@ -2982,12 +2986,13 @@ ] }, "booleanfield": { + "skeleton": false, "name": "Checkbox", "icon": "SelectBox", "editable": true, "size": { - "width": 400, - "height": 50 + "width": 20, + "height": 20 }, "settings": [ { @@ -3139,6 +3144,7 @@ ] }, "datetimefield": { + "skeleton": false, "name": "Date Picker", "icon": "Date", "styles": [ @@ -3220,6 +3226,7 @@ ] }, "codescanner": { + "skeleton": false, "name": "Barcode/QR Scanner", "icon": "Camera", "styles": [ @@ -3385,6 +3392,7 @@ ] }, "attachmentfield": { + "skeleton": false, "name": "Attachment", "icon": "Attach", "styles": [ @@ -3443,6 +3451,7 @@ ] }, "relationshipfield": { + "skeleton": false, "name": "Relationship Picker", "icon": "TaskList", "styles": [ @@ -3506,6 +3515,7 @@ ] }, "jsonfield": { + "skeleton": false, "name": "JSON Field", "icon": "Brackets", "styles": [ @@ -3707,6 +3717,7 @@ } }, "table": { + "skeleton": false, "name": "Table", "icon": "Table", "illegalChildren": [ diff --git a/packages/client/src/components/BlockComponent.svelte b/packages/client/src/components/BlockComponent.svelte index 0131c5f0d4..c23a31b8b9 100644 --- a/packages/client/src/components/BlockComponent.svelte +++ b/packages/client/src/components/BlockComponent.svelte @@ -23,6 +23,7 @@ // to render this part of the block, taking advantage of binding enrichment $: id = `${block.id}-${context ?? rand}` $: instance = { + _blockElementHasChildren: $$slots?.default ?? false, _component: `@budibase/standard-components/${type}`, _id: id, _instanceName: type[0].toUpperCase() + type.slice(1), diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index b98548fc9c..c44225cd71 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -29,6 +29,7 @@ import Placeholder from "components/app/Placeholder.svelte" import ScreenPlaceholder from "components/app/ScreenPlaceholder.svelte" import ComponentPlaceholder from "components/app/ComponentPlaceholder.svelte" + import Skeleton from "components/app/Skeleton.svelte" export let instance = {} export let isLayout = false @@ -38,6 +39,7 @@ // Get parent contexts const context = getContext("context") + const loading = getContext("loading") const insideScreenslot = !!getContext("screenslot") // Create component context @@ -470,9 +472,21 @@ componentStore.actions.unregisterInstance(id) } }) + + $: showSkeleton = + $loading && + definition.name !== "Screenslot" && + children.length === 0 && + !instance._blockElementHasChildren && + definition.skeleton !== false -{#if constructor && initialSettings && (visible || inSelectedPath) && !builderHidden} +{#if showSkeleton} + +{:else if constructor && initialSettings && (visible || inSelectedPath) && !builderHidden}
+ import { writable } from "svelte/store" import { setContext, getContext, onMount } from "svelte" import Router, { querystring } from "svelte-spa-router" import { routeStore, stateStore } from "stores" @@ -9,6 +10,9 @@ const component = getContext("component") setContext("screenslot", true) + const loading = writable(false) + setContext("loading", loading) + // Only wrap this as an array to take advantage of svelte keying, // to ensure the svelte-spa-router is fully remounted when route config // changes diff --git a/packages/client/src/components/app/DataProvider.svelte b/packages/client/src/components/app/DataProvider.svelte index 8cd2f00eec..c28cdef24c 100644 --- a/packages/client/src/components/app/DataProvider.svelte +++ b/packages/client/src/components/app/DataProvider.svelte @@ -1,6 +1,7 @@ {#if $component.empty} - {:else if rows.length > 0} + {:else if !$loading && rows.length === 0} +
{noRowsMessage}
+ {:else} {#each rows as row, index} {/each} - {:else if loaded && noRowsMessage} -
{noRowsMessage}
{/if}
diff --git a/packages/client/src/components/app/Skeleton.svelte b/packages/client/src/components/app/Skeleton.svelte new file mode 100644 index 0000000000..5c247bf3e4 --- /dev/null +++ b/packages/client/src/components/app/Skeleton.svelte @@ -0,0 +1,31 @@ + + +
+ + + +
diff --git a/packages/client/src/components/app/forms/AttachmentField.svelte b/packages/client/src/components/app/forms/AttachmentField.svelte index 9887901d4c..da04c57e82 100644 --- a/packages/client/src/components/app/forms/AttachmentField.svelte +++ b/packages/client/src/components/app/forms/AttachmentField.svelte @@ -76,18 +76,26 @@ bind:fieldApi defaultValue={[]} > - {#if fieldState} - - {/if} +
+ {#if fieldState} + + {/if} +
+ + diff --git a/packages/client/src/components/app/forms/Field.svelte b/packages/client/src/components/app/forms/Field.svelte index d6dddbbe39..a14c6ac9c8 100644 --- a/packages/client/src/components/app/forms/Field.svelte +++ b/packages/client/src/components/app/forms/Field.svelte @@ -1,6 +1,7 @@