|
100 | 100 | <link rel="manifest" href="/static/img/site.webmanifest" /> |
101 | 101 | </head> |
102 | 102 | <body class="min-h-screen bg-gray-50"> |
103 | | - <!-- Verhuisbericht modal --> |
104 | | - <div x-data="{ showMoveModal: localStorage.getItem('regelrecht-move-notice-dismissed') !== 'true' }" |
| 103 | + <!-- Verhuisbericht modal. |
| 104 | + Telt af en stuurt daarna zelf door. Wegklikken kan, en geldt dan voor |
| 105 | + de rest van de sessie: wie de oude proof of concept bewust wil |
| 106 | + doorklikken wordt niet op elke pagina opnieuw onderbroken. |
| 107 | +
|
| 108 | + `sessionStorage` en niet `localStorage`, want dat is het verschil met |
| 109 | + de vorige versie. Die zette een vlag die eeuwig bleef staan, dus wie |
| 110 | + het bericht één keer wegklikte kreeg het nooit meer te zien en bleef |
| 111 | + op de oude omgeving werken zonder dat te weten. Nu is het bij een |
| 112 | + nieuw bezoek weer een schone lei. |
| 113 | +
|
| 114 | + De afteller is er zodat de sprong aangekondigd is en niet als een |
| 115 | + storing voelt. Hij pauzeert bij muis of focus in de dialoog, want |
| 116 | + een tijdslimiet moet te verlengen zijn (WCAG 2.2.1). --> |
| 117 | + <script> |
| 118 | + // Staat hier en niet in het x-data attribuut zelf: de djlint |
| 119 | + // pre-commit hook plakt zo'n attribuut op één regel, en dan slikt de |
| 120 | + // eerste `//` alle code erna op. In een script-blok blijft het heel. |
| 121 | + window.moveNotice = () => ({ |
| 122 | + showMoveModal: (() => { |
| 123 | + try { |
| 124 | + return sessionStorage.getItem('regelrecht-move-notice-dismissed') !== 'true'; |
| 125 | + } catch (e) { |
| 126 | + return true; |
| 127 | + } |
| 128 | + })(), |
| 129 | + seconds: 20, |
| 130 | + timer: null, |
| 131 | + paused: false, |
| 132 | + target: 'https://demo.regelrecht.rijks.app', |
| 133 | + start() { |
| 134 | + if (!this.showMoveModal) return; |
| 135 | + // Eén timer, ook als Alpine dit component opnieuw initialiseert. |
| 136 | + // Zonder deze wacht liepen er twee intervals en telde de teller |
| 137 | + // twee per seconde af, waardoor de sprong op de helft van de |
| 138 | + // aangekondigde tijd viel. |
| 139 | + if (this.timer) return; |
| 140 | + // Respecteer wie bewegende/automatische dingen heeft afgezet: |
| 141 | + // dan blijft het een mededeling die je zelf wegklikt. |
| 142 | + if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; |
| 143 | + this.timer = setInterval(() => { |
| 144 | + if (this.paused) return; |
| 145 | + this.seconds--; |
| 146 | + if (this.seconds <= 0) { |
| 147 | + clearInterval(this.timer); |
| 148 | + this.timer = null; |
| 149 | + window.location.href = this.target; |
| 150 | + } |
| 151 | + }, 1000); |
| 152 | + }, |
| 153 | + // WCAG 2.2.1 wil dat een tijdslimiet te stoppen of te verlengen is. |
| 154 | + // Muis erop of toetsenbordfocus in de dialoog pauzeert het aftellen, |
| 155 | + // zodat wie meer tijd nodig heeft om te lezen die ook krijgt. |
| 156 | + pause() { |
| 157 | + this.paused = true; |
| 158 | + }, |
| 159 | + resume() { |
| 160 | + this.paused = false; |
| 161 | + }, |
| 162 | + stay() { |
| 163 | + clearInterval(this.timer); |
| 164 | + this.timer = null; |
| 165 | + this.showMoveModal = false; |
| 166 | + try { |
| 167 | + sessionStorage.setItem('regelrecht-move-notice-dismissed', 'true'); |
| 168 | + } catch (e) { |
| 169 | + /* private mode */ |
| 170 | + } |
| 171 | + } |
| 172 | + }); |
| 173 | + </script> |
| 174 | + <div x-data="moveNotice()" |
| 175 | + x-init="start()" |
105 | 176 | x-show="showMoveModal" |
106 | 177 | x-cloak |
107 | 178 | style="display: none" |
108 | | - @keydown.escape.window="showMoveModal = false; localStorage.setItem('regelrecht-move-notice-dismissed', 'true')" |
| 179 | + @keydown.escape.window="stay()" |
109 | 180 | class="fixed inset-0 z-[11000] flex items-center justify-center p-4"> |
110 | | - <div class="absolute inset-0 bg-black/50" |
111 | | - @click="showMoveModal = false; localStorage.setItem('regelrecht-move-notice-dismissed', 'true')"></div> |
| 181 | + <div class="absolute inset-0 bg-black/50" @click="stay()"></div> |
112 | 182 | <div class="relative bg-white rounded-lg shadow-xl max-w-lg w-full p-6" |
113 | 183 | role="dialog" |
114 | 184 | aria-modal="true" |
115 | 185 | aria-labelledby="move-notice-title" |
| 186 | + @mouseenter="pause()" |
| 187 | + @mouseleave="resume()" |
| 188 | + @focusin="pause()" |
| 189 | + @focusout="resume()" |
116 | 190 | x-transition:enter="transition ease-out duration-200" |
117 | 191 | x-transition:enter-start="opacity-0 transform scale-95" |
118 | 192 | x-transition:enter-end="opacity-100 transform scale-100"> |
119 | | - <button @click="showMoveModal = false; localStorage.setItem('regelrecht-move-notice-dismissed', 'true')" |
| 193 | + <button @click="stay()" |
120 | 194 | class="absolute top-4 right-4 text-gray-400 hover:text-gray-600 focus:outline-none rounded-lg p-1 cursor-pointer" |
121 | 195 | aria-label="Sluiten"> |
122 | 196 | <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"> |
123 | 197 | <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" /> |
124 | 198 | </svg> |
125 | 199 | </button> |
126 | 200 | <h2 id="move-notice-title" |
127 | | - class="text-xl font-semibold text-gray-900 pr-8">Deze demo verhuist</h2> |
| 201 | + class="text-xl font-semibold text-gray-900 pr-8">Deze demo is verhuisd</h2> |
128 | 202 | <p class="mt-3 text-sm text-gray-700"> |
129 | 203 | Er staat een nieuwe versie van RegelRecht klaar: een nieuw ontwerp, een nieuwe |
130 | 204 | implementatie onder de motorkap en een eigen adres: |
|
143 | 217 | Deze omgeving is de oude proof of concept en blijft voorlopig nog beschikbaar, maar |
144 | 218 | wordt niet meer doorontwikkeld. Werk uw bladwijzers bij. |
145 | 219 | </p> |
| 220 | + <!-- De teller zelf is `aria-hidden`. Een live region die elke |
| 221 | + seconde verandert laat een schermlezer twintig keer achter |
| 222 | + elkaar een getal voorlezen, dwars door de rest van de dialoog |
| 223 | + heen. De statische zin eronder vertelt hetzelfde, één keer. --> |
| 224 | + <p class="mt-4 text-sm text-gray-700" x-show="timer" aria-hidden="true"> |
| 225 | + U gaat er over <span class="font-semibold" x-text="seconds"></span> |
| 226 | + <span x-text="seconds === 1 ? 'seconde' : 'seconden'"></span> automatisch heen. |
| 227 | + <span x-show="paused" class="text-gray-500">(gepauzeerd)</span> |
| 228 | + </p> |
| 229 | + <p class="sr-only" x-show="timer"> |
| 230 | + U wordt na twintig seconden automatisch doorgestuurd naar de nieuwe omgeving. |
| 231 | + Het aftellen pauzeert zodra u met de muis of het toetsenbord in deze melding bent. |
| 232 | + Kies "Hier verder" om op deze omgeving te blijven. |
| 233 | + </p> |
146 | 234 | <div class="mt-6 flex flex-wrap gap-3"> |
147 | 235 | <a href="https://demo.regelrecht.rijks.app" |
148 | 236 | class="inline-flex items-center px-4 py-2 rounded-md bg-blue-600 text-white text-sm font-medium hover:bg-blue-700"> |
149 | | - Naar de nieuwe RegelRecht |
| 237 | + Nu naar de nieuwe RegelRecht |
150 | 238 | </a> |
151 | | - <button @click="showMoveModal = false; localStorage.setItem('regelrecht-move-notice-dismissed', 'true')" |
| 239 | + <button @click="stay()" |
152 | 240 | class="inline-flex items-center px-4 py-2 rounded-md border border-gray-300 text-gray-700 text-sm font-medium hover:bg-gray-50 cursor-pointer"> |
153 | 241 | Hier verder |
154 | 242 | </button> |
|
157 | 245 | </div> |
158 | 246 | {% if not demo_mode %} |
159 | 247 | <!-- Proof of Concept Ribbon --> |
160 | | - <button onclick="localStorage.removeItem('regelrecht-banner-dismissed'); localStorage.removeItem('regelrecht-move-notice-dismissed'); location.reload();" |
| 248 | + <!-- Haalt de weggeklikte berichten terug. Wist ook de oude |
| 249 | + localStorage-sleutel van het verhuisbericht: die zat er eeuwig in |
| 250 | + bij wie hem ooit heeft weggeklikt, en het bericht leest nu uit |
| 251 | + sessionStorage. --> |
| 252 | + <button onclick="localStorage.removeItem('regelrecht-banner-dismissed'); localStorage.removeItem('regelrecht-move-notice-dismissed'); sessionStorage.removeItem('regelrecht-move-notice-dismissed'); location.reload();" |
161 | 253 | class="fixed z-[10000] w-[180px] top-[30px] right-[-50px] text-center text-[15px] font-medium py-[5px] bg-[#FACC15] text-black transform rotate-45 origin-center shadow-md hover:bg-[#EAB308] transition-colors no-underline cursor-pointer border-0"> |
162 | 254 | Proof of Concept |
163 | 255 | </button> |
|
0 commit comments