Skip to content

Commit

Permalink
component: Snippet (#60)
Browse files Browse the repository at this point in the history
* Done

* update casing

* format

* Update snippet.svelte

Prevent highlighting of $

* inverted, simplify, consistency, & tweaks

* missed a few spots (due to the new hsl tokens)

* thanks, @ieedan

* mirror variants to the og

---------

Co-authored-by: Davis SHYAKA <[email protected]>
  • Loading branch information
ieedan and shyakadavis authored Sep 10, 2024
1 parent ccac8e8 commit 672f9fa
Show file tree
Hide file tree
Showing 22 changed files with 533 additions and 315 deletions.
364 changes: 182 additions & 182 deletions src/app.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/lib/assets/icons/brand-assets.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 18 additions & 18 deletions src/lib/assets/icons/error-states.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/lib/assets/icons/face-sad.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/lib/assets/icons/face-smile.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/lib/assets/icons/logo-next.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/lib/assets/icons/logo-turborepo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/lib/assets/icons/logo-vercel-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 3 additions & 4 deletions src/lib/components/ui/dialog/dialog-overlay.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@
type $$Props = DialogPrimitive.OverlayProps;
let className: $$Props['class'] = undefined;
let class_name: $$Props['class'] = undefined;
export let transition: $$Props['transition'] = fade;
export let transitionConfig: $$Props['transitionConfig'] = {
duration: 150
};
export { className as class };
export { class_name as class };
</script>

<!-- TODO: Messed up when I removed opacity modifiers. 🤦‍♂️ i.e. being able to do `bg-background-200/80`. And Tailwind v4 will deprecate the `opacity` utility class. A resolution will require re-writing the tokens in app.css because doing `opacity-80` doesn't show the blur, for example. -->
<DialogPrimitive.Overlay
{transition}
{transitionConfig}
class={cn('fixed inset-0 z-50 bg-background-100 opacity-80 backdrop-blur-sm', className)}
class={cn('fixed inset-0 z-50 bg-background-100/80 backdrop-blur-[1px]', class_name)}
{...$$restProps}
/>
39 changes: 39 additions & 0 deletions src/lib/components/ui/snippet/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { tv, type VariantProps } from 'tailwind-variants';
import Snippet from './snippet.svelte';

export const snippet_variants = tv({
base: 'relative w-fit max-w-full rounded-md border bg-background-100 py-2.5 pl-3 pr-12',
variants: {
variant: {
default: 'border-gray-alpha-400',
success: 'bg-blue-100 text-blue-900',
error: 'bg-red-100 text-red-900',
warning: 'bg-amber-100 text-amber-900'
}
}
});

export const copy_button_variants = tv({
base: 'absolute right-3 top-1/2 -translate-y-1/2 transition-opacity ease-in-out hover:text-opacity-80',
variants: {
variant: {
default: 'text-gray-1000',
success: 'text-blue-900',
error: 'text-red-900',
warning: 'text-amber-900'
}
}
});

type Variant = VariantProps<typeof snippet_variants>['variant'];

export type Props = {
variant?: Variant;
text: string | string[];
class?: string;
prompt?: boolean;
on_copy?: () => void;
inverted?: boolean;
};

export { Snippet };
78 changes: 78 additions & 0 deletions src/lib/components/ui/snippet/snippet.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<script lang="ts">
import { Icons } from '$lib/assets/icons';
import { cn } from '$lib/utils';
import { scale } from 'svelte/transition';
import { copy_button_variants, snippet_variants, type Props } from '.';
type $$Props = Props;
export let text: $$Props['text'];
export let prompt: $$Props['prompt'] = true;
export let variant: $$Props['variant'] = 'default';
export let on_copy: $$Props['on_copy'] = undefined;
export let inverted: $$Props['inverted'] = false;
let class_name: $$Props['class'] = undefined;
export { class_name as class };
let copied = false;
async function copy_snippet() {
if (typeof text == 'string') {
await navigator.clipboard.writeText(text);
} else {
await navigator.clipboard.writeText(text.join('\n'));
}
copied = true;
if (on_copy) {
on_copy();
}
setTimeout(() => (copied = false), 750);
}
</script>

<div
class={cn(snippet_variants({ variant, className: class_name }), {
'bg-gray-1000 text-gray-100': inverted
})}
>
{#if typeof text == 'string'}
<pre
class={cn('overflow-y-auto whitespace-nowrap text-left font-mono text-[13px] leading-5', {
"before:content-['$']": prompt
})}>
{text}
</pre>
{:else}
{#each text as line}
<pre
class={cn('overflow-y-auto whitespace-nowrap text-left font-mono text-[13px] leading-5', {
"before:content-['$']": prompt
})}>
{line}
</pre>
{/each}
{/if}

<button
on:click={copy_snippet}
type="button"
class={cn(copy_button_variants({ variant }), {
'bg-gray-1000 text-gray-100': inverted
})}
>
{#if copied}
<div in:scale={{ start: 0.75, duration: 250 }}>
<Icons.Check class="size-4" />
<span class="sr-only">Copied</span>
</div>
{:else}
<div in:scale={{ start: 0.75, duration: 250 }}>
<Icons.Copy class="size-4" />
<span class="sr-only">Copy</span>
</div>
{/if}
</button>
</div>
2 changes: 1 addition & 1 deletion src/lib/config/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export const aside_items: Aside = {
{
title: 'Snippet',
href: '/snippet',
status: 'soon'
status: 'new'
},
{
title: 'Spinner',
Expand Down
22 changes: 11 additions & 11 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@
];
const preview_colors = [
'--gray-800',
'--blue-800',
'--purple-700',
'--pink-800',
'--red-800',
'--amber-800',
'--green-800',
'--teal-800'
'bg-gray-800',
'bg-blue-800',
'bg-purple-700',
'bg-pink-800',
'bg-red-800',
'bg-amber-800',
'bg-green-800',
'bg-teal-800'
];
</script>

<PageWrapper
title="Geist Design System"
title="[Svelte] Geist Design System"
description="Vercel design system for building consistent web experiences."
>
<section class="grid auto-rows-fr sm:grid-cols-2">
Expand All @@ -56,7 +56,7 @@
<div class="relative mx-auto w-fit">
<Icons.BrandAssets aria-hidden="true" height="96" width="322" />
<div
class="absolute inset-0 transition-[box-shadow] delay-0 [box-shadow:_0_0_8px_8px_var(--background-200)_inset] group-hover:[box-shadow:_0_0_8px_8px_var(--background-100)_inset]"
class="absolute inset-0 transition-[box-shadow] delay-0 [box-shadow:_0_0_8px_8px_hsl(var(--background-200))_inset] group-hover:[box-shadow:_0_0_8px_8px_hsl(var(--background-100))_inset]"
></div>
</div>
</IntroductionLink>
Expand Down Expand Up @@ -92,7 +92,7 @@
<div
class="flex h-[96px] w-[32px] items-center justify-center overflow-hidden rounded-full border border-gray-alpha-400 bg-background-200"
>
<div class="h-[72px] w-2 rounded-full" style="background: var({color});"></div>
<div class="h-[72px] w-2 rounded-full {color}"></div>
</div>
{/each}
</div>
Expand Down
45 changes: 44 additions & 1 deletion src/routes/snippet/+page.svelte
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
<h1>snippet</h1>
<script lang="ts">
import Demo from '$lib/components/shared/demo.svelte';
import PageWrapper from '$lib/components/shared/page-wrapper.svelte';
import Callback from './callback.svelte';
import callback_code from './callback.svelte?raw';
import Default from './default.svelte';
import default_code from './default.svelte?raw';
import Inverted from './inverted.svelte';
import inverted_code from './inverted.svelte?raw';
import Multiline from './multiline.svelte';
import multiline_code from './multiline.svelte?raw';
import NoPrompt from './no-prompt.svelte';
import no_prompt_code from './no-prompt.svelte?raw';
import Variants from './variants.svelte';
import variants_code from './variants.svelte?raw';
export let data;
</script>

<PageWrapper title={data.title} description={data.description}>
<Demo id="default" code={default_code}>
<Default />
</Demo>

<Demo id="inverted" code={inverted_code}>
<Inverted />
</Demo>

<Demo id="multi-line" code={multiline_code}>
<Multiline />
</Demo>

<Demo id="no-prompt" code={no_prompt_code}>
<NoPrompt />
</Demo>

<Demo id="callback" code={callback_code}>
<Callback />
</Demo>

<Demo id="variants" code={variants_code}>
<Variants />
</Demo>
</PageWrapper>
21 changes: 21 additions & 0 deletions src/routes/snippet/+page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { MetaTagsProps } from 'svelte-meta-tags';

export function load() {
const title = 'Snippet';
const description = 'Display a snippet of copyable code for the command line.';

const pageMetaTags = Object.freeze({
title,
description,
openGraph: {
title,
description
}
}) satisfies MetaTagsProps;

return {
pageMetaTags,
title,
description
};
}
9 changes: 9 additions & 0 deletions src/routes/snippet/callback.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script lang="ts">
import { Snippet } from '$lib/components/ui/snippet';
</script>

<Snippet
on_copy={() => alert('You copied the text!')}
text="pnpm create svelte@latest"
class="w-[300px]"
/>
5 changes: 5 additions & 0 deletions src/routes/snippet/default.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script lang="ts">
import { Snippet } from '$lib/components/ui/snippet';
</script>

<Snippet text="pnpm create svelte@latest" class="w-[300px]" />
5 changes: 5 additions & 0 deletions src/routes/snippet/inverted.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script lang="ts">
import { Snippet } from '$lib/components/ui/snippet';
</script>

<Snippet inverted text="pnpm create svelte@latest" class="w-[300px]" />
5 changes: 5 additions & 0 deletions src/routes/snippet/multiline.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script lang="ts">
import { Snippet } from '$lib/components/ui/snippet';
</script>

<Snippet text={['cd project', 'now']} class="w-full" />
5 changes: 5 additions & 0 deletions src/routes/snippet/no-prompt.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script lang="ts">
import { Snippet } from '$lib/components/ui/snippet';
</script>

<Snippet prompt={false} text="pnpm create svelte@latest" class="w-[300px]" />
9 changes: 9 additions & 0 deletions src/routes/snippet/variants.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script lang="ts">
import { Snippet } from '$lib/components/ui/snippet';
</script>

<div class="grid gap-3">
<Snippet variant="success" text="pnpm create svelte@latest" class="w-[300px]" />
<Snippet variant="error" text="pnpm create svelte@latest" class="w-[300px]" />
<Snippet variant="warning" text="pnpm create svelte@latest" class="w-[300px]" />
</div>
Loading

0 comments on commit 672f9fa

Please sign in to comment.