generated from tpl/obsidian-sample-plugin
Move all book designs into book element and fix text sizing a bit
This commit is contained in:
parent
db732fd8a6
commit
63221fb946
|
@ -19,6 +19,7 @@
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
"@types/chroma-js": "^3.1.1",
|
"@types/chroma-js": "^3.1.1",
|
||||||
"@types/node": "^24.0.6",
|
"@types/node": "^24.0.6",
|
||||||
|
"@types/textfit": "^2.4.5",
|
||||||
"@typescript-eslint/eslint-plugin": "5.29.0",
|
"@typescript-eslint/eslint-plugin": "5.29.0",
|
||||||
"@typescript-eslint/parser": "5.29.0",
|
"@typescript-eslint/parser": "5.29.0",
|
||||||
"builtin-modules": "3.3.0",
|
"builtin-modules": "3.3.0",
|
||||||
|
@ -46,6 +47,7 @@
|
||||||
"chart.js": "^4.5.0",
|
"chart.js": "^4.5.0",
|
||||||
"chroma-js": "^3.1.2",
|
"chroma-js": "^3.1.2",
|
||||||
"esbuild-sass-plugin": "^3.3.1",
|
"esbuild-sass-plugin": "^3.3.1",
|
||||||
|
"textfit": "^2.4.0",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"yaml": "^2.8.0",
|
"yaml": "^2.8.0",
|
||||||
"zod": "^3.25.67"
|
"zod": "^3.25.67"
|
||||||
|
|
|
@ -17,6 +17,9 @@ importers:
|
||||||
esbuild-sass-plugin:
|
esbuild-sass-plugin:
|
||||||
specifier: ^3.3.1
|
specifier: ^3.3.1
|
||||||
version: 3.3.1(esbuild@0.17.3)(sass-embedded@1.89.2)
|
version: 3.3.1(esbuild@0.17.3)(sass-embedded@1.89.2)
|
||||||
|
textfit:
|
||||||
|
specifier: ^2.4.0
|
||||||
|
version: 2.4.0
|
||||||
uuid:
|
uuid:
|
||||||
specifier: ^11.1.0
|
specifier: ^11.1.0
|
||||||
version: 11.1.0
|
version: 11.1.0
|
||||||
|
@ -42,6 +45,9 @@ importers:
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^24.0.6
|
specifier: ^24.0.6
|
||||||
version: 24.0.6
|
version: 24.0.6
|
||||||
|
'@types/textfit':
|
||||||
|
specifier: ^2.4.5
|
||||||
|
version: 2.4.5
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: 5.29.0
|
specifier: 5.29.0
|
||||||
version: 5.29.0(@typescript-eslint/parser@5.29.0(eslint@9.30.0)(typescript@5.0.4))(eslint@9.30.0)(typescript@5.0.4)
|
version: 5.29.0(@typescript-eslint/parser@5.29.0(eslint@9.30.0)(typescript@5.0.4))(eslint@9.30.0)(typescript@5.0.4)
|
||||||
|
@ -453,15 +459,24 @@ packages:
|
||||||
'@types/estree@1.0.8':
|
'@types/estree@1.0.8':
|
||||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||||
|
|
||||||
|
'@types/jquery@3.5.32':
|
||||||
|
resolution: {integrity: sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==}
|
||||||
|
|
||||||
'@types/json-schema@7.0.15':
|
'@types/json-schema@7.0.15':
|
||||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||||
|
|
||||||
'@types/node@24.0.6':
|
'@types/node@24.0.6':
|
||||||
resolution: {integrity: sha512-ZOyn+gOs749xU7ovp+Ibj0g1o3dFRqsfPnT22C2t5JzcRvgsEDpGawPbCISGKLudJk9Y0wiu9sYd6kUh0pc9TA==}
|
resolution: {integrity: sha512-ZOyn+gOs749xU7ovp+Ibj0g1o3dFRqsfPnT22C2t5JzcRvgsEDpGawPbCISGKLudJk9Y0wiu9sYd6kUh0pc9TA==}
|
||||||
|
|
||||||
|
'@types/sizzle@2.3.9':
|
||||||
|
resolution: {integrity: sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==}
|
||||||
|
|
||||||
'@types/tern@0.23.9':
|
'@types/tern@0.23.9':
|
||||||
resolution: {integrity: sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==}
|
resolution: {integrity: sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==}
|
||||||
|
|
||||||
|
'@types/textfit@2.4.5':
|
||||||
|
resolution: {integrity: sha512-C/1i+vGFD7xi1UZPePa6pNdoR0eGFCOe7QrZlTuPGPF+Y4JnFcp9cSJGZko+6tW8GmdDdKt7S9W6sCf3ncvk5g==}
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@5.29.0':
|
'@typescript-eslint/eslint-plugin@5.29.0':
|
||||||
resolution: {integrity: sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==}
|
resolution: {integrity: sha512-kgTsISt9pM53yRFQmLZ4npj99yGl3x3Pl7z4eA66OuTzAGC4bQB5H5fuLwPnqTKU3yyrrg4MIhjF17UYnL4c0w==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
|
@ -1676,6 +1691,9 @@ packages:
|
||||||
resolution: {integrity: sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==}
|
resolution: {integrity: sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==}
|
||||||
engines: {node: '>=16.0.0'}
|
engines: {node: '>=16.0.0'}
|
||||||
|
|
||||||
|
textfit@2.4.0:
|
||||||
|
resolution: {integrity: sha512-/x4aoY5+/tJmu+iwpBH1yw75TFp86M6X15SvaaY/Eep7YySQYtqdOifEtfvVyMwzl7SZ+G4RQw00FD9g5R6i1Q==}
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||||
engines: {node: '>=8.0'}
|
engines: {node: '>=8.0'}
|
||||||
|
@ -2047,16 +2065,26 @@ snapshots:
|
||||||
|
|
||||||
'@types/estree@1.0.8': {}
|
'@types/estree@1.0.8': {}
|
||||||
|
|
||||||
|
'@types/jquery@3.5.32':
|
||||||
|
dependencies:
|
||||||
|
'@types/sizzle': 2.3.9
|
||||||
|
|
||||||
'@types/json-schema@7.0.15': {}
|
'@types/json-schema@7.0.15': {}
|
||||||
|
|
||||||
'@types/node@24.0.6':
|
'@types/node@24.0.6':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 7.8.0
|
undici-types: 7.8.0
|
||||||
|
|
||||||
|
'@types/sizzle@2.3.9': {}
|
||||||
|
|
||||||
'@types/tern@0.23.9':
|
'@types/tern@0.23.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': 1.0.8
|
'@types/estree': 1.0.8
|
||||||
|
|
||||||
|
'@types/textfit@2.4.5':
|
||||||
|
dependencies:
|
||||||
|
'@types/jquery': 3.5.32
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@5.29.0(@typescript-eslint/parser@5.29.0(eslint@9.30.0)(typescript@5.0.4))(eslint@9.30.0)(typescript@5.0.4)':
|
'@typescript-eslint/eslint-plugin@5.29.0(@typescript-eslint/parser@5.29.0(eslint@9.30.0)(typescript@5.0.4))(eslint@9.30.0)(typescript@5.0.4)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/parser': 5.29.0(eslint@9.30.0)(typescript@5.0.4)
|
'@typescript-eslint/parser': 5.29.0(eslint@9.30.0)(typescript@5.0.4)
|
||||||
|
@ -3374,6 +3402,8 @@ snapshots:
|
||||||
|
|
||||||
sync-message-port@1.1.3: {}
|
sync-message-port@1.1.3: {}
|
||||||
|
|
||||||
|
textfit@2.4.0: {}
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-number: 7.0.0
|
is-number: 7.0.0
|
||||||
|
|
|
@ -1,19 +1,9 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Self from "./Book.svelte";
|
import Self from "./Book.svelte";
|
||||||
import {
|
import { Color, isColorName, type ColorName } from "@utils/color";
|
||||||
Color,
|
import BookTilted from "./BookTilted.svelte";
|
||||||
COLOR_NAMES,
|
import BookOnDisplay from "./BookOnDisplay.svelte";
|
||||||
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 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_DEFAULT: number = 40;
|
||||||
const BOOK_SIZE_MIN: number = 15;
|
const BOOK_SIZE_MIN: number = 15;
|
||||||
|
|
||||||
|
@ -57,12 +47,22 @@
|
||||||
: Color.fromCSSColor(colorRaw),
|
: Color.fromCSSColor(colorRaw),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const backgroundColor = $derived(
|
||||||
|
design === "colored-spine"
|
||||||
|
? color.chroma.mix("black", 0.14)
|
||||||
|
: color.chroma,
|
||||||
|
);
|
||||||
|
const borderLeftColor = $derived(color.chroma.mix("white", 0.04));
|
||||||
|
const borderRightColor = $derived(color.chroma.mix("black", 0.04));
|
||||||
|
const bandColor = $derived(color.chroma.mix("black", 0.14));
|
||||||
|
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
|
||||||
|
|
||||||
const verifiedWidth = $derived(normalizeWidth(width));
|
const verifiedWidth = $derived(normalizeWidth(width));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if orientation}
|
{#if orientation}
|
||||||
{#if orientation === "tilted"}
|
{#if orientation === "tilted"}
|
||||||
<BookTiltedDefault {design} width={verifiedWidth}>
|
<BookTilted {design} width={verifiedWidth}>
|
||||||
<Self
|
<Self
|
||||||
{title}
|
{title}
|
||||||
{subtitle}
|
{subtitle}
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
{width}
|
{width}
|
||||||
{onClick}
|
{onClick}
|
||||||
/>
|
/>
|
||||||
</BookTiltedDefault>
|
</BookTilted>
|
||||||
{:else if orientation === "on-display"}
|
{:else if orientation === "on-display"}
|
||||||
<BookOnDisplay color={color.hex} {onClick}>
|
<BookOnDisplay color={color.hex} {onClick}>
|
||||||
<div
|
<div
|
||||||
|
@ -86,25 +86,30 @@
|
||||||
{/if}
|
{/if}
|
||||||
</BookOnDisplay>
|
</BookOnDisplay>
|
||||||
{/if}
|
{/if}
|
||||||
{:else if design === "split-bands"}
|
|
||||||
<BookSplitBands color={color.hex} width={verifiedWidth} {onClick}>
|
|
||||||
<BookText {title} {subtitle} />
|
|
||||||
</BookSplitBands>
|
|
||||||
{:else if design === "dual-top-bands"}
|
|
||||||
<BookDualTopBands color={color.hex} width={verifiedWidth} {onClick}>
|
|
||||||
<BookText {title} {subtitle} />
|
|
||||||
</BookDualTopBands>
|
|
||||||
{:else if design === "colored-spine"}
|
|
||||||
<BookColoredSpine color={color.hex} width={verifiedWidth} {onClick}>
|
|
||||||
<BookText {title} {subtitle} />
|
|
||||||
</BookColoredSpine>
|
|
||||||
{:else}
|
{:else}
|
||||||
<BookDefault color={color.hex} width={verifiedWidth} {onClick}>
|
<div
|
||||||
|
class="bookshelf__book-wrapper"
|
||||||
|
class:default={design === "default"}
|
||||||
|
class:colored-spine={design === "colored-spine"}
|
||||||
|
class:dual-top-bands={design === "dual-top-bands"}
|
||||||
|
class:split-bands={design === "split-bands"}
|
||||||
|
style:--book-color={backgroundColor.css()}
|
||||||
|
style:--book-border-left-color={borderLeftColor.css()}
|
||||||
|
style:--book-border-right-color={borderRightColor.css()}
|
||||||
|
style:--book-band-color={bandColor.css()}
|
||||||
|
style:--book-width={verifiedWidth + "px"}
|
||||||
|
style:width={verifiedWidth + "px"}
|
||||||
|
style:color={textColor}
|
||||||
|
onclick={onClick}
|
||||||
|
onkeydown={(ev) => ev.key === "Enter" && onClick?.()}
|
||||||
|
role="link"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
<BookText {title} {subtitle} />
|
<BookText {title} {subtitle} />
|
||||||
</BookDefault>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style lang="scss">
|
||||||
.book-display-crease {
|
.book-display-crease {
|
||||||
background-color: color-mix(in srgb, var(--book-color), black 14%);
|
background-color: color-mix(in srgb, var(--book-color), black 14%);
|
||||||
width: 5px;
|
width: 5px;
|
||||||
|
@ -113,4 +118,107 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 8px;
|
left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.bookshelf__book-wrapper {
|
||||||
|
background: var(--book-color);
|
||||||
|
border-left: 2px solid var(--book-border-left-color);
|
||||||
|
border-right: 2px solid var(--book-border-right-color);
|
||||||
|
|
||||||
|
&.default,
|
||||||
|
&.colored-spine {
|
||||||
|
:global(.bookshelf__book-content) {
|
||||||
|
height: calc(var(--book-width));
|
||||||
|
margin: 0 var(--book-width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.colored-spine {
|
||||||
|
&:before {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
background: var(--book-background-color);
|
||||||
|
height: 100%;
|
||||||
|
width: calc(var(--book-width));
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: -2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.dual-top-bands {
|
||||||
|
&:after,
|
||||||
|
&:before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background: var(--book-band-color);
|
||||||
|
width: calc(100% + 4px);
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
height: 10px;
|
||||||
|
top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
height: 15px;
|
||||||
|
top: 26px;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.bookshelf__book-content) {
|
||||||
|
height: calc(var(--book-width));
|
||||||
|
width: calc(200px - 41px) !important;
|
||||||
|
margin: 41px var(--book-width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.split-bands {
|
||||||
|
&:after,
|
||||||
|
&:before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background: var(--book-band-color);
|
||||||
|
height: 20px;
|
||||||
|
width: calc(100% + 4px);
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background: var(--book-band-color);
|
||||||
|
height: 20px;
|
||||||
|
width: calc(100% + 4px);
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background: var(--book-band-color);
|
||||||
|
height: 20px;
|
||||||
|
width: calc(100% + 4px);
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.bookshelf__book-content) {
|
||||||
|
height: calc(var(--book-width));
|
||||||
|
width: calc(200px - 60px) !important;
|
||||||
|
margin: 30px var(--book-width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { fitText } from "@ui/directives";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title?: string;
|
title?: string;
|
||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
|
@ -12,9 +14,40 @@
|
||||||
class:center-content={subtitle === undefined}
|
class:center-content={subtitle === undefined}
|
||||||
>
|
>
|
||||||
{#if title}
|
{#if title}
|
||||||
<h2 class="bookshelf__book-title">{title}</h2>
|
<h2
|
||||||
|
class="bookshelf__book-title"
|
||||||
|
style:width="100%"
|
||||||
|
use:fitText={{ minFontSize: 12, maxFontSize: 16 }}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
{/if}
|
{/if}
|
||||||
{#if subtitle}
|
{#if subtitle}
|
||||||
<h4 class="bookshelf__book-subtitle">{subtitle}</h4>
|
<h4
|
||||||
|
class="bookshelf__book-subtitle"
|
||||||
|
style:width="100%"
|
||||||
|
use:fitText={{ minFontSize: 12, maxFontSize: 16 }}
|
||||||
|
>
|
||||||
|
{subtitle}
|
||||||
|
</h4>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.bookshelf__book-title,
|
||||||
|
.bookshelf__book-subtitle {
|
||||||
|
:global(.textFitted) {
|
||||||
|
width: 100%;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bookshelf__book-subtitle {
|
||||||
|
:global(.textFitted) {
|
||||||
|
width: 100%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -35,7 +35,6 @@ $bookEdge: 2px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 1.2;
|
|
||||||
letter-spacing: 1.25px;
|
letter-spacing: 1.25px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
@ -205,11 +204,18 @@ $bookEdge: 2px;
|
||||||
|
|
||||||
.bookshelf__book-title,
|
.bookshelf__book-title,
|
||||||
.bookshelf__book-subtitle {
|
.bookshelf__book-subtitle {
|
||||||
line-height: 2;
|
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bookshelf__book-title {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bookshelf__book-subtitle {
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bookshelf__book-author {
|
.bookshelf__book-author {
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import type { Snippet } from "svelte";
|
|
||||||
import chroma from "chroma-js";
|
|
||||||
import { Color } from "@utils/color";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children?: Snippet;
|
|
||||||
color?: string;
|
|
||||||
width?: number;
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { children, color = "green", width = 40, onClick }: Props = $props();
|
|
||||||
|
|
||||||
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
|
|
||||||
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
|
|
||||||
const backgroundColor = $derived(chroma(color).mix("black", 0.14));
|
|
||||||
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="bookshelf__book-wrapper"
|
|
||||||
style:--book-color={color}
|
|
||||||
style:--book-border-left-color={borderLeftColor.css()}
|
|
||||||
style:--book-border-right-color={borderRightColor.css()}
|
|
||||||
style:--book-background-color={backgroundColor.css()}
|
|
||||||
style:--book-width={width + "px"}
|
|
||||||
style:width={width + "px"}
|
|
||||||
style:color={textColor}
|
|
||||||
onclick={onClick}
|
|
||||||
onkeydown={(ev) => ev.key === "Enter" && onClick?.()}
|
|
||||||
role="link"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
div {
|
|
||||||
background: var(--book-color);
|
|
||||||
border-left: 2px solid var(--book-border-left-color);
|
|
||||||
border-right: 2px solid var(--book-border-right-color);
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: " ";
|
|
||||||
display: block;
|
|
||||||
background: var(--book-background-color);
|
|
||||||
height: 100%;
|
|
||||||
width: calc(var(--book-width));
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
left: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.bookshelf__book-content) {
|
|
||||||
height: calc(var(--book-width));
|
|
||||||
width: calc(200px - 60px);
|
|
||||||
margin: 0 var(--book-width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,49 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import type { Snippet } from "svelte";
|
|
||||||
import chroma from "chroma-js";
|
|
||||||
import { Color } from "@utils/color";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children?: Snippet;
|
|
||||||
color?: string;
|
|
||||||
width?: number;
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { children, color = "green", width = 40, onClick }: Props = $props();
|
|
||||||
|
|
||||||
const backgroundColor = $derived(chroma(color));
|
|
||||||
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
|
|
||||||
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
|
|
||||||
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="bookshelf__book-wrapper"
|
|
||||||
style:--book-color={backgroundColor.css()}
|
|
||||||
style:--book-border-left-color={borderLeftColor.css()}
|
|
||||||
style:--book-border-right-color={borderRightColor.css()}
|
|
||||||
style:--book-width={width + "px"}
|
|
||||||
style:width={width + "px"}
|
|
||||||
style:color={textColor}
|
|
||||||
onclick={onClick}
|
|
||||||
onkeydown={(ev) => ev.key === "Enter" && onClick?.()}
|
|
||||||
role="link"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
div {
|
|
||||||
background: var(--book-color);
|
|
||||||
border-left: 2px solid var(--book-border-left-color);
|
|
||||||
border-right: 2px solid var(--book-border-right-color);
|
|
||||||
|
|
||||||
:global(.bookshelf__book-content) {
|
|
||||||
height: calc(var(--book-width));
|
|
||||||
width: calc(200px - 60px);
|
|
||||||
margin: 0 var(--book-width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,76 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import type { Snippet } from "svelte";
|
|
||||||
import chroma from "chroma-js";
|
|
||||||
import { Color } from "@utils/color";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children?: Snippet;
|
|
||||||
color?: string;
|
|
||||||
width?: number;
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { children, color = "green", width = 40, onClick }: Props = $props();
|
|
||||||
|
|
||||||
const backgroundColor = $derived(chroma(color));
|
|
||||||
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
|
|
||||||
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
|
|
||||||
const bandColor = $derived(chroma(color).mix("black", 0.14));
|
|
||||||
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="bookshelf__book-wrapper"
|
|
||||||
style:--book-color={backgroundColor.css()}
|
|
||||||
style:--book-border-left-color={borderLeftColor.css()}
|
|
||||||
style:--book-border-right-color={borderRightColor.css()}
|
|
||||||
style:--book-band-color={bandColor.css()}
|
|
||||||
style:--book-width={width + "px"}
|
|
||||||
style:width={width + "px"}
|
|
||||||
style:color={textColor}
|
|
||||||
onclick={onClick}
|
|
||||||
onkeydown={(ev) => ev.key === "Enter" && onClick?.()}
|
|
||||||
role="link"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
div {
|
|
||||||
background: var(--book-color);
|
|
||||||
border-left: 2px solid var(--book-border-left-color);
|
|
||||||
border-right: 2px solid var(--book-border-right-color);
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
background: var(--book-band-color);
|
|
||||||
height: 20px;
|
|
||||||
width: calc(100% + 4px);
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
left: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
background: var(--book-band-color);
|
|
||||||
height: 20px;
|
|
||||||
width: calc(100% + 4px);
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
left: -2px;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.bookshelf__book-content) {
|
|
||||||
height: calc(var(--book-width));
|
|
||||||
width: calc(200px - 60px) !important;
|
|
||||||
margin: 30px var(--book-width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,76 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import type { Snippet } from "svelte";
|
|
||||||
import chroma from "chroma-js";
|
|
||||||
import { Color } from "@utils/color";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
children?: Snippet;
|
|
||||||
color?: string;
|
|
||||||
width?: number;
|
|
||||||
onClick?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { children, color = "green", width = 40, onClick }: Props = $props();
|
|
||||||
|
|
||||||
const backgroundColor = $derived(chroma(color));
|
|
||||||
const borderLeftColor = $derived(chroma(color).mix("white", 0.04));
|
|
||||||
const borderRightColor = $derived(chroma(color).mix("black", 0.04));
|
|
||||||
const bandColor = $derived(chroma(color).mix("black", 0.14));
|
|
||||||
const textColor = $derived(new Color(backgroundColor).contrastColor.hex);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="bookshelf__book-wrapper"
|
|
||||||
style:--book-color={backgroundColor.css()}
|
|
||||||
style:--book-border-left-color={borderLeftColor.css()}
|
|
||||||
style:--book-border-right-color={borderRightColor.css()}
|
|
||||||
style:--book-band-color={bandColor.css()}
|
|
||||||
style:--book-width={width + "px"}
|
|
||||||
style:width={width + "px"}
|
|
||||||
style:color={textColor}
|
|
||||||
onclick={onClick}
|
|
||||||
onkeydown={(ev) => ev.key === "Enter" && onClick?.()}
|
|
||||||
role="link"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
{@render children?.()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
div {
|
|
||||||
background: var(--book-color);
|
|
||||||
border-left: 2px solid var(--book-border-left-color);
|
|
||||||
border-right: 2px solid var(--book-border-right-color);
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
background: var(--book-band-color);
|
|
||||||
height: 20px;
|
|
||||||
width: calc(100% + 4px);
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
left: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
content: "";
|
|
||||||
display: block;
|
|
||||||
background: var(--book-band-color);
|
|
||||||
height: 20px;
|
|
||||||
width: calc(100% + 4px);
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
left: -2px;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(.bookshelf__book-content) {
|
|
||||||
height: calc(var(--book-width));
|
|
||||||
width: calc(200px - 60px) !important;
|
|
||||||
margin: 30px var(--book-width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import type { ActionReturn } from "svelte/action";
|
||||||
|
import { default as doTextFit, type TextFitOption } from "textfit";
|
||||||
|
|
||||||
|
export function fitText(
|
||||||
|
el: HTMLElement,
|
||||||
|
opts: TextFitOption = {}
|
||||||
|
): ActionReturn<TextFitOption> {
|
||||||
|
doTextFit(el, opts);
|
||||||
|
|
||||||
|
return {
|
||||||
|
update(opts) {
|
||||||
|
doTextFit(el, opts);
|
||||||
|
},
|
||||||
|
destroy() {},
|
||||||
|
};
|
||||||
|
}
|
|
@ -1 +1,3 @@
|
||||||
|
export { chart } from "./chart";
|
||||||
export { clickOutside } from "./clickOutside";
|
export { clickOutside } from "./clickOutside";
|
||||||
|
export { fitText } from "./fitText";
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"verbatimModuleSyntax": true,
|
"verbatimModuleSyntax": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
"lib": [
|
"lib": [
|
||||||
"DOM",
|
"DOM",
|
||||||
"ES5",
|
"ES5",
|
||||||
|
|
Loading…
Reference in New Issue