gradio / js /imageeditor /shared /tools /ColorSwatch.svelte
mindmime's picture
Upload folder using huggingface_hub
a03b3ba verified
raw
history blame contribute delete
No virus
3.55 kB
<script lang="ts">
import tinycolor from "tinycolor2";
import { createEventDispatcher } from "svelte";
export let selected_color: string;
export let colors: string[];
export let user_colors: (string | null)[] | null = [];
export let show_empty = false;
export let current_mode: "hex" | "rgb" | "hsl" = "hex";
export let color_picker = false;
const dispatch = createEventDispatcher<{
select: { index: number | null; color: string | null };
edit: { index: number; color: string | null };
}>();
$: _colors = show_empty ? colors : colors.filter((c) => c);
function get_formatted_color(
color: string,
mode: "hex" | "rgb" | "hsl"
): string {
if (mode === "hex") {
return tinycolor(color).toHexString();
} else if (mode === "rgb") {
return tinycolor(color).toRgbString();
}
return tinycolor(color).toHslString();
}
let current_index = `select-${colors.findIndex(
(c) =>
get_formatted_color(c, current_mode) ===
get_formatted_color(selected_color, current_mode)
)}`;
function handle_select(
type: "edit" | "select",
detail: {
index: number;
color: string | null;
}
): void {
current_index = `${type}-${detail.index}`;
dispatch(type, detail);
}
function handle_picker_click(): void {
dispatch("select", { index: null, color: selected_color });
color_picker = !color_picker;
}
</script>
{#if user_colors}
<div class="swatch">
{#each user_colors as color, i}
<button
on:click={() => handle_select("edit", { index: i, color })}
class="color"
class:empty={color === null}
style="background-color: {color}"
class:selected={`edit-${i}` === current_index}
></button>
{/each}
<button
on:click={handle_picker_click}
class="color colorpicker"
class:hidden={!color_picker}
></button>
</div>
{/if}
<menu class="swatch">
{#each _colors as color, i}
<button
on:click={() => handle_select("select", { index: i, color })}
class="color"
class:empty={color === null}
style="background-color: {color}"
class:selected={`select-${i}` === current_index}
></button>
{/each}
</menu>
<style>
.swatch {
display: flex;
width: 100%;
gap: var(--size-2);
justify-content: center;
margin-bottom: var(--size-1);
}
.empty {
border: 1px solid var(--block-border-color);
font-weight: var(--weight-bold);
display: flex;
justify-content: center;
align-items: center;
padding-top: 1px;
text-align: center;
font-size: var(--scale-0);
cursor: pointer;
}
.empty::after {
content: "+";
margin-bottom: var(--size-1);
}
.color {
width: 30px;
height: 30px;
border-radius: 50%;
}
.empty.selected,
.color.selected {
border: 2px solid var(--color-accent);
}
.colorpicker {
border: 1px solid var(--block-border-color);
background: conic-gradient(
red,
#ff0 60deg,
lime 120deg,
cyan 180deg,
blue 240deg,
magenta 300deg,
red 360deg
);
overflow: hidden;
position: relative;
color: white;
cursor: pointer;
}
.colorpicker::before {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
opacity: 1;
transition: 0.1s;
top: 0;
left: 0;
}
.colorpicker::after {
display: flex;
justify-content: center;
align-content: center;
content: "⨯";
color: white;
font-size: var(--scale-5);
position: absolute;
width: 100%;
height: 100%;
transform: translateY(-17px);
opacity: 1;
transition: 0.1s;
top: 0;
}
.colorpicker.hidden::after,
.colorpicker.hidden::before {
opacity: 0;
}
</style>