Gisle Aune
1 year ago
6 changed files with 167 additions and 0 deletions
-
34frontend/src/lib/components/common/TagRow.svelte
-
82frontend/src/lib/components/controls/TagInput.svelte
-
2frontend/src/lib/components/project/ItemSubSection.svelte
-
13frontend/src/lib/modals/ItemCreateModal.svelte
-
4frontend/src/lib/models/item.ts
-
32ports/mysql/items.go
@ -0,0 +1,34 @@ |
|||
<script lang="ts"> |
|||
export let names: string[] |
|||
</script> |
|||
|
|||
<div class="tag-row"> |
|||
{#each names as name (name)} |
|||
<div class="tag">{name}<span class="comma">,</span></div> |
|||
{/each} |
|||
</div> |
|||
|
|||
<style lang="sass"> |
|||
@import "../../css/colors" |
|||
|
|||
div.tag-row |
|||
display: flex |
|||
flex-direction: row |
|||
flex-wrap: wrap |
|||
|
|||
&:empty |
|||
display: none |
|||
|
|||
> div.tag |
|||
margin: 0.25em 0.5ch |
|||
background-color: $color-entry2 |
|||
padding: 0.25em 1ch |
|||
border-radius: 0.25em |
|||
font-size: 0.75em |
|||
|
|||
> span.comma |
|||
font-size: 0 |
|||
|
|||
&:first-child |
|||
margin-left: 0 |
|||
</style> |
@ -0,0 +1,82 @@ |
|||
<script lang="ts"> |
|||
import Icon from "../layout/Icon.svelte"; |
|||
|
|||
export let value: string[]; |
|||
|
|||
let nextTag = ""; |
|||
|
|||
function onKey(ev: KeyboardEvent) { |
|||
if ((ev.metaKey||ev.ctrlKey) && nextTag === "" && ev.key === "Backspace") { |
|||
value = value.slice(0, -1); |
|||
} |
|||
|
|||
if ((ev.metaKey||ev.ctrlKey) && nextTag !== "" && ev.key === "Enter") { |
|||
value = [...value, nextTag]; |
|||
nextTag = ""; |
|||
ev.preventDefault(); |
|||
} |
|||
} |
|||
|
|||
$: while (nextTag.includes(",")) { |
|||
const newTags = nextTag.split(",").map(t => t.trim()); |
|||
value = [...value, ...newTags.slice(0, -1)]; |
|||
nextTag = newTags[newTags.length - 1]; |
|||
} |
|||
|
|||
$: value = (value||[]).filter((e, i) => !value.slice(0, i).includes(e)); |
|||
</script> |
|||
|
|||
<div class="tag-input"> |
|||
{#each value as tag (tag)} |
|||
<div class="tag"> |
|||
<span>{tag}</span> |
|||
<span class="comma">,</span> |
|||
<span class="x" on:click={() => value = value.filter(v => v !== tag)}> |
|||
<Icon name="times" /> |
|||
</span> |
|||
</div> |
|||
{/each} |
|||
<input placeholder="Add tag (type , or press Ctrl+Enter to add)" on:keyup={onKey} bind:value={nextTag} /> |
|||
</div> |
|||
|
|||
<style lang="sass"> |
|||
@import "../../css/colors" |
|||
|
|||
div.tag-input |
|||
width: calc(100% - 2ch) |
|||
margin-bottom: 1em |
|||
margin-top: 0.20em |
|||
min-height: 2em |
|||
|
|||
background: $color-entryhalf |
|||
color: $color-entry8 |
|||
border: none |
|||
outline: none |
|||
resize: vertical |
|||
padding: 0.5em 1ch |
|||
|
|||
display: flex |
|||
flex-direction: row |
|||
flex-wrap: wrap |
|||
|
|||
> div.tag |
|||
margin: 0.25em 0.5ch |
|||
background-color: $color-entry1 |
|||
padding: 0.25em 1ch |
|||
border-radius: 0.25em |
|||
|
|||
span.x |
|||
font-size: 0.75em |
|||
line-height: 1em |
|||
user-select: none |
|||
cursor: pointer |
|||
|
|||
&:hover |
|||
color: $color-entry12 |
|||
|
|||
span.comma |
|||
font-size: 0 |
|||
|
|||
> input |
|||
margin-bottom: 0.125em |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue