@hkdigital/lib-core 0.5.17 → 0.5.19

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.
@@ -3,34 +3,28 @@
3
3
 
4
4
  import {
5
5
  getGameWidthOnLandscape,
6
- getGameWidthOnPortrait,
7
- isIOS,
8
- isIpadOS,
9
- getOS,
10
- getIsMobile
6
+ getGameWidthOnPortrait
11
7
  } from './gamebox.util.js';
12
8
 
9
+ import {
10
+ getIsAppleMobile,
11
+ getIsIpadOS,
12
+ getIsMobile
13
+ } from '../../../browser/info/device.js';
14
+
15
+ import {
16
+ getIsPwa,
17
+ getIsFullscreen
18
+ } from '../../../browser/info/display.js';
19
+
13
20
  import ScaledContainer from './ScaledContainer.svelte';
14
21
 
15
22
  /**
16
- * @typedef {{
17
- * isLandscape: boolean,
18
- * isPortrait: boolean,
19
- * isMobile:boolean,
20
- * isIos:boolean,
21
- * isAndroid:boolean,
22
- * os:'Android'|'iOS',
23
- * isFullscreen:boolean,
24
- * isDevMode:boolean,
25
- * requestDevmode:function,
26
- * requestFullscreen:function,
27
- * gameWidth: number,
28
- * gameHeight: number
29
- * }} SnippetParams
23
+ * @typedef {import('./typedef.js').SnippetParams} SnippetParams
30
24
  */
31
25
 
32
26
  /**
33
- * @typedef {import('svelte').Snippet<[SnippetParams]>} GameBoxSnippet
27
+ * @typedef {import('./typedef.js').GameBoxSnippet} GameBoxSnippet
34
28
  */
35
29
 
