|
1 | 1 | <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' |
6 | 7 |
|
| 8 | + // Components |
7 | 9 | import DeleteFolder from './DeleteFolder.svelte'
|
8 |
| - import { uniqueTags } from '$lib/data/dbStore' |
9 | 10 | import Button from '$lib/ui/Button.svelte'
|
10 | 11 |
|
11 |
| - export let folder_id: string = '' |
| 12 | + // Utils |
| 13 | + import { clickOutside } from 'fractils' |
| 14 | + import { onMount } from 'svelte' |
12 | 15 |
|
13 |
| - const dispatch = createEventDispatcher() |
| 16 | + export let folder_id: string = '' |
14 | 17 |
|
15 | 18 | let emoji = '📌'
|
16 | 19 | let titleInput: HTMLInputElement
|
| 20 | + let header = '' |
| 21 | + let selectedTags: boolean[] = [] |
17 | 22 |
|
18 | 23 | async function handleSave() {
|
19 | 24 | if ($editorContext === 'edit') {
|
20 |
| - // TODO: |
21 | 25 | alert('todo')
|
22 |
| - // updateFolder_db($folderEditor) |
| 26 | + // TODO: updateFolder_db($folderEditor) |
23 | 27 | } else {
|
24 |
| - // TODO: |
25 | 28 | alert('todo')
|
26 |
| - // await newFolder_db($folderEditor) |
| 29 | + // TODO: await newFolder_db($folderEditor) |
27 | 30 | }
|
28 |
| - dispatch('close') |
| 31 | + editor.hide() |
29 | 32 | }
|
30 | 33 |
|
31 | 34 | onMount(async () => {
|
32 |
| - if ($editorContext === 'create') titleInput.select() |
| 35 | + if ($editorContext === 'create') { |
| 36 | + header = 'New Folder' |
| 37 | + titleInput.select() |
| 38 | + } |
33 | 39 | })
|
34 | 40 | </script>
|
35 | 41 |
|
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> |
71 | 93 |
|
72 | 94 | <style lang="scss">
|
73 | 95 | .editor-container {
|
74 | 96 | display: flex;
|
75 | 97 | position: relative;
|
76 | 98 | flex-direction: column;
|
| 99 | + flex-grow: 1; |
77 | 100 |
|
78 | 101 | width: 500px;
|
79 | 102 | height: max-content;
|
|
105 | 128 | }
|
106 | 129 | }
|
107 | 130 |
|
| 131 | + .header { |
| 132 | + margin: 1rem auto; |
| 133 | +
|
| 134 | + color: var(--dark-a); |
| 135 | +
|
| 136 | + text-align: center; |
| 137 | + font-size: 1.5rem; |
| 138 | + } |
| 139 | +
|
108 | 140 | .setting {
|
109 | 141 | display: flex;
|
110 | 142 | position: relative;
|
|
116 | 148 | }
|
117 | 149 |
|
118 | 150 | input {
|
119 |
| - width: 60%; |
120 |
| - padding: 5px 8px 5px 8px; |
| 151 | + width: 50%; |
| 152 | + padding: 8px; |
121 | 153 |
|
122 | 154 | color: var(--dark-a);
|
123 | 155 | border: 1px solid rgba(var(--light-b-rgb), 0);
|
124 | 156 | border-radius: 3px;
|
125 | 157 | outline: none;
|
126 | 158 | background: var(--light-a);
|
| 159 | + box-shadow: var(--shadow-sm); |
| 160 | + border-bottom: 1px solid rgba(var(--light-b-rgb), 1); |
127 | 161 |
|
128 | 162 | font-family: 'Abel';
|
129 | 163 | font-size: 1rem;
|
|
136 | 170 | opacity: 0;
|
137 | 171 | }
|
138 | 172 | }
|
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); |
140 | 180 | &: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); |
142 | 185 | }
|
| 186 | +
|
| 187 | + font-size: 1.25rem; |
143 | 188 | }
|
144 | 189 |
|
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; |
147 | 245 | }
|
148 | 246 |
|
149 | 247 | .tags {
|
150 | 248 | position: relative;
|
| 249 | + display: grid; |
| 250 | + grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); |
| 251 | + gap: 10px; |
151 | 252 |
|
152 |
| - width: 90%; |
153 |
| - height: 100%; |
| 253 | + max-width: 95%; |
| 254 | + max-height: 200px; |
154 | 255 | margin: 1rem auto;
|
155 | 256 |
|
156 | 257 | 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 | + } |
157 | 289 | }
|
158 | 290 |
|
159 | 291 | .buttons {
|
|
0 commit comments