Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/csjh/svelte-micro-components
A library for creating inline components in Svelte
https://github.com/csjh/svelte-micro-components
Last synced: 12 days ago
JSON representation
A library for creating inline components in Svelte
- Host: GitHub
- URL: https://github.com/csjh/svelte-micro-components
- Owner: csjh
- License: mit
- Created: 2023-02-27T06:19:38.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2023-04-17T20:58:35.000Z (almost 2 years ago)
- Last Synced: 2024-11-14T14:29:53.774Z (2 months ago)
- Language: TypeScript
- Homepage: https://svelte-micro-components.vercel.app
- Size: 256 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# `svelte-micro-components`
`svelte-micro-components` is a JavaScript library for creating small Svelte components that don't deserve their own file.
Currently supports:
- Text props (e.g. `
Hello ${'name'}!
`)
- Attribute props (``)
- Note: not `class="your-class {propClass}"`
- Event forwarding (optionally under an alias)
- `` ``
- `` ``
- Slots
- Default: `${slot()}`
- Named: `${slot('slotName')}`
- Actions, including:
- with events: `` `` (the component will emit a fully typed `outclick` event when the user clicks outside of the element)
- with props: `` ``
- Nested components
- ``${component`<${Nested} />`}``
- with props: ``${component`<${Nested} prop=${'nested_prop'} />`}`` (`Nested` will be passed the prop `nested_prop`)
- events are not currently supported## Usage
```svelte
import m from 'svelte-micro-components';
const Greeting = m`<h1>Hello ${'name'}!</h1>`;let name = '';
```
- Micro component props are typesafe, so trying `` will throw an error.
- They also support SSR, so you can use them easily in your SvelteKit app.
- Also note that for attributes, you have to do `class={`your-class ${propClass}`}` instead of `class="your-class {propClass}"`, and that there can't be spaces padding the equals sign.## Examples
Basic text interpolation:
Link to REPL:
[REPL](https://svelte.dev/repl/5c837032b30e4322857d2ba9820baccb?version=3.58.0)
```svelteimport m from 'svelte-micro-components';
const Greeting = m`<h1>Hello ${'name'}</h1>`;
```
Dynamic attributes:
[REPL](https://svelte.dev/repl/13e16447f48045f89af04b10a58a0974?version=3.58.0)
```svelteimport m from 'svelte-micro-components';
const src = 'https://svelte.dev/tutorial/image.gif';
const name = 'Rick Astley';const Image = m`<img src=${'src'} alt=${'alt'}>`;
```
Nested components:
[REPL](https://svelte.dev/repl/2d104d50e8af4ce29178fa2136e8d6eb?version=3.58.0)
```svelteimport m, { component } from 'svelte-micro-components';
import Nested from './Nested.svelte';const Wrapper = m`<div class="wrapper">${component`<${Nested} />`}</div>`;
```
DOM events:
[REPL](https://svelte.dev/repl/90aae0da3ab349efbc25a9ed7910559e?version=3.58.0)
```sveltelet pos = { x: 0, y: 0 };
function handleMousemove(event: MouseEvent) {
pos.x = event.clientX;
pos.y = event.clientY;
}import m, { on } from 'svelte-micro-components';
const Tracker = m`
<div ${on`${'mousemove'}`}>
The mouse position is ${'x'} x ${'y'}
</div>
`;```
Event forwarding:
[REPL](https://svelte.dev/repl/8c29f13eff8e4d70b98ee8dd5db0c411?version=3.58.0)
```sveltelet pos = { x: 0, y: 0 };
function handleMousemove(event: MouseEvent) {
pos.x = event.clientX;
pos.y = event.clientY;
}import m, { on } from 'svelte-micro-components';
const Tracker = m`
<div ${on`${'mousemove'}=${'moved'}`}>
The mouse position is ${'x'} x ${'y'}
</div>
`;```
Basic action:
[REPL](https://svelte.dev/repl/39570d0aa2e7433893d25bba2a524b09?version=3.58.0)
```svelteimport type { Action } from 'svelte/action';
const changeColor: Action<HTMLElement, string> = (node, param = 'red') => {
node.style.color = param;return {
update(parameter) {
node.style.color = parameter;
}
};
};import m, { on, use } from 'svelte-micro-components';
const Box = m`
<div ${use`${changeColor}=${'color'}`} ${on`${'click'}`}>
I start off as red, but when you click me I turn green.
</div>
`;let color = 'rgb(255, 0, 0)';
(color = 'rgb(0, 255, 0)')} {color} />
```Parameterized action (longpress from [this official example](https://svelte.dev/examples/adding-parameters-to-actions)):
[REPL](https://svelte.dev/repl/05bbcba99418486692a7979b3d88e206?version=3.58.0)
```svelteimport type { Action } from 'svelte/action';
declare const longpress: Action<
HTMLElement,
number,
{ 'on:longpress': (e: CustomEvent) => void }
>;import m, { on, use } from 'svelte-micro-components';
let pressed = false;
let duration = 2000;const Button = m`
<button
${use`${longpress}=${'duration'}`}
${on`${'longpress'}`}
${on`${'mouseenter'}`}
>
press and hold
</button>
`;const Message = m`<p>congratulations, you pressed and held for ${'duration'}ms</p>`;
{duration}ms(pressed = true)} on:mouseenter={() => (pressed = false)} />
{#if pressed}
{/if}
```Complex action:
[REPL](https://svelte.dev/repl/38ee0361bb904d448414959077829f0a?version=3.58.0)
```svelteimport type { Action } from 'svelte/action';
declare const pannable: Action<
HTMLElement,
null,
{
'on:panstart': CustomEvent<{ x: number; y: number }>;
'on:panmove': CustomEvent<{ x: number; y: number; dx: number; dy: number }>;
'on:panend': CustomEvent<{ x: number; y: number }>;
}
>;import { spring } from 'svelte/motion';
const coords = spring({ x: 0, y: 0 }, { stiffness: 0.2, damping: 0.4 });
function handlePanStart() {
coords.stiffness = coords.damping = 1;
}function handlePanMove(event: CustomEvent<{ x: number; y: number; dx: number; dy: number }>) {
coords.update(($coords) => ({
x: $coords.x + event.detail.dx,
y: $coords.y + event.detail.dy
}));
}function handlePanEnd() {
coords.stiffness = 0.2;
coords.damping = 0.4;
coords.set({ x: 0, y: 0 });
}import m, { on, use } from 'svelte-micro-components';
const Box = m`
<div class="box"
${use`${pannable}`}
${on`${'panstart'}`}
${on`${'panmove'}`}
${on`${'panend'}`}
style=${'style'}
></div>
`;```
Slots:
[REPL](https://svelte.dev/repl/848b525661094ac7b45e6a5f3d1206a5?version=3.58.0)
```svelteimport m, { slot } from 'svelte-micro-components';
const Box = m`
<div class="box">
${slot()}
</div>
`;
Hello!
This is a box. It can contain anything.
```
Named slots:
[REPL](https://svelte.dev/repl/b18dfb2c26c641c8b861b61a28fce7a4?version=3.58.0)
```svelteimport m, { slot } from 'svelte-micro-components';
const ContactCard = m`
<article class="contact-card">
<h2>
${slot('name')}
</h2><div class="address">
${slot('address')}
</div><div class="email">
${slot('email')}
</div>
</article>
`;P. Sherman
42 Wallaby Way
Sydney
```
Modal:
[REPL](https://svelte.dev/repl/4cb5fb9f668e423cb770e700b9109ef9?version=3.58.0)
```sveltelet showModal = false;
function dialogShow(node) {
return {
update(showModal) {
if (showModal) node.showModal();
else node.close();
}
}
}
import m, { slot, on, use } from "svelte-micro-components";
const Modal = m`
<dialog
${on`${"close"}`}
${on`${"click"}`}
${use`${dialogShow}=${"showmodal"}`}
>
<div ${on`${"click"}=${'divClick'}`}>
${slot("header")}
<hr />
${slot()}
<hr />
<!-- svelte-ignore a11y-autofocus -->
<button autofocus ${on`${"click"}`}>close modal</button>
</div>
</dialog>
`;
function hide() { showModal = false }
function show() { showModal = true }
function stopPropagation(e) { e.stopPropagation(); }show modal
modal
adjective mod·al \ˈmō-dəl\
- of or relating to modality in logic
containing provisions as to the mode of procedure or the manner of taking effect —used of a contract or legacy
- of or relating to a musical mode
- of or relating to structure as opposed to substance
- of, relating to, or constituting a grammatical form or category characteristically indicating predication
- of or relating to a statistical mode
```