Okno zmiany peronu na tablicy odjazdów
NawigacjaPodgląd
Ładowanie podglądu…
Dworcowa tablica odjazdów z bocznym oknem wyboru peronu, anulowaniem zmian i aktualizacją komunikatu.
Kod źródłowy
Licencja MIT — także do użytku komercyjnego. Zachowaj informacje o autorze i licencji.
HTML
<main class="departure-board" data-platform="p3">
<header><span>DWORZEC CENTRALNY · ODJAZDY</span><time datetime="08:42">08:42</time></header>
<section class="departure" aria-labelledby="train-name">
<div class="train"><small>IC 5410</small><h1 id="train-name">BAŁTYK</h1><p>do Gdyni Głównej</p></div>
<dl class="journey"><div><dt>Odjazd</dt><dd>09:06</dd></div><div><dt>Peron</dt><dd id="active-platform">3</dd></div><div><dt>Tor</dt><dd id="active-track">5</dd></div></dl>
<ol class="stops" aria-label="Główne stacje na trasie"><li>Warszawa</li><li>Iława</li><li>Malbork</li><li>Gdańsk</li><li>Gdynia</li></ol>
</section>
<div class="board-actions"><button id="platform-open" type="button">Zmień peron</button><p id="platform-result" role="status">Wejście na peron od hali głównej.</p></div>
</main>
<dialog id="platform-dialog" aria-labelledby="platform-title" aria-describedby="platform-desc">
<header><small>ZMIANA MIEJSCA ODJAZDU</small><button class="platform-close" type="button" aria-label="Zamknij wybór peronu">×</button><h2 id="platform-title" tabindex="-1">Wybierz peron</h2><p id="platform-desc">Sprawdź tor i drogę dojścia przed zapisaniem zmiany.</p></header>
<fieldset><legend>Dostępne miejsca</legend>
<label><input type="radio" name="platform" value="p3" data-platform="3" data-track="5" data-access="hala główna" checked><span><b>03</b><i>Tor 5</i><small>Hala główna · 4 min</small></span></label>
<label><input id="platform-p5" type="radio" name="platform" value="p5" data-platform="5" data-track="8" data-access="tunel północny"><span><b>05</b><i>Tor 8</i><small>Tunel północny · 6 min</small></span></label>
<label><input type="radio" name="platform" value="p7" data-platform="7" data-track="11" data-access="kładka zachodnia"><span><b>07</b><i>Tor 11</i><small>Kładka zachodnia · 8 min</small></span></label>
</fieldset>
<div class="platform-actions"><button class="secondary platform-close" type="button">Anuluj</button><button id="platform-apply" type="button">Ustaw peron</button></div>
</dialog>
CSS
*{box-sizing:border-box}html{color-scheme:dark}body{margin:0;min-width:320px;min-height:100vh;background:#111318;color:#f4f1e8;font:16px/1.45 Arial,sans-serif}.departure-board{width:min(1120px,100%);min-height:100vh;margin:auto;padding:24px}.departure-board>header{display:flex;justify-content:space-between;align-items:center;border-bottom:2px solid #ffd84a;padding:11px 0 17px;color:#ffd84a;font:12px "Courier New",monospace;letter-spacing:.13em}.departure-board time{font-size:28px;font-weight:900;letter-spacing:0}.departure{display:grid;grid-template-columns:1.05fr .95fr;gap:44px;min-height:500px;padding:52px 0 32px}.train small{color:#ffd84a;font:800 14px "Courier New",monospace}.train h1{margin:12px 0 4px;font-size:clamp(68px,12vw,144px);line-height:.76;letter-spacing:-.08em}.train p{margin:20px 0;color:#c0c3c9;font-size:20px}.journey{display:grid;grid-template-columns:repeat(3,1fr);align-self:start;margin:0;border-top:1px solid #626873}.journey div{min-height:134px;border-bottom:1px solid #626873;padding:15px 8px 12px 0}.journey dt{color:#aeb3bd;font-size:12px}.journey dd{margin:6px 0 0;color:#ffd84a;font:900 clamp(38px,6vw,64px)/1 "Courier New",monospace}.stops{grid-column:1/-1;display:grid;grid-template-columns:repeat(5,1fr);margin:35px 0 0;padding:24px 0 0;border-top:4px solid #ffd84a;list-style:none;counter-reset:stop}.stops li{position:relative;padding:18px 10px 0 0;font-size:13px}.stops li:before{content:"";position:absolute;top:-34px;left:0;width:17px;height:17px;border:4px solid #111318;background:#ffd84a}.board-actions{display:flex;align-items:center;gap:20px;border-top:1px solid #626873;padding-top:22px}.board-actions p{margin:0;color:#c0c3c9;font-size:13px}button{min-height:46px;padding:10px 18px;border:2px solid #ffd84a;border-radius:0;background:#ffd84a;color:#111318;font:900 14px Arial,sans-serif;cursor:pointer}button:hover{border-color:#f4f1e8;background:#f4f1e8}button:focus-visible,input:focus-visible,[tabindex]:focus-visible{outline:4px solid #53d7ff;outline-offset:4px}dialog{width:min(510px,100%);max-width:none;height:100dvh;max-height:none;margin:0 0 0 auto;padding:0;border:0;border-left:4px solid #111318;background:#f4f1e8;color:#111318;overflow:auto}dialog::backdrop{background:rgba(5,6,8,.8)}dialog[open]{animation:platform-in .24s ease-out}dialog>header{position:relative;padding:29px 27px 23px;border-bottom:4px solid #111318}.platform-close[aria-label]{position:absolute;right:12px;top:12px;width:46px;padding:0;border-color:#111318;background:transparent;color:#111318;font-size:28px}.platform-close[aria-label]:hover{background:#ffd84a}dialog header small{font:800 11px "Courier New",monospace;letter-spacing:.12em}dialog h2{margin:29px 0 9px;font-size:clamp(47px,8vw,72px);line-height:.8;letter-spacing:-.065em}dialog header p{margin:17px 0 0;max-width:42ch}fieldset{margin:0;padding:0;border:0}legend{width:100%;padding:13px 27px;border-bottom:1px solid #92928c;font:800 12px "Courier New",monospace;text-transform:uppercase}fieldset label{display:grid;grid-template-columns:28px 1fr;align-items:center;gap:14px;min-height:96px;padding:13px 27px;border-bottom:1px solid #92928c;cursor:pointer}fieldset label:hover{background:#fff8d7}fieldset label:has(input:checked){background:#ffd84a}fieldset label:has(input:focus-visible){outline:4px solid #126082;outline-offset:-4px}fieldset input{width:24px;height:24px;margin:0;accent-color:#111318}fieldset span{display:grid;grid-template-columns:54px 1fr;align-items:baseline;gap:7px 12px}fieldset b{font:900 30px "Courier New",monospace}fieldset i{font-style:normal;font-weight:900}fieldset small{grid-column:1/-1;font-size:12px}.platform-actions{display:flex;justify-content:flex-end;gap:9px;padding:22px 27px}.platform-actions .secondary{border-color:#111318;background:transparent;color:#111318}@keyframes platform-in{from{transform:translateX(100%)}to{transform:none}}@media(max-width:620px){.departure-board{padding:14px}.departure-board>header{align-items:flex-start;flex-direction:column;gap:10px}.departure{grid-template-columns:1fr;gap:28px;min-height:0;padding:36px 0 28px}.train h1{font-size:74px}.journey div{min-height:100px}.stops{display:flex;gap:24px;overflow:auto;margin-top:8px}.stops li{min-width:88px}.board-actions{align-items:flex-start;flex-direction:column}dialog{width:100%}}@media(max-width:370px){.train h1{font-size:62px}.journey dd{font-size:35px}dialog>header{padding-left:18px;padding-right:18px}fieldset label{padding-left:18px;padding-right:18px}.platform-actions{flex-direction:column;padding:18px}.platform-actions button{width:100%}}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
JavaScript
$(function(){const dialog=$('#platform-dialog')[0],$dialog=$(dialog),opener=$('#platform-open')[0];let downOutside=false,appliedPlatform='p3';const outside=e=>{const r=dialog.getBoundingClientRect();return e.clientX<r.left||e.clientX>r.right||e.clientY<r.top||e.clientY>r.bottom};const trap=event=>{if(event.key!=='Tab')return;const items=[...dialog.querySelectorAll('button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[href],[tabindex]:not([tabindex="-1"])')].filter(item=>item.getClientRects().length),first=items[0],last=items[items.length-1],current=document.activeElement;if(!first){event.preventDefault();dialog.focus()}else if(event.shiftKey&&(current===first||!items.includes(current))){event.preventDefault();last.focus()}else if(!event.shiftKey&¤t===last){event.preventDefault();first.focus()}};function restore(){$('[name=platform][value='+appliedPlatform+']').prop('checked',true)}$('#platform-open').on('click',function(){restore();dialog.showModal();$('#platform-title').trigger('focus')});$('.platform-close').on('click',()=>dialog.close('cancel'));$('#platform-apply').on('click',function(){const selected=$('[name=platform]:checked');appliedPlatform=selected.val();const platform=selected.data('platform'),track=selected.data('track'),access=selected.data('access');$('.departure-board').attr('data-platform',appliedPlatform);$('#active-platform').text(platform);$('#active-track').text(track);$('#platform-result').text('Odjazd przeniesiony na peron '+platform+', tor '+track+'. Wejście: '+access+'.');dialog.close('apply')});$dialog.on('keydown',trap).on('cancel',function(event){event.preventDefault();dialog.close('cancel')}).on('close',function(){restore();opener.focus()}).on('pointerdown',event=>{downOutside=outside(event)}).on('pointerup',event=>{if(downOutside&&outside(event))dialog.close('backdrop');downOutside=false}).on('pointercancel',()=>{downOutside=false})});
Edytuj swój pen
Podaj adres e-mail użyty przy zapisie. Wyślemy link do edycji.