Skip to content

Commit bc4d74d

Browse files
committed
[feat] new folder editor
1 parent 64a37b7 commit bc4d74d

File tree

5 files changed

+234
-109
lines changed

5 files changed

+234
-109
lines changed

src/lib/data/bookmarks/defaults.ts

+10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ const default_theme = {
99
foreground: '#F5F5F5'
1010
}
1111

12+
export const emptyFolder = (current_folder_count: number): Folder => ({
13+
folder_id: cuid(),
14+
user_id: '',
15+
icon: '📌',
16+
title: 'My Folder',
17+
bookmarks: [],
18+
position: current_folder_count + 1,
19+
active: true
20+
})
21+
1222
export const emptyBookmark = (current_folder: Folder): Bookmark => {
1323
const { title } = current_folder
1424
return {

src/lib/ui/Folders/FolderEditor.svelte

+188-56
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,102 @@
11
<script lang="ts">
2-
import { folderEditor, editorContext } from '$lib/stores/folderEditor'
3-
// TODO:
4-
// import { newFolder_db, updateFolder_db } from '$lib/data/transactions'
5-
import { createEventDispatcher, onMount } from 'svelte'
2+
// Data
3+
import { folderEditor, editorContext } from '$lib/stores/bookmarkEditor'
4+
import { editor } from '$lib/stores/bookmarkEditor'
5+
import { uniqueTags } from '$lib/data/dbStore'
6+
// TODO: import { newFolder_db, updateFolder_db } from '$lib/data/transactions'
67
8+
// Components
79
import DeleteFolder from './DeleteFolder.svelte'
8-
import { uniqueTags } from '$lib/data/dbStore'
910
import Button from '$lib/ui/Button.svelte'
1011
11-
export let folder_id: string = ''
12+
// Utils
13+
import { clickOutside } from 'fractils'
14+
import { onMount } from 'svelte'
1215
13-
const dispatch = createEventDispatcher()
16+
export let folder_id: string = ''
1417
1518
let emoji = '📌'
1619
let titleInput: HTMLInputElement
20+
let header = ''
21+
let selectedTags: boolean[] = []
1722
1823
async function handleSave() {
1924
if ($editorContext === 'edit') {
20-
// TODO:
2125
alert('todo')
22-
// updateFolder_db($folderEditor)
26+
// TODO: updateFolder_db($folderEditor)
2327
} else {
24-
// TODO:
2528
alert('todo')
26-
// await newFolder_db($folderEditor)
29+
// TODO: await newFolder_db($folderEditor)
2730
}
28-
dispatch('close')
31+
editor.hide()
2932
}
3033
3134
onMount(async () => {
32-
if ($editorContext === 'create') titleInput.select()
35+
if ($editorContext === 'create') {
36+
header = 'New Folder'
37+
titleInput.select()
38+
}
3339
})
3440
</script>
3541

36-
{#if $folderEditor}
37-
<div class="editor-container">
38-
<!-- TODO: Emoji Picker -->
39-
<div class="emoji">{emoji}</div>
40-
41-
<div class="setting title">
42-
<input
43-
name="title"
44-
placeholder="title"
45-
bind:this={titleInput}
46-
bind:value={$folderEditor['title']}
47-
on:click={() => titleInput.select()}
48-
on:keydown={(e) => e.key === 'Enter' && handleSave()}
49-
/>
50-
</div>
51-
52-
<div class="setting">
53-
<div name="tags" class="tags">
54-
{#each $uniqueTags as tag}
55-
{tag}
56-
{/each}
57-
</div>
58-
</div>
59-
60-
<div class="buttons">
61-
<Button --colorHover="var(--warn)" --borderHover="1px solid var(--warn)" on:click={() => dispatch('close')}
62-
>Cancel</Button
63-
>
64-
<Button --colorHover="var(--confirm)" --borderHover="1px solid var(--confirm)" on:click={handleSave}
65-
>Save</Button
66-
>
67-
<DeleteFolder {folder_id} on:close={() => dispatch('close')} />
68-
</div>
69-
</div>
70-
{/if}
42+
<template lang="pug">
43+
44+
h1 selectedTags: {selectedTags}
45+
+if('$folderEditor')
46+
.editor-container(use:clickOutside!='{() => editor.hide()}')
47+
.space-sm
48+
h2.header {header}
49+
.space-sm
50+
51+
.setting.title
52+
.emoji {emoji}
53+
input.title(
54+
placeholder="My Folder"
55+
bind:this='{titleInput}'
56+
bind:value='{$folderEditor.title}'
57+
on:click!='{() => titleInput.select()}'
58+
on:keydown!='{(e) => e.key === "Enter" && handleSave()}'
59+
)
60+
.space-lg
61+
62+
.setting.tag-manager.scroller
63+
.info Add bookmarks from tags (optional)
64+
.tags
65+
+if('$uniqueTags')
66+
+each('$uniqueTags as tag, i')
67+
.tag(
68+
class:selected='{selectedTags[i]}'
69+
on:click!='{() => selectedTags[i] = !selectedTags[i]}'
70+
) {tag}
71+
.tag(
72+
class:selected='{selectedTags[i]}'
73+
on:click!='{() => selectedTags[i] = !selectedTags[i]}'
74+
) {tag}
75+
76+
.buttons
77+
Button(
78+
'--colorHover'='var(--warn)'
79+
'--borderHover'='1px solid var(--warn)'
80+
on:click!='{() => editor.hide()}'
81+
) Cancel
82+
83+
Button(
84+
'--colorHover'='var(--confirm)'
85+
'--borderHover'='1px solid var(--confirm)'
86+
on:click='{handleSave}'
87+
) Save
88+
89+
DeleteFolder({folder_id} on:close!='{() => editor.hide()}')
90+
91+
92+
</template>
7193

7294
<style lang="scss">
7395
.editor-container {
7496
display: flex;
7597
position: relative;
7698
flex-direction: column;
99+
flex-grow: 1;
77100
78101
width: 500px;
79102
height: max-content;
@@ -105,6 +128,15 @@
105128
}
106129
}
107130
131+
.header {
132+
margin: 1rem auto;
133+
134+
color: var(--dark-a);
135+
136+
text-align: center;
137+
font-size: 1.5rem;
138+
}
139+
108140
.setting {
109141
display: flex;
110142
position: relative;
@@ -116,14 +148,16 @@
116148
}
117149
118150
input {
119-
width: 60%;
120-
padding: 5px 8px 5px 8px;
151+
width: 50%;
152+
padding: 8px;
121153
122154
color: var(--dark-a);
123155
border: 1px solid rgba(var(--light-b-rgb), 0);
124156
border-radius: 3px;
125157
outline: none;
126158
background: var(--light-a);
159+
box-shadow: var(--shadow-sm);
160+
border-bottom: 1px solid rgba(var(--light-b-rgb), 1);
127161
128162
font-family: 'Abel';
129163
font-size: 1rem;
@@ -136,24 +170,122 @@
136170
opacity: 0;
137171
}
138172
}
139-
&:focus,
173+
}
174+
175+
input.title {
176+
min-width: max-content;
177+
max-width: 90%;
178+
179+
border: 1px solid rgba(var(--dark-a-rgb), 0.1);
140180
&:hover {
141-
border-bottom: 1px solid rgba(var(--light-b-rgb), 1);
181+
border: 1px solid rgba(var(--dark-a-rgb), 0.5);
182+
}
183+
&:focus {
184+
border: 1px solid rgba(var(--dark-a-rgb), 1);
142185
}
186+
187+
font-size: 1.25rem;
143188
}
144189
145-
input[name='title'] {
146-
font-size: 1.5rem;
190+
.title {
191+
display: flex;
192+
justify-content: center;
193+
align-items: center;
194+
195+
margin: auto;
196+
197+
transform: translateX(-0.4rem);
198+
}
199+
200+
.emoji {
201+
display: flex;
202+
justify-content: center;
203+
align-items: center;
204+
205+
width: 40px;
206+
height: 40px;
207+
margin: auto;
208+
209+
border-radius: 4px;
210+
border: 1px solid rgba(var(--dark-a-rgb), 0.1);
211+
&:hover {
212+
border: 1px solid rgba(var(--dark-a-rgb), 0.5);
213+
}
214+
&:focus {
215+
border: 1px solid rgba(var(--dark-a-rgb), 1);
216+
}
217+
218+
cursor: pointer;
219+
transform: translateX(-2rem);
220+
}
221+
222+
.tag-manager {
223+
display: flex;
224+
flex-direction: column;
225+
226+
width: 90%;
227+
margin: auto;
228+
229+
border: 1px solid var(--light-b);
230+
border-radius: 5px;
231+
opacity: 0.5;
232+
233+
&:hover {
234+
opacity: 1;
235+
}
236+
}
237+
238+
.info {
239+
margin: 1rem auto;
240+
241+
color: var(--dark-c);
242+
243+
text-align: center;
244+
font-size: 0.95rem;
147245
}
148246
149247
.tags {
150248
position: relative;
249+
display: grid;
250+
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
251+
gap: 10px;
151252
152-
width: 90%;
153-
height: 100%;
253+
max-width: 95%;
254+
max-height: 200px;
154255
margin: 1rem auto;
155256
156257
font-family: var(--font-primary);
258+
259+
transition: opacity 0.2s;
260+
}
261+
262+
.tag {
263+
display: flex;
264+
justify-content: center;
265+
266+
height: max-content;
267+
padding: 0.25rem 0.4rem;
268+
269+
opacity: 0.5;
270+
border: 1px solid;
271+
border-radius: 5px;
272+
border-color: rgba(var(--dark-a-rgb), 0.25);
273+
274+
font-size: 0.95rem;
275+
text-align: center;
276+
277+
cursor: pointer;
278+
transition: 0.15s;
279+
280+
&:hover {
281+
opacity: 0.75;
282+
border-color: rgba(var(--dark-a-rgb), 0.5);
283+
}
284+
285+
&.selected {
286+
opacity: 1;
287+
border-color: var(--dark-a);
288+
}
157289
}
158290
159291
.buttons {

src/lib/ui/Folders/FolderSidebar.svelte

+5-3
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@
44
55
// Data
66
import { activeBookmarks, activeFolder, activeFolderBookmarks, tagFilter, uniqueTags } from '$lib/data/dbStore'
7+
import { editor } from '$lib/stores/bookmarkEditor'
8+
import { init_db } from '$lib/data/transactions'
79
import db from '$lib/data/db'
810
911
// Utils
12+
import { smoothHover } from '$lib/utils/smoothHover'
13+
import { reRender } from '$lib/stores/gridStore'
1014
import { fly, fade } from 'svelte/transition'
1115
import { onMount } from 'svelte'
1216
1317
// Components
1418
import Tooltip from '$lib/ui/Tooltip.svelte'
15-
import { init_db } from '$lib/data/transactions'
16-
import { reRender } from '$lib/stores/gridStore'
17-
import { smoothHover } from '$lib/utils/smoothHover'
1819
1920
let folderIcons = []
2021
@@ -71,6 +72,7 @@
7172
7273
const newFolder = () => {
7374
// TODO: Create new folder
75+
editor.show(['create', 'folder'])
7476
}
7577
</script>
7678

0 commit comments

Comments
 (0)