36
30
  /**
@@ -97,11 +91,6 @@
97
91
  let windowWidth = $state();
98
92
  let windowHeight = $state();
99
93
 
100
- let debouncedWindowWidth = $state();
101
- let debouncedWindowHeight = $state();
102
-
103
- let debounceTimer;
104
-
105
94
  let gameWidthOnPortrait = $state();
106
95
  let gameHeightOnPortrait = $state();
107
96
 
@@ -132,47 +121,19 @@
132
121
  } );
133
122
 
134
123
  // iPad is also considered Apple mobile
135
- const isAppleMobile = isIOS();
136
-
137
- let os = $state();
138
- let isIos = $derived(os === 'iOS');
139
- let isAndroid = $derived(os === 'Android');
140
-
141
- // Debounce window dimensions on iOS to skip intermediate resize events
142
- let skipNextResize = false;
143
- let resetTimer;
144
-
145
- $effect(() => {
146
- if (isAppleMobile && windowWidth && windowHeight) {
147
- if (skipNextResize) {
148
- skipNextResize = false;
149
- return; // Skip first of the two resize events
150
- }
124
+ const isAppleMobile = getIsAppleMobile();
151
125
 
152
- // skipNextResize = true; // disabled to test <<
126
+ let isIos = $state(false);
127
+ let isAndroid = $state(false);
128
+ let isIpadOS = $state(false);
153
129
 
154
- debouncedWindowWidth = windowWidth;
155
- debouncedWindowHeight = windowHeight;
156
-
157
- // Reset flag after resize events settle
158
- clearTimeout(resetTimer);
159
- resetTimer = setTimeout(() => {
160
- skipNextResize = false;
161
- }, 500);
162
- } else {
163
- // Non-iOS: use dimensions immediately
164
- debouncedWindowWidth = windowWidth;
165
- debouncedWindowHeight = windowHeight;
166
- }
167
- });
168
-
169
- // Update iOS dimensions when debounced window size changes
130
+ // Update iOS dimensions when window size changes
170
131
  $effect(() => {
171
132
  if (
172
133
  isPwa &&
173
134
  isAppleMobile &&
174
- debouncedWindowWidth &&
175
- debouncedWindowHeight
135
+ windowWidth &&
136
+ windowHeight
176
137
  ) {
177
138
  updateIosWidthHeight();
178
139
  }
@@ -285,13 +246,13 @@
285
246
 
286
247
  isMobile = getIsMobile();
287
248
 
288
- os = getOS();
249
+ isIos = isAppleMobile;
250
+ isAndroid = !isAppleMobile && /Android/.test(navigator.userAgent);
251
+ isIpadOS = getIsIpadOS();
289
252
 
290
253
  isFullscreen = getIsFullscreen();
291
254
 
292
- isPwa = window.matchMedia(
293
- '(display-mode: fullscreen) or (display-mode: standalone)'
294
- ).matches;
255
+ isPwa = getIsPwa();
295
256
 
296
257
  updateIosWidthHeight();
297
258
 
@@ -364,26 +325,6 @@
364
325
  }
365
326
  });
366
327
 
367
- /**
368
- * Returns true if the window is in full screen
369
- * - Checks if CSS thinks we're in fullscreen mode
370
- * - Checks if there is a fullscreen element (for safari)
371
- */
372
- function getIsFullscreen() {
373
- if (
374
- window.matchMedia(
375
- '(display-mode: fullscreen) or (display-mode: standalone)'
376
- ).matches
377
- ) {
378
- return true;
379
- } else if (document.fullscreenElement) {
380
- // Safari
381
- return true;
382
- }
383
-
384
- return false;
385
- }
386
-
387
328
  async function requestFullscreen() {
388
329
  // console.debug('Request full screen');
389
330
  show = false;
@@ -484,7 +425,8 @@
484
425
  isMobile,
485
426
  isIos,
486
427
  isAndroid,
487
- os,
428
+ isIpadOS,
429
+ isPwa,
488
430
  isFullscreen,
489
431
  isDevMode,
490
432
  requestDevmode,
@@ -508,7 +450,8 @@
508
450
  isMobile,
509
451
  isIos,
510
452
  isAndroid,
511
- os,
453
+ isIpadOS,
454
+ isPwa,
512
455
  isFullscreen,
513
456
  isDevMode,
514
457
  requestDevmode,
@@ -532,7 +475,8 @@
532
475
  isMobile,
533
476
  isIos,
534
477
  isAndroid,
535
- os,
478
+ isIpadOS,
479
+ isPwa,
536
480
  isFullscreen,
537
481
  isDevMode,
538
482
  requestDevmode,
@@ -556,7 +500,8 @@
556
500
  isMobile,
557
501
  isIos,
558
502
  isAndroid,
559
- os,
503
+ isIpadOS,
504
+ isPwa,
560
505
  isFullscreen,
561
506
  isDevMode,
562
507
  requestDevmode,
@@ -581,7 +526,8 @@
581
526
  isMobile,
582
527
  isIos,
583
528
  isAndroid,
584
- os,
529
+ isIpadOS,
530
+ isPwa,
585
531
  isFullscreen,
586
532
  isDevMode,
587
533
  requestDevmode,
@@ -605,7 +551,8 @@
605
551
  isMobile,
606
552
  isIos,
607
553
  isAndroid,
608
- os,
554
+ isIpadOS,
555
+ isPwa,
609
556
  isFullscreen,
610
557
  isDevMode,
611
558
  requestDevmode,
@@ -87,74 +87,8 @@ declare const GameBox: import("svelte").Component<{
87
87
  max: number;
88
88
  };
89
89
  };
90
- snippetLandscape?: import("svelte").Snippet<[{
91
- isLandscape: boolean;
92
- isPortrait: boolean;
93
- isMobile: boolean;
94
- isIos: boolean;
95
- isAndroid: boolean;
96
- os: "Android" | "iOS";
97
- isFullscreen: boolean;
98
- isDevMode: boolean;
99
- requestDevmode: Function;
100
- requestFullscreen: Function;
101
- gameWidth: number;
102
- gameHeight: number;
103
- }]>;
104
- snippetPortrait?: import("svelte").Snippet<[{
105
- isLandscape: boolean;
106
- isPortrait: boolean;
107
- isMobile: boolean;
108
- isIos: boolean;
109
- isAndroid: boolean;
110
- os: "Android" | "iOS";
111
- isFullscreen: boolean;
112
- isDevMode: boolean;
113
- requestDevmode: Function;
114
- requestFullscreen: Function;
115
- gameWidth: number;
116
- gameHeight: number;
117
- }]>;
118
- snippetRequireFullscreen?: import("svelte").Snippet<[{
119
- isLandscape: boolean;
120
- isPortrait: boolean;
121
- isMobile: boolean;
122
- isIos: boolean;
123
- isAndroid: boolean;
124
- os: "Android" | "iOS";
125
- isFullscreen: boolean;
126
- isDevMode: boolean;
127
- requestDevmode: Function;
128
- requestFullscreen: Function;
129
- gameWidth: number;
130
- gameHeight: number;
131
- }]>;
132
- snippetInstallOnHomeScreen?: import("svelte").Snippet<[{
133
- isLandscape: boolean;
134
- isPortrait: boolean;
135
- isMobile: boolean;
136
- isIos: boolean;
137
- isAndroid: boolean;
138
- os: "Android" | "iOS";
139
- isFullscreen: boolean;
140
- isDevMode: boolean;
141
- requestDevmode: Function;
142
- requestFullscreen: Function;
143
- gameWidth: number;
144
- gameHeight: number;
145
- }]>;
90
+ snippetLandscape?: import("svelte").Snippet<[import("./typedef.js").SnippetParams]>;
91
+ snippetPortrait?: import("svelte").Snippet<[import("./typedef.js").SnippetParams]>;
92
+ snippetRequireFullscreen?: import("svelte").Snippet<[import("./typedef.js").SnippetParams]>;
93
+ snippetInstallOnHomeScreen?: import("svelte").Snippet<[import("./typedef.js").SnippetParams]>;
146
94
  }, {}, "">;
