@pie-players/pie-assessment-toolkit 0.2.3 → 0.2.5

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.
Files changed (100) hide show
  1. package/README.md +159 -1
  2. package/dist/index.d.ts +16 -2
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +9 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/player/AssessmentPlayer.d.ts +10 -1
  7. package/dist/player/AssessmentPlayer.d.ts.map +1 -1
  8. package/dist/player/AssessmentPlayer.js +13 -4
  9. package/dist/player/AssessmentPlayer.js.map +1 -1
  10. package/dist/services/AnnotationToolbarConfig.d.ts +134 -0
  11. package/dist/services/AnnotationToolbarConfig.d.ts.map +1 -0
  12. package/dist/services/AnnotationToolbarConfig.js +100 -0
  13. package/dist/services/AnnotationToolbarConfig.js.map +1 -0
  14. package/dist/services/HighlightCoordinator.d.ts +23 -10
  15. package/dist/services/HighlightCoordinator.d.ts.map +1 -1
  16. package/dist/services/HighlightCoordinator.js +87 -40
  17. package/dist/services/HighlightCoordinator.js.map +1 -1
  18. package/dist/services/PNPMapper.d.ts +12 -2
  19. package/dist/services/PNPMapper.d.ts.map +1 -1
  20. package/dist/services/PNPMapper.js +12 -2
  21. package/dist/services/PNPMapper.js.map +1 -1
  22. package/dist/services/PNPToolResolver.d.ts +171 -15
  23. package/dist/services/PNPToolResolver.d.ts.map +1 -1
  24. package/dist/services/PNPToolResolver.js +324 -32
  25. package/dist/services/PNPToolResolver.js.map +1 -1
  26. package/dist/services/RangeSerializer.d.ts +119 -0
  27. package/dist/services/RangeSerializer.d.ts.map +1 -0
  28. package/dist/services/RangeSerializer.js +199 -0
  29. package/dist/services/RangeSerializer.js.map +1 -0
  30. package/dist/services/TTSService.d.ts +4 -1
  31. package/dist/services/TTSService.d.ts.map +1 -1
  32. package/dist/services/TTSService.js +58 -3
  33. package/dist/services/TTSService.js.map +1 -1
  34. package/dist/services/ToolRegistry.d.ts +225 -0
  35. package/dist/services/ToolRegistry.d.ts.map +1 -0
  36. package/dist/services/ToolRegistry.js +248 -0
  37. package/dist/services/ToolRegistry.js.map +1 -0
  38. package/dist/services/ToolkitCoordinator.d.ts +22 -0
  39. package/dist/services/ToolkitCoordinator.d.ts.map +1 -1
  40. package/dist/services/ToolkitCoordinator.js +44 -0
  41. package/dist/services/ToolkitCoordinator.js.map +1 -1
  42. package/dist/services/createDefaultToolRegistry.d.ts +72 -0
  43. package/dist/services/createDefaultToolRegistry.d.ts.map +1 -0
  44. package/dist/services/createDefaultToolRegistry.js +147 -0
  45. package/dist/services/createDefaultToolRegistry.js.map +1 -0
  46. package/dist/services/interfaces.d.ts +8 -0
  47. package/dist/services/interfaces.d.ts.map +1 -1
  48. package/dist/services/interfaces.js.map +1 -1
  49. package/dist/services/pnp-provenance.d.ts +167 -0
  50. package/dist/services/pnp-provenance.d.ts.map +1 -0
  51. package/dist/services/pnp-provenance.js +230 -0
  52. package/dist/services/pnp-provenance.js.map +1 -0
  53. package/dist/services/pnp-standard-features.d.ts +240 -0
  54. package/dist/services/pnp-standard-features.d.ts.map +1 -0
  55. package/dist/services/pnp-standard-features.js +342 -0
  56. package/dist/services/pnp-standard-features.js.map +1 -0
  57. package/dist/services/tool-context.d.ts +150 -0
  58. package/dist/services/tool-context.d.ts.map +1 -0
  59. package/dist/services/tool-context.js +157 -0
  60. package/dist/services/tool-context.js.map +1 -0
  61. package/dist/services/tool-providers/ToolProviderRegistry.d.ts.map +1 -1
  62. package/dist/services/tool-providers/ToolProviderRegistry.js +7 -7
  63. package/dist/services/tool-providers/ToolProviderRegistry.js.map +1 -1
  64. package/dist/tools/registrations/accessibility-tools.d.ts +43 -0
  65. package/dist/tools/registrations/accessibility-tools.d.ts.map +1 -0
  66. package/dist/tools/registrations/accessibility-tools.js +230 -0
  67. package/dist/tools/registrations/accessibility-tools.js.map +1 -0
  68. package/dist/tools/registrations/calculator.d.ts +21 -0
  69. package/dist/tools/registrations/calculator.d.ts.map +1 -0
  70. package/dist/tools/registrations/calculator.js +98 -0
  71. package/dist/tools/registrations/calculator.js.map +1 -0
  72. package/dist/tools/registrations/interaction-tools.d.ts +28 -0
  73. package/dist/tools/registrations/interaction-tools.d.ts.map +1 -0
  74. package/dist/tools/registrations/interaction-tools.js +124 -0
  75. package/dist/tools/registrations/interaction-tools.js.map +1 -0
  76. package/dist/tools/registrations/measurement-tools.d.ts +25 -0
  77. package/dist/tools/registrations/measurement-tools.d.ts.map +1 -0
  78. package/dist/tools/registrations/measurement-tools.js +112 -0
  79. package/dist/tools/registrations/measurement-tools.js.map +1 -0
  80. package/dist/tools/registrations/subject-specific-tools.d.ts +28 -0
  81. package/dist/tools/registrations/subject-specific-tools.d.ts.map +1 -0
  82. package/dist/tools/registrations/subject-specific-tools.js +118 -0
  83. package/dist/tools/registrations/subject-specific-tools.js.map +1 -0
  84. package/dist/tools/registrations/tts.d.ts +20 -0
  85. package/dist/tools/registrations/tts.d.ts.map +1 -0
  86. package/dist/tools/registrations/tts.js +86 -0
  87. package/dist/tools/registrations/tts.js.map +1 -0
  88. package/dist/tools/tool-tag-map.d.ts +24 -0
  89. package/dist/tools/tool-tag-map.d.ts.map +1 -0
  90. package/dist/tools/tool-tag-map.js +38 -0
  91. package/dist/tools/tool-tag-map.js.map +1 -0
  92. package/package.json +25 -7
  93. package/src/README.md +25 -11
  94. package/src/components/PNPProfileTester.example.svelte +188 -0
  95. package/src/components/PNPProfileTester.svelte +397 -0
  96. package/src/components/PNPProvenanceViewer.svelte +260 -0
  97. package/src/components/QuestionToolBar.svelte +160 -83
  98. package/src/components/ToolButton.svelte +146 -0
  99. package/src/components/ToolButtonGroup.svelte +109 -0
  100. package/src/reference-layout/ReferenceLayout.svelte +5 -13
