forked from MapComplete/MapComplete
		
	🚧 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, |   "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 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( | ||||||
|  |  | ||||||
							
								
								
									
										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", |   "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
									
								
							
							
						
						
									
										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} */ | /** @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` | ||||||
|         }); |         }) | ||||||
|       }); |       }) | ||||||
|     }), |     }), | ||||||
|   ], |   ], | ||||||
| }; | } | ||||||
|  | @ -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, | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue