Graph calculator improvmentes
All checks were successful
Build and Deploy Nuxt / build (push) Successful in 24s

This commit is contained in:
2026-10-02 14:53:00 +02:00
parent e36fef7290
commit 68b74eb60b
21 changed files with 1092 additions and 392 deletions

View File

@@ -0,0 +1,85 @@
<script setup lang="ts">
/* One page of the open book that holds one of the wiki's own surfaces — the
link map, the graphing calculator — instead of an article. The paper is the
same as an article's page: a spine with the title standing on end and the ×
that closes the page, click anywhere to turn back to it. What fills the
page is not scrolling prose but the live surface, edge to edge — its own
instance, kept warm beside the articles you are reading.
Everything but the spine of a page that isn't in view is `inert`: the map
won't take drags and the calculator won't take typing until you turn to it. */
import type { ToolPage } from '~/utils/routes'
const props = defineProps<{
/** which of the wiki's own pages this page holds */
tool: ToolPage
index: number
active: boolean
}>()
const emit = defineEmits<{
activate: []
close: []
}>()
const { t } = useI18n()
const title = computed(() => t(TOOL_LABEL_KEYS[props.tool]))
function turnToThisPage() {
if (!props.active) emit('activate')
}
</script>
<template>
<section
class="book-pane pane-tools"
:class="{ active }"
:data-tab="toolPageIdentity(tool)"
:data-index="index"
:style="{ '--i': index }"
:aria-label="t('pane.aria', { title })"
@click="turnToThisPage"
>
<div
class="pane-spine"
role="button"
tabindex="0"
:aria-current="active ? 'page' : undefined"
:aria-disabled="active"
:title="t('pane.spineHint', { title })"
@click.stop="turnToThisPage"
@keydown.enter.prevent="turnToThisPage"
>
<button
type="button"
class="spine-close"
:aria-label="t('common.closeTab')"
@click.stop="emit('close')"
>
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" aria-hidden="true">
<path d="M6 6l12 12M18 6L6 18" />
</svg>
</button>
<!-- the surface's own mark, under the ×, so the spine reads as the
page it holds even fanned out among articles -->
<svg v-if="tool === 'graph'" class="spine-glyph" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="18" cy="5" r="3" />
<circle cx="6" cy="12" r="3" />
<circle cx="18" cy="19" r="3" />
<path d="m8.6 10.5 6.8-4M8.6 13.5l6.8 4" />
</svg>
<svg v-else class="spine-glyph" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M4 3v17a1 1 0 0 0 1 1h17" />
<path d="M4.5 16.5c2.6 0 3.4-10.5 6.8-10.5s3.9 7 8.2 7" />
</svg>
<span class="spine-title">{{ title }}</span>
</div>
<div class="pane-body" :inert="active ? null : ''">
<div class="pane-stage">
<GraphStage v-if="tool === 'graph'" />
<CalculatorStage v-else />
</div>
</div>
</section>
</template>