147
- type SnippetParams = {
148
- isLandscape: boolean;
149
- isPortrait: boolean;
150
- isMobile: boolean;
151
- isIos: boolean;
152
- isAndroid: boolean;
153
- os: "Android" | "iOS";
154
- isFullscreen: boolean;
155
- isDevMode: boolean;
156
- requestDevmode: Function;
157
- requestFullscreen: Function;
158
- gameWidth: number;
159
- gameHeight: number;
160
- };
@@ -1,27 +1,3 @@
1
- /**
2
- * Check if the device is running iOS (iPhone, iPod, or iPad)
3
- *
4
- * @returns {boolean} true if iOS device
5
- */
6
- export function isIOS(): boolean;
7
- /**
8
- * Check if the device is running iPadOS
9
- *
10
- * @returns {boolean} true if iPadOS device
11
- */
12
- export function isIpadOS(): boolean;
13
- /**
14
- * Get the operating system of the device
15
- *
16
- * @returns {'iOS'|'Android'|'unknown'} operating system
17
- */
18
- export function getOS(): "iOS" | "Android" | "unknown";
19
- /**
20
- * Check if the device is a mobile phone or tablet
21
- *
22
- * @returns {boolean} true if mobile device
23
- */
24
- export function getIsMobile(): boolean;
25
1
  /**
26
2
  * Get game width for landscape mode
27
3
  *
@@ -2,67 +2,6 @@ export const ERROR_WINDOW_SIZE_NOT_LANDSCAPE = 'Window size is not landsccape';
2
2
 
3
3
  export const ERROR_WINDOW_SIZE_NOT_PORTRAIT = 'Window size is not portrait';
4
4
 
5
- /**
6
- * Check if the device is running iOS (iPhone, iPod, or iPad)
7
- *
8
- * @returns {boolean} true if iOS device
9
- */
10
- export function isIOS() {
11
- if (/iPad|iPhone|iPod/.test(navigator.platform)) {
12
- return true;
13
- } else {
14
- return navigator.maxTouchPoints &&
15
- navigator.maxTouchPoints > 2 &&
16
- /MacIntel/.test(navigator.platform);
17
- }
18
- }
19
-
20
- /**
21
- * Check if the device is running iPadOS
22
- *
23
- * @returns {boolean} true if iPadOS device
24
- */
25
- export function isIpadOS() {
26
- return navigator.maxTouchPoints &&
27
- navigator.maxTouchPoints > 2 &&
28
- /MacIntel/.test(navigator.platform);
29
- }
30
-
31
- /**
32
- * Get the operating system of the device
33
- *
34
- * @returns {'iOS'|'Android'|'unknown'} operating system
35
- */
36
- export function getOS() {
37
- if (isIOS()) {
38
- return 'iOS';
39
- } else if (/Android/.test(navigator.userAgent)) {
40
- return 'Android';
41
- } else {
42
- return 'unknown';
43
- }
44
- }
45
-
46
- /**
47
- * Check if the device is a mobile phone or tablet
48
- *
49
- * @returns {boolean} true if mobile device
50
- */
51
- export function getIsMobile() {
52
- // @ts-ignore
53
- if (navigator?.userAgentData?.mobile !== undefined) {
54
- // Supports for mobile flag
55
- // @ts-ignore
56
- return navigator.userAgentData.mobile;
57
- } else if (isIOS()) {
58
- return true;
59
- } else if (/Android/.test(navigator.userAgent)) {
60
- return true;
61
- }
62
-
63
- return false;
64
- }
65
-
66
5
  /**
67
6
  * Get game width for landscape mode
68
7
  *
@@ -0,0 +1,16 @@
1
+ export type SnippetParams = {
2
+ isLandscape: boolean;
3
+ isPortrait: boolean;
4
+ isMobile: boolean;
5
+ isIos: boolean;
6
+ isAndroid: boolean;
7
+ isIpadOS: boolean;
8
+ isPwa: boolean;
9
+ isFullscreen: boolean;
10
+ isDevMode: boolean;
11
+ requestDevmode: Function;
12
+ requestFullscreen: Function;
13
+ gameWidth: number;
14
+ gameHeight: number;
15
+ };
16
+ export type GameBoxSnippet = import("svelte").Snippet<[SnippetParams]>;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @typedef {{
3
+ * isLandscape: boolean,
4
+ * isPortrait: boolean,
5
+ * isMobile: boolean,
6
+ * isIos: boolean,
7
+ * isAndroid: boolean,
8
+ * isIpadOS: boolean,
9
+ * isPwa: boolean,
10
+ * isFullscreen: boolean,
11
+ * isDevMode: boolean,
12
+ * requestDevmode: function,
13
+ * requestFullscreen: function,
14
+ * gameWidth: number,
15
+ * gameHeight: number
16
+ * }} SnippetParams
17
+ */
18
+
19
+ /**
20
+ * @typedef {import('svelte').Snippet<[SnippetParams]>} GameBoxSnippet
21
+ */
22
+
23
+ export {};
@@ -1,5 +1,6 @@
1
1
  export * from "./button-group/typedef.js";
