Add conversion-rate tooltips to category calculator cards
This commit is contained in:
@@ -674,6 +674,7 @@ a:focus-visible {
|
|||||||
}
|
}
|
||||||
.calc-list-item {
|
.calc-list-item {
|
||||||
display: block;
|
display: block;
|
||||||
|
position: relative;
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
background: var(--card-bg);
|
background: var(--card-bg);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
@@ -695,6 +696,32 @@ a:focus-visible {
|
|||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
box-shadow: 0 0 0 3px var(--accent-glow);
|
box-shadow: 0 0 0 3px var(--accent-glow);
|
||||||
}
|
}
|
||||||
|
.calc-list-tooltip {
|
||||||
|
position: absolute;
|
||||||
|
bottom: calc(100% + 0.4rem);
|
||||||
|
left: 50%;
|
||||||
|
background: var(--section-bg);
|
||||||
|
color: var(--text);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 0.35rem 0.55rem;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transform: translate(-50%, 0.2rem);
|
||||||
|
transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.calc-list-item:hover .calc-list-tooltip,
|
||||||
|
.calc-list-item:focus-visible .calc-list-tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* ─── Related Converters ─────────────────────────────────── */
|
/* ─── Related Converters ─────────────────────────────────── */
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { onDestroy, onMount } from 'svelte';
|
import { onDestroy, onMount } from 'svelte';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
|
import { getConversionRateText } from '$lib/utils/conversionRate';
|
||||||
import QuickDefinitionCard from '$lib/components/QuickDefinitionCard.svelte';
|
import QuickDefinitionCard from '$lib/components/QuickDefinitionCard.svelte';
|
||||||
import QuickConversionExample from '$lib/components/QuickConversionExample.svelte';
|
import QuickConversionExample from '$lib/components/QuickConversionExample.svelte';
|
||||||
import QuickConversionTable from '$lib/components/QuickConversionTable.svelte';
|
import QuickConversionTable from '$lib/components/QuickConversionTable.svelte';
|
||||||
@@ -27,9 +28,11 @@
|
|||||||
let tooltipX = 20;
|
let tooltipX = 20;
|
||||||
let copyStatusMessage = '';
|
let copyStatusMessage = '';
|
||||||
let initializedSlug: string | null = null;
|
let initializedSlug: string | null = null;
|
||||||
|
let conversionRateText: string | null = null;
|
||||||
|
|
||||||
$: has3 = ['3col', '3col-mul'].includes(config.type) || !!config.labels.in3;
|
$: has3 = ['3col', '3col-mul'].includes(config.type) || !!config.labels.in3;
|
||||||
$: isTextInput = ['base', 'text-bin', 'bin-text', 'dec-frac', 'dms-dd', 'dd-dms'].includes(config.type);
|
$: isTextInput = ['base', 'text-bin', 'bin-text', 'dec-frac', 'dms-dd', 'dd-dms'].includes(config.type);
|
||||||
|
$: conversionRateText = getConversionRateText(config);
|
||||||
|
|
||||||
// Clear inputs only when navigating to a different calculator slug.
|
// Clear inputs only when navigating to a different calculator slug.
|
||||||
$: if (config?.slug) {
|
$: if (config?.slug) {
|
||||||
@@ -337,9 +340,9 @@
|
|||||||
{copyStatusMessage}
|
{copyStatusMessage}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{#if config.factor && config.type === 'standard'}
|
{#if conversionRateText}
|
||||||
<span class="formula-hint">
|
<span class="formula-hint">
|
||||||
1 {config.labels.in1} = {config.factor}{config.offset ? ` + ${config.offset}` : ''} {config.labels.in2}
|
{conversionRateText}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
16
hdyc-svelte/src/lib/utils/conversionRate.ts
Normal file
16
hdyc-svelte/src/lib/utils/conversionRate.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { CalculatorDef } from '$lib/data/calculators';
|
||||||
|
|
||||||
|
type RateConfig = Pick<CalculatorDef, 'type' | 'factor' | 'offset' | 'labels'>;
|
||||||
|
|
||||||
|
export const getConversionRateText = (config: RateConfig): string | null => {
|
||||||
|
if (config.type !== 'standard' || !config.factor) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { in1, in2 } = config.labels;
|
||||||
|
if (!in1 || !in2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `1 ${in1} = ${config.factor}${config.offset ? ` + ${config.offset}` : ''} ${in2}`;
|
||||||
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
import { buildSeoMeta, canonicalUrl, SITE_NAME, SITE_URL, toJsonLd } from '$lib/seo';
|
import { buildSeoMeta, canonicalUrl, SITE_NAME, SITE_URL, toJsonLd } from '$lib/seo';
|
||||||
|
import { getConversionRateText } from '$lib/utils/conversionRate';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
@@ -85,8 +86,12 @@
|
|||||||
|
|
||||||
<div class="calc-list">
|
<div class="calc-list">
|
||||||
{#each data.calculators as calc}
|
{#each data.calculators as calc}
|
||||||
|
{@const conversionRateText = getConversionRateText(calc)}
|
||||||
<a href="/{calc.slug}" class="calc-list-item">
|
<a href="/{calc.slug}" class="calc-list-item">
|
||||||
{calc.name}
|
{calc.name}
|
||||||
|
{#if conversionRateText}
|
||||||
|
<span class="calc-list-tooltip" role="tooltip">{conversionRateText}</span>
|
||||||
|
{/if}
|
||||||
</a>
|
</a>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user