mirror of https://github.com/sveltejs/svelte
commit
64064231c4
@ -0,0 +1,89 @@
|
||||
---
|
||||
title: "What's new in Svelte: May 2022"
|
||||
description: "Dynamically switch between HTML element types with `<svelte:element>`"
|
||||
author: Daniel Sandoval
|
||||
authorURL: https://desandoval.net
|
||||
---
|
||||
|
||||
With yesterday's Svelte Summit behind us, we've got a lot of news to share! Check out all of the recordings on the [Svelte Society YouTube Channel](https://www.youtube.com/sveltesociety) and the rest of this month's updates below...
|
||||
|
||||
## What's new in Svelte
|
||||
- The `<svelte:element>` element lets you render an element of a dynamically specified type. This is useful, for example, when rendering rich text content from a CMS. Check out the [docs](https://svelte.dev/docs#template-syntax-svelte-element) or the [tutorial](https://svelte.dev/tutorial/svelte-element) for more info (**3.47.0**)!
|
||||
|
||||
|
||||
## Language Tools updates
|
||||
- `svelte:element` and `sveltekit:reload` are now supported
|
||||
- Invalid Svelte import paths will now be automatically detected - see PR for getting back the old behavior ([#1448](https://github.com/sveltejs/language-tools/pull/1448))
|
||||
- `source.sortImports` lets you sort imports without deleting unused imports ([#1338](https://github.com/sveltejs/language-tools/issues/1338))
|
||||
- Hovering over HTML attributes will now show HTML hover info instead of the TS hover info - resulting in much more useful information ([#1447](https://github.com/sveltejs/language-tools/pull/1447))
|
||||
- In VS Code, you can now wrap existing blocks of code in control flow tags using the `Insert Snippet` command ([#1373](https://github.com/sveltejs/language-tools/pull/1373))
|
||||
|
||||
## What's new in SvelteKit
|
||||
- Files and directories can now be named `__tests__` and `__test__` in the routes directory ([#4438](https://github.com/sveltejs/kit/pull/4438))
|
||||
- Netlify Edge Functions ([#4657](https://github.com/sveltejs/kit/pull/4657)) and the Vercel build output API ([#4663](https://github.com/sveltejs/kit/pull/4663)) are now supported
|
||||
- Custom `load` dependencies, array of strings representing URLs the page depends on, are now available when loading routes ([Docs](https://kit.svelte.dev/docs/loading#output-dependencies), [#4536](https://github.com/sveltejs/kit/pull/4536))
|
||||
|
||||
|
||||
**Breaking Changes**
|
||||
- Validators are now called "matchers" ([Docs](https://kit.svelte.dev/docs/routing#advanced-routing-matching), [#4358](https://github.com/sveltejs/kit/pull/4358))
|
||||
- `__layout.reset` has been replaced by named layouts - which have much configurability for shared layout elements ([Docs](https://kit.svelte.dev/docs/layouts#named-layouts), [#4388](https://github.com/sveltejs/kit/pull/4388))
|
||||
- Prerendering is now skipped for `rel="external"` links ([#4545](https://github.com/sveltejs/kit/pull/4545))
|
||||
- `maxage` is now `cache` in `LoadOutput` ([#4690](https://github.com/sveltejs/kit/pull/4690))
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Community Showcase
|
||||
|
||||
**Apps & Sites built with Svelte**
|
||||
- [polySpectra AR](https://ar.polyspectra.com/) lets you prototype faster 3D Printing with seamless AR file handoffs ([video demo](https://www.youtube.com/watch?v=VhYCeVGcG3E))
|
||||
- [Pixel Art Together](https://github.com/liveblocks/pixel-art-together) is a free multiplayer pixel art editor powered by Liveblocks
|
||||
- [Tooling Manager](https://tooling-manager.netlify.app/) lets you compare your JavaScript tech stack against industry standard boilerplates
|
||||
- [Easy Portfolio](https://easy-portfolio.com/) generates a portfolio based on your GitHub profile
|
||||
- [FLOAT](https://github.com/muttoni/float) is an attendance tracking program for events
|
||||
- [The Coin Perspective](https://thecoinperspective.com/) is a cryptocurrency price tracker and portfolio management tool
|
||||
- [Locutionis](https://github.com/pbouillon/locutionis) is a small, online reference of figures of speech (en français)
|
||||
- [ASM Editor](https://asm-editor.specy.app/) is an all in one web editor for M68K and MIPS
|
||||
- [Otium](https://github.com/alombi/otium) is a free and open source book manager and bookshelf organiser, that helps you managing your books and the ones you would like to read
|
||||
- [Sinwaver](https://github.com/Hugo-Dz/Sinwaver) is an SVG sine wave generator
|
||||
|
||||
Want to contribute to a modern SvelteKit website? [Help build the Svelte Society site](https://github.com/svelte-society/sveltesociety.dev/issues)!
|
||||
|
||||
|
||||
**Learning Resources**
|
||||
|
||||
_To Read_
|
||||
- [4 tips for cleaner Svelte components](https://geoffrich.net/posts/clean-component-tips/) by Geoff Rich
|
||||
- [Building a Clubhouse clone with Svelte and 100ms](https://www.100ms.live/blog/clubhouse-clone-with-svelte) By Seun Taiwo
|
||||
- [SvelteKit uvu Testing: Fast Component Unit Tests](https://rodneylab.com/sveltekit-uvu-testing/) by Rodney Lab
|
||||
- [SvelteKit JWT authentication tutorial](https://dev.to/pilcrowonpaper/sveltekit-jwt-authentication-tutorial-2m34) by pilcrowOnPaper
|
||||
- [Converting a Rollup-based Svelte SPA to SvelteKit](https://github.com/sveltejs/kit/discussions/4595) by Simon H
|
||||
- [Add Commitint, Commitizen, Standard Version, and Husky to SvelteKit Project](https://davipon.hashnode.dev/add-commitint-commitizen-standard-version-and-husky-to-sveltekit-project) by David Peng
|
||||
|
||||
_To Watch or Hear_
|
||||
- [Rich Harris - The Road to SvelteKit 1.0 (Svelte Society NYC)](https://www.youtube.com/watch?v=s6a1pbTVcUs) by Svelte Society
|
||||
- [Svelte Fundamentals - Intro to Svelte](https://codingcat.dev/course/intro-to-svelte) by Coding Cat
|
||||
- [Svelte Components Using Custom Markdown Renderers - Weekly Svelte](https://www.youtube.com/watch?v=ZiEROAqobwM) by LevelUpTuts
|
||||
- [Implementing {@const} in if block](https://www.youtube.com/watch?v=f5iReGqjmG0) by lihautan
|
||||
- [Svelte and Contributing to Open-Source with Geoff Rich](https://podcast.20minjs.com/1952066/10417700-episode-6-svelte-and-contributing-to-open-source-with-geoff-rich) by 20minJS
|
||||
|
||||
|
||||
**Libraries, Tools & Components**
|
||||
- [KitDocs](https://github.com/svelteness/kit-docs) is a documentation integration for SvelteKit - like VitePress for Svelte.
|
||||
- [Svelte Copy](https://github.com/ghostdevv/svelte-copy) is a click/tap-to-copy library that makes it easy to copy to the clipboard
|
||||
- [Svend3r](https://github.com/oslabs-beta/svend3r) provides beautiful visualizations that harness the power of D3 to bring your data to life while abstracting away its imperative-style code
|
||||
- [Svelte Hamburgers](https://github.com/ghostdevv/svelte-hamburgers) is the easy to use Hamburger menu component for Svelte
|
||||
- [Svelte Droplet](https://github.com/probablykasper/svelte-droplet) is a file dropzone for Svelte
|
||||
- [Svelte MP3](https://www.npmjs.com/package/svelte-mp3) is a light blazingly fast yet simple minimalistic audio player for Svelte
|
||||
- [SvelteUI](https://github.com/Brisklemonade/svelteui) is a component library for building fully functional & accessible web applications faster than ever
|
||||
- [svelte-spotlight](https://github.com/beynar/svelte-spotlight) is a headless spotlight component to help you build your site's global search box in minutes
|
||||
- [svelte-pdf-simple](https://github.com/gspasov/svelte-pdf-simple) is a simple svelte library for displaying PDFs and giving you all the control
|
||||
- [persistent-svelte-store](https://github.com/omer-g/persistent-svelte-store) is a generic persistent writable store, built from scratch in TypeScript according to the Svelte store contract
|
||||
- [svelte-exmarkdown](https://github.com/ssssota/svelte-exmarkdown) is Svelte component to render markdown dynamically
|
||||
- [Bookit](https://github.com/leveluptuts/bookit) is a storybook-like component rendering environment - finely tuned to work directly within your SvelteKit projects
|
||||
|
||||
Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs) to continue the conversation.
|
||||
|
||||
If you'd prefer to join us in person, Svelte Summit is finally transitioning properly into the real world. Come join us for two days of awesome Svelte content! [Get your tickets now!](https://ti.to/svelte/svelte-summit-fall-edition)
|
||||
|
||||
See y'all next month!
|
||||
@ -1,17 +1,21 @@
|
||||
import IfBlock from '../../nodes/IfBlock';
|
||||
import Renderer, { RenderOptions } from '../Renderer';
|
||||
import { x } from 'code-red';
|
||||
import { get_const_tags } from './shared/get_const_tags';
|
||||
import { Node } from 'estree';
|
||||
|
||||
export default function (node: IfBlock, renderer: Renderer, options: RenderOptions) {
|
||||
const condition = node.expression.node;
|
||||
|
||||
renderer.push();
|
||||
renderer.render(node.children, options);
|
||||
const consequent = renderer.pop();
|
||||
let consequent: Node = renderer.pop();
|
||||
if (node.const_tags.length > 0) consequent = x`(() => { ${get_const_tags(node.const_tags)}; return ${consequent} })()`;
|
||||
|
||||
renderer.push();
|
||||
if (node.else) renderer.render(node.else.children, options);
|
||||
const alternate = renderer.pop();
|
||||
let alternate: Node = renderer.pop();
|
||||
if (node.else && node.else.const_tags.length > 0) alternate = x`(() => { ${get_const_tags(node.else.const_tags)}; return ${alternate} })()`;
|
||||
|
||||
renderer.add_expression(x`${condition} ? ${consequent} : ${alternate}`);
|
||||
}
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
const void_element_names = /^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/;
|
||||
|
||||
export function is_void(name: string) {
|
||||
return void_element_names.test(name) || name.toLowerCase() === '!doctype';
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
dialog[open].svelte-xyz{display:grid}
|
||||
@ -0,0 +1,7 @@
|
||||
<dialog>Hello</dialog>
|
||||
|
||||
<style>
|
||||
dialog[open] {
|
||||
display: grid;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,26 @@
|
||||
export default {
|
||||
html: `
|
||||
<div>12 120 70, 30+4=34</div>
|
||||
<div>35 350 120, 50+7=57</div>
|
||||
<div>48 480 140, 60+8=68</div>
|
||||
`,
|
||||
async test({ component, target, assert }) {
|
||||
component.boxes = [];
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div>10 * 2 = 20</div>
|
||||
`);
|
||||
|
||||
component.constant = 35;
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div>35 * 2 = 70</div>
|
||||
`);
|
||||
|
||||
component.boxes = [
|
||||
{width: 3, height: 4}
|
||||
];
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div>12 420 245, 105+4=109</div>
|
||||
`);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,22 @@
|
||||
<script>
|
||||
export let boxes = [
|
||||
{width: 3, height: 4},
|
||||
{width: 5, height: 7},
|
||||
{width: 6, height: 8},
|
||||
];
|
||||
export let constant = 10;
|
||||
|
||||
function calculate(width, height, constant) {
|
||||
return { area: width * height, volume: width * height * constant };
|
||||
}
|
||||
</script>
|
||||
|
||||
{#each boxes as box}
|
||||
{@const {area, volume} = calculate(box.width, box.height, constant)}
|
||||
{@const perimeter = (box.width + box.height) * constant}
|
||||
{@const [width, height, sum] = [box.width * constant, box.height, box.width * constant + box.height]}
|
||||
<div>{area} {volume} {perimeter}, {width}+{height}={sum}</div>
|
||||
{:else}
|
||||
{@const double = constant + constant}
|
||||
<div>{constant} * 2 = {double}</div>
|
||||
{/each}
|
||||
@ -0,0 +1,56 @@
|
||||
export default {
|
||||
html: `
|
||||
<div>20 x 40</div>
|
||||
<div>20 x 40</div>
|
||||
`,
|
||||
props: {
|
||||
boxes: [{ width: 20, height: 40 }]
|
||||
},
|
||||
async test({ component, target, assert }) {
|
||||
component.boxes = [{ width: 40, height: 70 }];
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<div>40 x 70</div>
|
||||
<div>40 x 70</div>
|
||||
`
|
||||
);
|
||||
|
||||
component.boxes = [];
|
||||
|
||||
assert.htmlEqual(target.innerHTML, '');
|
||||
|
||||
component.boxes = [
|
||||
{ width: 20, height: 40 },
|
||||
{ width: 30, height: 50 }
|
||||
];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<div>20 x 40</div>
|
||||
<div>30 x 50</div>
|
||||
<div>20 x 40</div>
|
||||
<div>30 x 50</div>
|
||||
`
|
||||
);
|
||||
|
||||
component.boxes = [
|
||||
{ width: 80, height: 70 },
|
||||
{ width: 90, height: 60 }
|
||||
];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<div>80 x 70</div>
|
||||
<div>90 x 60</div>
|
||||
<div>80 x 70</div>
|
||||
<div>90 x 60</div>
|
||||
`
|
||||
);
|
||||
|
||||
component.boxes = [];
|
||||
assert.htmlEqual(target.innerHTML, '');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,24 @@
|
||||
<script>
|
||||
export let boxes;
|
||||
</script>
|
||||
|
||||
{#if boxes.length > 1}
|
||||
{@const box1 = boxes[0]}
|
||||
{@const box2 = boxes[1]}
|
||||
{@const { width, height } = box1}
|
||||
<div>{width} x {height}</div>
|
||||
<div>{box2.width} x {box2.height}</div>
|
||||
{:else if boxes.length > 0}
|
||||
{@const box = boxes[0]}
|
||||
{@const { width, height } = box}
|
||||
<div>{width} x {height}</div>
|
||||
{/if}
|
||||
|
||||
{#if boxes.length > 1}
|
||||
<div>{boxes[0].width} x {boxes[0].height}</div>
|
||||
<div>{boxes[1].width} x {boxes[1].height}</div>
|
||||
{:else if boxes.length > 0}
|
||||
{@const box = boxes[0]}
|
||||
{@const { width, height } = box}
|
||||
<div>{width} x {height}</div>
|
||||
{/if}
|
||||
@ -0,0 +1,57 @@
|
||||
export default {
|
||||
html: `
|
||||
<div>20 x 40</div>
|
||||
<div>20 x 40</div>
|
||||
`,
|
||||
props: {
|
||||
boxes: [{ width: 20, height: 40 }]
|
||||
},
|
||||
async test({ component, target, assert, raf }) {
|
||||
component.boxes = [{ width: 40, height: 70 }];
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<div>40 x 70</div>
|
||||
<div>40 x 70</div>
|
||||
`
|
||||
);
|
||||
|
||||
component.boxes = [];
|
||||
|
||||
raf.tick(0);
|
||||
assert.htmlEqual(target.innerHTML, '');
|
||||
|
||||
component.boxes = [
|
||||
{ width: 20, height: 40 },
|
||||
{ width: 30, height: 50 }
|
||||
];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<div>20 x 40</div>
|
||||
<div>30 x 50</div>
|
||||
<div>20 x 40</div>
|
||||
<div>30 x 50</div>
|
||||
`
|
||||
);
|
||||
|
||||
component.boxes = [
|
||||
{ width: 80, height: 70 },
|
||||
{ width: 90, height: 60 }
|
||||
];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<div>80 x 70</div>
|
||||
<div>90 x 60</div>
|
||||
<div>80 x 70</div>
|
||||
<div>90 x 60</div>
|
||||
`
|
||||
);
|
||||
|
||||
component.boxes = [];
|
||||
assert.htmlEqual(target.innerHTML, '');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,29 @@
|
||||
<script>
|
||||
export let boxes;
|
||||
function fade() {
|
||||
return {
|
||||
duration: 0,
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if boxes.length > 1}
|
||||
{@const box1 = boxes[0]}
|
||||
{@const box2 = boxes[1]}
|
||||
{@const { width, height } = box1}
|
||||
<div>{width} x {height}</div>
|
||||
<div>{box2.width} x {box2.height}</div>
|
||||
{:else if boxes.length > 0}
|
||||
{@const box = boxes[0]}
|
||||
{@const { width, height } = box}
|
||||
<div out:fade>{width} x {height}</div>
|
||||
{/if}
|
||||
|
||||
{#if boxes.length > 1}
|
||||
<div>{boxes[0].width} x {boxes[0].height}</div>
|
||||
<div>{boxes[1].width} x {boxes[1].height}</div>
|
||||
{:else if boxes.length > 0}
|
||||
{@const box = boxes[0]}
|
||||
{@const { width, height } = box}
|
||||
<div out:fade>{width} x {height}</div>
|
||||
{/if}
|
||||
@ -0,0 +1,43 @@
|
||||
export default {
|
||||
html: '<div>20 x 40</div>',
|
||||
props: {
|
||||
boxes: [{ width: 20, height: 40 }]
|
||||
},
|
||||
async test({ component, target, assert }) {
|
||||
component.boxes = [{ width: 30, height: 60 }];
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div>30 x 60</div>
|
||||
`);
|
||||
|
||||
component.boxes = [
|
||||
{ width: 20, height: 40 },
|
||||
{ width: 30, height: 50 }
|
||||
];
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div>20 x 40</div>
|
||||
<div>30 x 50</div>
|
||||
`);
|
||||
|
||||
component.boxes = [
|
||||
{ width: 80, height: 70 },
|
||||
{ width: 90, height: 60 }
|
||||
];
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<div>80 x 70</div>
|
||||
<div>90 x 60</div>
|
||||
`);
|
||||
|
||||
component.boxes = [
|
||||
{ width: 20, height: 40 },
|
||||
{ width: 30, height: 50 },
|
||||
{ width: 30, height: 50 }
|
||||
];
|
||||
assert.htmlEqual(target.innerHTML, '<div>3</div>');
|
||||
|
||||
component.boxes = [];
|
||||
assert.htmlEqual(target.innerHTML, '<div>0</div>');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,18 @@
|
||||
<script>
|
||||
export let boxes;
|
||||
</script>
|
||||
|
||||
{#if boxes.length === 2}
|
||||
{@const box1 = boxes[0]}
|
||||
{@const box2 = boxes[1]}
|
||||
{@const { width, height } = box1}
|
||||
<div>{width} x {height}</div>
|
||||
<div>{box2.width} x {box2.height}</div>
|
||||
{:else if boxes.length === 1}
|
||||
{@const box = boxes[0]}
|
||||
{@const { width, height } = box}
|
||||
<div>{width} x {height}</div>
|
||||
{:else}
|
||||
{@const length = boxes.length}
|
||||
<div>{length}</div>
|
||||
{/if}
|
||||
@ -0,0 +1,28 @@
|
||||
export default {
|
||||
html: '<div>10 x 34</div>',
|
||||
props: {
|
||||
boxes: [{ width: 10, height: 34 }]
|
||||
},
|
||||
async test({ component, target, assert }) {
|
||||
component.boxes = [{ width: 20, height: 40 }];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<div>20 x 40</div>
|
||||
`
|
||||
);
|
||||
|
||||
component.boxes = [];
|
||||
assert.htmlEqual(target.innerHTML, '');
|
||||
|
||||
component.boxes = [{ width: 18, height: 48 }];
|
||||
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<div>18 x 48</div>
|
||||
`
|
||||
);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
export let boxes;
|
||||
</script>
|
||||
|
||||
{#if boxes.length > 0}
|
||||
{@const box = boxes[0]}
|
||||
{@const { width, height } = box}
|
||||
<div>{width} x {height}</div>
|
||||
{/if}
|
||||
@ -0,0 +1,15 @@
|
||||
export default {
|
||||
props: {
|
||||
disabled: false
|
||||
},
|
||||
html: '<button>Click me</button>',
|
||||
|
||||
test({ assert, component, target }) {
|
||||
const button = target.querySelector('button');
|
||||
assert.equal(button.disabled, false);
|
||||
|
||||
component.disabled = true;
|
||||
assert.htmlEqual(target.innerHTML, '<button disabled>Click me</button>');
|
||||
assert.equal(button.disabled, true);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,5 @@
|
||||
<script>
|
||||
export let disabled = false;
|
||||
</script>
|
||||
|
||||
<svelte:element {disabled} this="button">Click me</svelte:element>
|
||||
@ -0,0 +1,23 @@
|
||||
export default {
|
||||
props: {
|
||||
props: {
|
||||
disabled: true,
|
||||
type: 'button',
|
||||
'data-named': 'foo'
|
||||
}
|
||||
},
|
||||
html: '<button disabled type="button" data-named="foo">Click me</button>',
|
||||
|
||||
test({ assert, component, target }) {
|
||||
const button = target.querySelector('button');
|
||||
assert.equal(button.disabled, true);
|
||||
assert.equal(button.type, 'button');
|
||||
assert.equal(button.dataset.named, 'foo');
|
||||
|
||||
component.props = { type: 'submit' };
|
||||
assert.htmlEqual(target.innerHTML, '<button type="submit">Click me</button>');
|
||||
assert.equal(button.disabled, false);
|
||||
assert.equal(button.type, 'submit');
|
||||
assert.equal(button.dataset.named, undefined);
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
export let props = {
|
||||
disabled: false,
|
||||
type: 'button',
|
||||
'data-named': 'foo'
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:element this="button" {...props}>Click me</svelte:element>
|
||||
@ -0,0 +1,12 @@
|
||||
export default {
|
||||
props: {
|
||||
propTag: 'hr'
|
||||
},
|
||||
html: '<h1></h1><col><img><hr><input><br>',
|
||||
|
||||
test({ assert, component, target }) {
|
||||
assert.htmlEqual(target.innerHTML, '<h1></h1><col><img><hr><input><br>');
|
||||
component.propTag = 'link';
|
||||
assert.htmlEqual(target.innerHTML, '<h1></h1><col><img><link><input><br>');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,12 @@
|
||||
<script>
|
||||
export let propTag;
|
||||
const static_tag = 'input';
|
||||
const func_tag = () => 'br';
|
||||
</script>
|
||||
|
||||
<h1></h1>
|
||||
<svelte:element this="{'col'}"></svelte:element>
|
||||
<svelte:element this="img"></svelte:element>
|
||||
<svelte:element this="{propTag}"></svelte:element>
|
||||
<svelte:element this="{static_tag}"></svelte:element>
|
||||
<svelte:element this="{func_tag()}"></svelte:element>
|
||||
@ -0,0 +1,9 @@
|
||||
export default {
|
||||
compileOptions: {
|
||||
dev: true
|
||||
},
|
||||
props: {
|
||||
tag: 'br'
|
||||
},
|
||||
error: '<svelte:element this="br"> is self-closing and cannot have content.'
|
||||
};
|
||||
@ -0,0 +1,5 @@
|
||||
<script>
|
||||
export let tag;
|
||||
</script>
|
||||
|
||||
<svelte:element this='{tag}'>foo</svelte:element>
|
||||
@ -0,0 +1,9 @@
|
||||
export default {
|
||||
compileOptions: {
|
||||
dev: true
|
||||
},
|
||||
props: {
|
||||
tag: 'br'
|
||||
},
|
||||
error: '<svelte:element this="br"> is self-closing and cannot have content.'
|
||||
};
|
||||
@ -0,0 +1,5 @@
|
||||
<script>
|
||||
export let tag;
|
||||
</script>
|
||||
|
||||
<svelte:element this='{tag}'><div>bar</div></svelte:element>
|
||||
@ -0,0 +1 @@
|
||||
<div>This is nested</div>
|
||||
@ -0,0 +1,9 @@
|
||||
export default {
|
||||
compileOptions: {
|
||||
dev: true
|
||||
},
|
||||
props: {
|
||||
tag: 'br'
|
||||
},
|
||||
error: '<svelte:element this="br"> is self-closing and cannot have content.'
|
||||
};
|
||||
@ -0,0 +1,6 @@
|
||||
<script>
|
||||
import Nested from './Nested.svelte';
|
||||
export let tag;
|
||||
</script>
|
||||
|
||||
<svelte:element this='{tag}'><Nested/></svelte:element>
|
||||
@ -0,0 +1 @@
|
||||
<div>This is nested</div>
|
||||
@ -0,0 +1,6 @@
|
||||
export default {
|
||||
props: {
|
||||
tag: 'br'
|
||||
},
|
||||
html: '<br>'
|
||||
};
|
||||
@ -0,0 +1,6 @@
|
||||
<script>
|
||||
import Nested from './Nested.svelte';
|
||||
export let tag;
|
||||
</script>
|
||||
|
||||
<svelte:element this='{tag}'><Nested/></svelte:element>
|
||||
@ -1,9 +1,9 @@
|
||||
[
|
||||
{
|
||||
"code": "invalid-const-placement",
|
||||
"message": "{@const} must be the immediate child of {#each}, {:then}, {:catch}, <svelte:fragment> or <Component>",
|
||||
"start": { "line": 6, "column": 2, "character": 46 },
|
||||
"end": { "line": 6, "column": 20, "character": 64 },
|
||||
"pos": 46
|
||||
"message": "{@const} must be the immediate child of {#if}, {:else if}, {:else}, {#each}, {:then}, {:catch}, <svelte:fragment> or <Component>",
|
||||
"start": { "line": 7, "column": 4, "character": 63 },
|
||||
"end": { "line": 7, "column": 18, "character": 77 },
|
||||
"pos": 63
|
||||
}
|
||||
]
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
[
|
||||
{
|
||||
"code": "invalid-const-placement",
|
||||
"message": "{@const} must be the immediate child of {#each}, {:then}, {:catch}, <svelte:fragment> or <Component>",
|
||||
"start": { "line": 7, "column": 4, "character": 63 },
|
||||
"end": { "line": 7, "column": 18, "character": 77 },
|
||||
"pos": 63
|
||||
}
|
||||
]
|
||||
@ -1,9 +0,0 @@
|
||||
<script>
|
||||
export let a;
|
||||
</script>
|
||||
|
||||
{#each a as i}
|
||||
<div>
|
||||
{@const b = i}
|
||||
</div>
|
||||
{/each}
|
||||
Loading…
Reference in new issue