Skip to content

Commit

Permalink
feat: switch
Browse files Browse the repository at this point in the history
  • Loading branch information
jrasm91 committed Dec 23, 2024
1 parent 2ec90ae commit be3dc78
Show file tree
Hide file tree
Showing 17 changed files with 222 additions and 16 deletions.
12 changes: 8 additions & 4 deletions src/docs/components/ExampleLayout.svelte
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
<script lang="ts">
import Examples from '$docs/components/Examples.svelte';
import { Theme, type ExampleItem } from '$docs/constants.js';
import { Scrollable, Stack } from '@immich/ui';
import { Heading, Scrollable, Stack } from '@immich/ui';
import type { Snippet } from 'svelte';
type Props = {
name: string;
examples: ExampleItem[];
children?: Snippet;
};
const { name, examples }: Props = $props();
const { name, examples, children }: Props = $props();
</script>

<div class="flex h-full flex-col">
Expand All @@ -25,8 +27,10 @@
</div>
</nav>

<Scrollable>
<Stack gap={4} class="max-w-screen-lg p-4">
<Scrollable class="p-4">
<Heading size="large">{name}</Heading>
{@render children?.()}
<Stack gap={4} class="mt-4 max-w-screen-md">
<Examples theme={Theme.Dark} {examples} />
</Stack>
</Scrollable>
Expand Down
8 changes: 3 additions & 5 deletions src/docs/components/Lorem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
</script>

