self-resizing text
This commit is contained in:
parent
bc29510bb5
commit
9649d407fd
4 changed files with 63 additions and 10 deletions
|
@ -12,14 +12,14 @@
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"solid-js": "^1.9.3",
|
|
||||||
"@tauri-apps/api": "^2",
|
"@tauri-apps/api": "^2",
|
||||||
"@tauri-apps/plugin-opener": "^2"
|
"@tauri-apps/plugin-opener": "^2",
|
||||||
|
"solid-js": "^1.9.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@tauri-apps/cli": "^2",
|
||||||
"typescript": "~5.6.2",
|
"typescript": "~5.6.2",
|
||||||
"vite": "^6.0.3",
|
"vite": "^6.0.3",
|
||||||
"vite-plugin-solid": "^2.11.0",
|
"vite-plugin-solid": "^2.11.0"
|
||||||
"@tauri-apps/cli": "^2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/App.css
10
src/App.css
|
@ -76,13 +76,13 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: calc(1 * var(--unit));
|
gap: calc(1 * var(--unit));
|
||||||
font-size: calc(3 * var(--unit));
|
font-size: calc(3 * var(--unit));
|
||||||
font-weight: 700;
|
|
||||||
width: calc((20 * 4 + 3) * var(--unit));
|
width: calc((20 * 4 + 3) * var(--unit));
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.puzzle-header {
|
.puzzle-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
> h1 {
|
> h1 {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
@ -112,10 +112,11 @@
|
||||||
user-select: none;
|
user-select: none;
|
||||||
flex-basis: 0;
|
flex-basis: 0;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
padding: 0;
|
padding: calc(1 * var(--unit));
|
||||||
border-radius: calc(1 * var(--unit));
|
border-radius: calc(1 * var(--unit));
|
||||||
background-color: var(--color-foreground-trace);
|
background-color: var(--color-foreground-trace);
|
||||||
font-weight: 500;
|
font-size: calc(5 * var(--unit));
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.badge {
|
.badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -194,6 +195,7 @@ h1 {
|
||||||
button {
|
button {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
min-width: 2em;
|
||||||
background: var(--color-foreground-faint);
|
background: var(--color-foreground-faint);
|
||||||
color: var(--color-foreground);
|
color: var(--color-foreground);
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
|
@ -202,7 +204,7 @@ button {
|
||||||
border-radius: calc(1 * var(--unit, 0.5em));
|
border-radius: calc(1 * var(--unit, 0.5em));
|
||||||
}
|
}
|
||||||
button:disabled {
|
button:disabled {
|
||||||
opacity: 0.5;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
button:focus-visible, button:hover {
|
button:focus-visible, button:hover {
|
||||||
box-shadow: 0 0 3em -1.5em inset var(--color-foreground)
|
box-shadow: 0 0 3em -1.5em inset var(--color-foreground)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { For } from "solid-js";
|
import { For } from "solid-js";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
import useAppModel from "./useAppModel";
|
import useAppModel from "./useAppModel";
|
||||||
|
import FitText from "./FitText";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const {
|
const {
|
||||||
|
@ -35,6 +36,7 @@ function App() {
|
||||||
on:input={({ target: { value } }) =>
|
on:input={({ target: { value } }) =>
|
||||||
handleSelectGame(parseInt(value, 10))
|
handleSelectGame(parseInt(value, 10))
|
||||||
}
|
}
|
||||||
|
value={store.puzzleId}
|
||||||
>
|
>
|
||||||
<For each={connections}>
|
<For each={connections}>
|
||||||
{({ id }) => <option value={id}>{id}</option>}
|
{({ id }) => <option value={id}>{id}</option>}
|
||||||
|
@ -53,6 +55,7 @@ function App() {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
<div>Create four groups of four words!</div>
|
||||||
<For each={store.solvedGroups}>
|
<For each={store.solvedGroups}>
|
||||||
{({ group, level, members }) => (
|
{({ group, level, members }) => (
|
||||||
<div class="puzzle-row">
|
<div class="puzzle-row">
|
||||||
|
@ -68,7 +71,7 @@ function App() {
|
||||||
<div class="puzzle-row">
|
<div class="puzzle-row">
|
||||||
{[0, 1, 2, 3].map((col) => {
|
{[0, 1, 2, 3].map((col) => {
|
||||||
const index = 4 * row + col;
|
const index = 4 * row + col;
|
||||||
const answer = getFromPuzzle(index).answer;
|
const answer = () => getFromPuzzle(index).answer;
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
classList={{
|
classList={{
|
||||||
|
@ -85,7 +88,7 @@ function App() {
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{answer}
|
<FitText body={answer} />
|
||||||
{store.pinnedCount > index && <div class="badge">🔒</div>}
|
{store.pinnedCount > index && <div class="badge">🔒</div>}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
48
src/FitText.tsx
Normal file
48
src/FitText.tsx
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import { createEffect, createSignal, on, type Accessor } from "solid-js";
|
||||||
|
|
||||||
|
export default function FitText(props: { body: Accessor<string> }) {
|
||||||
|
let textRef: SVGTextElement | undefined;
|
||||||
|
const [width, setWidth] = createSignal(100);
|
||||||
|
const [height, setHeight] = createSignal(100);
|
||||||
|
|
||||||
|
createEffect(
|
||||||
|
on(
|
||||||
|
props.body,
|
||||||
|
async () => {
|
||||||
|
setWidth(100)
|
||||||
|
setHeight(100)
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1))
|
||||||
|
const bounds = textRef?.getBBox();
|
||||||
|
if (bounds === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setWidth(bounds.width);
|
||||||
|
setHeight(bounds.height);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
"max-height": "50%",
|
||||||
|
}}
|
||||||
|
viewBox={`0 0 ${width()} ${height()}`}
|
||||||
|
overflow="visible"
|
||||||
|
fill="currentcolor"
|
||||||
|
>
|
||||||
|
<text
|
||||||
|
ref={textRef}
|
||||||
|
x="50%"
|
||||||
|
y="50%"
|
||||||
|
dominant-baseline="central"
|
||||||
|
text-anchor="middle"
|
||||||
|
font-size="1rem"
|
||||||
|
font-family="inherit"
|
||||||
|
>
|
||||||
|
{props.body()}
|
||||||
|
</text>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue