Show a visible source icon for Open-Meteo fallback values on NWS
Replace the hidden hover-only native title with a dedicated SourceTooltip component: a small ⓘ badge rendered inline next to Pressure and UV values (Current + Details views) that reveals a styled tooltip on hover/focus, so it is obvious the value came from the non-selected source (Open-Meteo) instead of requiring discovery by hovering the data.
This commit is contained in:
parent
c0ec45f170
commit
6c7fbf68eb
@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { app } from '../lib/stores/app.svelte.js'
|
import { app } from '../lib/stores/app.svelte.js'
|
||||||
import { getWeatherInfo, getWeatherSeverity } from '../lib/api/weather-codes.js'
|
import { getWeatherInfo, getWeatherSeverity } from '../lib/api/weather-codes.js'
|
||||||
|
import SourceTooltip from './SourceTooltip.svelte'
|
||||||
|
|
||||||
const data = $derived(app.forecastData)
|
const data = $derived(app.forecastData)
|
||||||
const current = $derived(data?.current)
|
const current = $derived(data?.current)
|
||||||
@ -71,15 +72,15 @@
|
|||||||
<span class="metric-value">{Math.round(current.wind_speed_10m)} {windUnit}</span>
|
<span class="metric-value">{Math.round(current.wind_speed_10m)} {windUnit}</span>
|
||||||
<span class="metric-sub">{windCompass(current.wind_direction_10m)}</span>
|
<span class="metric-sub">{windCompass(current.wind_direction_10m)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="metric-card" title={fbPressure ? 'Pressure from Open-Meteo — NWS does not provide it' : undefined}>
|
<div class="metric-card">
|
||||||
<span class="metric-icon">🌡️</span>
|
<span class="metric-icon">🌡️</span>
|
||||||
<span class="metric-label">Pressure</span>
|
<span class="metric-label">Pressure</span>
|
||||||
<span class="metric-value">{Math.round(current.pressure_msl || 0)} hPa</span>
|
<span class="metric-value">{Math.round(current.pressure_msl || 0)} hPa{#if fbPressure}<SourceTooltip label="Pressure from Open-Meteo — NWS does not provide it" />{/if}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="metric-card" title={fbUv ? 'UV index from Open-Meteo — NWS does not provide it' : undefined}>
|
<div class="metric-card">
|
||||||
<span class="metric-icon">☀️</span>
|
<span class="metric-icon">☀️</span>
|
||||||
<span class="metric-label">UV Index</span>
|
<span class="metric-label">UV Index</span>
|
||||||
<span class="metric-value">{current.uv_index != null ? Math.round(current.uv_index) : '--'}</span>
|
<span class="metric-value">{current.uv_index != null ? Math.round(current.uv_index) : '--'}{#if fbUv}<SourceTooltip label="UV index from Open-Meteo — NWS does not provide it" />{/if}</span>
|
||||||
{#if current.uv_index != null}
|
{#if current.uv_index != null}
|
||||||
<span class="metric-sub">{current.uv_index <= 2 ? 'Low' : current.uv_index <= 5 ? 'Moderate' : current.uv_index <= 7 ? 'High' : 'Very High'}</span>
|
<span class="metric-sub">{current.uv_index <= 2 ? 'Low' : current.uv_index <= 5 ? 'Moderate' : current.uv_index <= 7 ? 'High' : 'Very High'}</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
79
src/components/SourceTooltip.svelte
Normal file
79
src/components/SourceTooltip.svelte
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<script>
|
||||||
|
/** Small info badge whose tooltip explains the value came from the
|
||||||
|
* non-selected source (e.g. Open-Meteo while NWS is selected). */
|
||||||
|
let { label = '' } = $props()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span class="srctip" tabindex="0" role="note" aria-label={label}>
|
||||||
|
<span class="srctip-icon" aria-hidden="true">ⓘ</span>
|
||||||
|
<span class="srctip-bubble">{label}</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.srctip {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 17px;
|
||||||
|
height: 17px;
|
||||||
|
margin-left: 6px;
|
||||||
|
vertical-align: middle;
|
||||||
|
cursor: help;
|
||||||
|
flex: none;
|
||||||
|
color: var(--color-primary, #38bdf8);
|
||||||
|
}
|
||||||
|
.srctip-icon {
|
||||||
|
font-size: 0.98rem;
|
||||||
|
line-height: 1;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.srctip-bubble {
|
||||||
|
position: absolute;
|
||||||
|
bottom: calc(100% + 7px);
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: max-content;
|
||||||
|
max-width: 210px;
|
||||||
|
padding: 7px 10px;
|
||||||
|
border-radius: 7px;
|
||||||
|
background: #0b1220;
|
||||||
|
color: #e2e8f0;
|
||||||
|
font-size: 0.74rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.4;
|
||||||
|
white-space: normal;
|
||||||
|
text-align: left;
|
||||||
|
box-shadow: 0 5px 16px rgba(0, 0, 0, 0.4);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.12s ease, visibility 0.12s ease;
|
||||||
|
z-index: 60;
|
||||||
|
}
|
||||||
|
/* small arrow */
|
||||||
|
.srctip-bubble::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border: 5px solid transparent;
|
||||||
|
border-top-color: #0b1220;
|
||||||
|
}
|
||||||
|
.srctip:hover .srctip-bubble,
|
||||||
|
.srctip:focus .srctip-bubble,
|
||||||
|
.srctip:focus-visible .srctip-bubble {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.srctip:focus,
|
||||||
|
.srctip:focus-visible {
|
||||||
|
outline: 2px solid var(--color-primary, #38bdf8);
|
||||||
|
outline-offset: 2px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { app } from '../lib/stores/app.svelte.js'
|
import { app } from '../lib/stores/app.svelte.js'
|
||||||
import { getWeatherInfo } from '../lib/api/weather-codes.js'
|
import { getWeatherInfo } from '../lib/api/weather-codes.js'
|
||||||
|
import SourceTooltip from './SourceTooltip.svelte'
|
||||||
|
|
||||||
const data = $derived(app.forecastData)
|
const data = $derived(app.forecastData)
|
||||||
const current = $derived(data?.current)
|
const current = $derived(data?.current)
|
||||||
@ -97,7 +98,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>Pressure</span>
|
<span>Pressure</span>
|
||||||
<span class="detail-value" title={fbPressure ? 'Pressure from Open-Meteo — NWS does not provide it' : undefined}>{Math.round(current.pressure_msl || 0)} hPa</span>
|
<span class="detail-value">{Math.round(current.pressure_msl || 0)} hPa{#if fbPressure}<SourceTooltip label="Pressure from Open-Meteo — NWS does not provide it" />{/if}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>Feels Like</span>
|
<span>Feels Like</span>
|
||||||
@ -119,11 +120,12 @@
|
|||||||
<div class="detail-body">
|
<div class="detail-body">
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>UV Index</span>
|
<span>UV Index</span>
|
||||||
<span class="detail-value" title={fbUv ? 'UV index from Open-Meteo — NWS does not provide it' : undefined}>
|
<span class="detail-value">
|
||||||
{current.uv_index != null ? Math.round(current.uv_index) : '--'}
|
{current.uv_index != null ? Math.round(current.uv_index) : '--'}
|
||||||
{#if current.uv_index != null}
|
{#if current.uv_index != null}
|
||||||
<span class="uv-badge uv-{getUVLevel(current.uv_index).toLowerCase().replace(' ', '-')}">{getUVLevel(current.uv_index)}</span>
|
<span class="uv-badge uv-{getUVLevel(current.uv_index).toLowerCase().replace(' ', '-')}">{getUVLevel(current.uv_index)}</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if fbUv}<SourceTooltip label="UV index from Open-Meteo — NWS does not provide it" />{/if}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
@ -136,7 +138,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>Max UV Today</span>
|
<span>Max UV Today</span>
|
||||||
<span class="detail-value" title={fbUv ? 'UV from Open-Meteo — NWS does not provide it' : undefined}>{daily?.uv_index_max?.[0] != null ? Math.round(daily.uv_index_max[0]) : '--'}</span>
|
<span class="detail-value">{daily?.uv_index_max?.[0] != null ? Math.round(daily.uv_index_max[0]) : '--'}{#if fbUv}<SourceTooltip label="UV from Open-Meteo — NWS does not provide it" />{/if}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user