diff --git a/packages/builder/src/components/design/AppPreview/componentStructure.json b/packages/builder/src/components/design/AppPreview/componentStructure.json
index 3bc2554fde..b6675c2480 100644
--- a/packages/builder/src/components/design/AppPreview/componentStructure.json
+++ b/packages/builder/src/components/design/AppPreview/componentStructure.json
@@ -1,4 +1,11 @@
[
+ {
+ "name": "Blocks",
+ "icon": "Article",
+ "children": [
+ "tablewithsearch"
+ ]
+ },
"section",
"container",
"dataprovider",
diff --git a/packages/client/manifest.json b/packages/client/manifest.json
index 2adfd96626..9b0bf7605c 100644
--- a/packages/client/manifest.json
+++ b/packages/client/manifest.json
@@ -2574,5 +2574,88 @@
"label": "Horizontal"
}
]
+ },
+ "tablewithsearch": {
+ "block": true,
+ "name": "Table with search",
+ "icon": "Table",
+ "styles": ["size"],
+ "settings": [
+ {
+ "type": "dataSource",
+ "label": "Data",
+ "key": "dataSource"
+ },
+ {
+ "type": "multifield",
+ "label": "Search Columns",
+ "key": "searchColumns",
+ "dependsOn": "dataSource",
+ "placeholder": "All columns"
+ },
+ {
+ "type": "filter",
+ "label": "Filtering",
+ "key": "filter"
+ },
+ {
+ "type": "field",
+ "label": "Sort Column",
+ "key": "sortColumn"
+ },
+ {
+ "type": "select",
+ "label": "Sort Order",
+ "key": "sortOrder",
+ "options": ["Ascending", "Descending"],
+ "defaultValue": "Descending"
+ },
+ {
+ "type": "boolean",
+ "label": "Paginate",
+ "key": "paginate",
+ "defaultValue": true
+ },
+ {
+ "type": "number",
+ "label": "Row Count",
+ "key": "rowCount",
+ "defaultValue": 8
+ },
+ {
+ "type": "multifield",
+ "label": "Table Columns",
+ "key": "tableColumns",
+ "dependsOn": "dataSource",
+ "placeholder": "All columns"
+ },
+ {
+ "type": "select",
+ "label": "Size",
+ "key": "size",
+ "defaultValue": "spectrum--medium",
+ "options": [
+ {
+ "label": "Medium",
+ "value": "spectrum--medium"
+ },
+ {
+ "label": "Large",
+ "value": "spectrum--large"
+ }
+ ]
+ },
+ {
+ "type": "boolean",
+ "label": "Quiet",
+ "key": "quiet"
+ },
+ {
+ "type": "boolean",
+ "label": "Auto Columns",
+ "key": "showAutoColumns",
+ "defaultValue": false
+ }
+ ]
}
}
diff --git a/packages/client/src/components/app/blocks/TableWithSearch.svelte b/packages/client/src/components/app/blocks/TableWithSearch.svelte
new file mode 100644
index 0000000000..dba50eb4b8
--- /dev/null
+++ b/packages/client/src/components/app/blocks/TableWithSearch.svelte
@@ -0,0 +1,99 @@
+
+
+
+
+
diff --git a/packages/client/src/components/app/blocks/block-builder.js b/packages/client/src/components/app/blocks/block-builder.js
new file mode 100644
index 0000000000..2d56094806
--- /dev/null
+++ b/packages/client/src/components/app/blocks/block-builder.js
@@ -0,0 +1,14 @@
+import { ComponentBuilder } from "./component-builder"
+
+export class BlockBuilder {
+ context
+ componentCount = 0
+
+ constructor(context) {
+ this.context = context
+ }
+
+ createComponent(type, props) {
+ return new ComponentBuilder(this, type, props)
+ }
+}
diff --git a/packages/client/src/components/app/blocks/component-builder.js b/packages/client/src/components/app/blocks/component-builder.js
new file mode 100644
index 0000000000..90ce30c066
--- /dev/null
+++ b/packages/client/src/components/app/blocks/component-builder.js
@@ -0,0 +1,49 @@
+export class ComponentBuilder {
+ context
+
+ constructor(blockBuilder, type, props) {
+ this.blockBuilder = blockBuilder
+ this.type = type
+ this.id = `${blockBuilder.context.id}-${blockBuilder.componentCount++}`
+ this.props = props
+ this.children = []
+ this.styles = null
+ }
+
+ setProp(key, value) {
+ this.props[key] = value
+ return this
+ }
+
+ setProps(props) {
+ this.props = {
+ ...this.props,
+ ...props,
+ }
+ return this
+ }
+
+ setStyles(styles) {
+ this.styles = styles
+ return this
+ }
+
+ addChild(component) {
+ this.children.push(component)
+ return this
+ }
+
+ build() {
+ return {
+ _component: `@budibase/standard-components/${this.type}`,
+ _id: this.id,
+ _children: this.children?.map(child => child.build()),
+ _styles: {
+ normal: {
+ ...this.styles,
+ },
+ },
+ ...this.props,
+ }
+ }
+}
diff --git a/packages/client/src/components/app/blocks/index.js b/packages/client/src/components/app/blocks/index.js
new file mode 100644
index 0000000000..16b123d17e
--- /dev/null
+++ b/packages/client/src/components/app/blocks/index.js
@@ -0,0 +1 @@
+export { default as tablewithsearch } from "./TableWithSearch.svelte"
diff --git a/packages/client/src/components/app/index.js b/packages/client/src/components/app/index.js
index b01763e2f0..92725f0738 100644
--- a/packages/client/src/components/app/index.js
+++ b/packages/client/src/components/app/index.js
@@ -32,6 +32,7 @@ export { default as spectrumcard } from "./SpectrumCard.svelte"
export * from "./charts"
export * from "./forms"
export * from "./table"
+export * from "./blocks"
// Deprecated component left for compatibility in old apps
export { default as navigation } from "./deprecated/Navigation.svelte"