Skip to content

Commit

Permalink
Build UI builder with live svelte (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
cibernox authored Apr 1, 2024
1 parent 5d3345f commit 28a0d0c
Show file tree
Hide file tree
Showing 67 changed files with 16,347 additions and 1,603 deletions.
4 changes: 1 addition & 3 deletions .dialyzer_ignore.exs
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
[
{"lib/beacon/live_admin/components.ex", :unknown_function}
]
[]
10 changes: 5 additions & 5 deletions .github/workflows/elixir.yml → .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Elixir CI
name: CI

on:
push:
Expand Down Expand Up @@ -119,10 +119,10 @@ jobs:
- run: mix deps.get

- run: mix tailwind.install --no-assets

- run: mix compile --warnings-as-errors

- run: mix format --check-formatted
- run: mix assets.setup

- run: mix format.all.check

- run: mix deps.unlock --check-unused
- run: mix deps.unlock --check-unused
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,15 @@ npm-debug.log

# Local iex config
.iex.exs

# Ignore automatically generated Svelte files by the ~V sigil
/assets/svelte/_build/

# Ignore ssr build for svelte.
/priv/svelte/

# Ignore automatically generated Svelte files by the ~V sigil
/assets/svelte/_build/

# Ignore ssr build for svelte.
/priv/svelte/
15 changes: 15 additions & 0 deletions assets/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
env: {
browser: true,
node: true,
es2021: true,
},
extends: ["eslint:recommended", "prettier"],
globals: {
global: "writable",
},
parserOptions: {
ecmaVersion: 12,
sourceType: "module",
},
}
2 changes: 2 additions & 0 deletions assets/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
css/app.css
/vendor/
6 changes: 6 additions & 0 deletions assets/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
printWidth: 120,
semi: false,
plugins: ["prettier-plugin-svelte"],
overrides: [{ files: "*.svelte", options: { parser: "svelte" } }],
}
80 changes: 80 additions & 0 deletions assets/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
const esbuild = require("esbuild")
const sveltePlugin = require("esbuild-svelte")
const importGlobPlugin = require("esbuild-plugin-import-glob").default
const sveltePreprocess = require("svelte-preprocess")

const args = process.argv.slice(2)
const watch = args.includes("--watch")
const deploy = args.includes("--deploy")

let optsClient = {
entryPoints: ["js/beacon_live_admin.js"],
globalName: "BeaconLiveAdmin",
format: "iife",
loader: {
".ttf": "dataurl",
".woff": "dataurl",
".woff2": "dataurl",
},
bundle: true,
minify: deploy,
target: "es2020",
conditions: ["svelte", "browser"],
outfile: deploy ? "../priv/static/beacon_live_admin.min.js" : "../priv/static/beacon_live_admin.js",
logLevel: "info",
sourcemap: "external",
tsconfig: "./tsconfig.json",
plugins: [
importGlobPlugin(),
sveltePlugin({
preprocess: sveltePreprocess(),
compilerOptions: {
dev: !deploy,
hydratable: true,
css: "injected",
customElement: true,
},
}),
],
}

let optsServer = {
entryPoints: ["js/server.js"],
platform: "node",
bundle: true,
minify: deploy,
target: "node19.6.1",
conditions: ["svelte"],
outdir: "../priv/svelte",
logLevel: "info",
sourcemap: "external",
tsconfig: "./tsconfig.json",
plugins: [
importGlobPlugin(),
sveltePlugin({
preprocess: sveltePreprocess(),
compilerOptions: {
dev: !deploy,
hydratable: true,
generate: "ssr",
customElement: true,
},
}),
],
}

esbuild.build(optsServer)

if (watch) {
esbuild
.context(optsClient)
.then((ctx) => {
ctx.watch()
})
.catch((error) => {
console.log(error)
process.exit(1)
})
} else {
esbuild.build(optsClient)
}
2 changes: 1 addition & 1 deletion assets/css/beacon_live_admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "../../deps/live_monaco_editor/priv/static/live_monaco_editor.min.css";
@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@200;300;400;500;700;800&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@200;300;400;500;600;700;800&display=swap");
72 changes: 33 additions & 39 deletions assets/js/beacon_live_admin.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,54 @@
import topbar from "../vendor/topbar"
import { CodeEditorHook } from "../../deps/live_monaco_editor/priv/static/live_monaco_editor.esm"

import { getHooks } from "live_svelte"
import * as Components from "../svelte/**/*.svelte"
let Hooks = {}
Hooks.CodeEditorHook = CodeEditorHook

topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})

window.addEventListener("phx:page-loading-start", (_event) => {
topbar.show(300)
})

window.addEventListener("phx:page-loading-stop", (_event) => {
topbar.hide()
})
topbar.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" })
window.addEventListener("phx:page-loading-start", (_info) => topbar.show(300))
window.addEventListener("phx:page-loading-stop", (_info) => topbar.hide())

window.addEventListener("beacon_admin:clipcopy", (event) => {
const result_id = `${event.target.id}-copy-to-clipboard-result`
const el = document.getElementById(result_id);
const el = document.getElementById(result_id)

if ("clipboard" in navigator) {
if (event.target.tagName === "INPUT") {
txt = event.target.value;
txt = event.target.value
} else {
txt = event.target.textContent;
txt = event.target.textContent
}

navigator.clipboard.writeText(txt).then(() => {
el.innerText = 'Copied to clipboard';
// Make it visible
el.classList.remove('invisible', 'text-red-500', 'opacity-0');
// Fade in and translate upwards
el.classList.add('text-green-500', 'opacity-100', '-translate-y-2');

setTimeout(function() {
el.classList.remove('text-green-500', 'opacity-100', '-translate-y-2');
el.classList.add('invisible', 'text-red-500', 'opacity-0');
}, 2000);

}).catch(() => {
el.innerText = 'Could not copy';
// Make it visible
el.classList.remove('invisible', 'text-green-500', 'opacity-0');
// Fade in and translate upwards
el.classList.add('text-red-500', 'opacity-100', '-translate-y-2');
})
navigator.clipboard
.writeText(txt)
.then(() => {
el.innerText = "Copied to clipboard"
// Make it visible
el.classList.remove("invisible", "text-red-500", "opacity-0")
// Fade in and translate upwards
el.classList.add("text-green-500", "opacity-100", "-translate-y-2")

setTimeout(function () {
el.classList.remove("text-green-500", "opacity-100", "-translate-y-2")
el.classList.add("invisible", "text-red-500", "opacity-0")
}, 2000)
})
.catch(() => {
el.innerText = "Could not copy"
// Make it visible
el.classList.remove("invisible", "text-green-500", "opacity-0")
// Fade in and translate upwards
el.classList.add("text-red-500", "opacity-100", "-translate-y-2")
})
} else {
alert(
"Sorry, your browser does not support clipboard copy."
);
alert("Sorry, your browser does not support clipboard copy.")
}
});
})

let socketPath = document.querySelector("html").getAttribute("phx-socket") || "/live"
let csrfToken = document .querySelector("meta[name='csrf-token']") .getAttribute("content")
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveView.LiveSocket(socketPath, Phoenix.Socket, {
hooks: Hooks,
hooks: { ...getHooks(Components), ...Hooks },
params: { _csrf_token: csrfToken },
})
liveSocket.connect()
Expand Down
4 changes: 4 additions & 0 deletions assets/js/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as Components from "../svelte/**/*.svelte"
import { getRender } from "live_svelte"

export const render = getRender(Components)
Loading

0 comments on commit 28a0d0c

Please sign in to comment.