~james/core

core/docs/src/components/RepoCreationName.svelte -rw-r--r-- 3.3 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 15 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<script lang="ts">
	// a mock of the new-repository form's name field: the account picker next to
	// the repository-name input, composed from the web app's own Field, Dropdown
	// and Input. the accounts are fake -- a personal account and an organization
	// -- and carry gradient avatars in place of the profile pictures the avatar
	// service would sign, so the docs build stays clear of that service.
	import Card from "$lib/components/ui/Card.svelte";
	import Field from "$lib/components/ui/Field.svelte";
	import Input from "$lib/components/ui/Input.svelte";
	import Dropdown from "$lib/components/ui/Dropdown.svelte";
	import DropdownItem from "$lib/components/ui/DropdownItem.svelte";
	import Avatar from "$lib/components/ui/Avatar.svelte";
	import ChevronDown from "$icon/chevron-down";

	const gradient = (from: string, to: string): string =>
		`data:image/svg+xml,${encodeURIComponent(
			`<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><defs><linearGradient id="g" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="${from}"/><stop offset="1" stop-color="${to}"/></linearGradient></defs><rect width="64" height="64" fill="url(#g)"/></svg>`
		)}`;

	type Account = { did: string; handle: string; avatar: string };

	const accounts: Account[] = [
		{
			did: "did:plc:alice",
			handle: "alice.tngl.sh",
			avatar: gradient("#fb923c", "#f472b6")
		},
		{
			did: "did:plc:organization",
			handle: "organization.tngl.sh",
			avatar: gradient("#6366f1", "#a855f7")
		}
	];

	let selectedDid = $state(accounts[0].did);
	let name = $state("my-project");

	const selected = $derived(accounts.find((account) => account.did === selectedDid) ?? accounts[0]);
	const others = $derived(accounts.filter((account) => account.did !== selectedDid));
</script>

<Card
	padding="regular"
	class="repo-creation-name not-content my-lg typography-paragraph-regular">
	<Field
		label="Repository name"
		subtitle="Choose a unique, descriptive name. Use letters, numbers, periods, underscores, and hyphens."
	>
		{#snippet children({ id })}
			<div class="flex w-full flex-col gap-xs md:flex-row md:items-center md:gap-none">
				<Dropdown
					variant="button"
					label="Repository owner {selected.handle}"
					title="Select an account"
					class="min-w-0 md:me-xs md:max-w-[55%]">
					{#snippet trigger()}
						<span class="inline-flex min-w-0 items-center gap-1.5">
							<Avatar src={selected.avatar} size="regular" />
							<span class="min-w-0 truncate">{selected.handle}</span>
						</span>
						<ChevronDown class="ml-auto size-3.5 shrink-0" aria-hidden="true" />
					{/snippet}

					<div class="px-xs py-1.5 font-medium">Repository owner</div>
					{#each others as account (account.did)}
						<DropdownItem onclick={() => (selectedDid = account.did)}>
							<span class="inline-flex min-w-0 items-center gap-1.5">
								<Avatar src={account.avatar} size="regular" />
								<span class="min-w-0 truncate">{account.handle}</span>
							</span>
						</DropdownItem>
					{/each}
				</Dropdown>
				<Input
					{id}
					name="repo_name"
					placeholder="repository-name"
					maxlength={100}
					bind:value={name}
					class="flex-1" />
			</div>
		{/snippet}
	</Field>
</Card>

<style>
	/* the field's subtitle is a `p`, which takes the markdown column's margins;
	   give it back to the field */
	:global(.repo-creation-name p) {
		margin: 0;
	}
</style>