@kerusiweb/angular 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -87,6 +87,16 @@ import { KerusiSeatmapComponent } from '@kerusiweb/angular';
87
87
  | `expireHolds` | `boolean` | `false` | Revert a lapsed `holdExpires` to available on a ticker. |
88
88
  | `expiryIntervalMs` | `number` | `1000` | |
89
89
 
90
+ **Zoom, pan and maximize** (both off by default; see [Zoom, pan and maximize](#zoom-pan-and-maximize))
91
+
92
+ | Input | Type | Default | |
93
+ | ------------------ | ------------------------------- | ------- | -------------------------------------------------------------------------------------- |
94
+ | `zoomable` | `boolean` | `false` | Pinch, Ctrl/Cmd + wheel and drag to zoom and pan; `+` `-` `0` keys; on-screen buttons. |
95
+ | `maxZoom` | `number` | `4` | The zoom ceiling, relative to fit. The floor is always fit. |
96
+ | `showZoomControls` | `boolean` | `true` | The built-in zoom buttons. Turn off to supply your own. |
97
+ | `maximizable` | `boolean` | `false` | A button that fills the screen with the map. |
98
+ | `controlStrings` | `Partial<KerusiControlStrings>` | English | The names of the zoom and maximize buttons, for translation. |
99
+
90
100
  ### Outputs
91
101
 
92
102
  | Output | Payload | |
@@ -96,6 +106,8 @@ import { KerusiSeatmapComponent } from '@kerusiweb/angular';
96
106
  | `seatDisallowed` | `SeatDisallowed` | `reason` is `booked`, `held`, `blocked`, `not-selectable`, `max-selection` or `companion-unavailable`. |
97
107
  | `seatFocus` | `RenderSeat` | |
98
108
  | `validationIssues` | `readonly KerusiViolation[]` | Emitted whenever the documents change. |
109
+ | `viewportChange` | `KerusiViewport` | `{ zoom, x, y }`, whenever the zoom or pan changes. Only with `zoomable`. |
110
+ | `maximizedChange` | `boolean` | When the map is maximized or restored. Only with `maximizable`. |
99
111
 
100
112
  ### The seat glyph
101
113
 
@@ -238,6 +250,78 @@ For anything the palette does not cover, each seat group carries class hooks:
238
250
  Inside a seat: `.kerusi-seat__box`, `__wash`, `__core`, `__occupant`
239
251
  (`__occupant--selected` / `--held` / `--booked`), `__label`, `__wheelchair`.
240
252
 
253
+ ### Zoom, pan and maximize
254
+
255
+ Two features, both **off by default**: with them off the markup and behaviour are
256
+ exactly what they were. They are independent; turn on either or both.
257
+
258
+ On a phone a map of several hundred seats is drawn at fit-to-width, so a seat is
259
+ too small to tap. `[zoomable]="true"` lets the reader zoom in and pan; `[maximizable]="true"` adds a button
260
+ that fills the screen.
261
+
262
+ **Zoom and pan.**
263
+
264
+ - **Pinch** with two fingers on a touch screen. **Ctrl/Cmd + wheel**, or a
265
+ trackpad pinch (Safari's included), on desktop. A plain wheel is left alone, so
266
+ the page still scrolls.
267
+ - **Drag** with one finger or the primary mouse button to pan.
268
+ - **A tap still selects**, at any zoom level. A touch or click that moves less
269
+ than 8 CSS pixels is a tap, and reaches the seat exactly as it does without
270
+ `zoomable`. Anything that moves further is a drag, and a drag never selects the
271
+ seat under it.
272
+ - **Limits.** The floor is fit-to-container, the ceiling is `maxZoom` (default
273
+ `4`), and panning stays inside the map. A map smaller than its container, which
274
+ happens when it is maximized on a large screen, is centred.
275
+ - **Gestures and the page.** `touch-action` is `pan-y` at fit, so a one-finger
276
+ vertical swipe still scrolls the page while a pinch is the map's; once zoomed in
277
+ or maximized it is `none`. With `zoomable` off, no `touch-action` is set.
278
+ - **Reduced motion.** The short transition on the zoom buttons, the keys and
279
+ reset is dropped under `prefers-reduced-motion: reduce`. A finger or wheel moves
280
+ the map directly and never eases.
281
+
282
+ | Key | |
283
+ | --------------- | ------------------------------------------------------------ |
284
+ | `+` / `=`, `-` | Zoom in / out, from anywhere inside the map |
285
+ | `0` | Reset to fit |
286
+ | `←` `→` `↑` `↓` | Pan, when the zoomable viewport itself has focus (Tab to it) |
287
+
288
+ On a seat, the arrow keys keep their usual job of moving seat focus, and a seat
289
+ that takes keyboard focus is scrolled into view. Ctrl, Cmd and Alt combinations
290
+ are left to the browser, and keys typed into a field you put inside the map are
291
+ ignored.
292
+
293
+ **Controls.** The zoom buttons (zoom in, zoom out, reset to fit) are real
294
+ `<button>`s with accessible names. At a limit they set `aria-disabled` rather than
295
+ `disabled`, so keyboard focus is not thrown away mid-press. Their names come from
296
+ `controlStrings`, for translation. They use the theme's existing tokens
297
+ (`--kerusi-element-bg`, `--kerusi-element-fg`, `--kerusi-element-muted-fg`,
298
+ `--kerusi-focus-ring`), so there is nothing new to theme.
299
+
300
+ To put the controls somewhere else, turn the built-in ones off
301
+ (`[showZoomControls]="false"`) and drive the map yourself:
302
+
303
+ ```ts
304
+ readonly map = viewChild.required(KerusiSeatmapComponent);
305
+ // this.map().zoomIn(); this.map().zoomOut(); this.map().resetZoom(); this.map().toggleMaximized();
306
+ // this.map().viewport() -> { zoom, x, y }
307
+ // this.map().maximized() -> boolean
308
+ ```
309
+
310
+ `viewportChange` reports `{ zoom, x, y }` whenever the view changes, for a host that wants
311
+ to display or persist it. (Restoring a saved view is not supported.)
312
+
313
+ **Maximize.** The button fills the screen with the map and its legend, freezes the
314
+ page behind it, and swaps to an "Exit full screen" button. The layout is a fixed
315
+ overlay, which is all iPhone Safari offers; where the browser has the Fullscreen
316
+ API it is requested on top, and leaving it with the browser's own Esc leaves the
317
+ map's maximized state too. `Escape` from the map also leaves, except that on a
318
+ seat with a non-empty selection the first `Escape` still clears the selection, as
319
+ it always has. The backdrop is `--kerusi-backdrop`, or the page's own canvas colour
320
+ while that is transparent; `--kerusi-maximized-z-index` (default `1000`) sets the
321
+ stacking. It is not a modal dialog: focus is not trapped, and an ancestor with a
322
+ `transform` or `filter` would anchor the fixed layout to itself instead of the
323
+ screen.
324
+
241
325
  ### Keyboard
242
326
 
243
327
  Tab moves between sections; each section keeps its own tab stop. Within a
@@ -258,6 +342,8 @@ Each seat is a `role="button"` announcing its position, type, price, status,
258
342
  every `Seat.accessibility` property and its attributes. A polite live region
259
343
  reports the running selection and any disallowed reason.
260
344
 
345
+ With `zoomable` on there are a few more keys: see [Zoom, pan and maximize](#zoom-pan-and-maximize).
346
+
261
347
  ---
262
348
 
263
349
  ## `<kerusi-legend>`