@pie-players/pie-tool-ruler 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/dist/index.d.ts +1 -0
- package/dist/tool-ruler.js +7750 -6679
- package/package.json +15 -6
- package/tool-ruler.svelte +53 -32
- package/dist/tool-ruler.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-tool-ruler",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ruler measurement 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-ruler"
|
|
9
10
|
},
|
|
10
11
|
"publishConfig": {
|
|
11
12
|
"access": "public"
|
|
@@ -44,9 +45,9 @@
|
|
|
44
45
|
"unpkg": "./dist/tool-ruler.js",
|
|
45
46
|
"jsdelivr": "./dist/tool-ruler.js",
|
|
46
47
|
"dependencies": {
|
|
47
|
-
"@pie-players/pie-assessment-toolkit": "0.2.
|
|
48
|
-
"@pie-players/pie-
|
|
49
|
-
"@
|
|
48
|
+
"@pie-players/pie-assessment-toolkit": "0.2.9",
|
|
49
|
+
"@pie-players/pie-context": "0.1.1",
|
|
50
|
+
"@pie-players/pie-players-shared": "0.2.5",
|
|
50
51
|
"daisyui": "^5.5.18",
|
|
51
52
|
"moveable": "^0.53.0"
|
|
52
53
|
},
|
|
@@ -64,5 +65,13 @@
|
|
|
64
65
|
"typescript": "^5.7.0",
|
|
65
66
|
"vite": "^7.0.8",
|
|
66
67
|
"vite-plugin-dts": "^4.5.3"
|
|
67
|
-
}
|
|
68
|
+
},
|
|
69
|
+
"homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/tool-ruler#readme",
|
|
70
|
+
"bugs": {
|
|
71
|
+
"url": "https://github.com/pie-framework/pie-players/issues"
|
|
72
|
+
},
|
|
73
|
+
"engines": {
|
|
74
|
+
"node": ">=18.0.0"
|
|
75
|
+
},
|
|
76
|
+
"sideEffects": true
|
|
68
77
|
}
|
package/tool-ruler.svelte
CHANGED
|
@@ -1,31 +1,40 @@
|
|
|
1
1
|
<svelte:options
|
|
2
2
|
customElement={{
|
|
3
3
|
tag: 'pie-tool-ruler',
|
|
4
|
-
shadow: '
|
|
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
|
-
import
|
|
15
|
-
|
|
13
|
+
import {
|
|
14
|
+
connectToolRuntimeContext,
|
|
15
|
+
ZIndexLayer,
|
|
16
|
+
} from '@pie-players/pie-assessment-toolkit';
|
|
17
|
+
import type {
|
|
18
|
+
AssessmentToolkitRuntimeContext,
|
|
19
|
+
IToolCoordinator,
|
|
20
|
+
} from '@pie-players/pie-assessment-toolkit';
|
|
16
21
|
import Moveable from 'moveable';
|
|
17
22
|
import { onDestroy, onMount } from 'svelte';
|
|
18
23
|
import rulerCm from './ruler-cm.svg';
|
|
19
24
|
import rulerInches from './ruler-inches.svg';
|
|
20
25
|
|
|
21
26
|
// Props
|
|
22
|
-
let { visible = false, toolId = 'ruler'
|
|
27
|
+
let { visible = false, toolId = 'ruler' }: { 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 announceText = $state('');
|
|
30
39
|
let unit = $state<'inches' | 'cm'>('inches');
|
|
31
40
|
let moveable: Moveable | null = null;
|
|
@@ -38,6 +47,13 @@
|
|
|
38
47
|
const ROTATE_STEP = 5; // degrees
|
|
39
48
|
const FINE_ROTATE_STEP = 1; // degrees
|
|
40
49
|
|
|
50
|
+
$effect(() => {
|
|
51
|
+
if (!containerEl) return;
|
|
52
|
+
return connectToolRuntimeContext(containerEl, (value: AssessmentToolkitRuntimeContext) => {
|
|
53
|
+
runtimeContext = value;
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
41
57
|
let currentRuler = $derived(unit === 'inches' ? rulerInches : rulerCm);
|
|
42
58
|
|
|
43
59
|
function announce(message: string) {
|
|
@@ -247,7 +263,7 @@
|
|
|
247
263
|
|
|
248
264
|
{#if visible && isBrowser}
|
|
249
265
|
<!-- Screen reader announcements -->
|
|
250
|
-
<div class="sr-only" role="status" aria-live="polite" aria-atomic="true">
|
|
266
|
+
<div class="pie-sr-only" role="status" aria-live="polite" aria-atomic="true">
|
|
251
267
|
{announceText}
|
|
252
268
|
</div>
|
|
253
269
|
|
|
@@ -255,7 +271,7 @@
|
|
|
255
271
|
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
256
272
|
<div
|
|
257
273
|
bind:this={containerEl}
|
|
258
|
-
class="ruler
|
|
274
|
+
class="pie-tool-ruler"
|
|
259
275
|
data-moveablejs-tool-id={toolId}
|
|
260
276
|
onpointerdown={() => coordinator?.bringToFront(containerEl)}
|
|
261
277
|
onkeydown={handleKeyDown}
|
|
@@ -264,19 +280,24 @@
|
|
|
264
280
|
aria-label="Ruler tool. Use arrow keys to move, Shift+arrows to rotate, PageUp/PageDown for fine rotation, U to toggle units. Current unit: {unit}"
|
|
265
281
|
aria-roledescription="Draggable and rotatable ruler measurement tool"
|
|
266
282
|
>
|
|
267
|
-
<div class="
|
|
283
|
+
<div class="pie-tool-ruler__container">
|
|
268
284
|
<img
|
|
269
|
-
class="
|
|
285
|
+
class="pie-tool-ruler__image"
|
|
270
286
|
src={currentRuler}
|
|
271
287
|
alt="Ruler showing {unit}"
|
|
272
288
|
draggable="false"
|
|
273
289
|
/>
|
|
274
290
|
|
|
275
291
|
<!-- Unit toggle button group (matching production implementation style) -->
|
|
276
|
-
<div
|
|
292
|
+
<div
|
|
293
|
+
class="pie-tool-ruler__unit-group"
|
|
294
|
+
role="group"
|
|
295
|
+
aria-label="Ruler unit selection"
|
|
296
|
+
onpointerdown={(e) => e.stopPropagation()}
|
|
297
|
+
>
|
|
277
298
|
<button
|
|
278
|
-
class="
|
|
279
|
-
class:active={unit === 'inches'}
|
|
299
|
+
class="pie-tool-ruler__unit-button"
|
|
300
|
+
class:pie-tool-ruler__unit-button--active={unit === 'inches'}
|
|
280
301
|
onclick={() => {
|
|
281
302
|
unit = 'inches';
|
|
282
303
|
announce('Switched to inches');
|
|
@@ -285,11 +306,11 @@
|
|
|
285
306
|
aria-label="Switch to inches"
|
|
286
307
|
aria-pressed={unit === 'inches'}
|
|
287
308
|
>
|
|
288
|
-
<span class="
|
|
309
|
+
<span class="pie-tool-ruler__unit-label">Inches</span>
|
|
289
310
|
</button>
|
|
290
311
|
<button
|
|
291
|
-
class="
|
|
292
|
-
class:active={unit === 'cm'}
|
|
312
|
+
class="pie-tool-ruler__unit-button"
|
|
313
|
+
class:pie-tool-ruler__unit-button--active={unit === 'cm'}
|
|
293
314
|
onclick={() => {
|
|
294
315
|
unit = 'cm';
|
|
295
316
|
announce('Switched to centimeters');
|
|
@@ -298,7 +319,7 @@
|
|
|
298
319
|
aria-label="Switch to centimeters"
|
|
299
320
|
aria-pressed={unit === 'cm'}
|
|
300
321
|
>
|
|
301
|
-
<span class="
|
|
322
|
+
<span class="pie-tool-ruler__unit-label">Centimeters</span>
|
|
302
323
|
</button>
|
|
303
324
|
</div>
|
|
304
325
|
</div>
|
|
@@ -306,7 +327,7 @@
|
|
|
306
327
|
{/if}
|
|
307
328
|
|
|
308
329
|
<style>
|
|
309
|
-
.sr-only {
|
|
330
|
+
.pie-sr-only {
|
|
310
331
|
position: absolute;
|
|
311
332
|
width: 1px;
|
|
312
333
|
height: 1px;
|
|
@@ -318,7 +339,7 @@
|
|
|
318
339
|
border-width: 0;
|
|
319
340
|
}
|
|
320
341
|
|
|
321
|
-
.ruler
|
|
342
|
+
.pie-tool-ruler {
|
|
322
343
|
border-left: 1px solid #000;
|
|
323
344
|
border-right: 1px solid #000;
|
|
324
345
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); /* Matching production implementation shadow */
|
|
@@ -333,35 +354,35 @@
|
|
|
333
354
|
width: 540px; /* Matching production implementation frame width */
|
|
334
355
|
}
|
|
335
356
|
|
|
336
|
-
.ruler
|
|
357
|
+
.pie-tool-ruler:focus {
|
|
337
358
|
outline: 3px solid #4A90E2;
|
|
338
359
|
outline-offset: 2px;
|
|
339
360
|
}
|
|
340
361
|
|
|
341
|
-
.ruler
|
|
362
|
+
.pie-tool-ruler:focus-visible {
|
|
342
363
|
outline: 3px solid #4A90E2;
|
|
343
364
|
outline-offset: 2px;
|
|
344
365
|
}
|
|
345
366
|
|
|
346
|
-
.
|
|
367
|
+
.pie-tool-ruler__container {
|
|
347
368
|
background-color: rgb(255 255 255 / 90%); /* Matching production implementation semi-transparent white background */
|
|
348
369
|
position: relative;
|
|
349
370
|
}
|
|
350
371
|
|
|
351
|
-
.
|
|
352
|
-
.
|
|
372
|
+
.pie-tool-ruler__container,
|
|
373
|
+
.pie-tool-ruler__image {
|
|
353
374
|
height: 100px; /* Matching production implementation ruler height */
|
|
354
375
|
width: 864px; /* Matching production implementation ruler width */
|
|
355
376
|
}
|
|
356
377
|
|
|
357
|
-
.
|
|
378
|
+
.pie-tool-ruler__image {
|
|
358
379
|
position: relative;
|
|
359
380
|
z-index: 2;
|
|
360
381
|
display: block;
|
|
361
382
|
}
|
|
362
383
|
|
|
363
384
|
/* Unit toggle button group (matching production implementation style) */
|
|
364
|
-
.
|
|
385
|
+
.pie-tool-ruler__unit-group {
|
|
365
386
|
border: 1px solid var(--pie-primary, #3f51b5); /* Matching production implementation primary color */
|
|
366
387
|
bottom: 0.5rem; /* Matching production implementation positioning */
|
|
367
388
|
left: 0.5rem; /* Matching production implementation positioning */
|
|
@@ -373,7 +394,7 @@
|
|
|
373
394
|
overflow: hidden;
|
|
374
395
|
}
|
|
375
396
|
|
|
376
|
-
.
|
|
397
|
+
.pie-tool-ruler__unit-button {
|
|
377
398
|
background: white;
|
|
378
399
|
border: none;
|
|
379
400
|
border-right: 1px solid var(--pie-primary, #3f51b5);
|
|
@@ -384,25 +405,25 @@
|
|
|
384
405
|
transition: background-color 0.2s, color 0.2s;
|
|
385
406
|
}
|
|
386
407
|
|
|
387
|
-
.
|
|
408
|
+
.pie-tool-ruler__unit-button:last-child {
|
|
388
409
|
border-right: none;
|
|
389
410
|
}
|
|
390
411
|
|
|
391
|
-
.
|
|
412
|
+
.pie-tool-ruler__unit-button:hover {
|
|
392
413
|
background-color: rgba(63, 81, 181, 0.1);
|
|
393
414
|
}
|
|
394
415
|
|
|
395
|
-
.
|
|
416
|
+
.pie-tool-ruler__unit-button.pie-tool-ruler__unit-button--active {
|
|
396
417
|
background-color: var(--pie-primary, #3f51b5);
|
|
397
418
|
color: white;
|
|
398
419
|
}
|
|
399
420
|
|
|
400
|
-
.
|
|
421
|
+
.pie-tool-ruler__unit-button:focus-visible {
|
|
401
422
|
outline: 2px solid var(--pie-primary, #3f51b5);
|
|
402
423
|
outline-offset: 2px;
|
|
403
424
|
}
|
|
404
425
|
|
|
405
|
-
.
|
|
426
|
+
.pie-tool-ruler__unit-label {
|
|
406
427
|
display: inline-block;
|
|
407
428
|
font-size: 12px;
|
|
408
429
|
line-height: 1.4;
|