@pie-players/pie-tool-line-reader 0.1.6 → 0.1.9

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/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@pie-players/pie-tool-line-reader",
3
- "version": "0.1.6",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "description": "Reading guide overlay tool for PIE assessment player",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/pie-framework/pie-players.git"
8
+ "url": "git+https://github.com/pie-framework/pie-players.git",
9
+ "directory": "packages/tool-line-reader"
9
10
  },
10
11
  "publishConfig": {
11
12
  "access": "public"
@@ -40,9 +41,9 @@
40
41
  "unpkg": "./dist/tool-line-reader.js",
41
42
  "jsdelivr": "./dist/tool-line-reader.js",
42
43
  "dependencies": {
43
- "@pie-players/pie-assessment-toolkit": "0.2.5",
44
- "@pie-players/pie-players-shared": "0.2.2",
45
- "@sveltejs/kit": "^2.52.0",
44
+ "@pie-players/pie-assessment-toolkit": "0.2.9",
45
+ "@pie-players/pie-context": "0.1.1",
46
+ "@pie-players/pie-players-shared": "0.2.5",
46
47
  "daisyui": "^5.5.18"
47
48
  },
48
49
  "types": "./dist/index.d.ts",
@@ -59,5 +60,13 @@
59
60
  "typescript": "^5.7.0",
60
61
  "vite": "^7.0.8",
61
62
  "vite-plugin-dts": "^4.5.3"
62
- }
63
+ },
64
+ "homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/tool-line-reader#readme",
65
+ "bugs": {
66
+ "url": "https://github.com/pie-framework/pie-players/issues"
67
+ },
68
+ "engines": {
69
+ "node": ">=18.0.0"
70
+ },
71
+ "sideEffects": true
63
72
  }
@@ -1,31 +1,40 @@
1
1
  <svelte:options
2
2
  customElement={{
3
3
  tag: 'pie-tool-line-reader',
4
- shadow: 'none',
4
+ shadow: 'open',
5
5
  props: {
6
6
  visible: { type: 'Boolean', attribute: 'visible' },
7
- toolId: { type: 'String', attribute: 'tool-id' },
8
- coordinator: { type: 'Object' }
7
+ toolId: { type: 'String', attribute: 'tool-id' }
9
8
  }
10
9
  }}
11
10
  />
12
11
 
13
12
  <script lang="ts">
14
13
 
15
- import type { IToolCoordinator } from '@pie-players/pie-assessment-toolkit';
16
- import { ZIndexLayer } from '@pie-players/pie-assessment-toolkit';
14
+ import {
15
+ connectToolRuntimeContext,
16
+ ZIndexLayer,
17
+ } from '@pie-players/pie-assessment-toolkit';
18
+ import type {
19
+ AssessmentToolkitRuntimeContext,
20
+ IToolCoordinator,
21
+ } from '@pie-players/pie-assessment-toolkit';
17
22
  import ToolSettingsButton from '@pie-players/pie-players-shared/components/ToolSettingsButton.svelte';
18
23
  import ToolSettingsPanel from '@pie-players/pie-players-shared/components/ToolSettingsPanel.svelte';
19
24
  import { onMount } from 'svelte';
20
25
 
21
26
  // Props
22
- let { visible = false, toolId = 'lineReader', coordinator }: { visible?: boolean; toolId?: string; coordinator?: IToolCoordinator } = $props();
27
+ let { visible = false, toolId = 'lineReader' }: { visible?: boolean; toolId?: string } = $props();
23
28
 
24
29
  // Check if running in browser
25
30
  const isBrowser = typeof window !== 'undefined';
26
31
 
27
32
  // State
28
33
  let containerEl = $state<HTMLDivElement | undefined>();
34
+ let runtimeContext = $state<AssessmentToolkitRuntimeContext | null>(null);
35
+ const coordinator = $derived(
36
+ runtimeContext?.toolCoordinator as IToolCoordinator | undefined,
37
+ );
29
38
  let settingsButtonEl = $state<HTMLButtonElement | undefined>();
30
39
  let isDragging = $state(false);
31
40
  let isResizing = $state(false);
@@ -58,6 +67,13 @@ import { onMount } from 'svelte';
58
67
  const MOVE_STEP = 10; // pixels
59
68
  const RESIZE_STEP = 10; // pixels
60
69
 
