obsidian-book-tracker/src/ui/components/bookshelf/Book.svelte

115 lines
2.8 KiB
Svelte

<script lang="ts">
import Self from "./Book.svelte";
import {
Color,
COLOR_NAMES,
isColorName,
type ColorName,
} from "@utils/color";
import BookTiltedDefault from "./designs/tilted/BookTiltedDefault.svelte";
import BookOnDisplay from "./designs/book/BookOnDisplay.svelte";
import BookText from "./BookText.svelte";
import BookSplitBands from "./designs/book/BookSplitBands.svelte";
import BookDualTopBands from "./designs/book/BookDualTopBands.svelte";
import BookColoredSpine from "./designs/book/BookColoredSpine.svelte";
import BookDefault from "./designs/book/BookDefault.svelte";
const BOOK_SIZE_DEFAULT: number = 40;
const BOOK_SIZE_MIN: number = 15;
interface BookProps {
title?: string;
subtitle?: string;
author?: string;
color?: ColorName | string;
design?: "default" | "colored-spine" | "dual-top-bands" | "split-bands";
orientation?: "tilted" | "on-display";
height?: number;
width?: number;
}
let {
title,
subtitle,
author,
color: colorRaw = "green",
design = "default",
orientation,
height,
width,
}: BookProps = $props();
function widthCheck(input: number | undefined) {
if (input) {
if (input <= 150) {
return BOOK_SIZE_MIN;
}
return input / 10;
}
return BOOK_SIZE_DEFAULT;
}
const color = $derived(
isColorName(colorRaw)
? Color.fromName(colorRaw).darken()
: Color.fromCSSColor(colorRaw),
);
const verifiedWidth = $derived(widthCheck(width));
const textColor = $derived(color.contrastColor.hex);
</script>
{#if orientation}
{#if orientation === "tilted"}
<BookTiltedDefault {design} width={verifiedWidth}>
<Self
{title}
{subtitle}
{author}
color={color.hex}
{design}
{height}
{width}
/>
</BookTiltedDefault>
{:else if orientation === "on-display"}
<BookOnDisplay color={color.hex}>
<div
class="book-display-crease"
style:--book-color={color.hex}
></div>
{#if title}
<BookText {title} {subtitle} />
<p class="bookshelf__book-author">By: {author}</p>
{/if}
</BookOnDisplay>
{/if}
{:else if design === "split-bands"}
<BookSplitBands color={color.hex} width={verifiedWidth} {textColor}>
<BookText {title} {subtitle} />
</BookSplitBands>
{:else if design === "dual-top-bands"}
<BookDualTopBands color={color.hex} width={verifiedWidth} {textColor}>
<BookText {title} {subtitle} />
</BookDualTopBands>
{:else if design === "colored-spine"}
<BookColoredSpine color={color.hex} width={verifiedWidth} {textColor}>
<BookText {title} {subtitle} />
</BookColoredSpine>
{:else}
<BookDefault color={color.hex} width={verifiedWidth} {textColor}>
<BookText {title} {subtitle} />
</BookDefault>
{/if}
<style>
.book-display-crease {
background-color: color-mix(in srgb, var(--book-color), black 14%);
width: 5px;
height: 100%;
position: absolute;
top: 0;
left: 8px;
}
</style>