🧱 AS Comps #

Simple and customizable building blocks for Svelte Apps.

work in progress. consider this as alpha software.

# Install the package using npm
npm i -D as-comps

# or your favorite package manager
ni -D as-comps
pnpm i -D as-comps
yarn add -D as-comps

🔲 Dialog #

Demo

<Dialog let:toggle triggerLabel="Delete Entry">
	<h2>Are you sure you want to delete the entry?</h2>
	<p>This action can not be reversed.</p>
	<svelte:fragment slot="dialog-actions">
		<button on:click={toggle}>No</button>
		<button
			on:click="{() => {
				deleteEntry();
				toggle();
			}}"
		>
			Yes
		</button>
	</svelte:fragment>
</Dialog>

Styled Dialog

<Dialog
	triggerProps={{ class: 'btn' }}
	triggerLabel="Dialog as Side Pane"
	dialogIn={fly}
	dialogInOptions={{ x: 500 }}
	--as-dialog-left="auto"
	--as-dialog-right="0"
	--as-dialog-transform="translateY(-50%)"
	--as-dialog-border-radius="0"
	--as-dialog-width="calc(100% - 2em)"
	--as-dialog-max-width="800px"
	--as-dialog-height="100%"
	--as-dialog-max-height="calc(100% - 2em)"
	>
	<h1>This is a side pane</h1>
	<p>
		Lorem ipsum dolor sit amet consectetur adipisicing elit. Natus rem non sunt! Id
		necessitatibus veritatis debitis est tempora iure esse. Nisi, dicta alias nobis velit libero
		deleniti corporis nihil? Eum.
	</p>
</Dialog>

Custom Trigger

<button
	class="btn"
	bind:this={buttonRef}
	on:click="{() => (dialogOpen = !dialogOpen)}"
>
<Dialog includedTrigger={false} {buttonRef} bind:isOpen={dialogOpen}>
	<h1>Hello Dialog</h1>
</Dialog>

Self-Destroying Dialog

{#if showDestroyDialogButton}
	<div>
		<Dialog let:toggle triggerProps="{{ class: 'btn' }}">
			<button
				class="btn"
				on:click="{() => {
					toggle();
					showDestroyDialogButton = false;
				}}"
			>
				Delete
			</button>
		</Dialog>
	</div>
{/if}

Docs

To display a dialog, import and place the <Dialog></Dialog> component inside a .svelte file. Slot the dialog content between the tags.

<script>
	import { Dialog } from 'as-comps';
</script>

<Dialog>Hello Dialog</Dialog>

{...$$restProps} get spread to the underlying <section> element that shows the slot content.

includedTrigger & bind:open

By default, the dialog comes with it’s own trigger, so you don’t have to handle the opening logic with local state.

You can also provide your own trigger if you pass includedTrigger={false} to the component and bind the open prop to control the opening logic.

Just be sure to pass in the buttonRef so the Dialog can focus it when its closed.

<script>
	let dialogOpen = false;
</script>

<button bind:this={buttonRef} on:click={() => (dialogOpen = !dialogOpen)}>toggle dialog</button>

<Dialog includedTrigger={false} {buttonRef} bind:open={dialogOpen}>Hello Dialog</Dialog>

triggerLabel & triggerClass

If you want to override the default trigger label or class you can pass in the props triggerLabel and triggerClass.

<Dialog triggerLabel="my dialog" triggerClass="btn">Hello Dialog</Dialog>

Or you can pass in a slot="trigger-label"

<Dialog>
	<svelte:fragment slot="trigger-label">my dialog</svelte:fragment>
	Hello Dialog
</Dialog>

let:toggle & slot="dialog-actions"

When creating a confirm dialog, you need to toggle the opening state at different places. For this, a toggle() function is provided via slot props. Simply add let:toggle to the <Dialog> tag and call it when appropriate.

<Dialog let:toggle triggerLabel="Delete Entry">
	<h2>Are you sure you want to delete the entry?</h2>
	<p>This action can not be reversed.</p>
	<svelte:fragment slot="dialogActions">
		<button on:click={toggle}>No</button>
		<button
			on:click={() => {
				deleteEntry();
				toggle();
			}}
		>
			Yes
		</button>
	</svelte:fragment>
</Dialog>

Above you can see the usage for slot="dialogActions". This can be used to display options / buttons of a dialog dialog in a row.

mandatory

By default the dialog is dismissable (not mandatory) and will close on ESC, by clicking outside or by clicking the x-mark button. If you pass in the mandatory prop the dialog is non-dismissable and won’t close unless you call let:toggle or change the value of bind:open.

<Dialog let:toggle mandatory>
	<h2>Non-Dismissable</h2>
	<svelte:fragment slot="dialogActions">
		<button on:click={toggle}>Close</button>
	</svelte:fragment>
</Dialog>

noCloseButton

If the modal isn’t mandatory, but you still want to hide the close button for some reason you can pass this boolean prop to hide the x--mark button.

on:dismiss

If the modal isn’t mandatory, you can listen to a dismiss via on:dismiss

💬 Notification #

Demo

notification("a notification");
// <Notifications position="top-right" />

Docs

To show the notifications, import and place the <Notifications /> component inside your src/routes/__layout.svelte for SvelteKit or src/pages/_layout.svelte for Routify, like this:

<script>
	import { Notifications } from 'as-comps';
</script>

<slot />

<Notifications />

This is used to display the notifications, so it needs to be rendered wherever you want your notifications visible.

{...$$restProps} get spread to the underlying <ul> element that shows the notifications.

Notification position

By default, the notifications will be displayed on the top right, i.e. "top-right". You can also place it to either "top-left" "top", "bottom-left", "bottom", or "bottom-right" by setting the position prop on the <Notifications /> component.

<Notifications position="top-right" />

notification(msg, {type, removeAfter, action})

To create or add a notification import the notification function from 'as-comps' and call it with a message or any HTML.

The second parameter is a notificationOption object where the the properties type, removeAfter or action can be set:

  • type controls the type of notification: ‘info’ (default) or ‘warn’
  • removeAfter controls how long a notification stays on screen in ms, defaulting to 5000
  • action can be used to attach an action to the component. Pass in an array consisting of two entries: at index 0 a label for the notification action button and at index 1 a callback function that gets called when the action button is pressed. Setting an Action increases the default removeAfter time by two.
import { notification } from 'as-comps';

notification('hello notification');

notification('<b>yaay!</b> you did it!');

notification('a warning notification', { type: 'warn' });

notification('This notification will display for about 11,574 days.', { removeAfter: 9001 });

notification('You did something undoable.', { action: ['undo', undoCallback] });