@pie-players/pie-tool-magnifier 0.1.1
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/Magnifier.svelte +340 -0
- package/README.md +135 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/tool-magnifier.js +3064 -0
- package/dist/tool-magnifier.js.map +1 -0
- package/index.ts +8 -0
- package/package.json +64 -0
- package/tool-magnifier.svelte +140 -0
package/index.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pie-players/pie-tool-magnifier",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "PIE magnification tool for accessibility - magnifies content on screen",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/pie-framework/pie-players.git"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"pie",
|
|
15
|
+
"assessment",
|
|
16
|
+
"tool",
|
|
17
|
+
"magnifier",
|
|
18
|
+
"magnification",
|
|
19
|
+
"accessibility",
|
|
20
|
+
"zoom"
|
|
21
|
+
],
|
|
22
|
+
"svelte": "./tool-magnifier.svelte",
|
|
23
|
+
"main": "./dist/tool-magnifier.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/tool-magnifier.js",
|
|
29
|
+
"svelte": "./tool-magnifier.svelte"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"tool-magnifier.svelte",
|
|
35
|
+
"index.ts",
|
|
36
|
+
"Magnifier.svelte",
|
|
37
|
+
"package.json",
|
|
38
|
+
"README.md"
|
|
39
|
+
],
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"svelte": "^5.0.0"
|
|
42
|
+
},
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"unpkg": "./dist/tool-magnifier.js",
|
|
45
|
+
"jsdelivr": "./dist/tool-magnifier.js",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@pie-players/pie-assessment-toolkit": "workspace:*",
|
|
48
|
+
"@pie-players/pie-players-shared": "workspace:*"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "vite build",
|
|
52
|
+
"dev": "vite build --watch",
|
|
53
|
+
"typecheck": "tsc --noEmit",
|
|
54
|
+
"lint": "biome check ."
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@biomejs/biome": "^2.3.10",
|
|
58
|
+
"@sveltejs/vite-plugin-svelte": "^6.1.4",
|
|
59
|
+
"svelte": "^5.16.1",
|
|
60
|
+
"typescript": "^5.7.0",
|
|
61
|
+
"vite": "^7.0.8",
|
|
62
|
+
"vite-plugin-dts": "^4.5.3"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
<!-- pie-api-aws/containers/pieoneer/src/lib/tags/tool-magnifier/tool-magnifier.svelte -->
|
|
2
|
+
<!--
|
|
3
|
+
Magnifier Tool - Modern Svelte 5 Implementation
|
|
4
|
+
|
|
5
|
+
This component provides a draggable magnification window that clones and magnifies
|
|
6
|
+
the entire page content using a native Svelte 5 component.
|
|
7
|
+
|
|
8
|
+
Features:
|
|
9
|
+
- Draggable magnification window
|
|
10
|
+
- Multiple zoom levels (1.5x, 2x, 3x)
|
|
11
|
+
- Auto-syncing with DOM changes via MutationObserver
|
|
12
|
+
- Scroll position preservation in magnified content
|
|
13
|
+
- Fully reactive using Svelte 5 runes
|
|
14
|
+
-->
|
|
15
|
+
<svelte:options
|
|
16
|
+
customElement={{
|
|
17
|
+
tag: 'pie-tool-magnifier',
|
|
18
|
+
shadow: 'none',
|
|
19
|
+
props: {
|
|
20
|
+
visible: { type: 'Boolean', attribute: 'visible' },
|
|
21
|
+
toolId: { type: 'String', attribute: 'tool-id' },
|
|
22
|
+
coordinator: { type: 'Object' }
|
|
23
|
+
}
|
|
24
|
+
}}
|
|
25
|
+
/>
|
|
26
|
+
|
|
27
|
+
<script lang="ts">
|
|
28
|
+
import type { IToolCoordinator } from '@pie-players/pie-assessment-toolkit';
|
|
29
|
+
import { ZIndexLayer } from '@pie-players/pie-assessment-toolkit';
|
|
30
|
+
import Magnifier from './Magnifier.svelte';
|
|
31
|
+
|
|
32
|
+
// Props
|
|
33
|
+
let {
|
|
34
|
+
visible = false,
|
|
35
|
+
toolId = 'magnifier',
|
|
36
|
+
coordinator
|
|
37
|
+
}: {
|
|
38
|
+
visible?: boolean;
|
|
39
|
+
toolId?: string;
|
|
40
|
+
coordinator?: IToolCoordinator;
|
|
41
|
+
} = $props();
|
|
42
|
+
|
|
43
|
+
// Check if running in browser
|
|
44
|
+
const isBrowser = typeof window !== 'undefined';
|
|
45
|
+
|
|
46
|
+
// State
|
|
47
|
+
let registered = $state(false);
|
|
48
|
+
let zoomLevel = $state<1.5 | 2 | 3>(1.5);
|
|
49
|
+
|
|
50
|
+
const ZOOM_LEVELS = [1.5, 2, 3] as const;
|
|
51
|
+
|
|
52
|
+
function handleZoomChange(level: 1.5 | 2 | 3) {
|
|
53
|
+
zoomLevel = level;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Register with coordinator when it becomes available
|
|
57
|
+
$effect(() => {
|
|
58
|
+
if (coordinator && toolId && !registered) {
|
|
59
|
+
coordinator.registerTool(toolId, 'Magnifier', undefined, ZIndexLayer.TOOL);
|
|
60
|
+
registered = true;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Cleanup on unmount
|
|
65
|
+
$effect(() => {
|
|
66
|
+
return () => {
|
|
67
|
+
if (coordinator && toolId && registered) {
|
|
68
|
+
coordinator.unregisterTool(toolId);
|
|
69
|
+
registered = false;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
{#if isBrowser}
|
|
76
|
+
<Magnifier bind:visible zoom={zoomLevel} width={420} height={280} shape="square">
|
|
77
|
+
<!-- Zoom controls -->
|
|
78
|
+
<div class="btn-group magnifier-clone-ignore" data-magnifier-ignore="true">
|
|
79
|
+
{#each ZOOM_LEVELS as level}
|
|
80
|
+
<button
|
|
81
|
+
class="zoom-btn"
|
|
82
|
+
class:active={zoomLevel === level}
|
|
83
|
+
data-zoom={level}
|
|
84
|
+
title="{level}x zoom"
|
|
85
|
+
aria-label="Set zoom to {level}x"
|
|
86
|
+
onclick={() => handleZoomChange(level)}
|
|
87
|
+
>
|
|
88
|
+
<span class="btn-label">{level}x</span>
|
|
89
|
+
</button>
|
|
90
|
+
{/each}
|
|
91
|
+
</div>
|
|
92
|
+
</Magnifier>
|
|
93
|
+
{/if}
|
|
94
|
+
|
|
95
|
+
<style>
|
|
96
|
+
.btn-group {
|
|
97
|
+
background-color: rgba(255, 255, 255, 0.8);
|
|
98
|
+
border: 1px solid var(--pie-primary, #007bff);
|
|
99
|
+
border-radius: 4px;
|
|
100
|
+
bottom: 0.5rem;
|
|
101
|
+
left: 0.5rem;
|
|
102
|
+
position: absolute;
|
|
103
|
+
z-index: 1001;
|
|
104
|
+
display: flex;
|
|
105
|
+
overflow: hidden;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.zoom-btn {
|
|
109
|
+
background: white;
|
|
110
|
+
border: none;
|
|
111
|
+
border-right: 1px solid var(--pie-primary, #007bff);
|
|
112
|
+
color: var(--pie-primary, #007bff);
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
padding: 4px 8px;
|
|
115
|
+
font-size: 12px;
|
|
116
|
+
transition: background-color 0.2s, color 0.2s;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.zoom-btn:last-child {
|
|
120
|
+
border-right: none;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.zoom-btn:hover {
|
|
124
|
+
background-color: rgba(0, 123, 255, 0.1);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.zoom-btn.active {
|
|
128
|
+
background-color: var(--pie-primary, #007bff);
|
|
129
|
+
color: white;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.zoom-btn:focus-visible {
|
|
133
|
+
outline: 2px solid var(--pie-primary, #007bff);
|
|
134
|
+
outline-offset: 2px;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.btn-label {
|
|
138
|
+
font-size: 0.8em;
|
|
139
|
+
}
|
|
140
|
+
</style>
|