mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-14 22:08:45 +00:00
Button 및 Input 컴포넌트를 atoms 디렉터리로 이동 및 리팩토링
This commit is contained in:
35
src/lib/components/atoms/buttons/Button.svelte
Normal file
35
src/lib/components/atoms/buttons/Button.svelte
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { Snippet } from "svelte";
|
||||||
|
import type { ClassValue } from "svelte/elements";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children?: Snippet;
|
||||||
|
class?: ClassValue;
|
||||||
|
color?: "primary" | "gray";
|
||||||
|
onclick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
let { children, color = "primary", onclick, ...props }: Props = $props();
|
||||||
|
|
||||||
|
let bgColor = $derived(
|
||||||
|
{
|
||||||
|
primary: "bg-primary-600 active:bg-primary-500",
|
||||||
|
gray: "bg-gray-300 active:bg-gray-400",
|
||||||
|
}[color],
|
||||||
|
);
|
||||||
|
let textColor = $derived(
|
||||||
|
{
|
||||||
|
primary: "text-white",
|
||||||
|
gray: "text-gray-800",
|
||||||
|
}[color],
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onclick={onclick && (() => setTimeout(onclick, 100))}
|
||||||
|
class={["h-12 min-w-fit rounded-xl font-medium", bgColor, textColor, props.class]}
|
||||||
|
>
|
||||||
|
<div class="h-full p-3 transition active:scale-95">
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
28
src/lib/components/atoms/buttons/EntryButton.svelte
Normal file
28
src/lib/components/atoms/buttons/EntryButton.svelte
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { Snippet } from "svelte";
|
||||||
|
import type { ClassValue } from "svelte/elements";
|
||||||
|
|
||||||
|
import IconChevronRight from "~icons/material-symbols/chevron-right";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children?: Snippet;
|
||||||
|
class?: ClassValue;
|
||||||
|
onclick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
let { children, onclick, ...props }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onclick={onclick && (() => setTimeout(onclick, 100))}
|
||||||
|
class={["rounded-xl active:bg-gray-100", props.class]}
|
||||||
|
>
|
||||||
|
<div class="flex h-full p-2 transition active:scale-95">
|
||||||
|
<div class="flex-grow">
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-shrink-0 items-center">
|
||||||
|
<IconChevronRight class="text-xl text-gray-800" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
@@ -1,30 +1,24 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Component } from "svelte";
|
import type { Component } from "svelte";
|
||||||
import type { SvelteHTMLElements } from "svelte/elements";
|
import type { ClassValue, SvelteHTMLElements } from "svelte/elements";
|
||||||
import { AdaptiveDiv } from "$lib/components/divs";
|
import { AdaptiveDiv } from "$lib/components/divs";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
icon: Component<SvelteHTMLElements["svg"]>;
|
icon: Component<SvelteHTMLElements["svg"]>;
|
||||||
offset?: string;
|
offset?: ClassValue;
|
||||||
onclick?: () => void;
|
onclick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { icon: Icon, offset = "bottom-20", onclick }: Props = $props();
|
let { icon: Icon, offset = "bottom-20", onclick }: Props = $props();
|
||||||
|
|
||||||
const click = () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
onclick?.();
|
|
||||||
}, 100);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="pointer-events-none fixed inset-0">
|
<div class="pointer-events-none fixed inset-0">
|
||||||
<div class="absolute w-full {offset}">
|
<div class={["absolute w-full", offset]}>
|
||||||
<AdaptiveDiv>
|
<AdaptiveDiv>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="absolute bottom-4 right-4">
|
<div class="absolute bottom-4 right-4">
|
||||||
<button
|
<button
|
||||||
onclick={click}
|
onclick={onclick && (() => setTimeout(onclick, 100))}
|
||||||
class="pointer-events-auto flex h-14 w-14 items-center justify-center rounded-full bg-gray-300 shadow-lg transition active:scale-95 active:bg-gray-400"
|
class="pointer-events-auto flex h-14 w-14 items-center justify-center rounded-full bg-gray-300 shadow-lg transition active:scale-95 active:bg-gray-400"
|
||||||
>
|
>
|
||||||
<Icon class="text-xl" />
|
<Icon class="text-xl" />
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { Snippet } from "svelte";
|
import type { Snippet } from "svelte";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: Snippet;
|
children?: Snippet;
|
||||||
onclick?: () => void;
|
onclick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10,14 +10,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onclick={() => {
|
onclick={onclick && (() => setTimeout(onclick, 100))}
|
||||||
setTimeout(() => {
|
|
||||||
onclick?.();
|
|
||||||
}, 100);
|
|
||||||
}}
|
|
||||||
class="text-sm font-medium text-gray-800 underline underline-offset-2 active:rounded-xl active:bg-gray-100"
|
class="text-sm font-medium text-gray-800 underline underline-offset-2 active:rounded-xl active:bg-gray-100"
|
||||||
>
|
>
|
||||||
<div class="h-full w-full p-1 transition active:scale-95">
|
<div class="h-full p-1 transition active:scale-95">
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
2
src/lib/components/atoms/index.ts
Normal file
2
src/lib/components/atoms/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./buttons";
|
||||||
|
export * from "./inputs";
|
||||||
@@ -5,16 +5,18 @@
|
|||||||
import IconCheckCircleOutline from "~icons/material-symbols/check-circle-outline";
|
import IconCheckCircleOutline from "~icons/material-symbols/check-circle-outline";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: Snippet;
|
|
||||||
checked?: boolean;
|
checked?: boolean;
|
||||||
|
children?: Snippet;
|
||||||
}
|
}
|
||||||
|
|
||||||
let { children, checked = $bindable(false) }: Props = $props();
|
let { checked = $bindable(false), children }: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="flex items-center gap-x-1">
|
<label class="flex items-center gap-x-1">
|
||||||
<input bind:checked type="checkbox" class="hidden" />
|
<input bind:checked type="checkbox" class="hidden" />
|
||||||
{@render children?.()}
|
<div>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
||||||
{#if checked}
|
{#if checked}
|
||||||
<IconCheckCircle class="text-primary-600" />
|
<IconCheckCircle class="text-primary-600" />
|
||||||
{:else}
|
{:else}
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
/>
|
/>
|
||||||
<!-- svelte-ignore a11y_label_has_associated_control -->
|
<!-- svelte-ignore a11y_label_has_associated_control -->
|
||||||
<label
|
<label
|
||||||
class="absolute left-0 top-1/2 -translate-y-1/2 transform text-xl text-gray-400 transition-all duration-300 ease-in-out"
|
class="pointer-events-none absolute left-0 top-1/2 -translate-y-1/2 transform text-xl text-gray-400 transition-all duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
{placeholder}
|
{placeholder}
|
||||||
</label>
|
</label>
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import type { Snippet } from "svelte";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children: Snippet;
|
|
||||||
color?: "primary" | "gray";
|
|
||||||
onclick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { children, color = "primary", onclick }: Props = $props();
|
|
||||||
|
|
||||||
const bgColorStyle = $derived(
|
|
||||||
{
|
|
||||||
primary: "bg-primary-600 active:bg-primary-500",
|
|
||||||
gray: "bg-gray-300 active:bg-gray-400",
|
|
||||||
}[color],
|
|
||||||
);
|
|
||||||
const fontColorStyle = $derived(
|
|
||||||
{
|
|
||||||
primary: "text-white",
|
|
||||||
gray: "text-gray-800",
|
|
||||||
}[color],
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onclick={() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
onclick?.();
|
|
||||||
}, 100);
|
|
||||||
}}
|
|
||||||
class="{bgColorStyle} {fontColorStyle} h-12 w-full min-w-fit rounded-xl font-medium"
|
|
||||||
>
|
|
||||||
<div class="h-full w-full p-3 transition active:scale-95">
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import type { Snippet } from "svelte";
|
|
||||||
|
|
||||||
import IconChevronRight from "~icons/material-symbols/chevron-right";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children: Snippet;
|
|
||||||
onclick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { children, onclick }: Props = $props();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onclick={() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
onclick?.();
|
|
||||||
}, 100);
|
|
||||||
}}
|
|
||||||
class="w-full rounded-xl active:bg-gray-100"
|
|
||||||
>
|
|
||||||
<div class="flex w-full justify-between p-2 transition active:scale-95">
|
|
||||||
<div>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center justify-center">
|
|
||||||
<IconChevronRight class="text-xl text-gray-800" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
import type { Component } from "svelte";
|
import type { Component } from "svelte";
|
||||||
import type { ClassValue, SvelteHTMLElements } from "svelte/elements";
|
import type { ClassValue, SvelteHTMLElements } from "svelte/elements";
|
||||||
import type { Writable } from "svelte/store";
|
import type { Writable } from "svelte/store";
|
||||||
import { EntryButton } from "$lib/components/buttons";
|
import { EntryButton } from "$lib/components/atoms";
|
||||||
import { getCategoryInfo, type CategoryInfo } from "$lib/modules/filesystem";
|
import { getCategoryInfo, type CategoryInfo } from "$lib/modules/filesystem";
|
||||||
import Categories, { type SelectedCategory } from "$lib/molecules/Categories";
|
import Categories, { type SelectedCategory } from "$lib/molecules/Categories";
|
||||||
import { masterKeyStore } from "$lib/stores";
|
import { masterKeyStore } from "$lib/stores";
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
<div class={["space-y-1", props.class]}>
|
<div class={["space-y-1", props.class]}>
|
||||||
{#snippet subCategoryCreate()}
|
{#snippet subCategoryCreate()}
|
||||||
<EntryButton onclick={onSubCategoryCreateClick}>
|
<EntryButton onclick={onSubCategoryCreateClick} class="w-full">
|
||||||
<div class="flex h-8 items-center gap-x-4">
|
<div class="flex h-8 items-center gap-x-4">
|
||||||
<IconAddCircle class="text-lg text-gray-600" />
|
<IconAddCircle class="text-lg text-gray-600" />
|
||||||
<p class="font-medium text-gray-700">카테고리 추가하기</p>
|
<p class="font-medium text-gray-700">카테고리 추가하기</p>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { untrack } from "svelte";
|
import { untrack } from "svelte";
|
||||||
import { get, type Writable } from "svelte/store";
|
import { get, type Writable } from "svelte/store";
|
||||||
import { CheckBox } from "$lib/components/inputs";
|
import { CheckBox } from "$lib/components/atoms";
|
||||||
import { getFileInfo, type FileInfo, type CategoryInfo } from "$lib/modules/filesystem";
|
import { getFileInfo, type FileInfo, type CategoryInfo } from "$lib/modules/filesystem";
|
||||||
import { SortBy, sortEntries } from "$lib/modules/util";
|
import { SortBy, sortEntries } from "$lib/modules/util";
|
||||||
import type { SelectedCategory } from "$lib/molecules/Categories";
|
import type { SelectedCategory } from "$lib/molecules/Categories";
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Modal } from "$lib/components";
|
import { Modal } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button, TextInput } from "$lib/components/atoms";
|
||||||
import { TextInput } from "$lib/components/inputs";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onCreateClick: (name: string) => void;
|
onCreateClick: (name: string) => void;
|
||||||
@@ -23,8 +22,8 @@
|
|||||||
<div class="mt-2 flex w-full">
|
<div class="mt-2 flex w-full">
|
||||||
<TextInput bind:value={name} placeholder="카테고리 이름" />
|
<TextInput bind:value={name} placeholder="카테고리 이름" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-7 flex gap-2">
|
<div class="mt-7 flex gap-x-2">
|
||||||
<Button color="gray" onclick={closeModal}>닫기</Button>
|
<Button color="gray" onclick={closeModal} class="flex-1">닫기</Button>
|
||||||
<Button onclick={() => onCreateClick(name)}>만들기</Button>
|
<Button onclick={() => onCreateClick(name)} class="flex-1">만들기</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { TopBar } from "$lib/components";
|
import { TopBar } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button, TextInput } from "$lib/components/atoms";
|
||||||
import { TitleDiv, BottomDiv } from "$lib/components/divs";
|
import { TitleDiv, BottomDiv } from "$lib/components/divs";
|
||||||
import { TextInput } from "$lib/components/inputs";
|
|
||||||
import { requestPasswordChange } from "./service";
|
import { requestPasswordChange } from "./service";
|
||||||
|
|
||||||
let oldPassword = $state("");
|
let oldPassword = $state("");
|
||||||
@@ -34,5 +33,5 @@
|
|||||||
</TitleDiv>
|
</TitleDiv>
|
||||||
</div>
|
</div>
|
||||||
<BottomDiv>
|
<BottomDiv>
|
||||||
<Button onclick={changePassword}>비밀번호 바꾸기</Button>
|
<Button onclick={changePassword} class="w-full">비밀번호 바꾸기</Button>
|
||||||
</BottomDiv>
|
</BottomDiv>
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { Button, TextButton } from "$lib/components/buttons";
|
import { Button, TextButton, TextInput } from "$lib/components/atoms";
|
||||||
import { TitleDiv, BottomDiv } from "$lib/components/divs";
|
import { TitleDiv, BottomDiv } from "$lib/components/divs";
|
||||||
import { TextInput } from "$lib/components/inputs";
|
|
||||||
import { clientKeyStore, masterKeyStore } from "$lib/stores";
|
import { clientKeyStore, masterKeyStore } from "$lib/stores";
|
||||||
import { requestLogin, requestSessionUpgrade, requestMasterKeyDownload } from "./service";
|
import { requestLogin, requestSessionUpgrade, requestMasterKeyDownload } from "./service";
|
||||||
|
|
||||||
@@ -58,6 +57,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</TitleDiv>
|
</TitleDiv>
|
||||||
<BottomDiv>
|
<BottomDiv>
|
||||||
<Button onclick={login}>로그인</Button>
|
<Button onclick={login} class="w-full">로그인</Button>
|
||||||
<TextButton>계정이 없어요</TextButton>
|
<TextButton>계정이 없어요</TextButton>
|
||||||
</BottomDiv>
|
</BottomDiv>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import { get, type Writable } from "svelte/store";
|
import { get, type Writable } from "svelte/store";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { TopBar } from "$lib/components";
|
import { TopBar } from "$lib/components";
|
||||||
import { EntryButton } from "$lib/components/buttons";
|
import { EntryButton } from "$lib/components/atoms";
|
||||||
import {
|
import {
|
||||||
getFileInfo,
|
getFileInfo,
|
||||||
getCategoryInfo,
|
getCategoryInfo,
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
onCategoryClick={({ id }) => goto(`/category/${id}`)}
|
onCategoryClick={({ id }) => goto(`/category/${id}`)}
|
||||||
onCategoryMenuClick={({ id }) => removeFromCategory(id)}
|
onCategoryMenuClick={({ id }) => removeFromCategory(id)}
|
||||||
/>
|
/>
|
||||||
<EntryButton onclick={() => (isAddToCategoryBottomSheetOpen = true)}>
|
<EntryButton onclick={() => (isAddToCategoryBottomSheetOpen = true)} class="w-full">
|
||||||
<div class="flex h-8 items-center gap-x-4">
|
<div class="flex h-8 items-center gap-x-4">
|
||||||
<IconAddCircle class="text-lg text-gray-600" />
|
<IconAddCircle class="text-lg text-gray-600" />
|
||||||
<p class="font-medium text-gray-700">카테고리에 추가하기</p>
|
<p class="font-medium text-gray-700">카테고리에 추가하기</p>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Writable } from "svelte/store";
|
import type { Writable } from "svelte/store";
|
||||||
import { BottomSheet } from "$lib/components";
|
import { BottomSheet } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button } from "$lib/components/atoms";
|
||||||
import { BottomDiv } from "$lib/components/divs";
|
import { BottomDiv } from "$lib/components/divs";
|
||||||
import { getCategoryInfo, type CategoryInfo } from "$lib/modules/filesystem";
|
import { getCategoryInfo, type CategoryInfo } from "$lib/modules/filesystem";
|
||||||
import SubCategories from "$lib/molecules/SubCategories.svelte";
|
import SubCategories from "$lib/molecules/SubCategories.svelte";
|
||||||
@@ -48,7 +48,9 @@
|
|||||||
/>
|
/>
|
||||||
{#if $category.id !== "root"}
|
{#if $category.id !== "root"}
|
||||||
<BottomDiv>
|
<BottomDiv>
|
||||||
<Button onclick={() => onAddToCategoryClick($category.id)}>이 카테고리에 추가하기</Button>
|
<Button onclick={() => onAddToCategoryClick($category.id)} class="w-full">
|
||||||
|
이 카테고리에 추가하기
|
||||||
|
</Button>
|
||||||
</BottomDiv>
|
</BottomDiv>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import FileSaver from "file-saver";
|
import FileSaver from "file-saver";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { Button, TextButton } from "$lib/components/buttons";
|
import { Button, TextButton } from "$lib/components/atoms";
|
||||||
import { TitleDiv, BottomDiv } from "$lib/components/divs";
|
import { TitleDiv, BottomDiv } from "$lib/components/divs";
|
||||||
import { clientKeyStore } from "$lib/stores";
|
import { clientKeyStore } from "$lib/stores";
|
||||||
import BeforeContinueBottomSheet from "./BeforeContinueBottomSheet.svelte";
|
import BeforeContinueBottomSheet from "./BeforeContinueBottomSheet.svelte";
|
||||||
@@ -101,14 +101,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</TitleDiv>
|
</TitleDiv>
|
||||||
<BottomDiv>
|
<BottomDiv>
|
||||||
<Button onclick={exportClientKeys}>암호 키 내보내기</Button>
|
<Button onclick={exportClientKeys} class="w-full">암호 키 내보내기</Button>
|
||||||
<TextButton
|
<TextButton onclick={() => (isBeforeContinueModalOpen = true)}>내보내지 않을래요</TextButton>
|
||||||
onclick={() => {
|
|
||||||
isBeforeContinueModalOpen = true;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
내보내지 않을래요
|
|
||||||
</TextButton>
|
|
||||||
</BottomDiv>
|
</BottomDiv>
|
||||||
|
|
||||||
<BeforeContinueModal bind:isOpen={isBeforeContinueModalOpen} onContinueClick={registerPubKeys} />
|
<BeforeContinueModal bind:isOpen={isBeforeContinueModalOpen} onContinueClick={registerPubKeys} />
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { BottomSheet } from "$lib/components";
|
import { BottomSheet } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button } from "$lib/components/atoms";
|
||||||
import { BottomDiv } from "$lib/components/divs";
|
import { BottomDiv } from "$lib/components/divs";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -22,9 +22,9 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<BottomDiv>
|
<BottomDiv>
|
||||||
<div class="flex w-full gap-2">
|
<div class="flex w-full gap-x-2">
|
||||||
<Button color="gray" onclick={onRetryClick}>다시 저장할래요</Button>
|
<Button color="gray" onclick={onRetryClick} class="flex-1">다시 저장할래요</Button>
|
||||||
<Button onclick={onContinueClick}>잘 저장되었어요</Button>
|
<Button onclick={onContinueClick} class="flex-1">잘 저장되었어요</Button>
|
||||||
</div>
|
</div>
|
||||||
</BottomDiv>
|
</BottomDiv>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Modal } from "$lib/components";
|
import { Modal } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button } from "$lib/components/atoms";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onContinueClick: () => void;
|
onContinueClick: () => void;
|
||||||
@@ -16,16 +16,9 @@
|
|||||||
<p class="text-xl font-bold">내보내지 않고 계속할까요?</p>
|
<p class="text-xl font-bold">내보내지 않고 계속할까요?</p>
|
||||||
<p>암호 키 파일은 유출 방지를 위해 이 화면에서만 저장할 수 있어요.</p>
|
<p>암호 키 파일은 유출 방지를 위해 이 화면에서만 저장할 수 있어요.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-x-2">
|
||||||
<Button
|
<Button color="gray" onclick={() => (isOpen = false)} class="flex-1">아니요</Button>
|
||||||
color="gray"
|
<Button onclick={onContinueClick} class="flex-1">계속할게요</Button>
|
||||||
onclick={() => {
|
|
||||||
isOpen = false;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
아니요
|
|
||||||
</Button>
|
|
||||||
<Button onclick={onContinueClick}>계속할게요</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { Button, TextButton } from "$lib/components/buttons";
|
import { Button, TextButton } from "$lib/components/atoms";
|
||||||
import { TitleDiv, BottomDiv } from "$lib/components/divs";
|
import { TitleDiv, BottomDiv } from "$lib/components/divs";
|
||||||
import { gotoStateful } from "$lib/hooks";
|
import { gotoStateful } from "$lib/hooks";
|
||||||
import { clientKeyStore } from "$lib/stores";
|
import { clientKeyStore } from "$lib/stores";
|
||||||
@@ -80,6 +80,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</TitleDiv>
|
</TitleDiv>
|
||||||
<BottomDiv>
|
<BottomDiv>
|
||||||
<Button onclick={generateKeys}>새 암호 키 생성하기</Button>
|
<Button onclick={generateKeys} class="w-full">새 암호 키 생성하기</Button>
|
||||||
<TextButton>키를 갖고 있어요</TextButton>
|
<TextButton>키를 갖고 있어요</TextButton>
|
||||||
</BottomDiv>
|
</BottomDiv>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { BottomSheet } from "$lib/components";
|
import { BottomSheet } from "$lib/components";
|
||||||
import { EntryButton } from "$lib/components/buttons";
|
import { EntryButton } from "$lib/components/atoms";
|
||||||
import type { SelectedCategory } from "$lib/molecules/Categories";
|
import type { SelectedCategory } from "$lib/molecules/Categories";
|
||||||
|
|
||||||
import IconCategory from "~icons/material-symbols/category";
|
import IconCategory from "~icons/material-symbols/category";
|
||||||
@@ -41,13 +41,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="my-2 h-px w-full bg-gray-200"></div>
|
<div class="my-2 h-px w-full bg-gray-200"></div>
|
||||||
{/if}
|
{/if}
|
||||||
<EntryButton onclick={onRenameClick}>
|
<EntryButton onclick={onRenameClick} class="w-full">
|
||||||
<div class="flex h-8 items-center gap-x-4">
|
<div class="flex h-8 items-center gap-x-4">
|
||||||
<IconEdit class="text-lg" />
|
<IconEdit class="text-lg" />
|
||||||
<p class="font-medium">이름 바꾸기</p>
|
<p class="font-medium">이름 바꾸기</p>
|
||||||
</div>
|
</div>
|
||||||
</EntryButton>
|
</EntryButton>
|
||||||
<EntryButton onclick={onDeleteClick}>
|
<EntryButton onclick={onDeleteClick} class="w-full">
|
||||||
<div class="flex h-8 items-center gap-x-4 text-red-500">
|
<div class="flex h-8 items-center gap-x-4 text-red-500">
|
||||||
<IconDelete class="text-lg" />
|
<IconDelete class="text-lg" />
|
||||||
<p class="font-medium">삭제하기</p>
|
<p class="font-medium">삭제하기</p>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Modal } from "$lib/components";
|
import { Modal } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button } from "$lib/components/atoms";
|
||||||
import type { SelectedCategory } from "$lib/molecules/Categories";
|
import type { SelectedCategory } from "$lib/molecules/Categories";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -39,9 +39,9 @@
|
|||||||
하지만 카테고리에 추가된 파일들은 삭제되지 않아요.
|
하지만 카테고리에 추가된 파일들은 삭제되지 않아요.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-x-2">
|
||||||
<Button color="gray" onclick={closeModal}>아니요</Button>
|
<Button color="gray" onclick={closeModal} class="flex-1">아니요</Button>
|
||||||
<Button onclick={deleteEntry}>삭제할게요</Button>
|
<Button onclick={deleteEntry} class="flex-1">삭제할게요</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Modal } from "$lib/components";
|
import { Modal } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button, TextInput } from "$lib/components/atoms";
|
||||||
import { TextInput } from "$lib/components/inputs";
|
|
||||||
import type { SelectedCategory } from "$lib/molecules/Categories";
|
import type { SelectedCategory } from "$lib/molecules/Categories";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -20,7 +19,7 @@
|
|||||||
selectedCategory = undefined;
|
selectedCategory = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const renameEntry = async () => {
|
const renameCategory = async () => {
|
||||||
// TODO: Validation
|
// TODO: Validation
|
||||||
|
|
||||||
if (await onRenameClick(name)) {
|
if (await onRenameClick(name)) {
|
||||||
@@ -40,8 +39,8 @@
|
|||||||
<div class="mt-2 flex w-full">
|
<div class="mt-2 flex w-full">
|
||||||
<TextInput bind:value={name} placeholder="이름" />
|
<TextInput bind:value={name} placeholder="이름" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-7 flex gap-2">
|
<div class="mt-7 flex gap-x-2">
|
||||||
<Button color="gray" onclick={closeModal}>닫기</Button>
|
<Button color="gray" onclick={closeModal} class="flex-1">닫기</Button>
|
||||||
<Button onclick={renameEntry}>바꾸기</Button>
|
<Button onclick={renameCategory} class="flex-1">바꾸기</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import type { Writable } from "svelte/store";
|
import type { Writable } from "svelte/store";
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { TopBar } from "$lib/components";
|
import { TopBar } from "$lib/components";
|
||||||
import { FloatingButton } from "$lib/components/buttons";
|
import { FloatingButton } from "$lib/components/atoms";
|
||||||
import { getDirectoryInfo, type DirectoryInfo } from "$lib/modules/filesystem";
|
import { getDirectoryInfo, type DirectoryInfo } from "$lib/modules/filesystem";
|
||||||
import { masterKeyStore, hmacSecretStore } from "$lib/stores";
|
import { masterKeyStore, hmacSecretStore } from "$lib/stores";
|
||||||
import CreateBottomSheet from "./CreateBottomSheet.svelte";
|
import CreateBottomSheet from "./CreateBottomSheet.svelte";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { BottomSheet } from "$lib/components";
|
import { BottomSheet } from "$lib/components";
|
||||||
import { EntryButton } from "$lib/components/buttons";
|
import { EntryButton } from "$lib/components/atoms";
|
||||||
|
|
||||||
import IconCreateNewFolder from "~icons/material-symbols/create-new-folder";
|
import IconCreateNewFolder from "~icons/material-symbols/create-new-folder";
|
||||||
import IconUploadFile from "~icons/material-symbols/upload-file";
|
import IconUploadFile from "~icons/material-symbols/upload-file";
|
||||||
@@ -16,13 +16,13 @@
|
|||||||
|
|
||||||
<BottomSheet bind:isOpen>
|
<BottomSheet bind:isOpen>
|
||||||
<div class="w-full py-4">
|
<div class="w-full py-4">
|
||||||
<EntryButton onclick={onDirectoryCreateClick}>
|
<EntryButton onclick={onDirectoryCreateClick} class="w-full">
|
||||||
<div class="flex h-12 items-center gap-x-4">
|
<div class="flex h-12 items-center gap-x-4">
|
||||||
<IconCreateNewFolder class="text-2xl text-yellow-500" />
|
<IconCreateNewFolder class="text-2xl text-yellow-500" />
|
||||||
<p class="font-medium">폴더 만들기</p>
|
<p class="font-medium">폴더 만들기</p>
|
||||||
</div>
|
</div>
|
||||||
</EntryButton>
|
</EntryButton>
|
||||||
<EntryButton onclick={onFileUploadClick}>
|
<EntryButton onclick={onFileUploadClick} class="w-full">
|
||||||
<div class="flex h-12 items-center gap-x-4">
|
<div class="flex h-12 items-center gap-x-4">
|
||||||
<IconUploadFile class="text-2xl text-blue-400" />
|
<IconUploadFile class="text-2xl text-blue-400" />
|
||||||
<p class="font-medium">파일 업로드</p>
|
<p class="font-medium">파일 업로드</p>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Modal } from "$lib/components";
|
import { Modal } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button, TextInput } from "$lib/components/atoms";
|
||||||
import { TextInput } from "$lib/components/inputs";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onCreateClick: (name: string) => void;
|
onCreateClick: (name: string) => void;
|
||||||
@@ -23,8 +22,8 @@
|
|||||||
<div class="mt-2 flex w-full">
|
<div class="mt-2 flex w-full">
|
||||||
<TextInput bind:value={name} placeholder="폴더 이름" />
|
<TextInput bind:value={name} placeholder="폴더 이름" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-7 flex gap-2">
|
<div class="mt-7 flex gap-x-2">
|
||||||
<Button color="gray" onclick={closeModal}>닫기</Button>
|
<Button color="gray" onclick={closeModal} class="flex-1">닫기</Button>
|
||||||
<Button onclick={() => onCreateClick(name)}>만들기</Button>
|
<Button onclick={() => onCreateClick(name)} class="flex-1">만들기</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Modal } from "$lib/components";
|
import { Modal } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button } from "$lib/components/atoms";
|
||||||
import type { SelectedDirectoryEntry } from "./service";
|
import type { SelectedDirectoryEntry } from "./service";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -47,9 +47,9 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-x-2">
|
||||||
<Button color="gray" onclick={closeModal}>아니요</Button>
|
<Button color="gray" onclick={closeModal} class="flex-1">아니요</Button>
|
||||||
<Button onclick={deleteEntry}>삭제할게요</Button>
|
<Button onclick={deleteEntry} class="flex-1">삭제할게요</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { BottomSheet } from "$lib/components";
|
import { BottomSheet } from "$lib/components";
|
||||||
import { EntryButton } from "$lib/components/buttons";
|
import { EntryButton } from "$lib/components/atoms";
|
||||||
import type { SelectedDirectoryEntry } from "./service";
|
import type { SelectedDirectoryEntry } from "./service";
|
||||||
|
|
||||||
import IconFolder from "~icons/material-symbols/folder";
|
import IconFolder from "~icons/material-symbols/folder";
|
||||||
@@ -46,13 +46,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="my-2 h-px w-full bg-gray-200"></div>
|
<div class="my-2 h-px w-full bg-gray-200"></div>
|
||||||
{/if}
|
{/if}
|
||||||
<EntryButton onclick={onRenameClick}>
|
<EntryButton onclick={onRenameClick} class="w-full">
|
||||||
<div class="flex h-8 items-center gap-x-4">
|
<div class="flex h-8 items-center gap-x-4">
|
||||||
<IconEdit class="text-lg" />
|
<IconEdit class="text-lg" />
|
||||||
<p class="font-medium">이름 바꾸기</p>
|
<p class="font-medium">이름 바꾸기</p>
|
||||||
</div>
|
</div>
|
||||||
</EntryButton>
|
</EntryButton>
|
||||||
<EntryButton onclick={onDeleteClick}>
|
<EntryButton onclick={onDeleteClick} class="w-full">
|
||||||
<div class="flex h-8 items-center gap-x-4 text-red-500">
|
<div class="flex h-8 items-center gap-x-4 text-red-500">
|
||||||
<IconDelete class="text-lg" />
|
<IconDelete class="text-lg" />
|
||||||
<p class="font-medium">삭제하기</p>
|
<p class="font-medium">삭제하기</p>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Modal } from "$lib/components";
|
import { Modal } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button } from "$lib/components/atoms";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
file: File | undefined;
|
file: File | undefined;
|
||||||
@@ -21,9 +21,9 @@
|
|||||||
<p class="text-xl font-bold">'{nameShort}' 파일이 있어요.</p>
|
<p class="text-xl font-bold">'{nameShort}' 파일이 있어요.</p>
|
||||||
<p>예전에 이미 업로드된 파일이에요. 그래도 업로드할까요?</p>
|
<p>예전에 이미 업로드된 파일이에요. 그래도 업로드할까요?</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-x-2">
|
||||||
<Button color="gray" onclick={onclose}>아니요</Button>
|
<Button color="gray" onclick={onclose} class="flex-1">아니요</Button>
|
||||||
<Button onclick={onDuplicateClick}>업로드할게요</Button>
|
<Button onclick={onDuplicateClick} class="flex-1">업로드할게요</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Modal } from "$lib/components";
|
import { Modal } from "$lib/components";
|
||||||
import { Button } from "$lib/components/buttons";
|
import { Button, TextInput } from "$lib/components/atoms";
|
||||||
import { TextInput } from "$lib/components/inputs";
|
|
||||||
import type { SelectedDirectoryEntry } from "./service";
|
import type { SelectedDirectoryEntry } from "./service";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -40,8 +39,8 @@
|
|||||||
<div class="mt-2 flex w-full">
|
<div class="mt-2 flex w-full">
|
||||||
<TextInput bind:value={name} placeholder="이름" />
|
<TextInput bind:value={name} placeholder="이름" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-7 flex gap-2">
|
<div class="mt-7 flex gap-x-2">
|
||||||
<Button color="gray" onclick={closeModal}>닫기</Button>
|
<Button color="gray" onclick={closeModal} class="flex-1">닫기</Button>
|
||||||
<Button onclick={renameEntry}>바꾸기</Button>
|
<Button onclick={renameEntry} class="flex-1">바꾸기</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Component, Snippet } from "svelte";
|
import type { Component, Snippet } from "svelte";
|
||||||
import type { SvelteHTMLElements } from "svelte/elements";
|
import type { SvelteHTMLElements } from "svelte/elements";
|
||||||
import { EntryButton } from "$lib/components/buttons";
|
import { EntryButton } from "$lib/components/atoms";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
children: Snippet;
|
children: Snippet;
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
let { children, icon: Icon, iconColor, onclick }: Props = $props();
|
let { children, icon: Icon, iconColor, onclick }: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<EntryButton {onclick}>
|
<EntryButton {onclick} class="w-full">
|
||||||
<div class="flex items-center gap-x-4">
|
<div class="flex items-center gap-x-4">
|
||||||
<div class="rounded-lg bg-gray-200 p-1 {iconColor}">
|
<div class="rounded-lg bg-gray-200 p-1 {iconColor}">
|
||||||
<Icon />
|
<Icon />
|
||||||
|
|||||||
Reference in New Issue
Block a user