Move all book designs into book element and fix text sizing a bit

This commit is contained in:
Evan Fiordeliso 2025-07-05 16:15:50 -04:00
parent db732fd8a6
commit 63221fb946
14 changed files with 232 additions and 298 deletions

View File

@ -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"

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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 {

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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() {},
};
}

View File

@ -1 +1,3 @@
export { chart } from "./chart";
export { clickOutside } from "./clickOutside"; export { clickOutside } from "./clickOutside";
export { fitText } from "./fitText";

View File

@ -13,6 +13,7 @@
"strictNullChecks": true, "strictNullChecks": true,
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true,
"skipLibCheck": true, "skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"lib": [ "lib": [
"DOM", "DOM",
"ES5", "ES5",