70
+ $effect(() => {
71
+ if (!containerEl) return;
72
+ return connectToolRuntimeContext(containerEl, (value: AssessmentToolkitRuntimeContext) => {
73
+ runtimeContext = value;
74
+ });
75
+ });
76
+
61
77
  function announce(message: string) {
62
78
  announceText = message;
63
79
  setTimeout(() => announceText = '', 1000);
@@ -276,7 +292,7 @@ import { onMount } from 'svelte';
276
292
 
277
293
  {#if visible}
278
294
  <!-- Screen reader announcements -->
279
- <div class="sr-only" role="status" aria-live="polite" aria-atomic="true">
295
+ <div class="pie-sr-only" role="status" aria-live="polite" aria-atomic="true">
280
296
  {announceText}
281
297
  </div>
282
298
 
@@ -284,25 +300,25 @@ import { onMount } from 'svelte';
284
300
  {#if maskingMode === 'obscure'}
285
301
  <!-- Top mask - from top of viewport to top of line reader -->
286
302
  <div
287
- class="line-reader-mask line-reader-mask-top"
303
+ class="pie-tool-line-reader__mask pie-tool-line-reader__mask--top"
288
304
  style="height: {Math.max(0, position.y - size.height / 2)}px;"
289
305
  aria-hidden="true"
290
306
  ></div>
291
307
  <!-- Bottom mask - from bottom of line reader to bottom of viewport -->
292
308
  <div
293
- class="line-reader-mask line-reader-mask-bottom"
309
+ class="pie-tool-line-reader__mask pie-tool-line-reader__mask--bottom"
294
310
  style="top: {position.y + size.height / 2}px;"
295
311
  aria-hidden="true"
296
312
  ></div>
297
313
  <!-- Left mask - left side of line reader window -->
298
314
  <div
299
- class="line-reader-mask line-reader-mask-left"
315
+ class="pie-tool-line-reader__mask pie-tool-line-reader__mask--left"
300
316
  style="top: {position.y - size.height / 2}px; height: {size.height}px; width: {Math.max(0, position.x - size.width / 2)}px;"
301
317
  aria-hidden="true"
302
318
  ></div>
303
319
  <!-- Right mask - right side of line reader window -->
304
320
  <div
305
- class="line-reader-mask line-reader-mask-right"
321
+ class="pie-tool-line-reader__mask pie-tool-line-reader__mask--right"
306
322
  style="top: {position.y - size.height / 2}px; height: {size.height}px; left: {position.x + size.width / 2}px;"
307
323
  aria-hidden="true"
308
324
  ></div>
@@ -312,8 +328,8 @@ import { onMount } from 'svelte';
312
328
  <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
313
329
  <div
314
330
  bind:this={containerEl}
315
- class="line-reader-frame"
316
- class:masking-mode={maskingMode === 'obscure'}
331
+ class="pie-tool-line-reader"
332
+ class:pie-tool-line-reader--masking-mode={maskingMode === 'obscure'}
317
333
  style="left: {position.x}px; top: {position.y}px; width: {size.width}px; height: {size.height}px;"
318
334
  onpointerdown={handlePointerDown}
319
335
  onkeydown={handleKeyDown}
@@ -322,7 +338,7 @@ import { onMount } from 'svelte';
322
338
  aria-label="Line Reader tool. Mode: {maskingMode === 'highlight' ? 'Highlight' : 'Masking'}. Use arrow keys to move, +/- to resize height, C to change color, [ and ] to adjust opacity, M to toggle mode. Current color: {colors.find(c => c.value === currentColor)?.name}, Opacity: {Math.round(currentOpacity * 100)}%"
323
339
  aria-roledescription="Draggable and resizable reading guide overlay"
324
340
  >
325
- <div class="line-reader-container" style="background-color: {backgroundColor};">
341
+ <div class="pie-tool-line-reader__container" style="background-color: {backgroundColor};">
326
342
  <!-- Settings Button -->
327
343
  <ToolSettingsButton
328
344
  bind:buttonEl={settingsButtonEl}
@@ -334,7 +350,7 @@ import { onMount } from 'svelte';
334
350
 
335
351
  <!-- Resize handle -->
336
352
  <div
337
- class="resize-handle resize-handle-bottom"
353
+ class="pie-tool-line-reader__resize-handle pie-tool-line-reader__resize-handle--bottom"
338
354
  title="Drag to resize height"
339
355
  role="button"
340
356
  tabindex="-1"
@@ -346,7 +362,7 @@ import { onMount } from 'svelte';
346
362
  </div>
347
363
  </div>
348
364
 
349
- <!-- Settings Panel - Rendered outside line-reader-frame to avoid height constraints -->
365
+ <!-- Settings Panel - Rendered outside pie-tool-line-reader to avoid height constraints -->
350
366
  <ToolSettingsPanel
351
367
  open={settingsOpen}
352
368
  title="Line Reader Settings"
@@ -425,7 +441,7 @@ import { onMount } from 'svelte';
425
441
  {/if}
426
442
 
427
443
  <style>
428
- .sr-only {
444
+ .pie-sr-only {
429
445
  position: absolute;
430
446
  width: 1px;
431
447
  height: 1px;
@@ -437,7 +453,7 @@ import { onMount } from 'svelte';
437
453
  border-width: 0;
438
454
  }
439
455
 
440
- .line-reader-frame {
456
+ .pie-tool-line-reader {
441
457
  border: 2px solid rgba(76, 175, 80, 0.8);
442
458
  cursor: move;
443
459
  overflow: visible;
@@ -448,17 +464,17 @@ import { onMount } from 'svelte';
448
464
  touch-action: none;
449
465
  }
450
466
 
451
- .line-reader-frame:focus {
467
+ .pie-tool-line-reader:focus {
452
468
  outline: 3px solid #4A90E2;
453
469
  outline-offset: 2px;
454
470
  }
455
471
 
456
- .line-reader-frame:focus-visible {
472
+ .pie-tool-line-reader:focus-visible {
457
473
  outline: 3px solid #4A90E2;
458
474
  outline-offset: 2px;
459
475
  }
460
476
 
461
- .line-reader-container {
477
+ .pie-tool-line-reader__container {
462
478
  width: 100%;
463
479
  height: 100%;
464
480
  position: relative;
@@ -466,7 +482,7 @@ import { onMount } from 'svelte';
466
482
  }
467
483
 
468
484
 
469
- .resize-handle {
485
+ .pie-tool-line-reader__resize-handle {
470
486
  position: absolute;
471
487
  cursor: ns-resize;
472
488
  z-index: 10;
@@ -475,7 +491,7 @@ import { onMount } from 'svelte';
475
491
  justify-content: center;
476
492
  }
477
493
 
478
- .resize-handle-bottom {
494
+ .pie-tool-line-reader__resize-handle--bottom {
479
495
  bottom: -10px;
480
496
  left: 50%;
481
497
  transform: translateX(-50%);
@@ -486,58 +502,58 @@ import { onMount } from 'svelte';
486
502
  border: 2px solid #4CAF50;
487
503
  }
488
504
 
489
- .resize-handle:hover {
505
+ .pie-tool-line-reader__resize-handle:hover {
490
506
  background-color: rgba(76, 175, 80, 0.2);
491
507
  }
492
508
 
493
- .resize-handle:active {
509
+ .pie-tool-line-reader__resize-handle:active {
494
510
  cursor: ns-resize;
495
511
  }
496
512
 
497
- .line-reader-frame:active {
513
+ .pie-tool-line-reader:active {
498
514
  cursor: grabbing;
499
515
  }
500
516
 
501
517
  /* Masking overlays for obscure mode - 4 rectangles covering all areas except line reader window */
502
- .line-reader-mask {
518
+ .pie-tool-line-reader__mask {
503
519
  position: fixed;
504
520
  background: rgba(0, 0, 0, 0.85);
505
521
  z-index: 999;
506
522
  pointer-events: none;
507
523
  }
508
524
 
509
- .line-reader-mask-top {
525
+ .pie-tool-line-reader__mask--top {
510
526
  top: 0;
511
527
  left: 0;
512
528
  right: 0;
513
529
  /* Height set via inline style */
514
530
  }
515
531
 
516
- .line-reader-mask-bottom {
532
+ .pie-tool-line-reader__mask--bottom {
517
533
  /* Top set via inline style */
518
534
  left: 0;
519
535
  right: 0;
520
536
  bottom: 0;
521
537
  }
522
538
 
523
- .line-reader-mask-left {
539
+ .pie-tool-line-reader__mask--left {
524
540
  /* Top, height, and width set via inline style */
525
541
  left: 0;
526
542
  }
527
543
 
528
- .line-reader-mask-right {
544
+ .pie-tool-line-reader__mask--right {
529
545
  /* Top, height, and left set via inline style */
530
546
  right: 0;
531
547
  }
532
548
 
533
549
  /* In masking mode, change the window appearance */
534
- .line-reader-frame.masking-mode {
550
+ .pie-tool-line-reader.pie-tool-line-reader--masking-mode {
535
551
  border-color: rgba(76, 175, 80, 1);
536
552
  box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.8), 0 0 20px rgba(76, 175, 80, 0.4);
537
553
  }
538
554
 
539
555
  /* In masking mode, the window should be transparent to show content underneath */
540
- .line-reader-frame.masking-mode .line-reader-container {
556
+ .pie-tool-line-reader.pie-tool-line-reader--masking-mode .pie-tool-line-reader__container {
541
557
  background-color: transparent !important;
542
558
  }
543
559