{#each Array(count) as i}

Check failure on line 6 in src/docs/components/Lorem.svelte

View workflow job for this annotation

GitHub Actions / Test

'i' is defined but never used
<p data-index={i}>
Lorem ipsum dolor sit amet consectetur adipisicing elit. A ipsam tenetur accusantium impedit
beatae omnis necessitatibus. Voluptatum blanditiis libero impedit, harum eius inventore nihil,
officia voluptate dolorum error consequatur animi.
</p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. A ipsam tenetur accusantium impedit
beatae omnis necessitatibus. Voluptatum blanditiis libero impedit, harum eius inventore nihil,
officia voluptate dolorum error consequatur animi.
{/each}
4 changes: 4 additions & 0 deletions src/docs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import {
mdiListBoxOutline,
mdiMenu,
mdiNumeric,
mdiPanVertical,
mdiPartyPopper,
mdiToggleSwitch,
mdiViewSequential,
} from '@mdi/js';
import type { Component } from 'svelte';
Expand Down Expand Up @@ -47,6 +49,7 @@ export const componentGroups = [
{ name: 'AppShell', icon: mdiApplicationOutline },
{ name: 'Card', icon: mdiCardOutline },
{ name: 'Navbar', icon: mdiMenu },
{ name: 'Scrollable', icon: mdiPanVertical },
{ name: 'Stack', icon: mdiViewSequential },
],
},
Expand All @@ -61,6 +64,7 @@ export const componentGroups = [
{ name: 'Input', icon: mdiFormTextbox },
{ name: 'LoadingSpinner', icon: mdiDotsCircle },
{ name: 'PasswordInput', icon: mdiFormTextboxPassword },
{ name: 'Switch', icon: mdiToggleSwitch },
],
},
{
Expand Down
3 changes: 2 additions & 1 deletion src/lib/components/Scrollable/Scrollable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
const { class: className, children }: Props = $props();
</script>

<div class={cleanClass('immich-scrollbar overflow-y-auto', className)}>
<div class={cleanClass('immich-scrollbar h-full w-full overflow-auto', className)}>
{@render children?.()}
</div>

<style>
/* width */
.immich-scrollbar::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/* Track */
Expand Down
102 changes: 102 additions & 0 deletions src/lib/components/Switch/Switch.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<script lang="ts">
import { getFieldContext } from '$lib/common/context.svelte.js';
import type { Color } from '$lib/types.js';
import { cleanClass } from '$lib/utils.js';
import type { Snippet } from 'svelte';
import type { HTMLInputAttributes } from 'svelte/elements';
import { tv } from 'tailwind-variants';
type Props = {
checked?: boolean;
color?: Color;
disabled?: boolean;
class?: string;
children?: Snippet;
onToggle?: ((checked: boolean) => void) | undefined;
} & HTMLInputAttributes;
let {
checked = $bindable(false),
class: className,
color = 'primary',
children,

Check failure on line 22 in src/lib/components/Switch/Switch.svelte

View workflow job for this annotation

GitHub Actions / Test

'children' is assigned a value but never used
onToggle = undefined,
...restProps
}: Props = $props();
const {
label,
readOnly = false,
required = false,
disabled = false,
} = $derived(getFieldContext());
const enabled = $derived(checked && !disabled);
const handleToggle = (event: Event) => onToggle?.((event.target as HTMLInputElement).checked);
const wrapper = tv({
base: 'relative flex flex-col justify-center',
variants: {
disabled: {
true: 'cursor-not-allowed',
false: 'cursor-pointer',
},
},
});
const bar = tv({
base: 'w-12 h-3 my-2 rounded-full border border-transparent',
variants: {
fillColor: {
default: 'bg-gray-400',
primary: 'bg-primary/50',
secondary: 'bg-dark/50',
success: 'bg-success/50',
danger: 'bg-danger/50',
warning: 'bg-warning/50',
info: 'bg-info/50',
},
},
});
const dot = tv({
base: 'absolute transition-colors h-6 w-6 rounded-full transition-transform duration-[400ms]',
variants: {
checked: {
true: 'translate-x-6',
false: '',
},
fillColor: {
default: 'bg-gray-600',
primary: 'bg-primary',
secondary: 'bg-dark',
success: 'bg-success',
danger: 'bg-danger',
warning: 'bg-warning',
info: 'bg-info',
},
},
});
</script>

<label class={cleanClass(className)}>
{label}
<span class={wrapper({ disabled })}>
<input
class="hidden"
type="checkbox"
bind:checked
onclick={handleToggle}
{required}
aria-required={required}
{disabled}
aria-disabled={disabled}
readonly={readOnly}
aria-readonly={readOnly}
{...restProps}
/>
<span class={bar({ fillColor: enabled ? color : 'default' })}> </span>
<span class={dot({ checked: enabled, fillColor: enabled ? color : 'default' })}></span>
</span>
</label>
1 change: 1 addition & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export { default as HStack } from '$lib/components/Stack/HStack.svelte';
export { default as Stack } from '$lib/components/Stack/Stack.svelte';
export { default as VStack } from '$lib/components/Stack/VStack.svelte';
export { default as SupporterBadge } from '$lib/components/SupporterBadge/SupporterBadge.svelte';
export { default as Switch } from '$lib/components/Switch/Switch.svelte';
export { default as Text } from '$lib/components/Text/Text.svelte';
export * from '$lib/types.js';
export * from '$lib/utilities/byte-units.js';
5 changes: 4 additions & 1 deletion src/routes/components/button/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import ExampleLayout from '$docs/components/ExampleLayout.svelte';
import { Text } from '@immich/ui';
import BasicExample from './BasicExample.svelte';
import basicExample from './BasicExample.svelte?raw';
import ColorExample from './ColorExample.svelte';
Expand Down Expand Up @@ -35,4 +36,6 @@
];
</script>

<ExampleLayout name="Button" {examples} />
<ExampleLayout name="Button" {examples}>
<Text>A button component, which can also be used to render links</Text>
</ExampleLayout>
5 changes: 4 additions & 1 deletion src/routes/components/field/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<script lang="ts">
import ExampleLayout from '$docs/components/ExampleLayout.svelte';
import { Text } from '@immich/ui';
import BasicExample from './BasicExample.svelte';
import basicExample from './BasicExample.svelte?raw';
const examples = [{ title: 'Basic', code: basicExample, component: BasicExample }];
</script>

<ExampleLayout name="Field" {examples} />
<ExampleLayout name="Field" {examples}>
<Text>A metadata component for tracking common form field information</Text>
</ExampleLayout>
2 changes: 1 addition & 1 deletion src/routes/components/navbar/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
];
</script>

