diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..afaa6dc --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: Release + +on: + push: + branches: + - master + - main + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v1 + with: + node-version: 16 + - name: Make the production plugin bundle + run: | + release_version=$(cat package.json | jq -r '.version') + echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV + yarn + yarn build + - name: Perform Github Release + uses: softprops/action-gh-release@v1 + with: + name: v${{ env.RELEASE_VERSION }} + tag_name: v${{ env.RELEASE_VERSION }} + generate_release_notes: true + files: | + dist/*.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6706b91 --- /dev/null +++ b/.gitignore @@ -0,0 +1,106 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +.idea/ diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..aeff293 --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +node_modules +.github +rollup.config.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..d43108e --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# Budibase-component +This is a readme for your new Budibase plugin. + +# Description +An amazing Budibase component! + +Find out more about [Budibase](https://github.com/Budibase/budibase). + +## Instructions + +To build your new plugin run the following in your Budibase CLI: +``` +budi plugins --build +``` + +You can also re-build everytime you make a change to your plugin with the command: +``` +budi plugins --watch +``` + diff --git a/index.js b/index.js new file mode 100644 index 0000000..91535e1 --- /dev/null +++ b/index.js @@ -0,0 +1,18 @@ +import Wrapper from "./lib/Wrapper.svelte" +import schema from "./schema.json" +import pkg from "./package.json" + +if (window) { + const plugin = { Component: Wrapper, schema, version: pkg.version } + if (!window["##BUDIBASE_CUSTOM_COMPONENTS##"]) { + window["##BUDIBASE_CUSTOM_COMPONENTS##"] = [] + } + window["##BUDIBASE_CUSTOM_COMPONENTS##"].push(plugin) + if (window.registerCustomComponent) { + window.registerCustomComponent(plugin) + } +} + +export const Component = Wrapper +export const version = pkg.version +export { schema } diff --git a/lib/Boundary.js b/lib/Boundary.js new file mode 100644 index 0000000..0e75577 --- /dev/null +++ b/lib/Boundary.js @@ -0,0 +1,4 @@ +import Boundary from "./Boundary.svelte" +import { createBoundary } from "@crownframework/svelte-error-boundary" + +export default createBoundary(Boundary); \ No newline at end of file diff --git a/lib/Boundary.svelte b/lib/Boundary.svelte new file mode 100644 index 0000000..64e2cc9 --- /dev/null +++ b/lib/Boundary.svelte @@ -0,0 +1,51 @@ + + + +{#if $error} +
+ There was an error running the "{pkg.name}" plugin: +
+ {$error} +
+
+{:else} + +{/if} + + \ No newline at end of file diff --git a/lib/Wrapper.svelte b/lib/Wrapper.svelte new file mode 100644 index 0000000..2c50d40 --- /dev/null +++ b/lib/Wrapper.svelte @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..0d93c8c --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "budibase-component-dropdown-list", + "version": "1.0.0", + "description": "A dropdown list Budibase component", + "license": "MIT", + "svelte": "index.js", + "module": "dist/plugin.min.js", + "scripts": { + "build": "rollup -c", + "watch": "rollup -cw" + }, + "dependencies": { + "@crownframework/svelte-error-boundary": "^1.0.3", + "svelte": "^3.49.0", + "svelte-outclick": "^3.3.3" + }, + "devDependencies": { + "@budibase/backend-core": "^2.0.13", + "@rollup/plugin-commonjs": "^18.0.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "npm-run-all": "^4.1.5", + "postcss": "^8.2.10", + "rollup": "^2.44.0", + "rollup-plugin-copy2": "^0.3.1", + "rollup-plugin-json": "^4.0.0", + "rollup-plugin-polyfill-node": "^0.8.0", + "rollup-plugin-postcss": "^4.0.0", + "rollup-plugin-svelte": "^7.1.0", + "rollup-plugin-svg": "^2.0.0", + "rollup-plugin-terser": "^7.0.2", + "tar": "^6.1.11" + } +} diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..ddb2b4c --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,122 @@ +import commonjs from "@rollup/plugin-commonjs" +import resolve from "@rollup/plugin-node-resolve" +import svelte from "rollup-plugin-svelte" +import { terser } from "rollup-plugin-terser" +import postcss from "rollup-plugin-postcss" +import svg from "rollup-plugin-svg" +import json from "rollup-plugin-json" +import nodePolyfills from "rollup-plugin-polyfill-node" +import copy from "rollup-plugin-copy2" +import tar from "tar" +import fs from "fs" +import pkg from "./package.json" +import crypto from "crypto" +import { validate } from "@budibase/backend-core/plugins" + +const ignoredWarnings = [ + "unused-export-let", + "css-unused-selector", + "module-script-reactive-declaration", + "a11y-no-onchange", +] + +// Custom plugin to clean the dist folder before building +const clean = () => ({ + buildStart() { + const dist = "./dist/" + if (fs.existsSync(dist)) { + fs.readdirSync(dist).forEach(path => { + if (path.endsWith(".tar.gz")) { + fs.unlinkSync(dist + path) + } + }) + } + }, +}) + +// Custom plugin to hash the JS bundle and write it in the schema +const hash = () => ({ + writeBundle() { + // Generate JS hash + const fileBuffer = fs.readFileSync("dist/plugin.min.js") + const hashSum = crypto.createHash("sha1") + hashSum.update(fileBuffer) + const hex = hashSum.digest("hex") + + // Read and parse existing schema from dist folder + const schema = JSON.parse(fs.readFileSync("./dist/schema.json", "utf8")) + + // Write updated schema to dist folder, pretty printed as JSON again + const newSchema = { + ...schema, + hash: hex, + version: pkg.version, + } + fs.writeFileSync("./dist/schema.json", JSON.stringify(newSchema, null, 2)) + }, +}) + +// Custom plugin to bundle up our files after building +const bundle = () => ({ + async writeBundle() { + const bundleName = `${pkg.name}-${pkg.version}.tar.gz` + return tar + .c({ gzip: true, cwd: "dist" }, [ + "plugin.min.js", + "schema.json", + "package.json", + ]) + .pipe(fs.createWriteStream(`dist/${bundleName}`)) + }, +}) + +const validateSchema = () => ({ + buildStart() { + const schema = fs.readFileSync("schema.json", "utf8") + validate(JSON.parse(schema)) + } +}) + +export default { + input: "index.js", + output: { + sourcemap: process.env.ROLLUP_WATCH ? "inline" : false, + format: "iife", + file: "dist/plugin.min.js", + name: "plugin", + globals: { + svelte: "svelte", + "svelte/internal": "svelte_internal", + }, + }, + external: ["svelte", "svelte/internal"], + plugins: [ + validateSchema(), + clean(), + svelte({ + emitCss: true, + onwarn: (warning, handler) => { + // Ignore some warnings + if (!ignoredWarnings.includes(warning.code)) { + handler(warning) + } + }, + }), + postcss(), + commonjs(), + nodePolyfills(), + resolve({ + preferBuiltins: true, + browser: true, + skip: ["svelte", "svelte/internal"], + }), + svg(), + json(), + terser(), + copy({ + assets: ["schema.json", "package.json"], + }), + hash(), + bundle(), + ], +} diff --git a/schema.json b/schema.json new file mode 100644 index 0000000..ccdeaa1 --- /dev/null +++ b/schema.json @@ -0,0 +1,14 @@ +{ + "type": "component", + "metadata": {}, + "schema": { + "name": "dropdown-list", + "friendlyName": "Dropdown List", + "description": "A dropdown list Budibase component", + "icon": "Button", + "hasChildren": true, + "illegalChildren": ["section"], + "showSettingsBar": true, + "settings": [] + } +} diff --git a/screenshots/1.jpg b/screenshots/1.jpg new file mode 100644 index 0000000..efc8abe Binary files /dev/null and b/screenshots/1.jpg differ diff --git a/screenshots/2.gif b/screenshots/2.gif new file mode 100644 index 0000000..e8a2588 Binary files /dev/null and b/screenshots/2.gif differ diff --git a/src/Component.svelte b/src/Component.svelte new file mode 100644 index 0000000..ce1986b --- /dev/null +++ b/src/Component.svelte @@ -0,0 +1,48 @@ + + +
+ (active = false)}> + + + {#if active === true} + + {/if} + +
+ +