🚧 First svelte component

This commit is contained in:
wjtje 2023-01-17 18:31:51 +01:00 committed by Pieter Vander Vennet
parent 1c1df43bf9
commit 203d1b6b34
10 changed files with 809 additions and 668 deletions

View file

@ -1,4 +1,6 @@
{ {
"semi": false, "semi": false,
"printWidth": 100 "printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
} }

View file

@ -0,0 +1,51 @@
<script lang="ts">
import { onMount } from "svelte"
import { Store } from "../../Logic/UIEventSource"
import BaseUIElement from "../BaseUIElement"
import Img from "./Img"
import Translations from "../i18n/Translations"
export let imageUrl: string | BaseUIElement
export let message: string | BaseUIElement
export let options: { url?: string | Store<string>; newTab?: boolean; imgSize?: string, extraClasses?: string }
let element: HTMLElement
let href = typeof options?.url == "string" ? options.url : ""
onMount(() => {
if (typeof options?.url != "string" && options?.url != undefined) {
options.url.addCallbackAndRun((data) => {
href = data
})
}
let img: BaseUIElement
const imgClasses = "block justify-center flex-none mr-4 " + (options?.imgSize ?? "h-11 w-11")
if ((imageUrl ?? "") === "") {
img = undefined
} else if (typeof imageUrl === "string") {
img = new Img(imageUrl)?.SetClass(imgClasses)
} else {
img = imageUrl?.SetClass(imgClasses)
}
if (img != undefined) element.appendChild(img.ConstructElement())
let msg = Translations.W(message)?.SetClass("block text-ellipsis no-images flex-shrink")
element.appendChild(msg.ConstructElement())
})
</script>
{#if options?.url == undefined}
<span bind:this={element} class="{options.extraClasses}"/>
{:else}
<a {href} class="no-underline" bind:this={element} target={options?.newTab ? "_blank" : ""} />
{/if}
<style lang="scss">
span,
a {
@apply flex p-3 my-2 rounded-lg hover:shadow-xl transition-colors transition-shadow;
@apply items-center w-full;
@apply bg-subtle text-black hover:bg-unsubtle;
}
</style>

View file

@ -1,13 +1,11 @@
import Translations from "../i18n/Translations"
import Combine from "./Combine"
import BaseUIElement from "../BaseUIElement" import BaseUIElement from "../BaseUIElement"
import Link from "./Link"
import Img from "./Img"
import { Store, UIEventSource } from "../../Logic/UIEventSource" import { Store, UIEventSource } from "../../Logic/UIEventSource"
import { UIElement } from "../UIElement" import { UIElement } from "../UIElement"
import { VariableUiElement } from "./VariableUIElement" import { VariableUiElement } from "./VariableUIElement"
import Lazy from "./Lazy" import Lazy from "./Lazy"
import Loading from "./Loading" import Loading from "./Loading"
import SubtleButtonSvelte from "./SubtleButton.svelte"
import SvelteUIElement from "./SvelteUIElement"
export class SubtleButton extends UIElement { export class SubtleButton extends UIElement {
private readonly imageUrl: string | BaseUIElement private readonly imageUrl: string | BaseUIElement
@ -15,7 +13,7 @@ export class SubtleButton extends UIElement {
private readonly options: { private readonly options: {
url?: string | Store<string> url?: string | Store<string>
newTab?: boolean newTab?: boolean
imgSize?: string imgSize?: string,
extraClasses?: string extraClasses?: string
} }
@ -25,9 +23,9 @@ export class SubtleButton extends UIElement {
options: { options: {
url?: string | Store<string> url?: string | Store<string>
newTab?: boolean newTab?: boolean
imgSize?: "h-11 w-11" | string imgSize?: "h-11 w-11" | string,
extraClasses?: string extraClasses?: string
} = undefined } = {}
) { ) {
super() super()
this.imageUrl = imageUrl this.imageUrl = imageUrl
@ -36,30 +34,11 @@ export class SubtleButton extends UIElement {
} }
protected InnerRender(): string | BaseUIElement { protected InnerRender(): string | BaseUIElement {
const classes = return new SvelteUIElement(SubtleButtonSvelte, {
"block flex p-3 my-2 bg-subtle rounded-lg hover:shadow-xl hover:bg-unsubtle transition-colors transition-shadow link-no-underline " + imageUrl: this?.imageUrl ?? undefined,
(this?.options?.extraClasses ?? "") message: this?.message ?? "",
const message = Translations.W(this.message)?.SetClass( options: this?.options ?? {},
"block text-ellipsis no-images flex-shrink" })
)
let img
const imgClasses =
"block justify-center flex-none mr-4 " + (this.options?.imgSize ?? "h-11 w-11")
if ((this.imageUrl ?? "") === "") {
img = undefined
} else if (typeof this.imageUrl === "string") {
img = new Img(this.imageUrl)?.SetClass(imgClasses)
} else {
img = this.imageUrl?.SetClass(imgClasses)
}
const button = new Combine([img, message]).SetClass("flex items-center group w-full")
if (this.options?.url == undefined) {
this.SetClass(classes)
return button
}
return new Link(button, this.options.url, this.options.newTab ?? false).SetClass(classes)
} }
public OnClickWithLoading( public OnClickWithLoading(

View file

@ -0,0 +1,21 @@
import BaseUIElement from "../BaseUIElement"
export default class SvelteUIElement extends BaseUIElement {
private readonly _svelteComponent
private readonly _props: Record<string, any>
constructor(svelteElement, props: Record<string, any>) {
super()
this._svelteComponent = svelteElement
this._props = props
}
protected InnerConstructElement(): HTMLElement {
const el = document.createElement("div")
new this._svelteComponent({
target: el,
props: this._props,
})
return el
}
}

1317
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,7 @@
"bugs": "https://github.com/pietervdvn/MapComplete/issues", "bugs": "https://github.com/pietervdvn/MapComplete/issues",
"homepage": "https://mapcomplete.osm.be", "homepage": "https://mapcomplete.osm.be",
"main": "index.js", "main": "index.js",
"type": "module",
"scripts": { "scripts": {
"start": "npm run generate:layeroverview && npm run strt", "start": "npm run generate:layeroverview && npm run strt",
"strt": "vite", "strt": "vite",
@ -108,6 +109,8 @@
"@babel/preset-env": "7.13.8", "@babel/preset-env": "7.13.8",
"@parcel/service-worker": "^2.6.0", "@parcel/service-worker": "^2.6.0",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",
"@sveltejs/vite-plugin-svelte": "^2.0.2",
"@tsconfig/svelte": "^3.0.0",
"@types/chai": "^4.3.0", "@types/chai": "^4.3.0",
"@types/geojson": "^7946.0.10", "@types/geojson": "^7946.0.10",
"@types/leaflet-markercluster": "^1.0.3", "@types/leaflet-markercluster": "^1.0.3",
@ -125,10 +128,15 @@
"fs": "0.0.1-security", "fs": "0.0.1-security",
"mocha": "^9.2.2", "mocha": "^9.2.2",
"prettier": "2.7.1", "prettier": "2.7.1",
"prettier-plugin-svelte": "^2.9.0",
"read-file": "^0.2.0", "read-file": "^0.2.0",
"sass": "^1.57.1",
"sharp": "^0.30.5", "sharp": "^0.30.5",
"svelte": "^3.55.1",
"svelte-check": "^3.0.2",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"ts2json-schema": "^1.4.0", "ts2json-schema": "^1.4.0",
"tslib": "^2.4.1",
"tslint": "^6.1.3", "tslint": "^6.1.3",
"tslint-no-circular-imports": "^0.7.0", "tslint-no-circular-imports": "^0.7.0",
"typescript": "^4.7.4", "typescript": "^4.7.4",

5
postcss.config.cjs Normal file
View file

@ -0,0 +1,5 @@
const tailwindcss = require("tailwindcss")
module.exports = {
plugins: [tailwindcss("./tailwind.config.cjs")],
}

7
svelte.config.js Normal file
View file

@ -0,0 +1,7 @@
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"
export default {
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
// for more information about preprocessors
preprocess: vitePreprocess(),
}

View file

@ -1,23 +1,27 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
const plugin = require("tailwindcss/plugin"); const plugin = require("tailwindcss/plugin")
module.exports = { module.exports = {
content: ["./**/*.html", "./**/*.ts"], content: ["./**/*.{html,ts,svelte}"],
theme: { theme: {
extend: { extend: {
maxHeight: { maxHeight: {
"65vh": "65vh", "65vh": "65vh",
"20vh": "20vh", "20vh": "20vh",
}, },
colors: {
subtle: "#dbeafe",
unsubtle: "#bfdbfe",
},
}, },
}, },
plugins: [ plugins: [
plugin(function ({ addVariant, e }) { plugin(function ({ addVariant, e }) {
addVariant("landscape", ({ modifySelectors, separator }) => { addVariant("landscape", ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => { modifySelectors(({ className }) => {
return `.${e(`landscape${separator}${className}`)}:landscape`; return `.${e(`landscape${separator}${className}`)}:landscape`
}); })
}); })
}), }),
], ],
}; }

View file

@ -1,5 +1,7 @@
const { defineConfig } = require("vite") import { defineConfig } from "vite"
import { svelte } from "@sveltejs/vite-plugin-svelte"
import fs from "fs" import fs from "fs"
const allHtmlFiles = fs.readdirSync(".").filter((f) => f.endsWith(".html")) const allHtmlFiles = fs.readdirSync(".").filter((f) => f.endsWith(".html"))
const input = {} const input = {}
const ASSET_URL = process.env.ASSET_URL || "" const ASSET_URL = process.env.ASSET_URL || ""
@ -9,13 +11,14 @@ for (const html of allHtmlFiles) {
input[name] = "./" + html input[name] = "./" + html
} }
module.exports = defineConfig({ export default defineConfig({
build: { build: {
rollupOptions: { rollupOptions: {
input, input,
}, },
}, },
base: `${ASSET_URL}`, base: `${ASSET_URL}`,
plugins: [svelte()],
server: { server: {
port: 1234, port: 1234,
}, },