@pie-players/pie-assessment-toolkit 0.3.25 → 0.3.27
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 +70 -17
- package/dist/components/ItemToolBar.custom-element.js +116 -9
- package/dist/components/PieAssessmentToolkit.custom-element.js +302 -7
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/services/HighlightCoordinator.d.ts +3 -2
- package/dist/services/HighlightCoordinator.d.ts.map +1 -1
- package/dist/services/HighlightCoordinator.js +6 -3
- package/dist/services/HighlightCoordinator.js.map +1 -1
- package/dist/services/TTSService.d.ts +3 -0
- package/dist/services/TTSService.d.ts.map +1 -1
- package/dist/services/TTSService.js +66 -5
- package/dist/services/TTSService.js.map +1 -1
- package/dist/services/ToolRegistry.d.ts +10 -1
- package/dist/services/ToolRegistry.d.ts.map +1 -1
- package/dist/services/ToolRegistry.js.map +1 -1
- package/dist/services/ToolkitCoordinator.d.ts +37 -5
- package/dist/services/ToolkitCoordinator.d.ts.map +1 -1
- package/dist/services/ToolkitCoordinator.js +114 -35
- package/dist/services/ToolkitCoordinator.js.map +1 -1
- package/dist/services/create-tools-config.d.ts +15 -0
- package/dist/services/create-tools-config.d.ts.map +1 -0
- package/dist/services/create-tools-config.js +13 -0
- package/dist/services/create-tools-config.js.map +1 -0
- package/dist/services/framework-error.d.ts +34 -0
- package/dist/services/framework-error.d.ts.map +1 -0
- package/dist/services/framework-error.js +43 -0
- package/dist/services/framework-error.js.map +1 -0
- package/dist/services/tool-config-validation.d.ts +31 -0
- package/dist/services/tool-config-validation.d.ts.map +1 -0
- package/dist/services/tool-config-validation.js +242 -0
- package/dist/services/tool-config-validation.js.map +1 -0
- package/dist/services/toolbar-items.d.ts +1 -0
- package/dist/services/toolbar-items.d.ts.map +1 -1
- package/dist/services/toolbar-items.js +28 -2
- package/dist/services/toolbar-items.js.map +1 -1
- package/dist/services/tts/visual-line-ranges.d.ts +19 -0
- package/dist/services/tts/visual-line-ranges.d.ts.map +1 -0
- package/dist/services/tts/visual-line-ranges.js +227 -0
- package/dist/services/tts/visual-line-ranges.js.map +1 -0
- package/dist/services/tts-runtime-config.d.ts +29 -0
- package/dist/services/tts-runtime-config.d.ts.map +1 -1
- package/dist/services/tts-runtime-config.js +101 -9
- package/dist/services/tts-runtime-config.js.map +1 -1
- package/dist/tools/registrations/accessibility-tools.js +1 -1
- package/dist/tools/registrations/accessibility-tools.js.map +1 -1
- package/dist/tools/registrations/measurement-tools.js +4 -4
- package/dist/tools/registrations/measurement-tools.js.map +1 -1
- package/dist/tools/registrations/tts.d.ts +1 -0
- package/dist/tools/registrations/tts.d.ts.map +1 -1
- package/dist/tools/registrations/tts.js +52 -21
- package/dist/tools/registrations/tts.js.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ const toolkitCoordinator = new ToolkitCoordinator({
|
|
|
33
33
|
assessmentId: 'my-assessment',
|
|
34
34
|
tools: {
|
|
35
35
|
providers: {
|
|
36
|
-
|
|
36
|
+
textToSpeech: { enabled: true, backend: 'browser' },
|
|
37
37
|
calculator: { enabled: true }
|
|
38
38
|
},
|
|
39
39
|
placement: {
|
|
@@ -126,7 +126,7 @@ const coordinator = new ToolkitCoordinator({
|
|
|
126
126
|
assessmentId: 'demo-assessment',
|
|
127
127
|
tools: {
|
|
128
128
|
providers: {
|
|
129
|
-
|
|
129
|
+
textToSpeech: { enabled: true, backend: 'browser', defaultVoice: 'en-US' },
|
|
130
130
|
calculator: { enabled: true }
|
|
131
131
|
},
|
|
132
132
|
placement: {
|
|
@@ -219,7 +219,7 @@ The toolkit uses one canonical `tools` model with three concerns:
|
|
|
219
219
|
|
|
220
220
|
- `policy`: allow/block constraints (global gates)
|
|
221
221
|
- `placement`: where tools appear (`assessment`, `section`, `item`, `passage`, `rubric`, plus custom registered levels)
|
|
222
|
-
- `providers`: provider/runtime options (calculator,
|
|
222
|
+
- `providers`: provider/runtime options (calculator, textToSpeech, etc.)
|
|
223
223
|
|
|
224
224
|
Example:
|
|
225
225
|
|
|
@@ -238,7 +238,7 @@ tools: {
|
|
|
238
238
|
},
|
|
239
239
|
providers: {
|
|
240
240
|
calculator: { authFetcher: async () => ({ apiKey: '...' }) },
|
|
241
|
-
|
|
241
|
+
textToSpeech: { enabled: true, backend: 'browser', defaultVoice: 'en-US' }
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
```
|
|
@@ -361,7 +361,7 @@ const coordinator = new ToolkitCoordinator({
|
|
|
361
361
|
return response.json();
|
|
362
362
|
}
|
|
363
363
|
},
|
|
364
|
-
|
|
364
|
+
textToSpeech: { enabled: true, backend: 'browser' }
|
|
365
365
|
}
|
|
366
366
|
},
|
|
367
367
|
accessibility: {
|
|
@@ -386,7 +386,7 @@ const coordinator = new ToolkitCoordinator({
|
|
|
386
386
|
},
|
|
387
387
|
providers: {
|
|
388
388
|
calculator: { enabled: true },
|
|
389
|
-
|
|
389
|
+
textToSpeech: { enabled: true, backend: 'browser' }
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
392
|
});
|
|
@@ -402,7 +402,7 @@ Common options are defaulted so you can start with:
|
|
|
402
402
|
```typescript
|
|
403
403
|
tools: {
|
|
404
404
|
providers: {
|
|
405
|
-
|
|
405
|
+
textToSpeech: {
|
|
406
406
|
enabled: true,
|
|
407
407
|
backend: 'polly'
|
|
408
408
|
}
|
|
@@ -425,7 +425,7 @@ Inline TTS speed buttons are configurable via `speedOptions` in provider setting
|
|
|
425
425
|
```typescript
|
|
426
426
|
tools: {
|
|
427
427
|
providers: {
|
|
428
|
-
|
|
428
|
+
textToSpeech: {
|
|
429
429
|
enabled: true,
|
|
430
430
|
backend: "browser",
|
|
431
431
|
settings: {
|
|
@@ -438,7 +438,7 @@ tools: {
|
|
|
438
438
|
|
|
439
439
|
`speedOptions` semantics:
|
|
440
440
|
|
|
441
|
-
- Omitted or non-array: default speed buttons are shown (`
|
|
441
|
+
- Omitted or non-array: default speed buttons are shown (`0.8x`, `1.25x`).
|
|
442
442
|
- Explicit empty array (`[]`): hide all speed buttons.
|
|
443
443
|
- Invalid-only arrays (for example `["fast", -1, 1]`): fall back to defaults.
|
|
444
444
|
- Valid numeric values are deduplicated and keep first-seen order.
|
|
@@ -468,7 +468,7 @@ requires runtime auth material for TTS requests:
|
|
|
468
468
|
```typescript
|
|
469
469
|
tools: {
|
|
470
470
|
providers: {
|
|
471
|
-
|
|
471
|
+
textToSpeech: {
|
|
472
472
|
enabled: true,
|
|
473
473
|
backend: 'polly',
|
|
474
474
|
apiEndpoint: '/api/tts',
|
|
@@ -493,7 +493,7 @@ prefer a host-owned proxy endpoint so secrets never ship to the browser.
|
|
|
493
493
|
```typescript
|
|
494
494
|
tools: {
|
|
495
495
|
providers: {
|
|
496
|
-
|
|
496
|
+
textToSpeech: {
|
|
497
497
|
enabled: true,
|
|
498
498
|
backend: "server",
|
|
499
499
|
serverProvider: "custom",
|
|
@@ -615,7 +615,7 @@ export interface ToolkitCoordinatorConfig {
|
|
|
615
615
|
rubric?: string[];
|
|
616
616
|
};
|
|
617
617
|
providers?: {
|
|
618
|
-
|
|
618
|
+
textToSpeech?: {
|
|
619
619
|
enabled?: boolean;
|
|
620
620
|
backend?: 'browser' | 'polly' | 'google' | 'server';
|
|
621
621
|
defaultVoice?: string;
|
|
@@ -627,6 +627,7 @@ export interface ToolkitCoordinatorConfig {
|
|
|
627
627
|
};
|
|
628
628
|
};
|
|
629
629
|
};
|
|
630
|
+
toolRegistry?: ToolRegistry | null;
|
|
630
631
|
accessibility?: {
|
|
631
632
|
catalogs?: any[];
|
|
632
633
|
language?: string;
|
|
@@ -642,9 +643,9 @@ const services = coordinator.getServiceBundle();
|
|
|
642
643
|
// Returns: { ttsService, toolCoordinator, highlightCoordinator, elementToolStateStore, catalogResolver }
|
|
643
644
|
|
|
644
645
|
// Tool configuration
|
|
645
|
-
coordinator.isToolEnabled('
|
|
646
|
-
coordinator.getToolConfig('
|
|
647
|
-
coordinator.updateToolConfig('
|
|
646
|
+
coordinator.isToolEnabled('textToSpeech'); // Check if tool is enabled
|
|
647
|
+
coordinator.getToolConfig('textToSpeech'); // Get tool-specific config
|
|
648
|
+
coordinator.updateToolConfig('textToSpeech', { rate: 1.5 }); // Update tool config
|
|
648
649
|
```
|
|
649
650
|
|
|
650
651
|
### Direct Service Access
|
|
@@ -865,7 +866,7 @@ The section player provides automatic ToolkitCoordinator integration:
|
|
|
865
866
|
const coordinator = new ToolkitCoordinator({
|
|
866
867
|
assessmentId: 'my-assessment',
|
|
867
868
|
tools: {
|
|
868
|
-
providers: {
|
|
869
|
+
providers: { textToSpeech: { enabled: true, backend: 'browser' } },
|
|
869
870
|
placement: {
|
|
870
871
|
section: ['calculator', 'graph', 'periodicTable', 'protractor', 'lineReader', 'ruler'],
|
|
871
872
|
item: ['calculator', 'textToSpeech', 'answerEliminator'],
|
|
@@ -929,7 +930,7 @@ player.section = mySection;
|
|
|
929
930
|
// new ToolkitCoordinator({
|
|
930
931
|
// assessmentId: 'anon_...', // auto-generated
|
|
931
932
|
// tools: {
|
|
932
|
-
// providers: {
|
|
933
|
+
// providers: { textToSpeech: { enabled: true, backend: 'browser' }, calculator: { enabled: true } },
|
|
933
934
|
// placement: {
|
|
934
935
|
// section: ['calculator', 'graph', 'periodicTable', 'protractor', 'lineReader', 'ruler'],
|
|
935
936
|
// item: ['calculator', 'textToSpeech', 'answerEliminator'],
|
|
@@ -939,6 +940,56 @@ player.section = mySection;
|
|
|
939
940
|
// })
|
|
940
941
|
```
|
|
941
942
|
|
|
943
|
+
### Safe Custom Tool Configuration
|
|
944
|
+
|
|
945
|
+
Default behavior is now framework-owned: invalid tools/runtime initialization is handled in `pie-assessment-toolkit` without host try/catch.
|
|
946
|
+
|
|
947
|
+
- Framework logs a deterministic console error prefix: `[pie-framework:<kind>:<source>]`
|
|
948
|
+
- Framework emits a canonical `framework-error` event (and still emits `runtime-error` for compatibility)
|
|
949
|
+
- Framework renders a fallback error panel instead of a blank player
|
|
950
|
+
- Startup tool-config validation can surface as `kind: "coordinator-init"` when the owned coordinator construction path throws.
|
|
951
|
+
|
|
952
|
+
Use `createToolsConfig()` when you want to pre-validate and inspect diagnostics before mounting:
|
|
953
|
+
|
|
954
|
+
```typescript
|
|
955
|
+
import {
|
|
956
|
+
createPackagedToolRegistry,
|
|
957
|
+
createToolsConfig,
|
|
958
|
+
ToolkitCoordinator
|
|
959
|
+
} from "@pie-players/pie-assessment-toolkit";
|
|
960
|
+
|
|
961
|
+
const toolRegistry = createPackagedToolRegistry();
|
|
962
|
+
const { config, diagnostics } = createToolsConfig({
|
|
963
|
+
source: "host.bootstrap",
|
|
964
|
+
strictness: "error",
|
|
965
|
+
toolRegistry,
|
|
966
|
+
tools: {
|
|
967
|
+
providers: {
|
|
968
|
+
textToSpeech: { enabled: true, backend: "browser" },
|
|
969
|
+
calculator: { enabled: true }
|
|
970
|
+
},
|
|
971
|
+
placement: {
|
|
972
|
+
item: ["calculator", "textToSpeech"]
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
});
|
|
976
|
+
|
|
977
|
+
// Fail-fast default: invalid config throws at the boundary.
|
|
978
|
+
const coordinator = new ToolkitCoordinator({
|
|
979
|
+
assessmentId: "demo-assessment",
|
|
980
|
+
toolRegistry,
|
|
981
|
+
tools: config,
|
|
982
|
+
toolConfigStrictness: "error"
|
|
983
|
+
});
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
Notes:
|
|
987
|
+
- `providers.textToSpeech` is the canonical TTS provider key.
|
|
988
|
+
- `providers.tts` is rejected by the validation contract.
|
|
989
|
+
- Custom tools can provide provider-level `sanitizeConfig` and `validateConfig` hooks.
|
|
990
|
+
- Hosts can react to framework errors via `onframework-error` listeners or `onFrameworkError` callback prop.
|
|
991
|
+
- See `docs/tools-and-accomodations/framework-owned-error-handling.md` for event payload and error-kind mapping details.
|
|
992
|
+
|
|
942
993
|
## State Separation: Tool State vs Session Data
|
|
943
994
|
|
|
944
995
|
The toolkit enforces a clear separation between ephemeral tool state and persistent session data:
|
|
@@ -1013,6 +1064,8 @@ import type {
|
|
|
1013
1064
|
- **[PNP Configuration Guide](docs/PNP_CONFIGURATION.md)** - ⭐ NEW - How to configure student profiles, district policies, and governance rules
|
|
1014
1065
|
- [ToolkitCoordinator Architecture](../../docs/architecture/TOOLKIT_COORDINATOR.md) - Design decisions and patterns
|
|
1015
1066
|
- [Section Player README](../section-player/README.md) - Section player integration
|
|
1067
|
+
- [Framework-Owned Error Handling](../../docs/tools-and-accomodations/framework-owned-error-handling.md) - Canonical framework error model/events and fallback behavior
|
|
1068
|
+
- [Safe Custom Tool Configuration](../../docs/tools-and-accomodations/safe-custom-tool-config.md) - Host-side config patterns and validation guidance
|
|
1016
1069
|
- [Architecture Overview](../../docs/architecture/architecture.md) - Complete system architecture
|
|
1017
1070
|
|
|
1018
1071
|
## License
|
|
@@ -22,7 +22,13 @@ import {
|
|
|
22
22
|
connectAssessmentToolkitShellContext
|
|
23
23
|
} from '../context/runtime-context-consumer.js';
|
|
24
24
|
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
isExternalIconUrl,
|
|
27
|
+
isInlineSvgIcon,
|
|
28
|
+
isToolbarLinkItem,
|
|
29
|
+
isValidToolbarItemShape
|
|
30
|
+
} from '../services/toolbar-items.js';
|
|
31
|
+
|
|
26
32
|
import { createPackagedToolRegistry } from '../services/createDefaultToolRegistry.js';
|
|
27
33
|
import { DEFAULT_TOOL_MODULE_LOADERS } from '../tools/default-tool-module-loaders.js';
|
|
28
34
|
import { normalizeToolsConfig, parseToolList, resolveToolsForLevel } from '../services/tools-config-normalizer.js';
|
|
@@ -38,11 +44,14 @@ var root_19 = $.from_html(`<i aria-hidden="true"></i>`);
|
|
|
38
44
|
var root_13 = $.from_html(`<button type="button"><!></button>`);
|
|
39
45
|
var root_21 = $.from_html(`<span class="item-toolbar__element-host svelte-rnx3ie"></span>`);
|
|
40
46
|
var root_22 = $.from_html(`<span class="item-toolbar__element-host svelte-rnx3ie"></span>`);
|
|
41
|
-
var
|
|
47
|
+
var root_25 = $.from_html(`<span class="item-toolbar__controls-host svelte-rnx3ie"></span>`);
|
|
48
|
+
var root_26 = $.from_html(`<span class="item-toolbar__controls-host svelte-rnx3ie"></span>`);
|
|
49
|
+
var root_23 = $.from_html(`<div></div>`);
|
|
50
|
+
var root_1 = $.from_html(`<div><div class="item-toolbar__tools-row svelte-rnx3ie"><!> <!> <!></div> <!></div>`);
|
|
42
51
|
|
|
43
52
|
const $$css = {
|
|
44
53
|
hash: 'svelte-rnx3ie',
|
|
45
|
-
code: '.item-toolbar.svelte-rnx3ie {display:flex;flex-direction:column;align-items:flex-end;gap:0;--pie-toolbar-tools-row-height: 2rem;--pie-tts-controls-row-height: 2.875rem;}.item-toolbar__tools-row.svelte-rnx3ie {display:flex;align-items:center;justify-content:flex-end;flex-wrap:nowrap;gap:0.5rem;min-height:var(--pie-toolbar-tools-row-height);}.item-toolbar__controls-row.svelte-rnx3ie {display:flex;align-items:center;justify-content:flex-end;width:100%;min-height:var(--pie-tts-controls-row-height);height:var(--pie-tts-controls-row-height);}.item-toolbar__controls-host.svelte-rnx3ie {display:inline-flex;align-items:center;justify-content:flex-end;width:100%;}.item-toolbar--top.svelte-rnx3ie,\n .item-toolbar--bottom.svelte-rnx3ie {align-items:flex-end;}.item-toolbar--left.svelte-rnx3ie,\n .item-toolbar--right.svelte-rnx3ie {align-items:stretch;}.item-toolbar--left.svelte-rnx3ie .item-toolbar__tools-row:where(.svelte-rnx3ie),\n .item-toolbar--right.svelte-rnx3ie .item-toolbar__tools-row:where(.svelte-rnx3ie) {flex-direction:column;align-items:center;justify-content:flex-start;flex-wrap:nowrap;}.item-toolbar--left.svelte-rnx3ie .item-toolbar__controls-row:where(.svelte-rnx3ie),\n .item-toolbar--right.svelte-rnx3ie .item-toolbar__controls-row:where(.svelte-rnx3ie) {justify-content:flex-start;width:auto;min-height:0;height:auto;}.item-toolbar__button.svelte-rnx3ie {display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0.25rem;border:1px solid var(--pie-button-border, var(--pie-border, #ccc));border-radius:0.25rem;background-color:var(--pie-button-bg, var(--pie-background, white));color:var(--pie-button-color, var(--pie-text, #333));cursor:pointer;transition:all 0.15s ease;text-decoration:none;}.item-toolbar__element-host.svelte-rnx3ie {display:contents;}.item-toolbar--sm.svelte-rnx3ie .item-toolbar__button:where(.svelte-rnx3ie) {width:2.75rem;height:2.75rem;}.item-toolbar--sm.svelte-rnx3ie {--pie-toolbar-tools-row-height: 2.75rem;--pie-tts-controls-row-height: 3.625rem;}.item-toolbar--lg.svelte-rnx3ie .item-toolbar__button:where(.svelte-rnx3ie) {width:2.5rem;height:2.5rem;}.item-toolbar--lg.svelte-rnx3ie {--pie-toolbar-tools-row-height: 2.5rem;--pie-tts-controls-row-height: 3.375rem;}.item-toolbar__button.svelte-rnx3ie:hover:not(:disabled) {background-color:var(--pie-button-hover-bg, var(--pie-secondary-background, #f5f5f5));border-color:var(--pie-button-hover-border, var(--pie-button-border, var(--pie-border, #ccc)));color:var(--pie-button-hover-color, var(--pie-button-color, var(--pie-text, #333)));transform:translateY(-1px);box-shadow:0 2px 4px color-mix(in srgb, var(--pie-black, #000) 10%, transparent);}.item-toolbar__button.svelte-rnx3ie:active:not(:disabled) {transform:translateY(0);box-shadow:none;}.item-toolbar__button--active.svelte-rnx3ie {background-color:var(--pie-primary, #1976d2);color:var(--pie-white, #fff);border-color:var(--pie-primary, #1976d2);}.item-toolbar__button--active.svelte-rnx3ie:hover:not(:disabled) {background-color:var(--pie-primary-dark, #1565c0);}.item-toolbar__button.svelte-rnx3ie:focus-visible {outline:2px solid var(--pie-button-focus-outline, var(--pie-primary, #1976d2));outline-offset:2px;}.item-toolbar__button.svelte-rnx3ie:disabled {opacity:0.5;cursor:not-allowed;}.item-toolbar__button.svelte-rnx3ie svg {width:100%;height:100%;}.item-toolbar__icon-image.svelte-rnx3ie {width:100%;height:100%;object-fit:contain;}'
|
|
54
|
+
code: '.item-toolbar.svelte-rnx3ie {display:flex;flex-direction:column;align-items:flex-end;gap:0;--pie-toolbar-tools-row-height: 2rem;--pie-tts-controls-row-height: 2.875rem;}.item-toolbar__tools-row.svelte-rnx3ie {display:flex;align-items:center;justify-content:flex-end;flex-wrap:nowrap;gap:0.5rem;min-height:var(--pie-toolbar-tools-row-height);}.item-toolbar__controls-row.svelte-rnx3ie {display:flex;align-items:center;justify-content:flex-end;width:100%;min-height:0;height:auto;}.item-toolbar__controls-row--reserve.svelte-rnx3ie {min-height:var(--pie-tts-controls-row-height);height:var(--pie-tts-controls-row-height);}.item-toolbar__controls-row--active.svelte-rnx3ie {min-height:var(--pie-tts-controls-row-height);height:var(--pie-tts-controls-row-height);}.item-toolbar__controls-row--align-start.svelte-rnx3ie {justify-content:flex-start;}.item-toolbar__controls-host.svelte-rnx3ie {display:inline-flex;align-items:center;justify-content:flex-end;width:100%;}.item-toolbar--top.svelte-rnx3ie,\n .item-toolbar--bottom.svelte-rnx3ie {align-items:flex-end;}.item-toolbar--left.svelte-rnx3ie,\n .item-toolbar--right.svelte-rnx3ie {align-items:stretch;}.item-toolbar--left.svelte-rnx3ie .item-toolbar__tools-row:where(.svelte-rnx3ie),\n .item-toolbar--right.svelte-rnx3ie .item-toolbar__tools-row:where(.svelte-rnx3ie) {flex-direction:column;align-items:center;justify-content:flex-start;flex-wrap:nowrap;}.item-toolbar--left.svelte-rnx3ie .item-toolbar__controls-row:where(.svelte-rnx3ie),\n .item-toolbar--right.svelte-rnx3ie .item-toolbar__controls-row:where(.svelte-rnx3ie) {justify-content:flex-start;width:auto;min-height:0;height:auto;}.item-toolbar__button.svelte-rnx3ie {display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0.25rem;border:1px solid var(--pie-button-border, var(--pie-border, #ccc));border-radius:0.25rem;background-color:var(--pie-button-bg, var(--pie-background, white));color:var(--pie-button-color, var(--pie-text, #333));cursor:pointer;transition:all 0.15s ease;text-decoration:none;}.item-toolbar__element-host.svelte-rnx3ie {display:contents;}.item-toolbar--sm.svelte-rnx3ie .item-toolbar__button:where(.svelte-rnx3ie) {width:2.75rem;height:2.75rem;}.item-toolbar--sm.svelte-rnx3ie {--pie-toolbar-tools-row-height: 2.75rem;--pie-tts-controls-row-height: 3.625rem;}.item-toolbar--lg.svelte-rnx3ie .item-toolbar__button:where(.svelte-rnx3ie) {width:2.5rem;height:2.5rem;}.item-toolbar--lg.svelte-rnx3ie {--pie-toolbar-tools-row-height: 2.5rem;--pie-tts-controls-row-height: 3.375rem;}.item-toolbar__button.svelte-rnx3ie:hover:not(:disabled) {background-color:var(--pie-button-hover-bg, var(--pie-secondary-background, #f5f5f5));border-color:var(--pie-button-hover-border, var(--pie-button-border, var(--pie-border, #ccc)));color:var(--pie-button-hover-color, var(--pie-button-color, var(--pie-text, #333)));transform:translateY(-1px);box-shadow:0 2px 4px color-mix(in srgb, var(--pie-black, #000) 10%, transparent);}.item-toolbar__button.svelte-rnx3ie:active:not(:disabled) {transform:translateY(0);box-shadow:none;}.item-toolbar__button--active.svelte-rnx3ie {background-color:var(--pie-primary, #1976d2);color:var(--pie-white, #fff);border-color:var(--pie-primary, #1976d2);}.item-toolbar__button--active.svelte-rnx3ie:hover:not(:disabled) {background-color:var(--pie-primary-dark, #1565c0);}.item-toolbar__button.svelte-rnx3ie:focus-visible {outline:2px solid var(--pie-button-focus-outline, var(--pie-primary, #1976d2));outline-offset:2px;}.item-toolbar__button.svelte-rnx3ie:disabled {opacity:0.5;cursor:not-allowed;}.item-toolbar__button.svelte-rnx3ie svg {width:100%;height:100%;}.item-toolbar__icon-image.svelte-rnx3ie {width:100%;height:100%;object-fit:contain;}'
|
|
46
55
|
};
|
|
47
56
|
|
|
48
57
|
export default function ItemToolBar($$anchor, $$props) {
|
|
@@ -401,9 +410,23 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
401
410
|
return rendered;
|
|
402
411
|
});
|
|
403
412
|
|
|
404
|
-
const normalizedHostButtons = $.derived(() =>
|
|
405
|
-
|
|
406
|
-
|
|
413
|
+
const normalizedHostButtons = $.derived(() => {
|
|
414
|
+
if (!Array.isArray(hostButtons())) return [];
|
|
415
|
+
|
|
416
|
+
const valid = [];
|
|
417
|
+
|
|
418
|
+
hostButtons().forEach((item, index) => {
|
|
419
|
+
if (isValidToolbarItemShape(item)) {
|
|
420
|
+
valid.push(item);
|
|
421
|
+
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
console.warn(`[ItemToolBar] Ignoring invalid host button at index ${index}. Expected { id, label, href | onClick } with valid types.`);
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
return valid;
|
|
429
|
+
});
|
|
407
430
|
|
|
408
431
|
const nativeToolbarItems = $.derived(() => $.get(renderedTools).filter((renderedTool) => !!renderedTool.button).map((renderedTool) => {
|
|
409
432
|
const button = renderedTool.button;
|
|
@@ -450,6 +473,22 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
450
473
|
entry
|
|
451
474
|
}))));
|
|
452
475
|
|
|
476
|
+
const mountedElementsControlsRow = $.derived(() => $.get(renderedTools).flatMap((renderedTool) => (renderedTool.elements || []).filter((entry) => entry.mount === 'controls-row').filter((entry) => Boolean(entry.element)).map((entry, index) => ({
|
|
477
|
+
key: `controls-row-${renderedTool.toolId}-${index}`,
|
|
478
|
+
toolId: renderedTool.toolId,
|
|
479
|
+
entry
|
|
480
|
+
}))));
|
|
481
|
+
|
|
482
|
+
const controlsRowHints = $.derived(() => $.get(renderedTools).flatMap((renderedTool) => (renderedTool.elements || []).map((entry) => ({
|
|
483
|
+
toolId: renderedTool.toolId,
|
|
484
|
+
hint: entry.layoutHints?.controlsRow
|
|
485
|
+
})).filter((entry) => Boolean(entry.hint))));
|
|
486
|
+
|
|
487
|
+
const controlsRowShouldReserveSpace = $.derived(() => $.get(controlsRowHints).some((entry) => entry.hint?.reserveSpace === true));
|
|
488
|
+
const controlsRowShouldExpandForActiveTool = $.derived(() => $.get(controlsRowHints).some((entry) => entry.hint?.showWhenToolActive === true && ($.get(renderedToolActiveById)[entry.toolId] ?? false)));
|
|
489
|
+
const controlsRowAlignStart = $.derived(() => position() === 'left' || position() === 'right');
|
|
490
|
+
const shouldRenderControlsRow = $.derived(() => $.get(mountedElementsControlsRow).length > 0 || $.get(controlsRowShouldReserveSpace) || $.get(controlsRowShouldExpandForActiveTool));
|
|
491
|
+
|
|
453
492
|
function isToolbarItemActive(item) {
|
|
454
493
|
if (item.id in $.get(activeToolState)) {
|
|
455
494
|
return $.get(activeToolState)[item.id] === true;
|
|
@@ -516,6 +555,20 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
516
555
|
});
|
|
517
556
|
});
|
|
518
557
|
|
|
558
|
+
$.user_effect(() => {
|
|
559
|
+
const toolkitCoordinator = $.get(toolbarContext).toolkitCoordinator;
|
|
560
|
+
|
|
561
|
+
if (typeof toolkitCoordinator?.subscribeTelemetry !== 'function') return;
|
|
562
|
+
|
|
563
|
+
return toolkitCoordinator.subscribeTelemetry(({ eventName, payload }) => {
|
|
564
|
+
if (eventName !== 'tool-config-updated') return;
|
|
565
|
+
if (payload?.toolId && !$.get(toolbarVisibleToolIds).includes(payload.toolId)) return;
|
|
566
|
+
|
|
567
|
+
$.set(moduleLoadVersion, $.get(moduleLoadVersion) + 1);
|
|
568
|
+
syncRenderedToolsState();
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
|
|
519
572
|
function mountElement(node, element) {
|
|
520
573
|
let mountedElement = null;
|
|
521
574
|
|
|
@@ -1245,7 +1298,7 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
1245
1298
|
var node_1 = $.first_child(fragment);
|
|
1246
1299
|
|
|
1247
1300
|
{
|
|
1248
|
-
var
|
|
1301
|
+
var consequent_13 = ($$anchor) => {
|
|
1249
1302
|
var div = root_1();
|
|
1250
1303
|
let classes;
|
|
1251
1304
|
var div_1 = $.child(div);
|
|
@@ -1530,7 +1583,61 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
1530
1583
|
});
|
|
1531
1584
|
|
|
1532
1585
|
$.reset(div_1);
|
|
1533
|
-
|
|
1586
|
+
|
|
1587
|
+
var node_18 = $.sibling(div_1, 2);
|
|
1588
|
+
|
|
1589
|
+
{
|
|
1590
|
+
var consequent_12 = ($$anchor) => {
|
|
1591
|
+
var div_2 = root_23();
|
|
1592
|
+
let classes_3;
|
|
1593
|
+
|
|
1594
|
+
$.each(div_2, 21, () => $.get(mountedElementsControlsRow), (mounted) => mounted.key, ($$anchor, mounted) => {
|
|
1595
|
+
var fragment_12 = $.comment();
|
|
1596
|
+
var node_19 = $.first_child(fragment_12);
|
|
1597
|
+
|
|
1598
|
+
{
|
|
1599
|
+
var consequent_11 = ($$anchor) => {
|
|
1600
|
+
var span_4 = root_25();
|
|
1601
|
+
|
|
1602
|
+
$.action(span_4, ($$node, $$action_arg) => mountElementWithShell?.($$node, $$action_arg), () => ({
|
|
1603
|
+
mounted: $.get(mounted),
|
|
1604
|
+
active: $.get(renderedToolActiveById)[$.get(mounted).toolId] ?? false
|
|
1605
|
+
}));
|
|
1606
|
+
|
|
1607
|
+
$.append($$anchor, span_4);
|
|
1608
|
+
};
|
|
1609
|
+
|
|
1610
|
+
var alternate_7 = ($$anchor) => {
|
|
1611
|
+
var span_5 = root_26();
|
|
1612
|
+
|
|
1613
|
+
$.action(span_5, ($$node, $$action_arg) => mountElement?.($$node, $$action_arg), () => $.get(mounted).entry.element);
|
|
1614
|
+
$.append($$anchor, span_5);
|
|
1615
|
+
};
|
|
1616
|
+
|
|
1617
|
+
$.if(node_19, ($$render) => {
|
|
1618
|
+
if ($.get(mounted).entry.shell) $$render(consequent_11); else $$render(alternate_7, -1);
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
$.append($$anchor, fragment_12);
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
$.reset(div_2);
|
|
1626
|
+
|
|
1627
|
+
$.template_effect(() => classes_3 = $.set_class(div_2, 1, 'item-toolbar__controls-row svelte-rnx3ie', null, classes_3, {
|
|
1628
|
+
'item-toolbar__controls-row--reserve': $.get(controlsRowShouldReserveSpace),
|
|
1629
|
+
'item-toolbar__controls-row--active': $.get(controlsRowShouldExpandForActiveTool),
|
|
1630
|
+
'item-toolbar__controls-row--align-start': $.get(controlsRowAlignStart)
|
|
1631
|
+
}));
|
|
1632
|
+
|
|
1633
|
+
$.append($$anchor, div_2);
|
|
1634
|
+
};
|
|
1635
|
+
|
|
1636
|
+
$.if(node_18, ($$render) => {
|
|
1637
|
+
if ($.get(shouldRenderControlsRow)) $$render(consequent_12);
|
|
1638
|
+
});
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1534
1641
|
$.reset(div);
|
|
1535
1642
|
$.bind_this(div, ($$value) => $.set(toolbarRootElement, $$value), () => $.get(toolbarRootElement));
|
|
1536
1643
|
|
|
@@ -1550,7 +1657,7 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
1550
1657
|
};
|
|
1551
1658
|
|
|
1552
1659
|
$.if(node_1, ($$render) => {
|
|
1553
|
-
if (isBrowser) $$render(
|
|
1660
|
+
if (isBrowser) $$render(consequent_13);
|
|
1554
1661
|
});
|
|
1555
1662
|
}
|
|
1556
1663
|
|