🚧 First svelte component
This commit is contained in:
parent
1c1df43bf9
commit
203d1b6b34
10 changed files with 809 additions and 668 deletions
|
@ -1,4 +1,6 @@
|
|||
{
|
||||
"semi": false,
|
||||
"printWidth": 100
|
||||
"printWidth": 100,
|
||||
"plugins": ["prettier-plugin-svelte"],
|
||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||
}
|
||||
|
|
51
UI/Base/SubtleButton.svelte
Normal file
51
UI/Base/SubtleButton.svelte
Normal 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>
|
|
@ -1,13 +1,11 @@
|
|||
import Translations from "../i18n/Translations"
|
||||
import Combine from "./Combine"
|
||||
import BaseUIElement from "../BaseUIElement"
|
||||
import Link from "./Link"
|
||||
import Img from "./Img"
|
||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { UIElement } from "../UIElement"
|
||||
import { VariableUiElement } from "./VariableUIElement"
|
||||
import Lazy from "./Lazy"
|
||||
import Loading from "./Loading"
|
||||
import SubtleButtonSvelte from "./SubtleButton.svelte"
|
||||
import SvelteUIElement from "./SvelteUIElement"
|
||||
|
||||
export class SubtleButton extends UIElement {
|
||||
private readonly imageUrl: string | BaseUIElement
|
||||
|
@ -15,7 +13,7 @@ export class SubtleButton extends UIElement {
|
|||
private readonly options: {
|
||||
url?: string | Store<string>
|
||||
newTab?: boolean
|
||||
imgSize?: string
|
||||
imgSize?: string,
|
||||
extraClasses?: string
|
||||
}
|
||||
|
||||
|
@ -25,9 +23,9 @@ export class SubtleButton extends UIElement {
|
|||
options: {
|
||||
url?: string | Store<string>
|
||||
newTab?: boolean
|
||||
imgSize?: "h-11 w-11" | string
|
||||
imgSize?: "h-11 w-11" | string,
|
||||
extraClasses?: string
|
||||
} = undefined
|
||||
} = {}
|
||||
) {
|
||||
super()
|
||||
this.imageUrl = imageUrl
|
||||
|
@ -36,30 +34,11 @@ export class SubtleButton extends UIElement {
|
|||
}
|
||||
|
||||
protected InnerRender(): string | BaseUIElement {
|
||||
const classes =
|
||||
"block flex p-3 my-2 bg-subtle rounded-lg hover:shadow-xl hover:bg-unsubtle transition-colors transition-shadow link-no-underline " +
|
||||
(this?.options?.extraClasses ?? "")
|
||||
const message = Translations.W(this.message)?.SetClass(
|
||||
"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)
|
||||
return new SvelteUIElement(SubtleButtonSvelte, {
|
||||
imageUrl: this?.imageUrl ?? undefined,
|
||||
message: this?.message ?? "",
|
||||
options: this?.options ?? {},
|
||||
})
|
||||
}
|
||||
|
||||
public OnClickWithLoading(
|
||||
|
|
21
UI/Base/SvelteUIElement.ts
Normal file
21
UI/Base/SvelteUIElement.ts
Normal 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
1317
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -6,6 +6,7 @@
|
|||
"bugs": "https://github.com/pietervdvn/MapComplete/issues",
|
||||
"homepage": "https://mapcomplete.osm.be",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "npm run generate:layeroverview && npm run strt",
|
||||
"strt": "vite",
|
||||
|
@ -108,6 +109,8 @@
|
|||
"@babel/preset-env": "7.13.8",
|
||||
"@parcel/service-worker": "^2.6.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/geojson": "^7946.0.10",
|
||||
"@types/leaflet-markercluster": "^1.0.3",
|
||||
|
@ -125,10 +128,15 @@
|
|||
"fs": "0.0.1-security",
|
||||
"mocha": "^9.2.2",
|
||||
"prettier": "2.7.1",
|
||||
"prettier-plugin-svelte": "^2.9.0",
|
||||
"read-file": "^0.2.0",
|
||||
"sass": "^1.57.1",
|
||||
"sharp": "^0.30.5",
|
||||
"svelte": "^3.55.1",
|
||||
"svelte-check": "^3.0.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"ts2json-schema": "^1.4.0",
|
||||
"tslib": "^2.4.1",
|
||||
"tslint": "^6.1.3",
|
||||
"tslint-no-circular-imports": "^0.7.0",
|
||||
"typescript": "^4.7.4",
|
||||
|
|
5
postcss.config.cjs
Normal file
5
postcss.config.cjs
Normal file
|
@ -0,0 +1,5 @@
|
|||
const tailwindcss = require("tailwindcss")
|
||||
|
||||
module.exports = {
|
||||
plugins: [tailwindcss("./tailwind.config.cjs")],
|
||||
}
|
7
svelte.config.js
Normal file
7
svelte.config.js
Normal 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(),
|
||||
}
|
|
@ -1,23 +1,27 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
const plugin = require("tailwindcss/plugin");
|
||||
const plugin = require("tailwindcss/plugin")
|
||||
|
||||
module.exports = {
|
||||
content: ["./**/*.html", "./**/*.ts"],
|
||||
content: ["./**/*.{html,ts,svelte}"],
|
||||
theme: {
|
||||
extend: {
|
||||
maxHeight: {
|
||||
"65vh": "65vh",
|
||||
"20vh": "20vh",
|
||||
},
|
||||
colors: {
|
||||
subtle: "#dbeafe",
|
||||
unsubtle: "#bfdbfe",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
plugin(function ({ addVariant, e }) {
|
||||
addVariant("landscape", ({ modifySelectors, separator }) => {
|
||||
modifySelectors(({ className }) => {
|
||||
return `.${e(`landscape${separator}${className}`)}:landscape`;
|
||||
});
|
||||
});
|
||||
return `.${e(`landscape${separator}${className}`)}:landscape`
|
||||
})
|
||||
})
|
||||
}),
|
||||
],
|
||||
};
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
const { defineConfig } = require("vite")
|
||||
import { defineConfig } from "vite"
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte"
|
||||
import fs from "fs"
|
||||
|
||||
const allHtmlFiles = fs.readdirSync(".").filter((f) => f.endsWith(".html"))
|
||||
const input = {}
|
||||
const ASSET_URL = process.env.ASSET_URL || ""
|
||||
|
@ -9,13 +11,14 @@ for (const html of allHtmlFiles) {
|
|||
input[name] = "./" + html
|
||||
}
|
||||
|
||||
module.exports = defineConfig({
|
||||
export default defineConfig({
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input,
|
||||
},
|
||||
},
|
||||
base: `${ASSET_URL}`,
|
||||
plugins: [svelte()],
|
||||
server: {
|
||||
port: 1234,
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue