@pie-players/pie-players-shared 1.0.0-beta.3 → 1.0.0-beta.4
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/dist/i18n/catalogs.d.ts +5 -0
- package/dist/i18n/catalogs.js +9 -0
- package/dist/i18n/content-language.d.ts +35 -0
- package/dist/i18n/content-language.js +51 -0
- package/dist/i18n/index.d.ts +6 -2
- package/dist/i18n/index.js +5 -2
- package/dist/i18n/language-tags.d.ts +9 -0
- package/dist/i18n/language-tags.js +21 -0
- package/dist/i18n/locale-load-error.d.ts +34 -0
- package/dist/i18n/locale-load-error.js +29 -0
- package/dist/i18n/messages/en-US.d.ts +113 -3
- package/dist/i18n/messages/en-US.js +128 -3
- package/dist/i18n/messages/nl-NL.d.ts +103 -2
- package/dist/i18n/messages/nl-NL.js +109 -8
- package/dist/i18n/provider.d.ts +20 -1
- package/dist/i18n/provider.js +71 -31
- package/dist/i18n/pseudo.d.ts +34 -0
- package/dist/i18n/pseudo.js +106 -0
- package/dist/loaders/esm-adapter.d.ts +10 -0
- package/dist/loaders/esm-adapter.js +88 -15
- package/dist/loaders/index.d.ts +1 -1
- package/dist/loaders/index.js +1 -1
- package/dist/pie/index.d.ts +1 -0
- package/dist/pie/math-rendering.d.ts +13 -1
- package/dist/pie/math-rendering.js +54 -1
- package/dist/types/index.d.ts +12 -0
- package/dist/ui/focus-trap.d.ts +12 -0
- package/dist/ui/focus-trap.js +39 -1
- package/dist/ui/overlay-containment.d.ts +13 -0
- package/dist/ui/overlay-containment.js +23 -0
- package/dist/ui/overlay-placement.d.ts +28 -0
- package/dist/ui/overlay-placement.js +17 -2
- package/package.json +4 -4
package/dist/types/index.d.ts
CHANGED
|
@@ -557,6 +557,10 @@ export interface ToolParameterMap {
|
|
|
557
557
|
pitch?: number;
|
|
558
558
|
volume?: number;
|
|
559
559
|
};
|
|
560
|
+
/** `zoom` is the lens's starting magnification, 2 meaning twice the size. */
|
|
561
|
+
magnification: {
|
|
562
|
+
zoom?: number;
|
|
563
|
+
};
|
|
560
564
|
}
|
|
561
565
|
/** The parameter shape of tool `K`: its {@link ToolParameterMap} entry, else open. */
|
|
562
566
|
export type ToolParametersFor<K extends string> = K extends keyof ToolParameterMap ? ToolParameterMap[K] : Record<string, unknown>;
|
|
@@ -582,6 +586,14 @@ export interface Env {
|
|
|
582
586
|
mode: PlayerMode;
|
|
583
587
|
role: PlayerRole;
|
|
584
588
|
partialScoring?: boolean;
|
|
589
|
+
/**
|
|
590
|
+
* BCP 47 tag of the language the item's content is written in, when the
|
|
591
|
+
* delivery knows it. The player reflects it onto the content subtree as
|
|
592
|
+
* `lang`/`dir`; a host that emits nothing leaves the content unstamped.
|
|
593
|
+
* The interface locale never travels here — it is the player's `locale`
|
|
594
|
+
* attribute and the `pie.interfaceLocale` context.
|
|
595
|
+
*/
|
|
596
|
+
locale?: string;
|
|
585
597
|
}
|
|
586
598
|
/** The `detail` of the `player-error` event `pie-item-player` dispatches. */
|
|
587
599
|
export interface PieItemPlayerErrorDetail {
|
package/dist/ui/focus-trap.d.ts
CHANGED
|
@@ -24,4 +24,16 @@ type FocusTrapOptions = {
|
|
|
24
24
|
* and restores prior focus when the trap is removed.
|
|
25
25
|
*/
|
|
26
26
|
export declare function createFocusTrap(container: HTMLElement, options?: FocusTrapOptions): () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Returns focus to where it was before a tool took it, for a tool that closes
|
|
29
|
+
* itself: the tool's element leaves the DOM on close, which drops focus to the
|
|
30
|
+
* document body. `capture` runs as the tool takes focus and `restore` as it
|
|
31
|
+
* closes, before its element goes.
|
|
32
|
+
*/
|
|
33
|
+
export declare function createFocusReturn(): {
|
|
34
|
+
/** Records the focused element, unless focus is already inside `container`. */
|
|
35
|
+
capture: (container: Node) => void;
|
|
36
|
+
/** Focuses the recorded element, if it is still in the document. */
|
|
37
|
+
restore: () => void;
|
|
38
|
+
};
|
|
27
39
|
export {};
|
package/dist/ui/focus-trap.js
CHANGED
|
@@ -44,7 +44,11 @@ export function createFocusTrap(container, options = {}) {
|
|
|
44
44
|
const wrap = options.wrap ?? true;
|
|
45
45
|
const onKeydown = (event) => {
|
|
46
46
|
if (event.key === "Escape") {
|
|
47
|
-
options.onEscape
|
|
47
|
+
if (!options.onEscape)
|
|
48
|
+
return;
|
|
49
|
+
// Claimed, so a page-wide Escape listener does not also act on it.
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
options.onEscape();
|
|
48
52
|
return;
|
|
49
53
|
}
|
|
50
54
|
if (event.key !== "Tab")
|
|
@@ -94,3 +98,37 @@ export function createFocusTrap(container, options = {}) {
|
|
|
94
98
|
}
|
|
95
99
|
};
|
|
96
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Returns focus to where it was before a tool took it, for a tool that closes
|
|
103
|
+
* itself: the tool's element leaves the DOM on close, which drops focus to the
|
|
104
|
+
* document body. `capture` runs as the tool takes focus and `restore` as it
|
|
105
|
+
* closes, before its element goes.
|
|
106
|
+
*/
|
|
107
|
+
export function createFocusReturn() {
|
|
108
|
+
let opener = null;
|
|
109
|
+
return {
|
|
110
|
+
capture(container) {
|
|
111
|
+
if (typeof document === "undefined")
|
|
112
|
+
return;
|
|
113
|
+
const active = getDeepActiveElement(document);
|
|
114
|
+
if (active && container.contains(active))
|
|
115
|
+
return;
|
|
116
|
+
opener =
|
|
117
|
+
active instanceof HTMLElement && active !== document.body
|
|
118
|
+
? active
|
|
119
|
+
: null;
|
|
120
|
+
},
|
|
121
|
+
restore() {
|
|
122
|
+
const target = opener;
|
|
123
|
+
opener = null;
|
|
124
|
+
if (!target?.isConnected)
|
|
125
|
+
return;
|
|
126
|
+
try {
|
|
127
|
+
target.focus();
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// ignore
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -17,6 +17,11 @@ export interface Point {
|
|
|
17
17
|
x: number;
|
|
18
18
|
y: number;
|
|
19
19
|
}
|
|
20
|
+
/** A box on screen: its top-left corner and its extent, as a `DOMRect` gives them. */
|
|
21
|
+
export interface ScreenBox extends Size {
|
|
22
|
+
left: number;
|
|
23
|
+
top: number;
|
|
24
|
+
}
|
|
20
25
|
/**
|
|
21
26
|
* The box `element` resolves its `left`/`top` against: its containing block, or
|
|
22
27
|
* the viewport when that is the initial containing block.
|
|
@@ -77,3 +82,11 @@ export declare function uprightDockCentre(box: Size, strip: Size, degrees: numbe
|
|
|
77
82
|
* where a box exceeds its block and centres on the offending axis.
|
|
78
83
|
*/
|
|
79
84
|
export declare function clampPointWithinBlock(point: Point, box: Size, block: Size, gutter?: number): Point;
|
|
85
|
+
/**
|
|
86
|
+
* The top-left corner, in viewport coordinates, of a control strip docked
|
|
87
|
+
* beside an upright `tool`: centred below it, or above it when only the space
|
|
88
|
+
* above holds the strip, and slid along the tool's edge to stay inside the
|
|
89
|
+
* block. A strip that fits on neither side takes the roomier one; a strip wider
|
|
90
|
+
* than the block centres on it.
|
|
91
|
+
*/
|
|
92
|
+
export declare function uprightDockCorner(tool: ScreenBox, strip: Size, block: ScreenBox, gap: number, gutter?: number): Point;
|
|
@@ -126,3 +126,26 @@ export function clampPointWithinBlock(point, box, block, gutter = DEFAULT_CONTAI
|
|
|
126
126
|
const offset = clampOffsetWithinBlock({ x: point.x - centre.x, y: point.y - centre.y }, box, block, gutter);
|
|
127
127
|
return { x: centre.x + offset.x, y: centre.y + offset.y };
|
|
128
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* The top-left corner, in viewport coordinates, of a control strip docked
|
|
131
|
+
* beside an upright `tool`: centred below it, or above it when only the space
|
|
132
|
+
* above holds the strip, and slid along the tool's edge to stay inside the
|
|
133
|
+
* block. A strip that fits on neither side takes the roomier one; a strip wider
|
|
134
|
+
* than the block centres on it.
|
|
135
|
+
*/
|
|
136
|
+
export function uprightDockCorner(tool, strip, block, gap, gutter = DEFAULT_CONTAINMENT_GUTTER) {
|
|
137
|
+
const top = block.top + gutter;
|
|
138
|
+
const bottom = block.top + block.height - gutter;
|
|
139
|
+
const below = tool.top + tool.height + gap;
|
|
140
|
+
const above = tool.top - gap - strip.height;
|
|
141
|
+
const roomBelow = bottom - below;
|
|
142
|
+
const roomAbove = tool.top - gap - top;
|
|
143
|
+
const y = roomBelow >= strip.height || (roomAbove < strip.height && roomBelow >= roomAbove)
|
|
144
|
+
? below
|
|
145
|
+
: above;
|
|
146
|
+
const travel = block.width - gutter * 2 - strip.width;
|
|
147
|
+
const x = travel <= 0
|
|
148
|
+
? block.left + (block.width - strip.width) / 2
|
|
149
|
+
: Math.max(block.left + gutter, Math.min(block.left + gutter + travel, tool.left + (tool.width - strip.width) / 2));
|
|
150
|
+
return { x, y };
|
|
151
|
+
}
|
|
@@ -53,6 +53,34 @@ export type OverlayPlacementNudge = keyof typeof OVERLAY_PLACEMENT_NUDGES;
|
|
|
53
53
|
export type OverlayPlacementAnnouncement = (typeof OVERLAY_PLACEMENT_NUDGES)[OverlayPlacementNudge]["announceKey"] | "toolkit.announce.rotatedTo";
|
|
54
54
|
/** The tap controls' rotations, the keyboard's two steps each way. */
|
|
55
55
|
export declare const OVERLAY_PLACEMENT_ROTATIONS: readonly [number, number, 1, 5];
|
|
56
|
+
/**
|
|
57
|
+
* What the tap controls drive: a step for each arrow, and a turn for a tool
|
|
58
|
+
* that rotates. An `OverlayPlacementController` is one; an upright tool that
|
|
59
|
+
* keeps its own position supplies `nudge` alone.
|
|
60
|
+
*/
|
|
61
|
+
export interface OverlayTapTarget {
|
|
62
|
+
nudge: (direction: OverlayPlacementNudge) => void;
|
|
63
|
+
rotateBy?: (degrees: number) => void;
|
|
64
|
+
}
|
|
65
|
+
/** A shrink-and-grow pair on the tap controls, labelled by the tool. */
|
|
66
|
+
export interface OverlaySizeControl {
|
|
67
|
+
shrink: {
|
|
68
|
+
glyph: string;
|
|
69
|
+
label: string;
|
|
70
|
+
};
|
|
71
|
+
grow: {
|
|
72
|
+
glyph: string;
|
|
73
|
+
label: string;
|
|
74
|
+
};
|
|
75
|
+
step: (direction: 1 | -1) => void;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Docks an upright tool's tap controls beside it, as `uprightDockCorner`
|
|
79
|
+
* places them. `OverlayPlacementControls` lays the controls out at the tool's
|
|
80
|
+
* top-left corner, so the offset is taken from there. A strip wider than the
|
|
81
|
+
* block wraps onto more rows, so a phone-width pane does not clip it.
|
|
82
|
+
*/
|
|
83
|
+
export declare function dockUprightControls(element: HTMLElement, controls: HTMLElement): void;
|
|
56
84
|
export interface OverlayPlacementOptions {
|
|
57
85
|
/** The tool's positioned element, which receives the transform. */
|
|
58
86
|
getElement: () => HTMLElement | undefined;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* its `style.transform`, so a drag, an arrow key and a tap control always agree
|
|
5
5
|
* about where the tool is.
|
|
6
6
|
*/
|
|
7
|
-
import { clampOffsetOverlappingBlock, resolveContainingBlockRect, rotatedExtent, rotationCentreShift, uprightDockCentre, } from "./overlay-containment.js";
|
|
7
|
+
import { clampOffsetOverlappingBlock, DEFAULT_CONTAINMENT_GUTTER, resolveContainingBlockRect, rotatedExtent, rotationCentreShift, uprightDockCentre, uprightDockCorner, } from "./overlay-containment.js";
|
|
8
8
|
import { createPointerDragController } from "./pointer-drag.js";
|
|
9
9
|
import { createPointerGesture } from "./pointer-gesture.js";
|
|
10
10
|
import { createPointerRotateController } from "./pointer-rotate.js";
|
|
@@ -60,8 +60,23 @@ const ARROW_KEYS = {
|
|
|
60
60
|
};
|
|
61
61
|
/** Pixels of the tool kept inside its containing block on each axis. */
|
|
62
62
|
const MIN_VISIBLE = 100;
|
|
63
|
-
/** Space between the tool
|
|
63
|
+
/** Space between the tool and its tap controls. */
|
|
64
64
|
const CONTROLS_GAP = 8;
|
|
65
|
+
/**
|
|
66
|
+
* Docks an upright tool's tap controls beside it, as `uprightDockCorner`
|
|
67
|
+
* places them. `OverlayPlacementControls` lays the controls out at the tool's
|
|
68
|
+
* top-left corner, so the offset is taken from there. A strip wider than the
|
|
69
|
+
* block wraps onto more rows, so a phone-width pane does not clip it.
|
|
70
|
+
*/
|
|
71
|
+
export function dockUprightControls(element, controls) {
|
|
72
|
+
const block = resolveContainingBlockRect(element);
|
|
73
|
+
if (!block)
|
|
74
|
+
return;
|
|
75
|
+
controls.style.maxWidth = `${Math.max(0, block.width - DEFAULT_CONTAINMENT_GUTTER * 2)}px`;
|
|
76
|
+
const tool = element.getBoundingClientRect();
|
|
77
|
+
const corner = uprightDockCorner(tool, { width: controls.offsetWidth, height: controls.offsetHeight }, block, CONTROLS_GAP);
|
|
78
|
+
controls.style.transform = `translate(${corner.x - tool.left - element.clientLeft}px, ${corner.y - tool.top - element.clientTop}px)`;
|
|
79
|
+
}
|
|
65
80
|
export function createOverlayPlacement(options) {
|
|
66
81
|
let placement = { x: 0, y: 0, rotation: 0 };
|
|
67
82
|
const sizeOf = (element) => ({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-players-shared",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared runtime + UI utilities for PIE players",
|
|
6
6
|
"license": "MIT",
|
|
@@ -106,9 +106,9 @@
|
|
|
106
106
|
"dist"
|
|
107
107
|
],
|
|
108
108
|
"dependencies": {
|
|
109
|
-
"@pie-element/shared-utils": "0.1.
|
|
109
|
+
"@pie-element/shared-utils": "0.1.4",
|
|
110
110
|
"@pie-lib/math-rendering-module": "6.0.0",
|
|
111
|
-
"dompurify": "^3.4.
|
|
111
|
+
"dompurify": "^3.4.17",
|
|
112
112
|
"semver": "^7.8.5"
|
|
113
113
|
},
|
|
114
114
|
"scripts": {
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
"@biomejs/biome": "^2.5.15",
|
|
126
126
|
"@happy-dom/global-registrator": "^20.14.5",
|
|
127
127
|
"@pie-element/shared-math-rendering-mathjax": "0.1.4",
|
|
128
|
-
"@playwright/test": "^1.64.
|
|
128
|
+
"@playwright/test": "^1.64.1",
|
|
129
129
|
"@types/semver": "^7.8.0",
|
|
130
130
|
"es-module-shims": "^2.8.4",
|
|
131
131
|
"esbuild": "^0.28.2",
|