@@ -0,0 +1,146 @@
1
+ <script lang="ts">
2
+ /**
3
+ * ToolButton
4
+ *
5
+ * Generic button component for rendering tool buttons in toolbars.
6
+ * Uses ToolButtonDefinition from ToolRegistry for consistent tool button rendering.
7
+ */
8
+
9
+ import type { ToolButtonDefinition } from "../services/ToolRegistry";
10
+
11
+ // Props
12
+ let {
13
+ button,
14
+ class: className = "",
15
+ }: {
16
+ button: ToolButtonDefinition;
17
+ class?: string;
18
+ } = $props();
19
+
20
+ // Handle button click
21
+ function handleClick() {
22
+ if (!button.disabled && button.onClick) {
23
+ button.onClick();
24
+ }
25
+ }
26
+
27
+ // Derive button classes
28
+ const buttonClasses = $derived(
29
+ [
30
+ "tool-button",
31
+ button.className,
32
+ className,
33
+ button.disabled ? "tool-button--disabled" : "",
34
+ ]
35
+ .filter(Boolean)
36
+ .join(" "),
37
+ );
38
+ </script>
39
+
40
+ <button
41
+ type="button"
42
+ class={buttonClasses}
43
+ disabled={button.disabled}
44
+ aria-label={button.ariaLabel}
45
+ title={button.tooltip || button.label}
46
+ onclick={handleClick}
47
+ data-tool-id={button.toolId}
48
+ >
49
+ {#if button.icon}
50
+ <span class="tool-button__icon" aria-hidden="true">
51
+ {#if button.icon.startsWith("<svg")}
52
+ <!-- Inline SVG -->
53
+ {@html button.icon}
54
+ {:else if button.icon.startsWith("http")}
55
+ <!-- External image URL -->
56
+ <img src={button.icon} alt="" />
57
+ {:else}
58
+ <!-- Icon name/class -->
59
+ <i class={`icon icon-${button.icon}`}></i>
60
+ {/if}
61
+ </span>
62
+ {/if}
63
+ <span class="tool-button__label">{button.label}</span>
64
+ </button>
65
+
66
+ <style>
67
+ .tool-button {
68
+ display: inline-flex;
69
+ align-items: center;
70
+ gap: 0.5rem;
71
+ padding: 0.5rem 1rem;
72
+ background: var(--tool-button-bg, #ffffff);
73
+ border: 1px solid var(--tool-button-border, #d1d5db);
74
+ border-radius: 0.375rem;
75
+ color: var(--tool-button-color, #374151);
76
+ font-size: 0.875rem;
77
+ font-weight: 500;
78
+ cursor: pointer;
79
+ transition: all 0.15s ease-in-out;
80
+ white-space: nowrap;
81
+ }
82
+
83
+ .tool-button:hover:not(:disabled) {
84
+ background: var(--tool-button-hover-bg, #f9fafb);
85
+ border-color: var(--tool-button-hover-border, #9ca3af);
86
+ color: var(--tool-button-hover-color, #111827);
87
+ }
88
+
89
+ .tool-button:active:not(:disabled) {
90
+ background: var(--tool-button-active-bg, #f3f4f6);
91
+ transform: translateY(1px);
92
+ }
93
+
94
+ .tool-button:focus-visible {
95
+ outline: 2px solid var(--tool-button-focus-outline, #3b82f6);
96
+ outline-offset: 2px;
97
+ }
98
+
99
+ .tool-button:disabled,
100
+ .tool-button--disabled {
101
+ opacity: 0.5;
102
+ cursor: not-allowed;
103
+ }
104
+
105
+ .tool-button__icon {
106
+ display: inline-flex;
107
+ align-items: center;
108
+ justify-content: center;
109
+ width: 1.25rem;
110
+ height: 1.25rem;
111
+ flex-shrink: 0;
112
+ }
113
+
114
+ .tool-button__icon :global(svg) {
115
+ width: 100%;
116
+ height: 100%;
117
+ fill: currentColor;
118
+ }
119
+
120
+ .tool-button__icon img {
121
+ width: 100%;
122
+ height: 100%;
123
+ object-fit: contain;
124
+ }
125
+
126
+ .tool-button__label {
127
+ line-height: 1.25;
128
+ }
129
+
130
+ /* Compact variant - icon only */
131
+ .tool-button--compact .tool-button__label {
132
+ position: absolute;
133
+ width: 1px;
134
+ height: 1px;
135
+ padding: 0;
136
+ margin: -1px;
137
+ overflow: hidden;
138
+ clip: rect(0, 0, 0, 0);
139
+ white-space: nowrap;
140
+ border-width: 0;
141
+ }
142
+
143
+ .tool-button--compact {
144
+ padding: 0.5rem;
145
+ }
146
+ </style>
@@ -0,0 +1,109 @@
1
+ <script lang="ts">
2
+ /**
3
+ * ToolButtonGroup
4
+ *
5
+ * Generic toolbar component that renders a group of tool buttons.
6
+ * Implements the two-pass visibility model:
7
+ * - Pass 1: Receives allowedToolIds from orchestrator (PNP/policies)
8
+ * - Pass 2: Filters by tool relevance using ToolRegistry
9
+ */
10
+
11
+ import type { ToolRegistry } from "../services/ToolRegistry";
12
+ import type { ToolContext } from "../services/tool-context";
13
+ import ToolButton from "./ToolButton.svelte";
14
+
15
+ // Props
16
+ let {
17
+ toolRegistry,
18
+ allowedToolIds,
19
+ context,
20
+ onToolClick,
21
+ orientation = "horizontal",
22
+ compact = false,
23
+ class: className = "",
24
+ }: {
25
+ /** Tool registry for filtering and button creation */
26
+ toolRegistry: ToolRegistry;
27
+ /** Tool IDs allowed by orchestrator (Pass 1) */
28
+ allowedToolIds: string[];
29
+ /** Context for visibility evaluation (Pass 2) */
30
+ context: ToolContext;
31
+ /** Callback when tool button is clicked */
32
+ onToolClick?: (toolId: string) => void;
33
+ /** Layout orientation */
34
+ orientation?: "horizontal" | "vertical";
35
+ /** Compact mode (icon only) */
36
+ compact?: boolean;
37
+ /** Additional CSS classes */
38
+ class?: string;
39
+ } = $props();
40
+
41
+ // Two-pass visibility model
42
+ // Pass 2: Filter by tool relevance
43
+ const visibleTools = $derived(
44
+ toolRegistry.filterVisibleInContext(allowedToolIds, context),
45
+ );
46
+
47
+ // Create button definitions for visible tools
48
+ const buttons = $derived(
49
+ visibleTools.map((tool) =>
50
+ tool.createButton(context, {
51
+ onClick: () => {
52
+ onToolClick?.(tool.toolId);
53
+ },
54
+ className: compact ? "tool-button--compact" : "",
55
+ }),
56
+ ),
57
+ );
58
+
59
+ // Derive container classes
60
+ const containerClasses = $derived(
61
+ [
62
+ "tool-button-group",
63
+ `tool-button-group--${orientation}`,
64
+ compact ? "tool-button-group--compact" : "",
65
+ className,
66
+ ]
67
+ .filter(Boolean)
68
+ .join(" "),
69
+ );
70
+ </script>
71
+
72
+ {#if buttons.length > 0}
73
+ <div class={containerClasses} role="toolbar" aria-label="Assessment tools">
74
+ {#each buttons as button (button.toolId)}
75
+ <ToolButton {button} />
76
+ {/each}
77
+ </div>
78
+ {/if}
79
+
80
+ <style>
81
+ .tool-button-group {
82
+ display: flex;
83
+ gap: 0.5rem;
84
+ padding: 0.5rem;
85
+ background: var(--tool-button-group-bg, transparent);
86
+ border-radius: 0.5rem;
87
+ }
88
+
89
+ .tool-button-group--horizontal {
90
+ flex-direction: row;
91
+ flex-wrap: wrap;
92
+ align-items: center;
93
+ }
94
+
95
+ .tool-button-group--vertical {
96
+ flex-direction: column;
97
+ align-items: stretch;
98
+ }
99
+
100
+ .tool-button-group--compact {
101
+ gap: 0.25rem;
102
+ padding: 0.25rem;
103
+ }
104
+
105
+ /* Empty state - hide when no buttons */
106
+ .tool-button-group:empty {
107
+ display: none;
108
+ }
109
+ </style>
@@ -39,24 +39,23 @@
39
39
  let passage = $state<PassageEntity | null>(null);
40
40
  let rubricBlocks = $state<RubricBlock[]>([]);
41
41
 
42
- // Picture Dictionary Modal state
43
- let showPictureDictionaryModal = $state(false);
44
- let pictureDictionaryWord = $state('');
45
-
46
42
  // Annotation toolbar event handlers
47
43
  function handleDictionaryLookup(detail: { text: string }) {
48
44
  // TODO: Open dictionary modal
49
45
  console.log('Dictionary lookup:', detail.text);
46
+ alert(`Dictionary lookup: ${detail.text}`);
50
47
  }
51
48
 
52
49
  function handleTranslationRequest(detail: { text: string }) {
53
50
  // TODO: Open translation modal
54
51
  console.log('Translation request:', detail.text);
52
+ alert(`Translation request: ${detail.text}`);
55
53
  }
56
54
 
57
55
  function handlePictureDictionaryLookup(detail: { text: string }) {
58
- pictureDictionaryWord = detail.text;
59
- showPictureDictionaryModal = true;
56
+ // TODO: Open picture dictionary modal
57
+ console.log('Picture dictionary lookup:', detail.text);
58
+ alert(`Picture dictionary: ${detail.text}`);
60
59
  }
61
60
 
62
61
  // Load passage when item changes
@@ -183,13 +182,6 @@
183
182
  onpicturedictionarylookup={handlePictureDictionaryLookup}
184
183
  />
185
184
 
186
- <!-- Picture Dictionary Modal -->
187
- <PictureDictionaryModal
188
- bind:visible={showPictureDictionaryModal}
189
- word={pictureDictionaryWord}
190
- organizationId={organizationId || undefined}
191
- />
192
-
193
185
  <style>
194
186
  .reference-layout {
195
187
  display: grid;