@kerusiweb/react 3.0.0 → 3.1.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 +198 -21
- package/dist/kerusi-seatmap.d.ts.map +1 -1
- package/dist/kerusi-seatmap.js +98 -15
- package/dist/kerusi-seatmap.js.map +1 -1
- package/dist/kerusi-section.d.ts +26 -3
- package/dist/kerusi-section.d.ts.map +1 -1
- package/dist/kerusi-section.js +4 -4
- package/dist/kerusi-section.js.map +1 -1
- package/dist/seat-card.d.ts +36 -0
- package/dist/seat-card.d.ts.map +1 -0
- package/dist/seat-card.js +99 -0
- package/dist/seat-card.js.map +1 -0
- package/dist/types.d.ts +65 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/use-seat-cards.d.ts +55 -0
- package/dist/use-seat-cards.d.ts.map +1 -0
- package/dist/use-seat-cards.js +202 -0
- package/dist/use-seat-cards.js.map +1 -0
- package/dist/use-viewport.d.ts +6 -1
- package/dist/use-viewport.d.ts.map +1 -1
- package/dist/use-viewport.js +6 -3
- package/dist/use-viewport.js.map +1 -1
- package/package.json +2 -2
- package/styles.css +181 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kerusi-section.d.ts","sourceRoot":"","sources":["../src/kerusi-section.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,mBAAmB,EAGnB,aAAa,EAEb,WAAW,EACX,cAAc,EACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,IAAI,kBAAkB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,0EAA0E;IAC1E,MAAM,EAAE,aAAa,CAAC;IACtB,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mCAAmC;IACnC,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mDAAmD;IACnD,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IACvC,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kDAAkD;IAClD,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,iEAAiE;IACjE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,SAAS,CAAC;IACnD
|
|
1
|
+
{"version":3,"file":"kerusi-section.d.ts","sourceRoot":"","sources":["../src/kerusi-section.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,mBAAmB,EAGnB,aAAa,EAEb,WAAW,EACX,cAAc,EACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,IAAI,kBAAkB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,0EAA0E;IAC1E,MAAM,EAAE,aAAa,CAAC;IACtB,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mCAAmC;IACnC,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mDAAmD;IACnD,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IACvC,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kDAAkD;IAClD,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,iEAAiE;IACjE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,SAAS,CAAC;IACnD;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qFAAqF;IACrF,WAAW,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpD,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAC7D,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,mEAAmE;IACnE,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACjE,oFAAoF;IACpF,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAChG,gFAAgF;IAChF,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;CACnE;AAKD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,KAAK,EACL,SAAgB,EAChB,SAA2B,EAC3B,aAAoB,EACpB,UAAyB,EACzB,MAA8B,EAC9B,UAAiB,EACjB,cAAc,EACd,SAAS,EACT,UAAU,EACV,WAAkB,EAClB,SAAiB,EACjB,SAAuB,EACvB,WAAkB,EAClB,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,YAAY,GACb,EAAE,kBAAkB,+BA0DpB"}
|
package/dist/kerusi-section.js
CHANGED
|
@@ -11,19 +11,19 @@ const EMPTY_LABELS = new Map();
|
|
|
11
11
|
*
|
|
12
12
|
* This component holds no state. It takes a placed layout and reports intent.
|
|
13
13
|
*/
|
|
14
|
-
export function KerusiSection({ layout, label, showLabel = true, selection = EMPTY_SELECTION, focusedSeatId = null, ariaLabels = EMPTY_LABELS, colors = DEFAULT_KERUSI_COLORS, typeColors = true, seatTypeStyles, seatStyle, renderSeat, interactive = true, onSeatActivate, onSeatFocused, onSeatKeyDown, registerSeat, }) {
|
|
14
|
+
export function KerusiSection({ layout, label, showLabel = true, selection = EMPTY_SELECTION, focusedSeatId = null, ariaLabels = EMPTY_LABELS, colors = DEFAULT_KERUSI_COLORS, typeColors = true, seatTypeStyles, seatStyle, renderSeat, interactive = true, clickable = false, reachable = interactive, describedBy = null, onSeatActivate, onSeatFocused, onSeatBlurred, onSeatKeyDown, onSeatPointer, registerSeat, }) {
|
|
15
15
|
const section = layout.section;
|
|
16
16
|
const anchor = layout.labelAnchor;
|
|
17
|
-
return (_jsxs("g", { className: "kerusi-section", role: "group", "aria-label": label ?? section.id, "data-section-id": section.id, children: [showLabel && label && section.boundsDeclared && (_jsx("text", { className: "kerusi-section-label", "aria-hidden": "true", textAnchor: "start", dominantBaseline: "hanging", x: anchor.x, y: anchor.y, fontSize: anchor.fontSize, style: { fill: elementTextFill(elementStyle('label').tone, colors) }, children: label })), layout.elements.map((placed) => (_jsx(SectionElement, { placed: placed, colors: colors }, placed.element.id))), layout.seats.map((placed) => (_jsx(SectionSeat, { placed: placed, selected: selection.has(placed.seat.id), tabStop: placed.seat.id === focusedSeatId, ariaLabel: ariaLabels.get(placed.seat.id) ?? placed.seat.label, colors: colors, typeColors: typeColors, seatTypeStyles: seatTypeStyles, seatStyle: seatStyle, renderSeat: renderSeat, interactive: interactive, onSeatActivate: onSeatActivate, onSeatFocused: onSeatFocused, onSeatKeyDown: onSeatKeyDown, registerSeat: registerSeat }, placed.seat.id)))] }));
|
|
17
|
+
return (_jsxs("g", { className: "kerusi-section", role: "group", "aria-label": label ?? section.id, "data-section-id": section.id, children: [showLabel && label && section.boundsDeclared && (_jsx("text", { className: "kerusi-section-label", "aria-hidden": "true", textAnchor: "start", dominantBaseline: "hanging", x: anchor.x, y: anchor.y, fontSize: anchor.fontSize, style: { fill: elementTextFill(elementStyle('label').tone, colors) }, children: label })), layout.elements.map((placed) => (_jsx(SectionElement, { placed: placed, colors: colors }, placed.element.id))), layout.seats.map((placed) => (_jsx(SectionSeat, { placed: placed, selected: selection.has(placed.seat.id), tabStop: placed.seat.id === focusedSeatId, ariaLabel: ariaLabels.get(placed.seat.id) ?? placed.seat.label, colors: colors, typeColors: typeColors, seatTypeStyles: seatTypeStyles, seatStyle: seatStyle, renderSeat: renderSeat, interactive: interactive, clickable: clickable, reachable: reachable, describedById: describedBy?.seatId === placed.seat.id ? describedBy.id : undefined, onSeatActivate: onSeatActivate, onSeatFocused: onSeatFocused, onSeatBlurred: onSeatBlurred, onSeatKeyDown: onSeatKeyDown, onSeatPointer: onSeatPointer, registerSeat: registerSeat }, placed.seat.id)))] }));
|
|
18
18
|
}
|
|
19
|
-
function SectionSeat({ placed, selected, tabStop, ariaLabel, colors, typeColors, seatTypeStyles, seatStyle, renderSeat, interactive, onSeatActivate, onSeatFocused, onSeatKeyDown, registerSeat, }) {
|
|
19
|
+
function SectionSeat({ placed, selected, tabStop, ariaLabel, colors, typeColors, seatTypeStyles, seatStyle, renderSeat, interactive, clickable, reachable, describedById, onSeatActivate, onSeatFocused, onSeatBlurred, onSeatKeyDown, onSeatPointer, registerSeat, }) {
|
|
20
20
|
const seat = placed.seat;
|
|
21
21
|
const style = resolveSeatStyle(seat, selected, seatTypeStyles, seatStyle);
|
|
22
22
|
const glyph = resolveSeatGlyph(placed, selected, colors, typeColors, style);
|
|
23
23
|
const stock = _jsx(SeatGlyphMarks, { glyph: glyph });
|
|
24
24
|
return (_jsx("g", { ref: (node) => {
|
|
25
25
|
registerSeat?.(seat.id, node);
|
|
26
|
-
}, className: glyph.className, role: "button", tabIndex:
|
|
26
|
+
}, className: glyph.className, role: "button", tabIndex: reachable && tabStop ? 0 : -1, "aria-label": ariaLabel, "aria-pressed": !interactive && clickable ? undefined : selected, "aria-disabled": !seat.selectable, "aria-describedby": describedById, "data-seat-id": seat.id, "data-seat-type": glyph.data.type, "data-seat-status": glyph.data.status, "data-section-id": glyph.data.section, "data-seat-row": glyph.data.row, "data-seat-attributes": glyph.data.attributes, transform: transform(placed) ?? undefined, onClick: reachable ? () => onSeatActivate?.(seat.id, 'pointer') : undefined, onFocus: reachable ? () => onSeatFocused?.(seat.id) : undefined, onBlur: reachable && onSeatBlurred ? () => onSeatBlurred(seat.id) : undefined, onKeyDown: reachable ? onSeatKeyDown : undefined, onPointerEnter: onSeatPointer ? (e) => onSeatPointer('enter', seat.id, e.pointerType) : undefined, onPointerLeave: onSeatPointer ? (e) => onSeatPointer('leave', seat.id, e.pointerType) : undefined, onPointerMove: onSeatPointer ? (e) => onSeatPointer('move', seat.id, e.pointerType) : undefined, children: renderSeat ? (_jsxs(_Fragment, { children: [renderSeat({ placed, seat, selected, glyph, defaultContent: stock }), _jsx("path", { className: "kerusi-seat__focus", d: glyph.body.d })] })) : (stock) }));
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* The stock seat drawing, from a glyph core has already resolved. A fragment,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kerusi-section.js","sourceRoot":"","sources":["../src/kerusi-section.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,GACX,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"kerusi-section.js","sourceRoot":"","sources":["../src/kerusi-section.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,GACX,MAAM,iBAAiB,CAAC;AAoEzB,MAAM,eAAe,GAAwB,IAAI,GAAG,EAAE,CAAC;AACvD,MAAM,YAAY,GAAgC,IAAI,GAAG,EAAE,CAAC;AAE5D;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,MAAM,EACN,KAAK,EACL,SAAS,GAAG,IAAI,EAChB,SAAS,GAAG,eAAe,EAC3B,aAAa,GAAG,IAAI,EACpB,UAAU,GAAG,YAAY,EACzB,MAAM,GAAG,qBAAqB,EAC9B,UAAU,GAAG,IAAI,EACjB,cAAc,EACd,SAAS,EACT,UAAU,EACV,WAAW,GAAG,IAAI,EAClB,SAAS,GAAG,KAAK,EACjB,SAAS,GAAG,WAAW,EACvB,WAAW,GAAG,IAAI,EAClB,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,YAAY,GACO;IACnB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC;IAClC,OAAO,CACL,aACE,SAAS,EAAC,gBAAgB,EAC1B,IAAI,EAAC,OAAO,gBACA,KAAK,IAAI,OAAO,CAAC,EAAE,qBACd,OAAO,CAAC,EAAE,aAE1B,SAAS,IAAI,KAAK,IAAI,OAAO,CAAC,cAAc,IAAI,CAG/C,eACE,SAAS,EAAC,sBAAsB,iBACpB,MAAM,EAClB,UAAU,EAAC,OAAO,EAClB,gBAAgB,EAAC,SAAS,EAC1B,CAAC,EAAE,MAAM,CAAC,CAAC,EACX,CAAC,EAAE,MAAM,CAAC,CAAC,EACX,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,KAAK,EAAE,EAAE,IAAI,EAAE,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,YAEnE,KAAK,GACD,CACR,EAGA,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC/B,KAAC,cAAc,IAAyB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAjD,MAAM,CAAC,OAAO,CAAC,EAAE,CAAoC,CAC3E,CAAC,EAED,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC5B,KAAC,WAAW,IAEV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EACvC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,aAAa,EACzC,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,EAC9D,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAClF,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,IAnBrB,MAAM,CAAC,IAAI,CAAC,EAAE,CAoBnB,CACH,CAAC,IACA,CACL,CAAC;AACJ,CAAC;AA0BD,SAAS,WAAW,CAAC,EACnB,MAAM,EACN,QAAQ,EACR,OAAO,EACP,SAAS,EACT,MAAM,EACN,UAAU,EACV,cAAc,EACd,SAAS,EACT,UAAU,EACV,WAAW,EACX,SAAS,EACT,SAAS,EACT,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,YAAY,GACF;IACV,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,GAAI,CAAC;IAE/C,OAAO,CACL,YACE,GAAG,EAAE,CAAC,IAAwB,EAAE,EAAE;YAChC,YAAY,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAChC,CAAC,EACD,SAAS,EAAE,KAAK,CAAC,SAAS,EAC1B,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAC3B,SAAS,kBAGP,CAAC,WAAW,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,mBAC/C,CAAC,IAAI,CAAC,UAAU,sBACb,aAAa,kBACjB,IAAI,CAAC,EAAE,oBACL,KAAK,CAAC,IAAI,CAAC,IAAI,sBACb,KAAK,CAAC,IAAI,CAAC,MAAM,qBAClB,KAAK,CAAC,IAAI,CAAC,OAAO,mBACpB,KAAK,CAAC,IAAI,CAAC,GAAG,0BACP,KAAK,CAAC,IAAI,CAAC,UAAU,EAC3C,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,SAAS,EACzC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EAC3E,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAC/D,MAAM,EAAE,SAAS,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAC7E,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAChD,cAAc,EACZ,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,EAEnF,cAAc,EACZ,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,EAEnF,aAAa,EACX,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,YAGjF,UAAU,CAAC,CAAC,CAAC,CACZ,8BACG,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAIrE,eAAM,SAAS,EAAC,oBAAoB,EAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,GAAI,IACvD,CACJ,CAAC,CAAC,CAAC,CACF,KAAK,CACN,GACC,CACL,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,EAAE,KAAK,EAAwB;IACrD,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAChE,OAAO,CACL,8BAGE,eAAM,SAAS,EAAC,kBAAkB,EAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAI,EAC3E,IAAI,IAAI,CAGP,eAAM,SAAS,EAAC,mBAAmB,EAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAI,CAC9E,EACA,IAAI,IAAI,CAKP,eAAM,SAAS,EAAC,mBAAmB,EAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAI,CAC9E,EACA,QAAQ,IAAI,CAGX,eACE,SAAS,EAAE,gDAAgD,QAAQ,CAAC,OAAO,EAAE,EAC7E,CAAC,EAAE,QAAQ,CAAC,CAAC,EACb,WAAW,EAAE,QAAQ,CAAC,WAAW,EACjC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,GACvD,CACH,EACD,eACE,SAAS,EAAC,oBAAoB,EAC9B,UAAU,EAAC,QAAQ,EACnB,gBAAgB,EAAC,SAAS,EAC1B,CAAC,EAAE,KAAK,CAAC,CAAC,EACV,CAAC,EAAE,KAAK,CAAC,CAAC,EACV,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB;;;;4CAI4B;gBAC5B,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,EAC/C,WAAW,EAAE,KAAK,CAAC,SAAS,EAC5B,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,SAAS,YAEtC,KAAK,CAAC,IAAI,GACN,EACN,UAAU,IAAI,CAEb,iBACE,SAAS,EAAC,yBAAyB,EACnC,EAAE,EAAE,UAAU,CAAC,EAAE,EACjB,EAAE,EAAE,UAAU,CAAC,EAAE,EACjB,CAAC,EAAE,UAAU,CAAC,CAAC,EACf,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,GAChC,CACH,IACA,CACJ,CAAC;AACJ,CAAC;AAED,+EAA+E;AAE/E,SAAS,cAAc,CAAC,EACtB,MAAM,EACN,MAAM,GAIP;IACC,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAErD,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;QAC3B,4EAA4E;QAC5E,uEAAuE;QACvE,6CAA6C;QAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAC3D,OAAO,CACL,YACE,SAAS,EAAE,kCAAkC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAClE,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,SAAS,YAEzC,eACE,SAAS,EAAC,uBAAuB,EACjC,UAAU,EAAC,QAAQ,EACnB,gBAAgB,EAAC,SAAS,EAC1B,CAAC,EAAE,MAAM,CAAC,OAAO,EACjB,CAAC,EAAE,MAAM,CAAC,OAAO,EACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,YAExB,MAAM,CAAC,OAAO,CAAC,KAAK,GAChB,GACL,CACL,CAAC;IACJ,CAAC;IAED,OAAO,CACL,aACE,SAAS,EAAE,kCAAkC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAClE,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,SAAS,aAExC,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAC1B,eAAM,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAI,CAC1F,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CAC3B,eACE,SAAS,EAAC,sBAAsB,EAChC,CAAC,EAAE,MAAM,CAAC,CAAC,EACX,CAAC,EAAE,MAAM,CAAC,CAAC,EACX,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EACrB,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAC3B,IAAI,EAAC,MAAM,GACX,CACH,CAAC,CAAC,CAAC,CACF,eACE,CAAC,EAAE,MAAM,CAAC,CAAC,EACX,CAAC,EAAE,MAAM,CAAC,CAAC,EACX,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,wDAAwD;gBACxD,EAAE,EAAE,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,EACnE,KAAK,EAAE,EAAE,IAAI,EAAE,GACf,CACH,EACA,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,CAC1C,eACE,SAAS,EAAC,uBAAuB,EACjC,UAAU,EAAC,QAAQ,EACnB,gBAAgB,EAAC,SAAS,EAC1B,CAAC,EAAE,MAAM,CAAC,OAAO,EACjB,CAAC,EAAE,MAAM,CAAC,OAAO,EACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EACzB,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,IAAI,SAAS,YAE5C,MAAM,CAAC,OAAO,CAAC,KAAK,GAChB,CACR,IACC,CACL,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,SAAS,SAAS,CAAC,IAAgC;IACjD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3F,CAAC;AAED,kFAAkF;AAClF,SAAS,aAAa,CAAC,IAAgC;IACrD,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5F,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { RenderSeat, SeatCardAppearance, SeatCardPlacement } from '@kerusiweb/core';
|
|
2
|
+
import type { ReactNode, RefObject } from 'react';
|
|
3
|
+
export interface SeatCardProps {
|
|
4
|
+
kind: 'hover' | 'click';
|
|
5
|
+
/** The card's `id`: a hover card is named by the seat's `aria-describedby`. */
|
|
6
|
+
id: string;
|
|
7
|
+
seat: RenderSeat;
|
|
8
|
+
/** Names a click card's dialog. */
|
|
9
|
+
label: string;
|
|
10
|
+
placement: SeatCardPlacement;
|
|
11
|
+
appearance: SeatCardAppearance;
|
|
12
|
+
className?: string;
|
|
13
|
+
/** The map's root element: the card is positioned in it and kept inside it. */
|
|
14
|
+
rootRef: RefObject<HTMLElement | null>;
|
|
15
|
+
getSeatNode: (seatId: string) => SVGGElement | null;
|
|
16
|
+
/** Moves focus into the card on mount; a click card opened from the keyboard. */
|
|
17
|
+
focusOnOpen?: boolean;
|
|
18
|
+
/** A hover card is hoverable (WCAG 1.4.13): the pointer may enter it. */
|
|
19
|
+
onPointerEnter?: () => void;
|
|
20
|
+
onPointerLeave?: () => void;
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* One seat card: a floating element anchored to a seat.
|
|
25
|
+
*
|
|
26
|
+
* It sits inside the map's root, outside the clipped viewport, so it shows in
|
|
27
|
+
* full screen and inherits the `--kerusi-*` properties set on the map. Where it
|
|
28
|
+
* goes is `placeSeatCard()`'s; this component measures the seat, the card and
|
|
29
|
+
* the root, and re-measures after every render and whenever the root or the card
|
|
30
|
+
* changes size, which is how it follows zoom, pan, maximize and full screen.
|
|
31
|
+
*
|
|
32
|
+
* It sets no colour, no padding and no font: that is the stylesheet's, and then
|
|
33
|
+
* the consumer's (D11).
|
|
34
|
+
*/
|
|
35
|
+
export declare function SeatCard({ kind, id, seat, label, placement, appearance, className, rootRef, getSeatNode, focusOnOpen, onPointerEnter, onPointerLeave, children, }: SeatCardProps): import("react").JSX.Element;
|
|
36
|
+
//# sourceMappingURL=seat-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seat-card.d.ts","sourceRoot":"","sources":["../src/seat-card.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAiB,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,iBAAiB,CAAC;IAC7B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,OAAO,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACvC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;IACpD,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,EAAE,EACF,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,SAAS,EACT,OAAO,EACP,WAAW,EACX,WAAmB,EACnB,cAAc,EACd,cAAc,EACd,QAAQ,GACT,EAAE,aAAa,+BAsHf"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cssLengthToPx, placeSeatCard, seatCardClassName, seatCardDataAttributes, } from '@kerusiweb/core';
|
|
3
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
4
|
+
const DEFAULT_OFFSET = 8;
|
|
5
|
+
const DEFAULT_ARROW = 6;
|
|
6
|
+
/**
|
|
7
|
+
* One seat card: a floating element anchored to a seat.
|
|
8
|
+
*
|
|
9
|
+
* It sits inside the map's root, outside the clipped viewport, so it shows in
|
|
10
|
+
* full screen and inherits the `--kerusi-*` properties set on the map. Where it
|
|
11
|
+
* goes is `placeSeatCard()`'s; this component measures the seat, the card and
|
|
12
|
+
* the root, and re-measures after every render and whenever the root or the card
|
|
13
|
+
* changes size, which is how it follows zoom, pan, maximize and full screen.
|
|
14
|
+
*
|
|
15
|
+
* It sets no colour, no padding and no font: that is the stylesheet's, and then
|
|
16
|
+
* the consumer's (D11).
|
|
17
|
+
*/
|
|
18
|
+
export function SeatCard({ kind, id, seat, label, placement, appearance, className, rootRef, getSeatNode, focusOnOpen = false, onPointerEnter, onPointerLeave, children, }) {
|
|
19
|
+
const cardRef = useRef(null);
|
|
20
|
+
const [position, setPosition] = useState(null);
|
|
21
|
+
/** False when the consumer set `--kerusi-seat-card-arrow-size: 0`. */
|
|
22
|
+
const [arrowShown, setArrowShown] = useState(true);
|
|
23
|
+
const measure = () => {
|
|
24
|
+
const root = rootRef.current;
|
|
25
|
+
const card = cardRef.current;
|
|
26
|
+
const seatNode = getSeatNode(seat.id);
|
|
27
|
+
if (!root || !card || !seatNode) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const rootBox = root.getBoundingClientRect();
|
|
31
|
+
const seatBox = seatNode.getBoundingClientRect();
|
|
32
|
+
// `position: absolute` is measured from the root's padding box.
|
|
33
|
+
const originX = rootBox.left + root.clientLeft;
|
|
34
|
+
const originY = rootBox.top + root.clientTop;
|
|
35
|
+
const styles = getComputedStyle(card);
|
|
36
|
+
const fontSizes = {
|
|
37
|
+
root: parseFloat(getComputedStyle(card.ownerDocument.documentElement).fontSize) || 16,
|
|
38
|
+
element: parseFloat(styles.fontSize) || 16,
|
|
39
|
+
};
|
|
40
|
+
const arrowSize = cssLengthToPx(styles.getPropertyValue('--kerusi-seat-card-arrow-size'), DEFAULT_ARROW, fontSizes);
|
|
41
|
+
setArrowShown(arrowSize > 0);
|
|
42
|
+
const next = placeSeatCard({
|
|
43
|
+
seat: {
|
|
44
|
+
x: seatBox.left - originX,
|
|
45
|
+
y: seatBox.top - originY,
|
|
46
|
+
width: seatBox.width,
|
|
47
|
+
height: seatBox.height,
|
|
48
|
+
},
|
|
49
|
+
card: { width: card.offsetWidth, height: card.offsetHeight },
|
|
50
|
+
container: { x: 0, y: 0, width: root.clientWidth, height: root.clientHeight },
|
|
51
|
+
placement,
|
|
52
|
+
offset: cssLengthToPx(styles.getPropertyValue('--kerusi-seat-card-offset'), DEFAULT_OFFSET, fontSizes),
|
|
53
|
+
arrowInset: Math.max(12, arrowSize * 2),
|
|
54
|
+
});
|
|
55
|
+
setPosition((current) => current &&
|
|
56
|
+
current.side === next.side &&
|
|
57
|
+
current.x === next.x &&
|
|
58
|
+
current.y === next.y &&
|
|
59
|
+
current.arrowOffset === next.arrowOffset
|
|
60
|
+
? current
|
|
61
|
+
: next);
|
|
62
|
+
};
|
|
63
|
+
// After every render, before paint: the card is in place when it first shows,
|
|
64
|
+
// and a zoom or pan (which re-renders the map) moves it with the seat.
|
|
65
|
+
useLayoutEffect(measure);
|
|
66
|
+
// A change the render did not announce: the root resized (maximize, full
|
|
67
|
+
// screen, a rotated phone), or the card's own content did.
|
|
68
|
+
useLayoutEffect(() => {
|
|
69
|
+
const root = rootRef.current;
|
|
70
|
+
const card = cardRef.current;
|
|
71
|
+
if (!root || !card || typeof ResizeObserver === 'undefined') {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const observer = new ResizeObserver(() => measure());
|
|
75
|
+
observer.observe(root);
|
|
76
|
+
observer.observe(card);
|
|
77
|
+
return () => observer.disconnect();
|
|
78
|
+
// `measure` closes over props that are stable for as long as the card is this seat's.
|
|
79
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
80
|
+
}, [seat.id, placement]);
|
|
81
|
+
useLayoutEffect(() => {
|
|
82
|
+
if (!focusOnOpen) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const card = cardRef.current;
|
|
86
|
+
if (!card) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const first = card.querySelector('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])');
|
|
90
|
+
(first ?? card).focus({ preventScroll: true });
|
|
91
|
+
}, [focusOnOpen, seat.id]);
|
|
92
|
+
const style = {
|
|
93
|
+
left: position?.x ?? 0,
|
|
94
|
+
top: position?.y ?? 0,
|
|
95
|
+
'--kerusi-seat-card-arrow-shift': `${position?.arrowOffset ?? 0}px`,
|
|
96
|
+
};
|
|
97
|
+
return (_jsxs("div", { ref: cardRef, id: id, className: seatCardClassName(kind, appearance, className), role: kind === 'hover' ? 'tooltip' : 'dialog', "aria-label": kind === 'click' ? label : undefined, tabIndex: kind === 'click' ? -1 : undefined, "data-placement": position?.side ?? (placement === 'auto' ? 'top' : placement), ...seatCardDataAttributes(seat), style: style, onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: [_jsx("div", { className: "kerusi-seat-card__body", children: children }), appearance === 'none' || !arrowShown ? null : (_jsx("span", { className: "kerusi-seat-card__arrow", "aria-hidden": "true" }))] }));
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=seat-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seat-card.js","sourceRoot":"","sources":["../src/seat-card.tsx"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DisallowedReason, KerusiControlStrings, KerusiMap, KerusiSeatContext, KerusiSeatmapColors, KerusiSession, KerusiState, KerusiViewport, KerusiViolation, RenderSeat, SeatAriaStrings, SeatRenderStatus, SeatStyleFn, SeatTypeStyles, SelectionSummary } from '@kerusiweb/core';
|
|
1
|
+
import type { DisallowedReason, HoverCardDelay, KerusiControlStrings, KerusiMap, KerusiSeatCardContext, KerusiSeatContext, KerusiSeatmapColors, KerusiSession, KerusiState, KerusiViewport, KerusiViolation, RenderSeat, SeatAriaStrings, SeatCardAppearance, SeatCardPlacement, SeatClick, SeatRenderStatus, SeatStyleFn, SeatTypeStyles, SelectionSummary } from '@kerusiweb/core';
|
|
2
2
|
import type { CSSProperties, ReactNode } from 'react';
|
|
3
3
|
/** How a document with validation errors is handled. */
|
|
4
4
|
export type ValidationMode =
|
|
@@ -44,6 +44,15 @@ export interface KerusiSeatmapHandle {
|
|
|
44
44
|
readonly summary: SelectionSummary;
|
|
45
45
|
/** Moves DOM focus to a seat, if it is rendered. */
|
|
46
46
|
focusSeat(seatId: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Opens the click card for a seat, for example from a search result. No-op
|
|
49
|
+
* without `renderClickCard`, or for a seat that is not rendered.
|
|
50
|
+
*/
|
|
51
|
+
openSeatCard(seatId: string): void;
|
|
52
|
+
/** Closes the click card. */
|
|
53
|
+
closeSeatCard(): void;
|
|
54
|
+
/** The seat whose click card is showing, or `null`. */
|
|
55
|
+
readonly openSeatCardId: string | null;
|
|
47
56
|
/** The current zoom and pan. Fit (`{ zoom: 1, x: 0, y: 0 }`) unless `zoomable`. */
|
|
48
57
|
readonly viewport: KerusiViewport;
|
|
49
58
|
/** Zooms in one step about the centre. No-op unless `zoomable`. */
|
|
@@ -135,7 +144,11 @@ export interface KerusiSeatmapProps {
|
|
|
135
144
|
* Memoize it — an inline arrow rebuilds the whole render model every render.
|
|
136
145
|
*/
|
|
137
146
|
seatSelectable?: (seat: RenderSeat) => boolean;
|
|
138
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* `false` turns selection off. Seats still take clicks, and stay
|
|
149
|
+
* keyboard-reachable, while `onSeatClick` or `renderClickCard` is set (D14).
|
|
150
|
+
* With neither set, a read-only map has no pointer or keyboard interaction.
|
|
151
|
+
*/
|
|
139
152
|
interactive?: boolean;
|
|
140
153
|
/**
|
|
141
154
|
* Revert a lapsed `holdExpires` to available on a ticker (§5.1). Off by
|
|
@@ -163,11 +176,61 @@ export interface KerusiSeatmapProps {
|
|
|
163
176
|
* Memoize it — a new object each render rebuilds the controls' strings.
|
|
164
177
|
*/
|
|
165
178
|
controlStrings?: Partial<KerusiControlStrings>;
|
|
179
|
+
/**
|
|
180
|
+
* Shown while a seat is hovered, anchored to it. Return `null` for no card on
|
|
181
|
+
* this seat. Never shown for touch. With neither card function set, nothing is
|
|
182
|
+
* rendered and the markup is unchanged (D10).
|
|
183
|
+
*
|
|
184
|
+
* A hover card is pointer-only unless `hoverCardOnFocus` is set, so it must not
|
|
185
|
+
* be the only place important information lives.
|
|
186
|
+
*/
|
|
187
|
+
renderHoverCard?: (ctx: KerusiSeatCardContext) => ReactNode;
|
|
188
|
+
/**
|
|
189
|
+
* Opened by a click, tap or Enter/Space on a seat, anchored to it. It stays
|
|
190
|
+
* open until dismissed: `Escape`, a press outside, a second click on the same
|
|
191
|
+
* seat, `ctx.close()`, or another seat's click card opening. Return `null` for
|
|
192
|
+
* no card on this seat.
|
|
193
|
+
*
|
|
194
|
+
* A click on a selectable seat still toggles it. To show details without
|
|
195
|
+
* selecting, turn selection off with `interactive={false}`,
|
|
196
|
+
* `selectableStatuses={[]}` or `seatSelectable`.
|
|
197
|
+
*/
|
|
198
|
+
renderClickCard?: (ctx: KerusiSeatCardContext) => ReactNode;
|
|
199
|
+
/** The side a card prefers; it flips when it would overflow the map. Default `top`. */
|
|
200
|
+
seatCardPlacement?: SeatCardPlacement;
|
|
201
|
+
/** Extra classes on the card element, for Tailwind or a design-system class (D11). */
|
|
202
|
+
seatCardClassName?: string;
|
|
203
|
+
/**
|
|
204
|
+
* `none` drops the card's background, border, padding, shadow and arrow,
|
|
205
|
+
* leaving only positioning, so your content is the card (D11). Default `default`.
|
|
206
|
+
*/
|
|
207
|
+
seatCardAppearance?: SeatCardAppearance;
|
|
208
|
+
/** Milliseconds before a hover card opens and closes. Default `{ open: 150, close: 100 }`. */
|
|
209
|
+
hoverCardDelay?: Partial<HoverCardDelay>;
|
|
210
|
+
/**
|
|
211
|
+
* Also show the hover card when a seat takes keyboard focus (D12). Default
|
|
212
|
+
* `false`. Setting it makes seats keyboard-reachable even on a read-only map.
|
|
213
|
+
*/
|
|
214
|
+
hoverCardOnFocus?: boolean;
|
|
166
215
|
validate?: ValidationMode;
|
|
167
216
|
onSeatSelect?: (event: SeatInteraction) => void;
|
|
168
217
|
onSeatDeselect?: (event: SeatInteraction) => void;
|
|
169
218
|
onSeatDisallowed?: (event: SeatDisallowed) => void;
|
|
170
219
|
onSeatFocus?: (seat: RenderSeat) => void;
|
|
220
|
+
/**
|
|
221
|
+
* The seat under the pointer when it enters a seat, and `null` when it leaves
|
|
222
|
+
* the seat or the map. Not repeated while the pointer moves within a seat.
|
|
223
|
+
* Pointer devices only (mouse and pen), never during a pan or zoom, and
|
|
224
|
+
* unaffected by `interactive` (D10).
|
|
225
|
+
*/
|
|
226
|
+
onSeatHover?: (seat: RenderSeat | null) => void;
|
|
227
|
+
/**
|
|
228
|
+
* Every activation of any seat, whether or not it can be selected: booked,
|
|
229
|
+
* held and blocked seats included. Fires before the selection callbacks, with
|
|
230
|
+
* `selected` as it was before the click. A read-only notification: it cannot
|
|
231
|
+
* cancel or change what the click does (D13).
|
|
232
|
+
*/
|
|
233
|
+
onSeatClick?: (event: SeatClick) => void;
|
|
171
234
|
/** Called whenever the documents change, unless `validate` is `off`. */
|
|
172
235
|
onValidationIssues?: (issues: readonly KerusiViolation[]) => void;
|
|
173
236
|
/** The zoom and pan, whenever they change. For a host that persists or shows them. */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,SAAS,EACT,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,EACb,WAAW,EACX,cAAc,EACd,eAAe,EACf,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,gBAAgB,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD,wDAAwD;AACxD,MAAM,MAAM,cAAc;AACxB,0EAA0E;AACxE,SAAS;AACX,4EAA4E;GAC1E,OAAO;AACT,mEAAmE;GACjE,KAAK,CAAC;AAEV,8DAA8D;AAC9D,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,sCAAsC;IACtC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,mEAAmE;IACnE,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D;;;OAGG;IACH,cAAc,EAAE,SAAS,CAAC;CAC3B;AAED,iDAAiD;AACjD,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,oDAAoD;IACpD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,6BAA6B;IAC7B,aAAa,IAAI,IAAI,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,mEAAmE;IACnE,MAAM,IAAI,IAAI,CAAC;IACf,oEAAoE;IACpE,OAAO,IAAI,IAAI,CAAC;IAChB,2EAA2E;IAC3E,SAAS,IAAI,IAAI,CAAC;IAClB;;;;OAIG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,qEAAqE;IACrE,eAAe,IAAI,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAGjC,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,aAAa,CAAC;IAIxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IAI3D,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,GAAG,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,eAAe,CAAC;IAI9B,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;OAGG;IACH,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,SAAS,CAAC;IACnD;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAI3B,mFAAmF;IACnF,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAIlE,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC;IAC/C;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAI1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2EAA2E;IAC3E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAI/C;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,SAAS,CAAC;IAC5D;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,SAAS,CAAC;IAC5D,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,8FAA8F;IAC9F,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAI3B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAI1B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAChD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACnD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACzC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,KAAK,IAAI,CAAC;IAClE,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;IACtD,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IAIjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { HoverCardDelay, KerusiSeatCardContext, RenderMap, RenderSeat, SeatAriaStrings, SeatCardAppearance, SeatCardPlacement, SeatClickSource } from '@kerusiweb/core';
|
|
2
|
+
import type { ReactNode, RefObject } from 'react';
|
|
3
|
+
export interface UseSeatCardsOptions {
|
|
4
|
+
rootRef: RefObject<HTMLElement | null>;
|
|
5
|
+
renderMap: RenderMap;
|
|
6
|
+
selection: ReadonlySet<string>;
|
|
7
|
+
locale: string;
|
|
8
|
+
ariaStrings: SeatAriaStrings;
|
|
9
|
+
getSeatNode: (seatId: string) => SVGGElement | null;
|
|
10
|
+
focusSeat: (seatId: string) => void;
|
|
11
|
+
onSeatHover?: (seat: RenderSeat | null) => void;
|
|
12
|
+
renderHoverCard?: (ctx: KerusiSeatCardContext) => ReactNode;
|
|
13
|
+
renderClickCard?: (ctx: KerusiSeatCardContext) => ReactNode;
|
|
14
|
+
placement: SeatCardPlacement;
|
|
15
|
+
className?: string;
|
|
16
|
+
appearance: SeatCardAppearance;
|
|
17
|
+
hoverCardDelay?: Partial<HoverCardDelay>;
|
|
18
|
+
hoverCardOnFocus: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface SeatCards {
|
|
21
|
+
/** Whether seats need pointer listeners at all. */
|
|
22
|
+
tracksPointer: boolean;
|
|
23
|
+
/** Whether seats need focus and blur listeners for a hover card (D12). */
|
|
24
|
+
tracksFocus: boolean;
|
|
25
|
+
/** A click behaviour is configured: `onSeatClick` or a click card (D14). */
|
|
26
|
+
pointer(type: 'enter' | 'leave' | 'move', seatId: string, pointerType: string): void;
|
|
27
|
+
focus(seatId: string): void;
|
|
28
|
+
blur(seatId: string): void;
|
|
29
|
+
/** A pan, pinch or wheel zoom began. */
|
|
30
|
+
gesture(): void;
|
|
31
|
+
/** Opens or closes the click card for an activated seat. */
|
|
32
|
+
activate(seatId: string, source: SeatClickSource): void;
|
|
33
|
+
/** Closes what is open, hover card first. True if a card was showing. */
|
|
34
|
+
dismiss(): boolean;
|
|
35
|
+
openSeatCard(seatId: string): void;
|
|
36
|
+
closeSeatCard(): void;
|
|
37
|
+
/** The seat whose click card is showing. */
|
|
38
|
+
openSeatCardId: string | null;
|
|
39
|
+
/** The seat → card `id` link, for the seat showing a hover card. */
|
|
40
|
+
describedBy: {
|
|
41
|
+
seatId: string;
|
|
42
|
+
id: string;
|
|
43
|
+
} | null;
|
|
44
|
+
/** Both cards, as elements to render inside the map's root. */
|
|
45
|
+
elements: ReactNode;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Seat hover events and the two seat cards (D10).
|
|
49
|
+
*
|
|
50
|
+
* The rules are core's: `reduceSeatHover()` decides what a pointer, a key or a
|
|
51
|
+
* timer means, and `placeSeatCard()` where a card goes. This hook holds the
|
|
52
|
+
* state, runs the one timer the reducer asks for, and renders the cards.
|
|
53
|
+
*/
|
|
54
|
+
export declare function useSeatCards(options: UseSeatCardsOptions): SeatCards;
|
|
55
|
+
//# sourceMappingURL=use-seat-cards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-seat-cards.d.ts","sourceRoot":"","sources":["../src/use-seat-cards.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,SAAS,EACT,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EAGhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGlD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACvC,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,eAAe,CAAC;IAC7B,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;IACpD,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,SAAS,CAAC;IAC5D,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,SAAS,CAAC;IAC5D,SAAS,EAAE,iBAAiB,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,mDAAmD;IACnD,aAAa,EAAE,OAAO,CAAC;IACvB,0EAA0E;IAC1E,WAAW,EAAE,OAAO,CAAC;IACrB,4EAA4E;IAC5E,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACrF,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,wCAAwC;IACxC,OAAO,IAAI,IAAI,CAAC;IAChB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IACxD,yEAAyE;IACzE,OAAO,IAAI,OAAO,CAAC;IACnB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,aAAa,IAAI,IAAI,CAAC;IACtB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,oEAAoE;IACpE,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACnD,+DAA+D;IAC/D,QAAQ,EAAE,SAAS,CAAC;CACrB;AAUD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,SAAS,CAiSpE"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IDLE_SEAT_HOVER, reduceSeatHover, resolveHoverCardDelay, seatAriaLabel, seatCardId, } from '@kerusiweb/core';
|
|
3
|
+
import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { SeatCard } from './seat-card.js';
|
|
5
|
+
/** `null`, `undefined`, `false`, `true`, `''` and `[]` draw nothing. */
|
|
6
|
+
function isEmptyContent(node) {
|
|
7
|
+
if (node === null || node === undefined || typeof node === 'boolean' || node === '') {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
return Array.isArray(node) && node.every(isEmptyContent);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Seat hover events and the two seat cards (D10).
|
|
14
|
+
*
|
|
15
|
+
* The rules are core's: `reduceSeatHover()` decides what a pointer, a key or a
|
|
16
|
+
* timer means, and `placeSeatCard()` where a card goes. This hook holds the
|
|
17
|
+
* state, runs the one timer the reducer asks for, and renders the cards.
|
|
18
|
+
*/
|
|
19
|
+
export function useSeatCards(options) {
|
|
20
|
+
const { rootRef, renderMap, selection, locale, ariaStrings, getSeatNode, focusSeat, renderHoverCard, renderClickCard, placement, className, appearance, hoverCardOnFocus, } = options;
|
|
21
|
+
const prefix = useId();
|
|
22
|
+
const delayOpen = options.hoverCardDelay?.open;
|
|
23
|
+
const delayClose = options.hoverCardDelay?.close;
|
|
24
|
+
const delay = useMemo(() => resolveHoverCardDelay({ open: delayOpen, close: delayClose }), [delayOpen, delayClose]);
|
|
25
|
+
// The latest of everything the long-lived callbacks read.
|
|
26
|
+
const live = useRef({ renderMap, delay, onSeatHover: options.onSeatHover });
|
|
27
|
+
live.current = { renderMap, delay, onSeatHover: options.onSeatHover };
|
|
28
|
+
// --- hover ----------------------------------------------------------------
|
|
29
|
+
const [hover, setHover] = useState(IDLE_SEAT_HOVER);
|
|
30
|
+
const hoverRef = useRef(IDLE_SEAT_HOVER);
|
|
31
|
+
const timer = useRef(undefined);
|
|
32
|
+
const feed = useCallback((event) => {
|
|
33
|
+
const result = reduceSeatHover(hoverRef.current, event, live.current.delay);
|
|
34
|
+
hoverRef.current = result.state;
|
|
35
|
+
setHover(result.state);
|
|
36
|
+
if (result.timer) {
|
|
37
|
+
clearTimeout(timer.current);
|
|
38
|
+
timer.current = undefined;
|
|
39
|
+
if (result.timer.action === 'start') {
|
|
40
|
+
const { kind, ms } = result.timer;
|
|
41
|
+
timer.current = setTimeout(() => feed({ type: 'timer', kind }), ms);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (result.report) {
|
|
45
|
+
const { seatId } = result.report;
|
|
46
|
+
const seat = seatId === null ? null : (live.current.renderMap.seatsById.get(seatId) ?? null);
|
|
47
|
+
if (seatId === null || seat) {
|
|
48
|
+
live.current.onSeatHover?.(seat);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}, []);
|
|
52
|
+
useEffect(() => () => clearTimeout(timer.current), []);
|
|
53
|
+
const tracksPointer = !!options.onSeatHover || !!renderHoverCard;
|
|
54
|
+
const tracksFocus = hoverCardOnFocus && !!renderHoverCard;
|
|
55
|
+
const pointer = useCallback((type, seatId, pointerType) => feed({ type, seatId, pointerType }), [feed]);
|
|
56
|
+
const focus = useCallback((seatId) => feed({ type: 'focus', seatId }), [feed]);
|
|
57
|
+
const blur = useCallback((seatId) => feed({ type: 'blur', seatId }), [feed]);
|
|
58
|
+
const gesture = useCallback(() => feed({ type: 'gesture' }), [feed]);
|
|
59
|
+
// --- click ----------------------------------------------------------------
|
|
60
|
+
const [clickId, setClickId] = useState(null);
|
|
61
|
+
const clickRef = useRef(null);
|
|
62
|
+
clickRef.current = clickId;
|
|
63
|
+
/** Set when the card is opened from the keyboard, so focus moves into it. */
|
|
64
|
+
const [clickFromKeyboard, setClickFromKeyboard] = useState(false);
|
|
65
|
+
/**
|
|
66
|
+
* Closes the click card. Focus goes back to the seat only when it was inside
|
|
67
|
+
* the card, so a press elsewhere on the page keeps the focus it just took.
|
|
68
|
+
*/
|
|
69
|
+
const closeClick = useCallback((restoreFocus) => {
|
|
70
|
+
const current = clickRef.current;
|
|
71
|
+
if (current !== null && restoreFocus) {
|
|
72
|
+
const card = rootRef.current?.querySelector('.kerusi-seat-card--click');
|
|
73
|
+
if (card?.contains(card.ownerDocument.activeElement)) {
|
|
74
|
+
// After the card is gone, so nothing fights the focus move.
|
|
75
|
+
queueMicrotask(() => focusSeat(current));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
setClickId(null);
|
|
79
|
+
setClickFromKeyboard(false);
|
|
80
|
+
}, [rootRef, focusSeat]);
|
|
81
|
+
const activate = useCallback((seatId, source) => {
|
|
82
|
+
if (!renderClickCard) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (clickId === seatId) {
|
|
86
|
+
closeClick(true);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
setClickId(seatId);
|
|
90
|
+
setClickFromKeyboard(source === 'keyboard');
|
|
91
|
+
}, [renderClickCard, clickId, closeClick]);
|
|
92
|
+
const openSeatCard = useCallback((seatId) => {
|
|
93
|
+
if (renderClickCard && live.current.renderMap.seatsById.has(seatId)) {
|
|
94
|
+
setClickId(seatId);
|
|
95
|
+
setClickFromKeyboard(false);
|
|
96
|
+
}
|
|
97
|
+
}, [renderClickCard]);
|
|
98
|
+
const closeSeatCard = useCallback(() => closeClick(true), [closeClick]);
|
|
99
|
+
// --- what is showing ------------------------------------------------------
|
|
100
|
+
const clickSeat = clickId ? renderMap.seatsById.get(clickId) : undefined;
|
|
101
|
+
const hoverSeat = hover.cardId ? renderMap.seatsById.get(hover.cardId) : undefined;
|
|
102
|
+
const contextFor = (seat, trigger, close) => ({ seat, selected: selection.has(seat.id), trigger, close });
|
|
103
|
+
const clickContent = renderClickCard && clickSeat
|
|
104
|
+
? renderClickCard(contextFor(clickSeat, 'click', () => closeClick(true)))
|
|
105
|
+
: null;
|
|
106
|
+
const clickShowing = clickSeat !== undefined && !isEmptyContent(clickContent);
|
|
107
|
+
// A click card open for a seat hides that seat's hover card.
|
|
108
|
+
const hoverContent = renderHoverCard && hoverSeat && hoverSeat.id !== clickId
|
|
109
|
+
? renderHoverCard(contextFor(hoverSeat, hover.cardTrigger === 'focus' ? 'focus' : 'hover', () => feed({ type: 'escape' })))
|
|
110
|
+
: null;
|
|
111
|
+
const hoverShowing = hoverSeat !== undefined && !isEmptyContent(hoverContent);
|
|
112
|
+
// A seat that goes away (a hidden section, a new map) takes its cards with it.
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (clickId !== null && !renderMap.seatsById.has(clickId)) {
|
|
115
|
+
closeClick(false);
|
|
116
|
+
}
|
|
117
|
+
if (hover.cardId !== null && !renderMap.seatsById.has(hover.cardId)) {
|
|
118
|
+
feed({ type: 'reset' });
|
|
119
|
+
}
|
|
120
|
+
}, [renderMap, clickId, hover.cardId, closeClick, feed]);
|
|
121
|
+
// A card whose render function is taken away has nothing to show.
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
if (!renderClickCard && clickId !== null) {
|
|
124
|
+
closeClick(false);
|
|
125
|
+
}
|
|
126
|
+
}, [renderClickCard, clickId, closeClick]);
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
if (!tracksPointer && hoverRef.current !== IDLE_SEAT_HOVER) {
|
|
129
|
+
feed({ type: 'reset' });
|
|
130
|
+
}
|
|
131
|
+
}, [tracksPointer, feed]);
|
|
132
|
+
const dismiss = useCallback(() => {
|
|
133
|
+
if (clickId !== null) {
|
|
134
|
+
closeClick(true);
|
|
135
|
+
return clickShowing;
|
|
136
|
+
}
|
|
137
|
+
if (hoverRef.current.cardId !== null || hoverRef.current.pendingId !== null) {
|
|
138
|
+
feed({ type: 'escape' });
|
|
139
|
+
return hoverShowing;
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}, [clickId, clickShowing, hoverShowing, closeClick, feed]);
|
|
143
|
+
const anyOpen = clickId !== null || hover.cardId !== null;
|
|
144
|
+
// Escape anywhere dismisses a card, including with focus outside the map: a
|
|
145
|
+
// hover card the pointer opened must be dismissible without moving it (WCAG
|
|
146
|
+
// 1.4.13). The map's own key handling runs first and marks the event handled.
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
if (!anyOpen) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const doc = rootRef.current?.ownerDocument ?? document;
|
|
152
|
+
const onKeyDown = (event) => {
|
|
153
|
+
if (event.key === 'Escape' && !event.defaultPrevented && dismiss()) {
|
|
154
|
+
event.preventDefault();
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
doc.addEventListener('keydown', onKeyDown);
|
|
158
|
+
return () => doc.removeEventListener('keydown', onKeyDown);
|
|
159
|
+
}, [anyOpen, dismiss, rootRef]);
|
|
160
|
+
// A press outside the click card and outside every seat closes it. A press on
|
|
161
|
+
// a seat is that seat's own click, which opens or closes a card by itself.
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
if (clickId === null) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const doc = rootRef.current?.ownerDocument ?? document;
|
|
167
|
+
const onPointerDown = (event) => {
|
|
168
|
+
const target = event.target;
|
|
169
|
+
const root = rootRef.current;
|
|
170
|
+
if (!target || !root) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const inCard = target.closest?.('.kerusi-seat-card--click');
|
|
174
|
+
const onSeat = root.contains(target) && target.closest?.('[data-seat-id]');
|
|
175
|
+
if (!inCard && !onSeat) {
|
|
176
|
+
closeClick(false);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
doc.addEventListener('pointerdown', onPointerDown, true);
|
|
180
|
+
return () => doc.removeEventListener('pointerdown', onPointerDown, true);
|
|
181
|
+
}, [clickId, closeClick, rootRef]);
|
|
182
|
+
// --- render ---------------------------------------------------------------
|
|
183
|
+
const hoverId = seatCardId(prefix, 'hover');
|
|
184
|
+
const clickCardId = seatCardId(prefix, 'click');
|
|
185
|
+
const elements = (_jsxs(_Fragment, { children: [hoverShowing && hoverSeat && (_jsx(SeatCard, { kind: "hover", id: hoverId, seat: hoverSeat, label: "", placement: placement, appearance: appearance, className: className, rootRef: rootRef, getSeatNode: getSeatNode, onPointerEnter: () => feed({ type: 'card-enter' }), onPointerLeave: () => feed({ type: 'card-leave' }), children: hoverContent }, `hover:${hoverSeat.id}`)), clickShowing && clickSeat && (_jsx(SeatCard, { kind: "click", id: clickCardId, seat: clickSeat, label: seatAriaLabel(clickSeat, locale, ariaStrings), placement: placement, appearance: appearance, className: className, rootRef: rootRef, getSeatNode: getSeatNode, focusOnOpen: clickFromKeyboard, children: clickContent }, `click:${clickSeat.id}`))] }));
|
|
186
|
+
return {
|
|
187
|
+
tracksPointer,
|
|
188
|
+
tracksFocus,
|
|
189
|
+
pointer,
|
|
190
|
+
focus,
|
|
191
|
+
blur,
|
|
192
|
+
gesture,
|
|
193
|
+
activate,
|
|
194
|
+
dismiss,
|
|
195
|
+
openSeatCard,
|
|
196
|
+
closeSeatCard,
|
|
197
|
+
openSeatCardId: clickShowing ? clickId : null,
|
|
198
|
+
describedBy: hoverShowing && hoverSeat ? { seatId: hoverSeat.id, id: hoverId } : null,
|
|
199
|
+
elements,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=use-seat-cards.js.map
|