@joewinke/jatui 0.27.1 → 0.29.0

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 (46) hide show
  1. package/CLAUDE.md +37 -0
  2. package/dist/assets/sounds/README.md +27 -14
  3. package/dist/assets/sounds/attention.d.ts +1 -0
  4. package/dist/assets/sounds/attention.js +4 -0
  5. package/dist/assets/sounds/chime.d.ts +1 -0
  6. package/dist/assets/sounds/chime.js +4 -0
  7. package/dist/assets/sounds/error-soft.d.ts +1 -0
  8. package/dist/assets/sounds/error-soft.js +4 -0
  9. package/dist/assets/sounds/select.d.ts +1 -0
  10. package/dist/assets/sounds/select.js +4 -0
  11. package/dist/assets/sounds/tick.d.ts +1 -0
  12. package/dist/assets/sounds/tick.js +4 -0
  13. package/dist/index.d.ts +4 -1
  14. package/dist/index.js +10 -2
  15. package/dist/motion/easing.d.ts +14 -0
  16. package/dist/motion/easing.js +67 -0
  17. package/dist/motion/index.d.ts +17 -0
  18. package/dist/motion/index.js +11 -0
  19. package/dist/motion/level.d.ts +88 -0
  20. package/dist/motion/level.js +132 -0
  21. package/dist/motion/store.d.ts +40 -0
  22. package/dist/motion/store.js +132 -0
  23. package/dist/motion/transitions.d.ts +72 -0
  24. package/dist/motion/transitions.js +112 -0
  25. package/dist/sound/SoundSettings.svelte +209 -0
  26. package/dist/sound/SoundSettings.svelte.d.ts +18 -0
  27. package/dist/sound/backend.d.ts +24 -0
  28. package/dist/sound/backend.js +96 -0
  29. package/dist/sound/index.d.ts +20 -0
  30. package/dist/sound/index.js +14 -0
  31. package/dist/sound/level.d.ts +42 -0
  32. package/dist/sound/level.js +63 -0
  33. package/dist/sound/names.d.ts +62 -0
  34. package/dist/sound/names.js +196 -0
  35. package/dist/sound/player.d.ts +73 -0
  36. package/dist/sound/player.js +158 -0
  37. package/dist/sound/policy.d.ts +36 -0
  38. package/dist/sound/policy.js +56 -0
  39. package/dist/sound/preferences.d.ts +76 -0
  40. package/dist/sound/preferences.js +152 -0
  41. package/dist/styles/motion.css +88 -9
  42. package/dist/transitions/glide.d.ts +18 -6
  43. package/dist/transitions/glide.js +26 -31
  44. package/dist/utils/sound.d.ts +6 -0
  45. package/dist/utils/sound.js +12 -54
  46. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
- // direction taxonomy after animista.net (Ana Travas, BSD-2-Clause site license); keyframes re-authored on jatui motion tokens
1
+ import { MOTION_LEVEL_TRAVEL } from '../motion/level';
2
+ import { resolveMotionTiming } from '../motion/transitions';
2
3
  /** Map from direction → [dx, dy] unit vector for the entrance travel. */