2
2
  export * from "./drag-drop/typedef.js";
3
+ export * from "./game-box/typedef.js";
3
4
  export * from "./image-box/typedef.js";
4
5
  export * from "./presenter/typedef.js";
5
6
  export * from "./tab-bar/typedef.js";
@@ -1,5 +1,6 @@
1
1
  export * from './button-group/typedef.js';
2
2
  export * from './drag-drop/typedef.js';
3
+ export * from './game-box/typedef.js';
3
4
  export * from './image-box/typedef.js';
4
5
  export * from './presenter/typedef.js';
5
6
  export * from './tab-bar/typedef.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-core",
3
- "version": "0.5.17",
3
+ "version": "0.5.19",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"
@@ -73,18 +73,20 @@
73
73
  },
74
74
  "./*": "./dist/*"
75
75
  },
76
+ "dependencies": {
77
+ "@tailwindcss/postcss": "^4.1.11",
78
+ "postcss": "^8.5.6"
79
+ },
76
80
  "peerDependencies": {
77
81
  "@eslint/js": "^9.33.0",
78
82
  "@skeletonlabs/skeleton": "^3.1.7",
79
83
  "@steeze-ui/heroicons": "^2.4.2",
80
84
  "@sveltejs/kit": "^2.37.1",
81
- "@tailwindcss/postcss": "^4.1.11",
82
85
  "autoprefixer": "^10.4.21",
83
86
  "eslint-plugin-import": "^2.32.0",
84
87
  "jsonwebtoken": "^9.0.0",
85
88
  "pino": "^9.8.0",
86
89
  "pino-pretty": "^13.1.1",
87
- "postcss": "^8.5.6",
88
90
  "runed": "^0.31.1",
89
91
  "svelte": "^5.38.1",
90
92
  "svelte-preprocess": "^6.0.3",
@@ -102,7 +104,6 @@
102
104
  "@sveltejs/kit": "^2.47.0",
103
105
  "@sveltejs/package": "^2.5.4",
104
106
  "@sveltejs/vite-plugin-svelte": "^6.2.1",
105
- "@tailwindcss/postcss": "^4.1.14",
106
107
  "@tailwindcss/typography": "^0.5.19",
107
108
  "@testing-library/svelte": "^5.2.8",
108
109
  "@testing-library/user-event": "^14.6.1",
@@ -121,8 +122,6 @@
121
122
  "npm-run-all": "^4.1.5",
122
123
  "pino": "^9.13.1",
123
124
  "pino-pretty": "^13.1.2",
124
- "postcss": "^8.5.6",
125
- "postcss-mixins": "^12.1.2",
126
125
  "prettier": "^3.6.2",
127
126
  "prettier-plugin-svelte": "^3.4.0",
128
127
  "prettier-plugin-tailwindcss": "^0.6.14",