@pie-players/pie-section-player 0.3.64 → 0.3.65
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 +64 -19
- package/dist/components/shared/card-media-region.d.ts +50 -0
- package/dist/components/shared/section-player-view-state.d.ts +35 -0
- package/dist/pie-section-player.js +17093 -18705
- package/package.json +9 -9
- package/dist/chunks/defineProperty-f7fab5da.js +0 -33
- package/dist/chunks/dist-c770ad18.js +0 -213
- package/dist/chunks/dist-fed7cb49.js +0 -492
- package/dist/components/shared/section-item-media.d.ts +0 -88
package/README.md
CHANGED
|
@@ -138,6 +138,7 @@ Both layout elements support:
|
|
|
138
138
|
- `content-max-width-with-passage` (number, optional): max width in px when passages are present. Clamped to 320–2200. Unset by default (layout uses available width).
|
|
139
139
|
- `split-pane-min-region-width` (number, optional): splitpane minimum pane width in px. Clamped to 160–1200. Unset by default (split bounds stay at 20–80). (Ignored by vertical layout; supported for API parity.)
|
|
140
140
|
- `split-pane-collapse-strategy` (string, optional): splitpane stacked-mode strategy. Supported values: `tabbed` (default) and `vertical`. (Ignored by vertical/tabbed layouts; supported for API parity.)
|
|
141
|
+
- `base-heading-level` (number, optional): the heading level this player's card headings occupy, and the level every descendant's outline derives from. Clamped to 1–6; default 2. See [Heading structure](#heading-structure).
|
|
141
142
|
- `show-toolbar` (boolean-like): accepts `true/false` and common string forms (`"true"`, `"false"`, `"1"`, `"0"`, `"yes"`, `"no"`)
|
|
142
143
|
- Host extension props (JS properties only): `toolRegistry`, `sectionHostButtons`, `itemHostButtons`, `passageHostButtons`, `hooks`
|
|
143
144
|
|
|
@@ -170,6 +171,51 @@ To force splitpane stacked mode to use vertical rendering:
|
|
|
170
171
|
|
|
171
172
|
By default, splitpane stacked mode uses tabs. The dedicated `pie-section-player-tabbed` layout also always renders passage/items tabs when passages are present.
|
|
172
173
|
|
|
174
|
+
### Heading structure
|
|
175
|
+
|
|
176
|
+
The player publishes one number and every descendant derives its outline from it.
|
|
177
|
+
Set `base-heading-level` to the level the cards should occupy in the surrounding
|
|
178
|
+
page — 2 when the page has its own `<h1>` above the player, 3 when the player sits
|
|
179
|
+
under an `<h2>`, and so on:
|
|
180
|
+
|
|
181
|
+
```html
|
|
182
|
+
<pie-section-player-splitpane base-heading-level="3"></pie-section-player-splitpane>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
At the default of 2 that produces:
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
h2 Passage <- passage card heading
|
|
189
|
+
h3 Sea Turtles in Trouble <- passage title
|
|
190
|
+
h4 Danger on Land <- authored data-heading content
|
|
191
|
+
h2 Question 1 <- item card heading
|
|
192
|
+
h3 Part A <- authored data-heading content in the prompt
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The two content kinds derive different levels from the same number, and the
|
|
196
|
+
difference is deliberate. An item card's heading *is* the item's heading, so the
|
|
197
|
+
item player is told not to emit a screen-reader item heading of its own — one at
|
|
198
|
+
that level already exists, and a second would read as its sibling. A passage
|
|
199
|
+
card's heading is a group label, so the passage player is told to start one level
|
|
200
|
+
deeper, putting the passage's own title beneath it.
|
|
201
|
+
|
|
202
|
+
Authored `data-heading="headingN"` markup in passages and prompts becomes real
|
|
203
|
+
heading elements only when a level is published, which the player now always does.
|
|
204
|
+
Content authored against
|
|
205
|
+
[PIE-151](https://illuminate.atlassian.net/browse/PIE-151) therefore renders as
|
|
206
|
+
structure without any host configuration.
|
|
207
|
+
|
|
208
|
+
A host that needs the element's own screen-reader item heading — because it is not
|
|
209
|
+
supplying question headings of its own — overrides per player through the runtime:
|
|
210
|
+
|
|
211
|
+
```js
|
|
212
|
+
sectionPlayer.runtime = { player: { includeSrHeading: true } };
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The pattern behind this, and the reason the value is published rather than pushed,
|
|
216
|
+
is in
|
|
217
|
+
[`docs/architecture/composition-context.md`](../../docs/architecture/composition-context.md).
|
|
218
|
+
|
|
173
219
|
### Tab styling hooks
|
|
174
220
|
|
|
175
221
|
`pie-section-player-tabbed` and splitpane `tabbed` collapse mode expose canonical `pie-*`
|
|
@@ -234,11 +280,17 @@ than no-passage mode.
|
|
|
234
280
|
|
|
235
281
|
### Item card media region
|
|
236
282
|
|
|
237
|
-
An item card can carry a `data-region="media"` region beside its content region
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
283
|
+
An item card can carry a `data-region="media"` region beside its content region.
|
|
284
|
+
It is a host surface named `item-media`, not a feature: whatever capability
|
|
285
|
+
declares `surfaces: ['item-media']` in its registration renders there, and this
|
|
286
|
+
package names none of them. The region appears only when policy grants the
|
|
287
|
+
capability *and* the capability's own `requiresAuthoredContent` resolves, so
|
|
288
|
+
there is no dead affordance on items that carry nothing.
|
|
289
|
+
|
|
290
|
+
Today's occupant is `@pie-players/pie-tool-sign-language` — a signed (ASL)
|
|
291
|
+
translation gated on the `signLanguage` PNP support. It is not part of the
|
|
292
|
+
packaged capability set: a deployment opts in by registering it on the tool
|
|
293
|
+
registry it passes to the player.
|
|
242
294
|
|
|
243
295
|
It sits to the right of the question content and is resizable via a
|
|
244
296
|
keyboard-accessible divider (`role="separator"`; arrow keys, `Home`/`End`,
|
|
@@ -246,20 +298,13 @@ keyboard-accessible divider (`role="separator"`; arrow keys, `Home`/`End`,
|
|
|
246
298
|
the content and the divider is withdrawn. Placement is fixed in this iteration:
|
|
247
299
|
there is no orientation toggle and no free repositioning.
|
|
248
300
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
```css
|
|
258
|
-
pie-section-player-item-card {
|
|
259
|
-
--pie-section-player-item-media-aspect-ratio: 4 / 5;
|
|
260
|
-
--pie-section-player-item-media-min-height: 260px;
|
|
261
|
-
}
|
|
262
|
-
```
|
|
301
|
+
This package owns the region's share of the card width and nothing inside it. A
|
|
302
|
+
capability mounted here sizes its own content: signing legibility needs height for
|
|
303
|
+
hands and face, so it is sized by an aspect-ratio target with a height floor
|
|
304
|
+
rather than by width alone. The `--pie-section-player-item-media-*` tokens hosts
|
|
305
|
+
set for that belong to `@pie-players/pie-tool-sign-language` and are documented
|
|
306
|
+
with their defaults in [its README](../tool-sign-language/README.md) — they keep
|
|
307
|
+
the `pie-section-player` prefix because hosts already set them by those names.
|
|
263
308
|
|
|
264
309
|
### API direction: CE defaults first, JS customization for advanced cases
|
|
265
310
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The media region a content card docks an alternate into: its surface name, and
|
|
3
|
+
* how wide it is.
|
|
4
|
+
*
|
|
5
|
+
* Sizing only. Which capability fills the region, and whether it has anything to
|
|
6
|
+
* show, belongs to the capability: the card asks the registry for whatever is
|
|
7
|
+
* registered on the surface below and knows nothing else about it. The
|
|
8
|
+
* signed-alternate resolution that used to live here moved to
|
|
9
|
+
* `@pie-players/pie-tool-sign-language` behind that capability's own
|
|
10
|
+
* `requiresAuthoredContent`.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Host slot for media docked beside a card's content.
|
|
14
|
+
*
|
|
15
|
+
* Named for the relationship rather than for one card kind, because item cards
|
|
16
|
+
* and passage cards open the same slot: an alternate is authored against a
|
|
17
|
+
* content node, and a passage owns content nodes exactly as an item does. A
|
|
18
|
+
* capability declares this surface once and reaches both.
|
|
19
|
+
*/
|
|
20
|
+
export declare const CONTENT_MEDIA_SURFACE = "content-media";
|
|
21
|
+
/**
|
|
22
|
+
* Default and bounds for the media region's share of the card width.
|
|
23
|
+
*
|
|
24
|
+
* Docked media generally needs height rather than width — a person on camera
|
|
25
|
+
* needs room for hands and face — so the region is sized by an aspect-ratio
|
|
26
|
+
* target with a minimum height rather than by width alone. A flat viewport
|
|
27
|
+
* percentage either wastes space on a short clip or crushes it on a narrow
|
|
28
|
+
* device. The percentage below only decides how the card's width is split;
|
|
29
|
+
* legibility is defended by the mounted element's own CSS.
|
|
30
|
+
*/
|
|
31
|
+
export declare const MEDIA_REGION_DEFAULT_PERCENT = 34;
|
|
32
|
+
export declare const MEDIA_REGION_MIN_PERCENT = 20;
|
|
33
|
+
export declare const MEDIA_REGION_MAX_PERCENT = 55;
|
|
34
|
+
/** Below this card width the split is dropped and the region stacks. */
|
|
35
|
+
export declare const MEDIA_REGION_STACK_BREAKPOINT_PX = 560;
|
|
36
|
+
export declare function clampMediaRegionPercent(value: number, min?: number, max?: number): number;
|
|
37
|
+
/**
|
|
38
|
+
* Convert a pointer drag into a media-region width percentage.
|
|
39
|
+
*
|
|
40
|
+
* Container-relative, unlike the passage/items divider's fixed 0.1%-per-pixel
|
|
41
|
+
* factor: the same drag has to mean the same thing in a wide card and a narrow
|
|
42
|
+
* one. The region is on the right, so dragging left grows it.
|
|
43
|
+
*/
|
|
44
|
+
export declare function mediaRegionPercentFromDrag(args: {
|
|
45
|
+
startPercent: number;
|
|
46
|
+
deltaX: number;
|
|
47
|
+
containerWidthPx: number;
|
|
48
|
+
min?: number;
|
|
49
|
+
max?: number;
|
|
50
|
+
}): number;
|
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import { ItemEntity } from '@pie-players/pie-players-shared/types';
|
|
2
2
|
import { SectionCompositionModel } from '../../controllers/types.js';
|
|
3
3
|
import { PlayerElementParams } from './player-action.js';
|
|
4
|
+
/**
|
|
5
|
+
* Heading depth as composition context.
|
|
6
|
+
*
|
|
7
|
+
* Where an item's headings belong in a document outline is a fact about the
|
|
8
|
+
* page, not about the item: the same item renders under a host `<h1>` here and
|
|
9
|
+
* three levels down there. The section player is the publisher — it knows the
|
|
10
|
+
* level its own card headings occupy — and each PIE element is a resolver,
|
|
11
|
+
* reading the level off the player host and deriving the outline it emits.
|
|
12
|
+
* `docs/architecture/composition-context.md` states the pattern and its
|
|
13
|
+
* invariants.
|
|
14
|
+
*
|
|
15
|
+
* The two content kinds get different values from the same level, and the
|
|
16
|
+
* difference is not arbitrary:
|
|
17
|
+
*
|
|
18
|
+
* - An item card's heading ("Question 3") *is* the item's heading. The element
|
|
19
|
+
* must not emit a second one at that level, so it renders no screen-reader
|
|
20
|
+
* item heading and nests authored content one level below.
|
|
21
|
+
* - A passage card's heading ("Passage") is a group label. The passage's own
|
|
22
|
+
* title is real content and belongs beneath it, so the passage player's level
|
|
23
|
+
* is one deeper again.
|
|
24
|
+
*
|
|
25
|
+
* At the default this yields card `h2` -> passage title `h3` -> passage content
|
|
26
|
+
* `h4`, and question `h2` -> prompt content `h3`, which is the outline
|
|
27
|
+
* PIE-159 specifies.
|
|
28
|
+
*/
|
|
29
|
+
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
30
|
+
/** Matches the level the cards rendered at before it was configurable. */
|
|
31
|
+
export declare const DEFAULT_SECTION_BASE_HEADING_LEVEL: HeadingLevel;
|
|
32
|
+
export declare function normalizeBaseHeadingLevel(value: unknown): HeadingLevel;
|
|
33
|
+
/** Card heading fills the item's slot, so the element adds none of its own. */
|
|
34
|
+
export declare function itemHeadingContext(level: HeadingLevel): Record<string, unknown>;
|
|
35
|
+
/** Card heading is a group label; the passage's own title sits one below it. */
|
|
36
|
+
export declare function passageHeadingContext(level: HeadingLevel): Record<string, unknown>;
|
|
4
37
|
export type LayoutCompositionSnapshot = {
|
|
5
38
|
compositionModel: SectionCompositionModel;
|
|
6
39
|
passages: SectionCompositionModel["passages"];
|
|
@@ -17,6 +50,7 @@ export declare function getPassagePlayerParams(args: {
|
|
|
17
50
|
resolvedPlayerAttributes: Record<string, string>;
|
|
18
51
|
resolvedPlayerProps: Record<string, unknown>;
|
|
19
52
|
playerStrategy: string;
|
|
53
|
+
baseHeadingLevel?: HeadingLevel;
|
|
20
54
|
}): PlayerElementParams;
|
|
21
55
|
export declare function getItemPlayerParams(args: {
|
|
22
56
|
item: ItemEntity;
|
|
@@ -26,6 +60,7 @@ export declare function getItemPlayerParams(args: {
|
|
|
26
60
|
resolvedPlayerProps: Record<string, unknown>;
|
|
27
61
|
playerStrategy: string;
|
|
28
62
|
itemIndex?: number;
|
|
63
|
+
baseHeadingLevel?: HeadingLevel;
|
|
29
64
|
}): PlayerElementParams;
|
|
30
65
|
export declare function getCanonicalItemId(args: {
|
|
31
66
|
compositionModel: SectionCompositionModel;
|