-
Notifications
You must be signed in to change notification settings - Fork 103
/
ColorPicker.svelte
78 lines (67 loc) · 2.76 KB
/
ColorPicker.svelte
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
<script lang="ts">
import { AccountColors } from '@core/account'
import { localize } from '@core/i18n'
import { Icon, Text } from '@ui'
import { isBright } from '@core/utils'
export let active: string
export let classes: string = ''
export let title: string = localize('views.picker.color.title')
const accountColors = Object.values(AccountColors).filter((c) => /[#]/.test(c as string)) as string[]
const activeAccountColorIndex = accountColors.findIndex((_, i) => accountColors[i] === active)
let activeElement: number = activeAccountColorIndex >= 0 ? activeAccountColorIndex : accountColors.length
let inputValue: string = activeAccountColorIndex >= 0 ? '#FFFFFF' : active
let inputColor: string
const handleKeyPress = (event, i) => event.key === 'Enter' && (activeElement = i)
const handleColorClick = (i) => (activeElement = i)
$: if (activeElement >= accountColors.length) {
active = inputValue.length >= 7 ? inputValue : '#FFFFFF'
} else {
active = accountColors[activeElement]
}
$: inputValue = `#${/[0-9|a-f|A-F]+/.exec(inputValue) || ''}`
$: if (inputValue.length >= 7) {
inputColor = isBright(inputValue) ? 'gray-800' : 'white'
} else {
inputColor = 'gray-800'
}
function hex2rgb(hex: string): string {
hex = hex.length >= 7 ? hex : '#FFFFFF'
return hex
.match(/\w\w/g)
?.map((x) => parseInt(x, 16))
.join(',')
}
</script>
<div
style="--account-color: {inputValue ? hex2rgb(active) : ''}; --custom-color: {hex2rgb(inputValue)};"
class={classes}
>
<div class="flex flex-row mb-4">
<Text type="h5">{title}</Text>
</div>
<ul class="flex flex-row flex-wrap gap-3.5">
{#each Object.keys(AccountColors).reduce((acc, val) => (/[#]/.test(val) ? acc : [...acc, val.toLowerCase()]), []) as color, i}
<li
tabindex="0"
class="w-12 h-12 rounded-lg ring-opacity-30 hover:ring-opacity-40 cursor-pointer flex justify-center items-center
bg-{color}-500 hover:bg-{color}-600 focus:bg-{color}-600 ring-{color}-500"
class:ring-4={activeElement === i}
on:click={() => handleColorClick(i)}
on:keypress={(event) => handleKeyPress(event, i)}
aria-label={color}
>
{#if activeElement === i}<Icon icon="checkmark" classes="text-white" />{/if}
</li>
{/each}
</ul>
</div>
<style type="text/scss">
input {
background-color: transparent;
}
.active {
background-color: rgb(var(--account-color));
--tw-ring-color: rgba(var(--account-color), var(--tw-ring-opacity));
--tw-ring-opacity: 0.3;
}
</style>