@multiplatform.one/platform 6.6.0 → 7.0.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.
package/README.md CHANGED
@@ -13,7 +13,7 @@ pnpm add @multiplatform.one/platform
13
13
  ## What it owns
14
14
 
15
15
  - **Detection flags** — `isWeb`, `isNative`, `isIos`, `isAndroid`, `isServer`,
16
- `isClient`, `isTauri`, `isDesktop`, `isExpo`, `isNext`, `isStorybook`,
16
+ `isClient`, `isGnome`, `isTauri`, `isDesktop`, `isExpo`, `isNext`, `isStorybook`,
17
17
  `isChrome`, `isFirefox`, `isWebExtension`, `isChromeExtension`,
18
18
  `isFirefoxExtension`, `isIframe`, `isTouchable`, `isWebTouchable`,
19
19
  `isWindowDefined`, … plus the full `platform` object (`platform.preciseName`)
@@ -29,12 +29,16 @@ pnpm add @multiplatform.one/platform
29
29
  ## Usage
30
30
 
31
31
  ```tsx
32
- import { isNative, isServer, isTauri } from "@multiplatform.one/platform";
32
+ import { isGnome, isNative, isServer, isTauri } from "@multiplatform.one/platform";
33
33
 
34
34
  export function saveFile(contents: string) {
35
35
  if (isServer) return;
36
36
  if (isTauri) {
37
- // desktop path (see @multiplatform.one/desktop)
37
+ // webview desktop path (see @multiplatform.one/desktop)
38
+ return;
39
+ }
40
+ if (isGnome) {
41
+ // GTK desktop path (see @multiplatform.one/desktop)
38
42
  return;
39
43
  }
40
44
  if (isNative) {
@@ -32,6 +32,7 @@ __export(index_exports, {
32
32
  isExpo: () => isExpo,
33
33
  isFirefox: () => isFirefox,
34
34
  isFirefoxExtension: () => isFirefoxExtension,
35
+ isGnome: () => isGnome,
35
36
  isIframe: () => isIframe,
36
37
  isIos: () => isIos,
37
38
  isNative: () => isNative,
@@ -65,6 +66,7 @@ const {
65
66
  isExpo,
66
67
  isFirefox,
67
68
  isFirefoxExtension,
69
+ isGnome,
68
70
  isIframe,
69
71
  isIos,
70
72
  isNative,
@@ -0,0 +1,59 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all) __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
21
+ value: true
22
+ }), mod);
23
+ var index_gnome_exports = {};
24
+ __export(index_gnome_exports, {
25
+ platform: () => platform
26
+ });
27
+ module.exports = __toCommonJS(index_gnome_exports);
28
+ var import_platformBase = require("./platformBase.cjs");
29
+ const platform = {
30
+ ...import_platformBase.platformBase,
31
+ isGnome: true,
32
+ // GTK is a desktop, and it is not a browser — so `isNative` too, which is
33
+ // exactly why Gnome sits ahead of Native in the precision order.
34
+ isDesktop: true,
35
+ isNative: true,
36
+ isClient: true,
37
+ isServer: false,
38
+ isWeb: false,
39
+ isBrowser: false,
40
+ isChrome: false,
41
+ isFirefox: false,
42
+ isIframe: false,
43
+ isStorybook: false,
44
+ isWebExtension: false,
45
+ isChromeExtension: false,
46
+ isFirefoxExtension: false,
47
+ isExpo: false,
48
+ isNext: false,
49
+ // A GTK pointer desktop. Touch exists on some hardware but is not the
50
+ // interaction model the layout should assume.
51
+ isTouchable: false,
52
+ isWebTouchable: false,
53
+ // There is a `window` under the react-gnome polyfills, but it is a stub
54
+ // with no layout, no events and no document. Callers branching on this are
55
+ // asking "can I touch the DOM", and the answer is no.
56
+ isWindowDefined: false
57
+ };
58
+ platform.preciseName = (0, import_platformBase.getPreciseName)(platform);
59
+ platform.broadName = (0, import_platformBase.getBroadName)(platform);
@@ -28,7 +28,13 @@ __export(platformBase_exports, {
28
28
  });
29
29
  module.exports = __toCommonJS(platformBase_exports);
30
30
  var import_constants = require("@tamagui/constants");
31
- const platformOrder = ["Ios", "Android", "Native", "Tauri", "Desktop", "ChromeExtension", "FirefoxExtension", "WebExtension", "Next", "Expo", "Chrome", "Firefox", "Web", "Browser", "Client", "Server", "Iframe", "Storybook"];
31
+ const platformOrder = ["Ios", "Android",
32
+ // Gnome outranks Native: the GTK target reports isNative (it is not a
33
+ // browser) but "gnome" is the precise answer callers want.
34
+ "Gnome", "Native",
35
+ // Tauri outranks Desktop/Web the same way: the webview host reports isWeb
36
+ // and isDesktop, but "tauri" is the precise answer.
37
+ "Tauri", "Desktop", "ChromeExtension", "FirefoxExtension", "WebExtension", "Next", "Expo", "Chrome", "Firefox", "Web", "Browser", "Client", "Server", "Iframe", "Storybook"];
32
38
  const platformBase = {
33
39
  isAndroid: false,
34
40
  isBrowser: false,
@@ -39,6 +45,7 @@ const platformBase = {
39
45
  isExpo: false,
40
46
  isFirefox: false,
41
47
  isFirefoxExtension: false,
48
+ isGnome: false,
42
49
  isIframe: false,
43
50
  isIos: false,
44
51
  isNative: false,
@@ -17,6 +17,7 @@ const {
17
17
  isExpo,
18
18
  isFirefox,
19
19
  isFirefoxExtension,
20
+ isGnome,
20
21
  isIframe,
21
22
  isIos,
22
23
  isNative,
@@ -31,5 +32,5 @@ const {
31
32
  isWebTouchable,
32
33
  isWindowDefined
33
34
  } = platform;
34
- export { isAndroid, isBrowser, isChrome, isChromeExtension, isClient, isDesktop, isExpo, isFirefox, isFirefoxExtension, isIframe, isIos, isNative, isNext, isServer, isStorybook, isTauri, isTouchable, isWeb, isWebExtension, isWebTouchable, isWindowDefined };
35
+ export { isAndroid, isBrowser, isChrome, isChromeExtension, isClient, isDesktop, isExpo, isFirefox, isFirefoxExtension, isGnome, isIframe, isIos, isNative, isNext, isServer, isStorybook, isTauri, isTouchable, isWeb, isWebExtension, isWebTouchable, isWindowDefined };
35
36
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"names":["platform","isAndroid","isBrowser","isChrome","isChromeExtension","isClient","isExpo","isFirefox","isFirefoxExtension","isIframe","isIos","isNative","isNext","isServer","isStorybook","isTauri","isDesktop","isTouchable","isWeb","isWebExtension","isWebTouchable","isWindowDefined"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,QAAgB;AA0BzB,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAhCP,MAAM;EACXC,SAAA;EACAC,SAAA;EACAC,QAAA;EACAC,iBAAA;EACAC,QAAA;EACAC,MAAA;EACAC,SAAA;EACAC,kBAAA;EACAC,QAAA;EACAC,KAAA;EACAC,QAAA;EACAC,MAAA;EACAC,QAAA;EACAC,WAAA;EACAC,OAAA;EACAC,SAAA;EACAC,WAAA;EACAC,KAAA;EACAC,cAAA;EACAC,cAAA;EACAC;AACF,IAAIrB,QAAA","ignoreList":[]}
1
+ {"version":3,"names":["platform","isAndroid","isBrowser","isChrome","isChromeExtension","isClient","isExpo","isFirefox","isFirefoxExtension","isGnome","isIframe","isIos","isNative","isNext","isServer","isStorybook","isTauri","isDesktop","isTouchable","isWeb","isWebExtension","isWebTouchable","isWindowDefined"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,QAAA,QAAgB;AA2BzB,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAjCP,MAAM;EACXC,SAAA;EACAC,SAAA;EACAC,QAAA;EACAC,iBAAA;EACAC,QAAA;EACAC,MAAA;EACAC,SAAA;EACAC,kBAAA;EACAC,OAAA;EACAC,QAAA;EACAC,KAAA;EACAC,QAAA;EACAC,MAAA;EACAC,QAAA;EACAC,WAAA;EACAC,OAAA;EACAC,SAAA;EACAC,WAAA;EACAC,KAAA;EACAC,cAAA;EACAC,cAAA;EACAC;AACF,IAAItB,QAAA","ignoreList":[]}
@@ -0,0 +1,34 @@
1
+ import { getBroadName, getPreciseName, platformBase } from "./platformBase.mjs";
2
+ const platform = {
3
+ ...platformBase,
4
+ isGnome: true,
5
+ // GTK is a desktop, and it is not a browser — so `isNative` too, which is
6
+ // exactly why Gnome sits ahead of Native in the precision order.
7
+ isDesktop: true,
8
+ isNative: true,
9
+ isClient: true,
10
+ isServer: false,
11
+ isWeb: false,
12
+ isBrowser: false,
13
+ isChrome: false,
14
+ isFirefox: false,
15
+ isIframe: false,
16
+ isStorybook: false,
17
+ isWebExtension: false,
18
+ isChromeExtension: false,
19
+ isFirefoxExtension: false,
20
+ isExpo: false,
21
+ isNext: false,
22
+ // A GTK pointer desktop. Touch exists on some hardware but is not the
23
+ // interaction model the layout should assume.
24
+ isTouchable: false,
25
+ isWebTouchable: false,
26
+ // There is a `window` under the react-gnome polyfills, but it is a stub
27
+ // with no layout, no events and no document. Callers branching on this are
28
+ // asking "can I touch the DOM", and the answer is no.
29
+ isWindowDefined: false
30
+ };
31
+ platform.preciseName = getPreciseName(platform);
32
+ platform.broadName = getBroadName(platform);
33
+ export { platform };
34
+ //# sourceMappingURL=index.gnome.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getBroadName","getPreciseName","platformBase","platform","isGnome","isDesktop","isNative","isClient","isServer","isWeb","isBrowser","isChrome","isFirefox","isIframe","isStorybook","isWebExtension","isChromeExtension","isFirefoxExtension","isExpo","isNext","isTouchable","isWebTouchable","isWindowDefined","preciseName","broadName"],"sources":["../../../src/platform/index.gnome.ts"],"sourcesContent":[null],"mappings":"AAeA,SAAwBA,YAAA,EAAcC,cAAA,EAAgBC,YAAA,QAAoB;AAEnE,MAAMC,QAAA,GAAqB;EAChC,GAAGD,YAAA;EACHE,OAAA,EAAS;EAAA;EAAA;EAGTC,SAAA,EAAW;EACXC,QAAA,EAAU;EACVC,QAAA,EAAU;EACVC,QAAA,EAAU;EACVC,KAAA,EAAO;EACPC,SAAA,EAAW;EACXC,QAAA,EAAU;EACVC,SAAA,EAAW;EACXC,QAAA,EAAU;EACVC,WAAA,EAAa;EACbC,cAAA,EAAgB;EAChBC,iBAAA,EAAmB;EACnBC,kBAAA,EAAoB;EACpBC,MAAA,EAAQ;EACRC,MAAA,EAAQ;EAAA;EAAA;EAGRC,WAAA,EAAa;EACbC,cAAA,EAAgB;EAAA;EAAA;EAAA;EAIhBC,eAAA,EAAiB;AACnB;AACAnB,QAAA,CAASoB,WAAA,GAActB,cAAA,CAAeE,QAAQ;AAC9CA,QAAA,CAASqB,SAAA,GAAYxB,YAAA,CAAaG,QAAQ","ignoreList":[]}
@@ -1,5 +1,11 @@
1
1
  import { isChrome, isClient, isServer, isTouchable, isWeb, isWebTouchable, isWindowDefined } from "@tamagui/constants";
2
- const platformOrder = ["Ios", "Android", "Native", "Tauri", "Desktop", "ChromeExtension", "FirefoxExtension", "WebExtension", "Next", "Expo", "Chrome", "Firefox", "Web", "Browser", "Client", "Server", "Iframe", "Storybook"];
2
+ const platformOrder = ["Ios", "Android",
3
+ // Gnome outranks Native: the GTK target reports isNative (it is not a
4
+ // browser) but "gnome" is the precise answer callers want.
5
+ "Gnome", "Native",
6
+ // Tauri outranks Desktop/Web the same way: the webview host reports isWeb
7
+ // and isDesktop, but "tauri" is the precise answer.
8
+ "Tauri", "Desktop", "ChromeExtension", "FirefoxExtension", "WebExtension", "Next", "Expo", "Chrome", "Firefox", "Web", "Browser", "Client", "Server", "Iframe", "Storybook"];
3
9
  const platformBase = {
4
10
  isAndroid: false,
5
11
  isBrowser: false,
@@ -10,6 +16,7 @@ const platformBase = {
10
16
  isExpo: false,
11
17
  isFirefox: false,
12
18
  isFirefoxExtension: false,
19
+ isGnome: false,
13
20
  isIframe: false,
14
21
  isIos: false,
15
22
  isNative: false,
@@ -1 +1 @@
1
- {"version":3,"names":["isChrome","isClient","isServer","isTouchable","isWeb","isWebTouchable","isWindowDefined","platformOrder","platformBase","isAndroid","isBrowser","isChromeExtension","isDesktop","isExpo","isFirefox","isFirefoxExtension","isIframe","isIos","isNative","isNext","isStorybook","window","__STORYBOOK_ADDONS_PREVIEW","isTauri","isWebExtension","preciseName","broadName","getPreciseName","platform","flags","name","toLowerCase","slice","getBroadName","reverse"],"sources":["../../../src/platform/platformBase.ts"],"sourcesContent":[null],"mappings":"AAAA,SACEA,QAAA,EACAC,QAAA,EACAC,QAAA,EACAC,WAAA,EACAC,KAAA,EACAC,cAAA,EACAC,eAAA,QACK;AAQP,MAAMC,aAAA,GAAgB,CACpB,OACA,WACA,UACA,SACA,WACA,mBACA,oBACA,gBACA,QACA,QACA,UACA,WACA,OACA,WACA,UACA,UACA,UACA,YACF;AAuBO,MAAMC,YAAA,GAAe;EAC1BC,SAAA,EAAW;EACXC,SAAA,EAAW;EACXV,QAAA;EACAW,iBAAA,EAAmB;EACnBV,QAAA;EACAW,SAAA,EAAW;EACXC,MAAA,EAAQ;EACRC,SAAA,EAAW;EACXC,kBAAA,EAAoB;EACpBC,QAAA,EAAU;EACVC,KAAA,EAAO;EACPC,QAAA,EAAU;EACVC,MAAA,EAAQ;EACRjB,QAAA;EACAkB,WAAA,EAAad,eAAA,IAAmB,OAAOe,MAAA,CAAOC,0BAAA,KAA+B;EAC7EC,OAAA,EAAS;EACTpB,WAAA;EACAC,KAAA;EACAoB,cAAA,EAAgB;EAChBnB,cAAA;EACAC,eAAA;EACAmB,WAAA,EAAa;EACbC,SAAA,EAAW;AACb;AAEO,SAASC,eAAeC,QAAA,EAAyC;EACtE,MAAMC,KAAA,GAAQD,QAAA;EACd,WAAWE,IAAA,IAAQvB,aAAA,EAAe;IAChC,IAAIsB,KAAA,CAAM,KAAKC,IAAI,EAAE,GAAG;MACtB,OAAO,GAAGA,IAAA,CAAK,CAAC,EAAEC,WAAA,CAAY,CAAC,GAAGD,IAAA,CAAKE,KAAA,CAAM,CAAC,CAAC;IACjD;EACF;EACA,OAAO;AACT;AAEO,SAASC,aAAaL,QAAA,EAAuC;EAClE,MAAMC,KAAA,GAAQD,QAAA;EACd,WAAWE,IAAA,IAAQvB,aAAA,CAAcyB,KAAA,CAAM,EAAEE,OAAA,CAAQ,GAAG;IAClD,IAAIL,KAAA,CAAM,KAAKC,IAAI,EAAE,GAAG;MACtB,OAAO,GAAGA,IAAA,CAAK,CAAC,EAAEC,WAAA,CAAY,CAAC,GAAGD,IAAA,CAAKE,KAAA,CAAM,CAAC,CAAC;IACjD;EACF;EACA,OAAO;AACT","ignoreList":[]}
1
+ {"version":3,"names":["isChrome","isClient","isServer","isTouchable","isWeb","isWebTouchable","isWindowDefined","platformOrder","platformBase","isAndroid","isBrowser","isChromeExtension","isDesktop","isExpo","isFirefox","isFirefoxExtension","isGnome","isIframe","isIos","isNative","isNext","isStorybook","window","__STORYBOOK_ADDONS_PREVIEW","isTauri","isWebExtension","preciseName","broadName","getPreciseName","platform","flags","name","toLowerCase","slice","getBroadName","reverse"],"sources":["../../../src/platform/platformBase.ts"],"sourcesContent":[null],"mappings":"AAAA,SACEA,QAAA,EACAC,QAAA,EACAC,QAAA,EACAC,WAAA,EACAC,KAAA,EACAC,cAAA,EACAC,eAAA,QACK;AAQP,MAAMC,aAAA,GAAgB,CACpB,OACA;AAAA;AAAA;AAGA,SACA;AAAA;AAAA;AAGA,SACA,WACA,mBACA,oBACA,gBACA,QACA,QACA,UACA,WACA,OACA,WACA,UACA,UACA,UACA,YACF;AAwBO,MAAMC,YAAA,GAAe;EAC1BC,SAAA,EAAW;EACXC,SAAA,EAAW;EACXV,QAAA;EACAW,iBAAA,EAAmB;EACnBV,QAAA;EACAW,SAAA,EAAW;EACXC,MAAA,EAAQ;EACRC,SAAA,EAAW;EACXC,kBAAA,EAAoB;EACpBC,OAAA,EAAS;EACTC,QAAA,EAAU;EACVC,KAAA,EAAO;EACPC,QAAA,EAAU;EACVC,MAAA,EAAQ;EACRlB,QAAA;EACAmB,WAAA,EAAaf,eAAA,IAAmB,OAAOgB,MAAA,CAAOC,0BAAA,KAA+B;EAC7EC,OAAA,EAAS;EACTrB,WAAA;EACAC,KAAA;EACAqB,cAAA,EAAgB;EAChBpB,cAAA;EACAC,eAAA;EACAoB,WAAA,EAAa;EACbC,SAAA,EAAW;AACb;AAEO,SAASC,eAAeC,QAAA,EAAyC;EACtE,MAAMC,KAAA,GAAQD,QAAA;EACd,WAAWE,IAAA,IAAQxB,aAAA,EAAe;IAChC,IAAIuB,KAAA,CAAM,KAAKC,IAAI,EAAE,GAAG;MACtB,OAAO,GAAGA,IAAA,CAAK,CAAC,EAAEC,WAAA,CAAY,CAAC,GAAGD,IAAA,CAAKE,KAAA,CAAM,CAAC,CAAC;IACjD;EACF;EACA,OAAO;AACT;AAEO,SAASC,aAAaL,QAAA,EAAuC;EAClE,MAAMC,KAAA,GAAQD,QAAA;EACd,WAAWE,IAAA,IAAQxB,aAAA,CAAc0B,KAAA,CAAM,EAAEE,OAAA,CAAQ,GAAG;IAClD,IAAIL,KAAA,CAAM,KAAKC,IAAI,EAAE,GAAG;MACtB,OAAO,GAAGA,IAAA,CAAK,CAAC,EAAEC,WAAA,CAAY,CAAC,GAAGD,IAAA,CAAKE,KAAA,CAAM,CAAC,CAAC;IACjD;EACF;EACA,OAAO;AACT","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/platform",
3
- "version": "6.6.0",
3
+ "version": "7.0.0",
4
4
  "description": "Platform detection flags and utilities for multiplatform.one",
5
5
  "keywords": [
6
6
  "detection",
@@ -44,16 +44,16 @@
44
44
  "access": "public"
45
45
  },
46
46
  "dependencies": {
47
- "@tamagui/constants": "2.0.0-rc.41"
47
+ "@tamagui/constants": "2.7.6"
48
48
  },
49
49
  "devDependencies": {
50
- "@tamagui/build": "2.0.0-rc.41",
50
+ "@tamagui/build": "2.7.6",
51
51
  "@types/chrome": "^0.1.40",
52
52
  "@types/firefox-webext-browser": "^143.0.0",
53
53
  "@types/react": "~19.2.14",
54
54
  "react": "19.2.5",
55
55
  "typescript": "~5.9.3",
56
- "@multiplatform.one/config": "6.6.0"
56
+ "@multiplatform.one/config": "7.0.0"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "expo-constants": "~55.0.15",
@@ -69,6 +69,7 @@
69
69
  },
70
70
  "scripts": {
71
71
  "build": "rm -rf dist types 2>/dev/null && tamagui-build --ts-project ./tsconfig.build.json --exclude '\\.spec\\.|\\.test\\.|\\.stories\\.' && find dist -name '*.native.js' -delete && find dist -name '*.native.js.map' -delete",
72
- "typecheck": "tsc --noEmit"
72
+ "test": "vitest run --coverage --coverage.provider=v8 --coverage.reporter=text --coverage.reporter=lcov --coverage.reporter=html",
73
+ "typecheck": "tsgo --noEmit"
73
74
  }
74
75
  }
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ export const {
9
9
  isExpo,
10
10
  isFirefox,
11
11
  isFirefoxExtension,
12
+ isGnome,
12
13
  isIframe,
13
14
  isIos,
14
15
  isNative,
@@ -0,0 +1,42 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { platform } from "./index.gnome";
3
+ import { platform as webPlatform } from "./index";
4
+
5
+ describe("the gnome platform entry", () => {
6
+ it("sets isGnome, which is the whole point of the file existing", () => {
7
+ expect(platform.isGnome).toBe(true);
8
+ });
9
+
10
+ it('resolves preciseName to "gnome" rather than "native"', () => {
11
+ expect(platform.preciseName).toBe("gnome");
12
+ });
13
+
14
+ it('resolves broadName to "client"', () => {
15
+ expect(platform.broadName).toBe("client");
16
+ });
17
+
18
+ it("reports a desktop that is not a browser", () => {
19
+ expect(platform.isDesktop).toBe(true);
20
+ expect(platform.isNative).toBe(true);
21
+ expect(platform.isWeb).toBe(false);
22
+ expect(platform.isBrowser).toBe(false);
23
+ });
24
+
25
+ it("does not claim a usable window, since GJS's is a polyfill stub", () => {
26
+ expect(platform.isWindowDefined).toBe(false);
27
+ });
28
+
29
+ it("claims no other platform", () => {
30
+ expect(platform.isIos).toBe(false);
31
+ expect(platform.isAndroid).toBe(false);
32
+ expect(platform.isExpo).toBe(false);
33
+ expect(platform.isNext).toBe(false);
34
+ expect(platform.isServer).toBe(false);
35
+ expect(platform.isWebExtension).toBe(false);
36
+ expect(platform.isStorybook).toBe(false);
37
+ });
38
+
39
+ it("answers every key the default entry does, so the flag set cannot drift", () => {
40
+ expect(Object.keys(platform).sort()).toEqual(Object.keys(webPlatform).sort());
41
+ });
42
+ });
@@ -0,0 +1,51 @@
1
+ // Platform flags for the GNOME (GTK4 / GJS / libadwaita) target.
2
+ //
3
+ // Resolved the same way `index.ios.ts` and `index.android.ts` are: the
4
+ // bundler picks this file over `index.ts` by extension. Metro does that for
5
+ // `.ios`/`.android` out of the box; on GNOME it is Vite, and the `.gnome.*`
6
+ // entries come ahead of the `.native.*` ones in `resolve.extensions` —
7
+ // `gnomePlatformExtensions` from @multiplatform.one/vite-plugin-gnome, wired
8
+ // into apps/one/vite.config.gnome.ts. Without that registration this file is
9
+ // inert and every consumer sees the base `isGnome: false`.
10
+ //
11
+ // Every value is stated rather than inherited from @tamagui/constants,
12
+ // because those are inferred from `document`/`window` and GJS's window is a
13
+ // polyfill stub — inference would answer questions about a fake DOM instead
14
+ // of about GTK.
15
+
16
+ import { type Platform, getBroadName, getPreciseName, platformBase } from "./platformBase";
17
+
18
+ export const platform: Platform = {
19
+ ...platformBase,
20
+ isGnome: true,
21
+ // GTK is a desktop, and it is not a browser — so `isNative` too, which is
22
+ // exactly why Gnome sits ahead of Native in the precision order.
23
+ isDesktop: true,
24
+ isNative: true,
25
+ isClient: true,
26
+ isServer: false,
27
+ isWeb: false,
28
+ isBrowser: false,
29
+ isChrome: false,
30
+ isFirefox: false,
31
+ isIframe: false,
32
+ isStorybook: false,
33
+ isWebExtension: false,
34
+ isChromeExtension: false,
35
+ isFirefoxExtension: false,
36
+ isExpo: false,
37
+ isNext: false,
38
+ // A GTK pointer desktop. Touch exists on some hardware but is not the
39
+ // interaction model the layout should assume.
40
+ isTouchable: false,
41
+ isWebTouchable: false,
42
+ // There is a `window` under the react-gnome polyfills, but it is a stub
43
+ // with no layout, no events and no document. Callers branching on this are
44
+ // asking "can I touch the DOM", and the answer is no.
45
+ isWindowDefined: false,
46
+ };
47
+ platform.preciseName = getPreciseName(platform);
48
+ platform.broadName = getBroadName(platform);
49
+
50
+ export type { Platform };
51
+ export type { PlatformName } from "./platformBase";
@@ -12,6 +12,7 @@ function makePlatform(overrides: Partial<Platform> = {}): Platform {
12
12
  isExpo: false,
13
13
  isFirefox: false,
14
14
  isFirefoxExtension: false,
15
+ isGnome: false,
15
16
  isIframe: false,
16
17
  isIos: false,
17
18
  isNative: false,
@@ -45,6 +46,12 @@ describe("getPreciseName", () => {
45
46
  expect(getPreciseName(makePlatform({ isAndroid: true, isNative: true }))).toBe("android");
46
47
  });
47
48
 
49
+ it('returns "gnome" for the GTK desktop target', () => {
50
+ expect(getPreciseName(makePlatform({ isGnome: true, isDesktop: true, isNative: true }))).toBe(
51
+ "gnome",
52
+ );
53
+ });
54
+
48
55
  it('returns "tauri" for desktop Tauri apps', () => {
49
56
  expect(getPreciseName(makePlatform({ isTauri: true, isDesktop: true, isWeb: true }))).toBe(
50
57
  "tauri",
@@ -17,7 +17,12 @@ declare global {
17
17
  const platformOrder = [
18
18
  "Ios",
19
19
  "Android",
20
+ // Gnome outranks Native: the GTK target reports isNative (it is not a
21
+ // browser) but "gnome" is the precise answer callers want.
22
+ "Gnome",
20
23
  "Native",
24
+ // Tauri outranks Desktop/Web the same way: the webview host reports isWeb
25
+ // and isDesktop, but "tauri" is the precise answer.
21
26
  "Tauri",
22
27
  "Desktop",
23
28
  "ChromeExtension",
@@ -38,6 +43,7 @@ const platformOrder = [
38
43
  export type PlatformName =
39
44
  | "ios"
40
45
  | "android"
46
+ | "gnome"
41
47
  | "native"
42
48
  | "tauri"
43
49
  | "desktop"
@@ -66,6 +72,7 @@ export const platformBase = {
66
72
  isExpo: false,
67
73
  isFirefox: false,
68
74
  isFirefoxExtension: false,
75
+ isGnome: false,
69
76
  isIframe: false,
70
77
  isIos: false,
71
78
  isNative: false,
@@ -112,6 +119,7 @@ export interface Platform {
112
119
  isExpo: boolean;
113
120
  isFirefox: boolean;
114
121
  isFirefoxExtension: boolean;
122
+ isGnome: boolean;
115
123
  isIframe: boolean;
116
124
  isIos: boolean;
117
125
  isNative: boolean;
package/types/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const isAndroid: boolean, isBrowser: boolean, isChrome: boolean, isChromeExtension: boolean, isClient: boolean, isExpo: boolean, isFirefox: boolean, isFirefoxExtension: boolean, isIframe: boolean, isIos: boolean, isNative: boolean, isNext: boolean, isServer: boolean, isStorybook: boolean, isTauri: boolean, isDesktop: boolean, isTouchable: boolean, isWeb: boolean, isWebExtension: boolean, isWebTouchable: boolean, isWindowDefined: boolean;
1
+ export declare const isAndroid: boolean, isBrowser: boolean, isChrome: boolean, isChromeExtension: boolean, isClient: boolean, isExpo: boolean, isFirefox: boolean, isFirefoxExtension: boolean, isGnome: boolean, isIframe: boolean, isIos: boolean, isNative: boolean, isNext: boolean, isServer: boolean, isStorybook: boolean, isTauri: boolean, isDesktop: boolean, isTouchable: boolean, isWeb: boolean, isWebExtension: boolean, isWebTouchable: boolean, isWindowDefined: boolean;
2
2
  export * from "./platform/index";
3
3
  export * from "./helpers";
4
4
  export * from "./types";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MACL,SAAS,WACT,SAAS,WACT,QAAQ,WACR,iBAAiB,WACjB,QAAQ,WACR,MAAM,WACN,SAAS,WACT,kBAAkB,WAClB,QAAQ,WACR,KAAK,WACL,QAAQ,WACR,MAAM,WACN,QAAQ,WACR,WAAW,WACX,OAAO,WACP,SAAS,WACT,WAAW,WACX,KAAK,WACL,cAAc,WACd,cAAc,WACd,eAAe,SACL,CAAC;AAEb,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MACL,SAAS,WACT,SAAS,WACT,QAAQ,WACR,iBAAiB,WACjB,QAAQ,WACR,MAAM,WACN,SAAS,WACT,kBAAkB,WAClB,OAAO,WACP,QAAQ,WACR,KAAK,WACL,QAAQ,WACR,MAAM,WACN,QAAQ,WACR,WAAW,WACX,OAAO,WACP,SAAS,WACT,WAAW,WACX,KAAK,WACL,cAAc,WACd,cAAc,WACd,eAAe,SACL,CAAC;AAEb,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type Platform } from "./platformBase";
2
+ export declare const platform: Platform;
3
+ export type { Platform };
4
+ export type { PlatformName } from "./platformBase";
5
+ //# sourceMappingURL=index.gnome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.gnome.d.ts","sourceRoot":"","sources":["../../src/platform/index.gnome.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,QAAQ,EAA8C,MAAM,gBAAgB,CAAC;AAE3F,eAAO,MAAM,QAAQ,EAAE,QA4BtB,CAAC;AAIF,YAAY,EAAE,QAAQ,EAAE,CAAC;AACzB,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
@@ -3,7 +3,7 @@ declare global {
3
3
  __STORYBOOK_ADDONS_PREVIEW: unknown;
4
4
  }
5
5
  }
6
- export type PlatformName = "ios" | "android" | "native" | "tauri" | "desktop" | "chromeExtension" | "firefoxExtension" | "webExtension" | "next" | "expo" | "chrome" | "firefox" | "web" | "browser" | "client" | "server" | "iframe" | "storybook" | "unknown";
6
+ export type PlatformName = "ios" | "android" | "gnome" | "native" | "tauri" | "desktop" | "chromeExtension" | "firefoxExtension" | "webExtension" | "next" | "expo" | "chrome" | "firefox" | "web" | "browser" | "client" | "server" | "iframe" | "storybook" | "unknown";
7
7
  export declare const platformBase: {
8
8
  readonly isAndroid: false;
9
9
  readonly isBrowser: false;
@@ -14,6 +14,7 @@ export declare const platformBase: {
14
14
  readonly isExpo: false;
15
15
  readonly isFirefox: false;
16
16
  readonly isFirefoxExtension: false;
17
+ readonly isGnome: false;
17
18
  readonly isIframe: false;
18
19
  readonly isIos: false;
19
20
  readonly isNative: false;
@@ -41,6 +42,7 @@ export interface Platform {
41
42
  isExpo: boolean;
42
43
  isFirefox: boolean;
43
44
  isFirefoxExtension: boolean;
45
+ isGnome: boolean;
44
46
  isIframe: boolean;
45
47
  isIos: boolean;
46
48
  isNative: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"platformBase.d.ts","sourceRoot":"","sources":["../../src/platform/platformBase.ts"],"names":[],"mappings":"AAUA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,0BAA0B,EAAE,OAAO,CAAC;KACrC;CACF;AAuBD,MAAM,MAAM,YAAY,GACpB,KAAK,GACL,SAAS,GACT,QAAQ,GACR,OAAO,GACP,SAAS,GACT,iBAAiB,GACjB,kBAAkB,GAClB,cAAc,GACd,MAAM,GACN,MAAM,GACN,QAAQ,GACR,SAAS,GACT,KAAK,GACL,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,SAAS,CAAC;AAEd,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;CAwBf,CAAC;AAEX,wBAAgB,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,gBAQrE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,gBAQjE;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,YAAY,CAAC;IACxB,WAAW,EAAE,YAAY,CAAC;CAC3B"}
1
+ {"version":3,"file":"platformBase.d.ts","sourceRoot":"","sources":["../../src/platform/platformBase.ts"],"names":[],"mappings":"AAUA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,0BAA0B,EAAE,OAAO,CAAC;KACrC;CACF;AA4BD,MAAM,MAAM,YAAY,GACpB,KAAK,GACL,SAAS,GACT,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,iBAAiB,GACjB,kBAAkB,GAClB,cAAc,GACd,MAAM,GACN,MAAM,GACN,QAAQ,GACR,SAAS,GACT,KAAK,GACL,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,SAAS,CAAC;AAEd,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;CAyBf,CAAC;AAEX,wBAAgB,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,gBAQrE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,gBAQjE;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,YAAY,CAAC;IACxB,WAAW,EAAE,YAAY,CAAC;CAC3B"}