3
4
  const ORIGIN_VECTOR = {
4
5
  center: [0, 0],
@@ -19,44 +20,38 @@ const ORIGIN_VECTOR = {
19
20
  *
20
21
  * <div in:glide={{ from: 'bottom' }} out:glide={{ from: 'bottom' }}>…</div>
21
22
  *
22
- * Reduced-motion: opacity fade only (no translate, scale, or blur).
23
+ * Level-aware (jatui-j6833): duration, delay and travel scale with the
24
+ * surface's `data-motion` level and ease on the `--motion-glide` curve.
25
+ * Reduced-motion: duration 0 — the element lands in its end state.
23
26
  */
24
27
  export function glide(node, params = {}) {
25
- const { from = 'bottom', distance = 16, scale, blur = false, duration = 200, delay = 0, } = params;
26
- const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
28
+ const { from = 'bottom', distance, scale, blur = false } = params;
29
+ const { ctx, delay, duration, easing } = resolveMotionTiming(node, params, {
30
+ duration: 'enter',
31
+ easing: 'glide'
32
+ });
27
33
  const [ux, uy] = ORIGIN_VECTOR[from];
34
+ const travel = distance === undefined
35
+ ? ctx.travel
36
+ : distance * (ctx.travel / MOTION_LEVEL_TRAVEL.standard);
28
37
  // Entrance start state — element travels FROM this position TO its natural position
29
- const tx = prefersReduced ? 0 : ux * distance;
30
- const ty = prefersReduced ? 0 : uy * distance;
31
- const s = (!prefersReduced && scale !== undefined) ? scale : 1;
32
- const blurPx = (!prefersReduced && blur) ? 4 : 0;
33
- function buildTransform(progress) {
34
- // progress goes 0 → 1 on enter; Svelte reverses for exit
35
- const invP = 1 - progress;
36
- const x = tx * invP;
37
- const y = ty * invP;
38
- const sc = 1 - (1 - s) * invP;
39
- const b = blurPx * invP;
40
- let t = `translate(${x}px, ${y}px)`;
41
- if (s !== 1)
42
- t += ` scale(${sc})`;
43
- const filter = b > 0 ? `blur(${b.toFixed(1)}px)` : '';
44
- return { transform: t, filter };
45
- }
38
+ const tx = ux * travel;
39
+ const ty = uy * travel;
40
+ const s = !ctx.reduced && scale !== undefined ? scale : 1;
41
+ const blurPx = !ctx.reduced && blur ? 4 : 0;
46
42
  return {
47
43
  delay,
48
44
  duration,
49
- easing: (t) => t, // easing applied via CSS var below
45
+ easing,
50
46
  css(t) {
51
- // t: 0 = start, 1 = end (for `in:`; Svelte inverts for `out:`)
52
- const { transform, filter } = buildTransform(t);
53
- // Apply the glide easing via CSS transition so the CSS var is honored
54
- return `
55
- opacity: ${t};
56
- transform: ${transform};
57
- ${filter ? `filter: ${filter};` : ''}
58
- transition-timing-function: var(--motion-glide, cubic-bezier(0.16, 1, 0.3, 1));
59
- `;
47
+ // t: 0 = start, 1 = end (for `in:`; Svelte inverts for `out:`), already eased
48
+ const invP = 1 - t;
49
+ let transform = `translate(${tx * invP}px, ${ty * invP}px)`;
50
+ if (s !== 1)
51
+ transform += ` scale(${1 - (1 - s) * invP})`;
52
+ const b = blurPx * invP;
53
+ return (`opacity: ${Math.min(1, Math.max(0, t))}; transform: ${transform};` +
54
+ (b > 0 ? ` filter: blur(${b.toFixed(1)}px);` : ''));
60
55
  },
61
56
  };
62
57
  }
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Legacy sound API (pre-semantic). Kept source-compatible, but every call now
3
+ * routes through the shared preferences store and player in `../sound`, so
4
+ * old call sites obey volume, categories, quiet hours and the hidden-tab rule
5
+ * too. New code: `import { playSound, getSoundPreferences } from '../../../dist'`.
6
+ */
1
7
  export declare function isSoundEnabled(): boolean;
2
8
  export declare function setSoundEnabled(enabled: boolean): void;
3
9
  export declare function registerSound(name: string, dataUri: string): Promise<void>;
@@ -1,62 +1,20 @@
1
- let ctx = null;
2
- const buffers = new Map();
3
- const STORAGE_KEY = 'jatui-sound-enabled';
4
- function getContext() {
5
- if (ctx)
6
- return ctx;
7
- try {
8
- ctx = new AudioContext();
9
- return ctx;
10
- }
11
- catch {
12
- return null;
13
- }
14
- }
1
+ /**
2
+ * Legacy sound API (pre-semantic). Kept source-compatible, but every call now
3
+ * routes through the shared preferences store and player in `../sound`, so
4
+ * old call sites obey volume, categories, quiet hours and the hidden-tab rule
5
+ * too. New code: `import { playSound, getSoundPreferences } from '../../../dist'`.
6
+ */
7
+ import { getSoundPlayer } from '../sound/player';
8
+ import { getSoundPreferences } from '../sound/preferences';
15
9
  export function isSoundEnabled() {
16
- if (typeof localStorage === 'undefined')
17
- return false;
18
- return localStorage.getItem(STORAGE_KEY) === 'true';
10
+ return getSoundPreferences().get().enabled;
19
11
  }
20
12
  export function setSoundEnabled(enabled) {
21
- if (typeof localStorage === 'undefined')
22
- return;
23
- localStorage.setItem(STORAGE_KEY, String(enabled));
13
+ getSoundPreferences().set({ enabled });
24
14
  }
25
15
  export async function registerSound(name, dataUri) {
26
- const audioCtx = getContext();
27
- if (!audioCtx)
28
- return;
29
- try {
30
- const base64 = dataUri.split(',')[1];
31
- const binary = atob(base64);
32
- const bytes = new Uint8Array(binary.length);
33
- for (let i = 0; i < binary.length; i++)
34
- bytes[i] = binary.charCodeAt(i);
35
- const buffer = await audioCtx.decodeAudioData(bytes.buffer);
36
- buffers.set(name, buffer);
37
- }
38
- catch {
39
- // Silently ignore decode failures — clip may not be supported in this browser
40
- }
16
+ await getSoundPlayer().register(name, dataUri);
41
17
  }
42
18
  export function play(name, options = {}) {
43
- if (!isSoundEnabled())
44
- return;
45
- const audioCtx = getContext();
46
- if (!audioCtx)
47
- return;
48
- const buffer = buffers.get(name);
49
- if (!buffer)
50
- return;
51
- // Resume suspended context (browser autoplay policy requires user gesture first)
52
- if (audioCtx.state === 'suspended') {
53
- audioCtx.resume().catch(() => { });
54
- }
55
- const source = audioCtx.createBufferSource();
56
- const gain = audioCtx.createGain();
57
- gain.gain.value = options.volume ?? 0.15;
58
- source.buffer = buffer;
59
- source.connect(gain);
60
- gain.connect(audioCtx.destination);
61
- source.start();
19
+ getSoundPlayer().play(name, options);
62
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joewinke/jatui",
3
- "version": "0.27.1",
3
+ "version": "0.29.0",
4
4
  "private": false,
5
5
  "description": "Shared Svelte 5 component library for JAT projects",
6
6
  "type": "module",