<ExampleLayout name="Basic" {examples} />
<ExampleLayout name="Navbar" {examples} />
2 changes: 1 addition & 1 deletion src/routes/components/navbar/BasicExample.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
import { mdiHome } from '@mdi/js';
</script>

<div class="w-[200px]">
<div class="max-w-[200px]">
<NavbarItem icon={mdiHome} title="Home" href="#" active />
</div>
3 changes: 1 addition & 2 deletions src/routes/components/navbar/GroupExample.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script lang="ts">
import NavbarGroup from '$lib/components/Navbar/NavbarGroup.svelte';
import { NavbarItem } from '@immich/ui';
import { NavbarGroup, NavbarItem } from '@immich/ui';
import { mdiButtonPointer, mdiCardOutline, mdiHome } from '@mdi/js';
</script>

Expand Down
9 changes: 9 additions & 0 deletions src/routes/components/scrollable/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script lang="ts">
import ExampleLayout from '$docs/components/ExampleLayout.svelte';
import BasicExample from './BasicExample.svelte';
import basicExample from './BasicExample.svelte?raw';
const examples = [{ title: 'Basic', code: basicExample, component: BasicExample }];
</script>

<ExampleLayout name="Scrollable" {examples} />
22 changes: 22 additions & 0 deletions src/routes/components/scrollable/BasicExample.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script lang="ts">
import Lorem from '$docs/components/Lorem.svelte';
import { Heading, Scrollable, Stack, Text } from '@immich/ui';
</script>

<Stack gap={4}>
<Heading size="tiny">Vertical</Heading>
<div class="h-64 w-32">
<Scrollable>
<Text>
<Lorem count={5} />
</Text>
</Scrollable>
</div>

<Heading size="tiny">Horizontal</Heading>
<Scrollable>
<Text class="h-8 w-[2000px]">
<Lorem />
</Text>
</Scrollable>
</Stack>
20 changes: 20 additions & 0 deletions src/routes/components/switch/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<script lang="ts">
import ExampleLayout from '$docs/components/ExampleLayout.svelte';
import { Text } from '@immich/ui';
import BasicExample from './BasicExample.svelte';
import basicExample from './BasicExample.svelte?raw';
import ColorExample from './ColorExample.svelte';
import colorExample from './ColorExample.svelte?raw';
import FormExample from './FormExample.svelte';
import formExample from './FormExample.svelte?raw';
const examples = [
{ title: 'Basic', code: basicExample, component: BasicExample },
{ title: 'Colors', code: colorExample, component: ColorExample },
{ title: 'Form', code: formExample, component: FormExample },
];
</script>

<ExampleLayout name="Switch" {examples}>
<Text>A boolean input element</Text>
</ExampleLayout>
11 changes: 11 additions & 0 deletions src/routes/components/switch/BasicExample.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
import { Field, Stack, Switch } from '@immich/ui';
</script>

<Stack>
<Switch />
<Switch checked />
<Field disabled>
<Switch disabled />
</Field>
</Stack>
12 changes: 12 additions & 0 deletions src/routes/components/switch/ColorExample.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script lang="ts">
import { Stack, Switch } from '@immich/ui';
</script>

<Stack>
<Switch color="primary" checked />
<Switch color="secondary" checked />
<Switch color="success" checked />
<Switch color="info" checked />
<Switch color="warning" checked />
<Switch color="danger" checked />
</Stack>
17 changes: 17 additions & 0 deletions src/routes/components/switch/FormExample.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script>
import { Field, Stack, Switch, Text } from '@immich/ui';
</script>

<Stack>
<Field label="Support Immich">
<Switch class="flex justify-between" checked />
</Field>
<Field label="Advanced features">
<Switch class="flex justify-between" />
</Field>
<Field label="Sell my privacy" disabled>
<Switch class="flex justify-between">
<Text>Disabled</Text>
</Switch>
</Field>
</Stack>

0 comments on commit be3dc78

Please sign in to comment.