🧱 AS Comps

Simple and customizable building blocks for Svelte

work in progress

# Install the package using your favorite package manager
npm i -D as-comps
pnpm i -D as-comps
yarn add -D as-comps

🔡 Input

Demo

<Input>Label</Input>

🔲 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
	triggerClass="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 bind:this={buttonRef} on:click="{() => (dialogOpen = !dialogOpen)}">toggle dialog</button>
<Dialog includedTrigger={false} {buttonRef} bind:open={dialogOpen}>Hello Dialog</Dialog>

Destroy

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:

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] });

📑 TabGroup + Tab

    <div class="card" style="width: 600px;">
    <TabGroup triggerClass="btn">
    	<Tab label="Tab One">some random tab content</Tab>
    	<Tab label="Second Tab">other tab content</Tab>
    	<Tab label="Tab, the Third">
    		Lorem ipsum dolor sit, amet consectetur adipisicing elit.
    	</Tab>
    </TabGroup>
    </div>
    

    Docs

    To create a TabGroup wrap <Tab/> components with a <TabGroup/>. The content of the tabs will still be rendered when JavaScript is disabled making it indexable and SSR compatible.

    <TabGroup>
    	<Tab label="Tab One">some random tab content</Tab>
    	<Tab label="Second Tab">other tab content</Tab>
    	<Tab label="Tab, the Third">
    		Lorem ipsum dolor sit, amet consectetur adipisicing elit. Earum, natus?
    	</Tab>
    </TabGroup>

    {...$$restProps} for <TabGroup> get spread to the underlying <ul> element that shows the different tab buttons.

    {...$$restProps} for <Tab> get spread to the underlying <section> element that displays the tab content.

    triggerClass

    You can pass in a CSS class to customize the look of the trigger buttons.

    <TabGroup triggerClass="btn">
    	<Tab label="Tab One">some random tab content</Tab>
    	<Tab label="Second Tab">other tab content</Tab>
    	<Tab label="Tab, the Third">
    		Lorem ipsum dolor sit, amet consectetur adipisicing elit. Earum, natus?
    	</Tab>
    </TabGroup>