@a-type/ui 3.0.36 → 3.0.37

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 (36) hide show
  1. package/dist/cjs/components/provider/Provider.d.ts +2 -1
  2. package/dist/cjs/components/provider/Provider.js +3 -2
  3. package/dist/cjs/components/provider/Provider.js.map +1 -1
  4. package/dist/cjs/components/pwaInstall/PwaInstall.d.ts +5 -0
  5. package/dist/cjs/components/pwaInstall/PwaInstall.js +79 -0
  6. package/dist/cjs/components/pwaInstall/PwaInstall.js.map +1 -0
  7. package/dist/cjs/components/pwaInstall/PwaInstallTrigger.d.ts +3 -4
  8. package/dist/cjs/components/pwaInstall/PwaInstallTrigger.js +5 -48
  9. package/dist/cjs/components/pwaInstall/PwaInstallTrigger.js.map +1 -1
  10. package/dist/cjs/components/pwaInstall/index.d.ts +1 -0
  11. package/dist/cjs/components/pwaInstall/index.js +1 -0
  12. package/dist/cjs/components/pwaInstall/index.js.map +1 -1
  13. package/dist/cjs/components/pwaInstall/state.d.ts +4 -0
  14. package/dist/cjs/components/pwaInstall/state.js +13 -0
  15. package/dist/cjs/components/pwaInstall/state.js.map +1 -0
  16. package/dist/esm/components/provider/Provider.d.ts +2 -1
  17. package/dist/esm/components/provider/Provider.js +3 -2
  18. package/dist/esm/components/provider/Provider.js.map +1 -1
  19. package/dist/esm/components/pwaInstall/PwaInstall.d.ts +5 -0
  20. package/dist/esm/components/pwaInstall/PwaInstall.js +76 -0
  21. package/dist/esm/components/pwaInstall/PwaInstall.js.map +1 -0
  22. package/dist/esm/components/pwaInstall/PwaInstallTrigger.d.ts +3 -4
  23. package/dist/esm/components/pwaInstall/PwaInstallTrigger.js +7 -50
  24. package/dist/esm/components/pwaInstall/PwaInstallTrigger.js.map +1 -1
  25. package/dist/esm/components/pwaInstall/index.d.ts +1 -0
  26. package/dist/esm/components/pwaInstall/index.js +1 -0
  27. package/dist/esm/components/pwaInstall/index.js.map +1 -1
  28. package/dist/esm/components/pwaInstall/state.d.ts +4 -0
  29. package/dist/esm/components/pwaInstall/state.js +9 -0
  30. package/dist/esm/components/pwaInstall/state.js.map +1 -0
  31. package/package.json +1 -1
  32. package/src/components/provider/Provider.tsx +4 -0
  33. package/src/components/pwaInstall/PwaInstall.tsx +228 -0
  34. package/src/components/pwaInstall/PwaInstallTrigger.tsx +15 -209
  35. package/src/components/pwaInstall/index.ts +1 -0
  36. package/src/components/pwaInstall/state.ts +9 -0
@@ -5,11 +5,12 @@ export interface ProviderProps {
5
5
  disableViewportOffset?: boolean;
6
6
  virtualKeyboardBehavior?: 'overlay' | 'displace';
7
7
  disableTitleBarColor?: boolean;
8
+ manifestPath?: string;
8
9
  }
9
10
  /**
10
11
  * Provides all the stuff for all global junk.
11
12
  */
12
- export declare function Provider({ children, disableParticles, disableViewportOffset, virtualKeyboardBehavior, disableTitleBarColor, }: ProviderProps): import("react/jsx-runtime.js").JSX.Element;
13
+ export declare function Provider({ children, disableParticles, disableViewportOffset, virtualKeyboardBehavior, disableTitleBarColor, manifestPath, }: ProviderProps): import("react/jsx-runtime.js").JSX.Element;
13
14
  export declare const ConfigContext: import("react").Context<{
14
15
  virtualKeyboardBehavior: "overlay" | "displace";
15
16
  }>;
@@ -10,19 +10,20 @@ const hooks_js_1 = require("../../hooks.js");
10
10
  const useVirtualKeyboardBehavior_js_1 = require("../../hooks/useVirtualKeyboardBehavior.js");
11
11
  const index_js_1 = require("../icon/index.js");
12
12
  const index_js_2 = require("../particles/index.js");
13
+ const PwaInstall_js_1 = require("../pwaInstall/PwaInstall.js");
13
14
  const toasts_js_1 = require("../toasts/toasts.js");
14
15
  const index_js_3 = require("../tooltip/index.js");
15
16
  /**
16
17
  * Provides all the stuff for all global junk.
17
18
  */
18
- function Provider({ children, disableParticles, disableViewportOffset, virtualKeyboardBehavior = 'displace', disableTitleBarColor, }) {
19
+ function Provider({ children, disableParticles, disableViewportOffset, virtualKeyboardBehavior = 'displace', disableTitleBarColor, manifestPath, }) {
19
20
  (0, hooks_js_1.useVisualViewportOffset)(disableViewportOffset);
20
21
  const supportedVirtualKeyboardBehavior = typeof navigator !== 'undefined' && 'virtualKeyboard' in navigator
21
22
  ? virtualKeyboardBehavior
22
23
  : 'displace';
23
24
  (0, useVirtualKeyboardBehavior_js_1.useVirtualKeyboardBehavior)(supportedVirtualKeyboardBehavior);
24
25
  (0, hooks_js_1.useThemedTitleBar)('gray', 'wash', undefined, disableTitleBarColor);
25
- const otherStuff = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(index_js_1.IconSpritesheet, {}), (0, jsx_runtime_1.jsx)(toasts_js_1.Toaster, {})] }));
26
+ const otherStuff = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(index_js_1.IconSpritesheet, {}), (0, jsx_runtime_1.jsx)(toasts_js_1.Toaster, {}), (0, jsx_runtime_1.jsx)(PwaInstall_js_1.PwaInstall, { manifestPath: manifestPath })] }));
26
27
  if (disableParticles)
27
28
  return ((0, jsx_runtime_1.jsx)(exports.ConfigContext.Provider, { value: { virtualKeyboardBehavior: supportedVirtualKeyboardBehavior }, children: (0, jsx_runtime_1.jsxs)(index_js_3.TooltipProvider, { children: [children, otherStuff] }) }));
28
29
  return ((0, jsx_runtime_1.jsx)(exports.ConfigContext.Provider, { value: { virtualKeyboardBehavior: supportedVirtualKeyboardBehavior }, children: (0, jsx_runtime_1.jsx)(index_js_3.TooltipProvider, { children: (0, jsx_runtime_1.jsxs)(index_js_2.ParticleLayer, { children: [children, otherStuff] }) }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"Provider.js","sourceRoot":"","sources":["../../../../src/components/provider/Provider.tsx"],"names":[],"mappings":";;;AAmBA,4BA6CC;AAQD,8BAEC;;AA1ED,iCAA6D;AAC7D,6CAA4E;AAC5E,6FAAuF;AACvF,+CAAmD;AACnD,oDAAsD;AACtD,mDAA8C;AAC9C,kDAAsD;AAUtD;;GAEG;AACH,SAAgB,QAAQ,CAAC,EACxB,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,GAAG,UAAU,EACpC,oBAAoB,GACL;IACf,IAAA,kCAAuB,EAAC,qBAAqB,CAAC,CAAC;IAC/C,MAAM,gCAAgC,GACrC,OAAO,SAAS,KAAK,WAAW,IAAI,iBAAiB,IAAI,SAAS;QACjE,CAAC,CAAC,uBAAuB;QACzB,CAAC,CAAC,UAAU,CAAC;IACf,IAAA,0DAA0B,EAAC,gCAAgC,CAAC,CAAC;IAC7D,IAAA,4BAAiB,EAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,CAClB,6DACC,uBAAC,0BAAe,KAAG,EACnB,uBAAC,mBAAO,KAAG,IACT,CACH,CAAC;IAEF,IAAI,gBAAgB;QACnB,OAAO,CACN,uBAAC,qBAAa,CAAC,QAAQ,IACtB,KAAK,EAAE,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,YAEpE,wBAAC,0BAAe,eACd,QAAQ,EACR,UAAU,IACM,GACM,CACzB,CAAC;IAEH,OAAO,CACN,uBAAC,qBAAa,CAAC,QAAQ,IACtB,KAAK,EAAE,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,YAEpE,uBAAC,0BAAe,cACf,wBAAC,wBAAa,eACZ,QAAQ,EACR,UAAU,IACI,GACC,GACM,CACzB,CAAC;AACH,CAAC;AAEY,QAAA,aAAa,GAAG,IAAA,qBAAa,EAEvC;IACF,uBAAuB,EAAE,UAAU;CACnC,CAAC,CAAC;AAEH,SAAgB,SAAS;IACxB,OAAO,IAAA,kBAAU,EAAC,qBAAa,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"Provider.js","sourceRoot":"","sources":["../../../../src/components/provider/Provider.tsx"],"names":[],"mappings":";;;AAqBA,4BA+CC;AAQD,8BAEC;;AA9ED,iCAA6D;AAC7D,6CAA4E;AAC5E,6FAAuF;AACvF,+CAAmD;AACnD,oDAAsD;AACtD,+DAAyD;AACzD,mDAA8C;AAC9C,kDAAsD;AAWtD;;GAEG;AACH,SAAgB,QAAQ,CAAC,EACxB,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,GAAG,UAAU,EACpC,oBAAoB,EACpB,YAAY,GACG;IACf,IAAA,kCAAuB,EAAC,qBAAqB,CAAC,CAAC;IAC/C,MAAM,gCAAgC,GACrC,OAAO,SAAS,KAAK,WAAW,IAAI,iBAAiB,IAAI,SAAS;QACjE,CAAC,CAAC,uBAAuB;QACzB,CAAC,CAAC,UAAU,CAAC;IACf,IAAA,0DAA0B,EAAC,gCAAgC,CAAC,CAAC;IAC7D,IAAA,4BAAiB,EAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,CAClB,6DACC,uBAAC,0BAAe,KAAG,EACnB,uBAAC,mBAAO,KAAG,EACX,uBAAC,0BAAU,IAAC,YAAY,EAAE,YAAY,GAAI,IACxC,CACH,CAAC;IAEF,IAAI,gBAAgB;QACnB,OAAO,CACN,uBAAC,qBAAa,CAAC,QAAQ,IACtB,KAAK,EAAE,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,YAEpE,wBAAC,0BAAe,eACd,QAAQ,EACR,UAAU,IACM,GACM,CACzB,CAAC;IAEH,OAAO,CACN,uBAAC,qBAAa,CAAC,QAAQ,IACtB,KAAK,EAAE,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,YAEpE,uBAAC,0BAAe,cACf,wBAAC,wBAAa,eACZ,QAAQ,EACR,UAAU,IACI,GACC,GACM,CACzB,CAAC;AACH,CAAC;AAEY,QAAA,aAAa,GAAG,IAAA,qBAAa,EAEvC;IACF,uBAAuB,EAAE,UAAU;CACnC,CAAC,CAAC;AAEH,SAAgB,SAAS;IACxB,OAAO,IAAA,kBAAU,EAAC,qBAAa,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { DialogTriggerProps } from '@radix-ui/react-dialog';
2
+ export interface PwaInstall extends DialogTriggerProps {
3
+ manifestPath?: string;
4
+ }
5
+ export declare function PwaInstall({ children, manifestPath, asChild: _, ...rest }: PwaInstall): import("react/jsx-runtime.js").JSX.Element | null;
@@ -0,0 +1,79 @@
1
+ // @unocss-include
2
+ "use strict";
3
+ var __rest = (this && this.__rest) || function (s, e) {
4
+ var t = {};
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
6
+ t[p] = s[p];
7
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
8
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
9
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
10
+ t[p[i]] = s[p[i]];
11
+ }
12
+ return t;
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.PwaInstall = PwaInstall;
16
+ const jsx_runtime_1 = require("react/jsx-runtime");
17
+ const react_1 = require("react");
18
+ const valtio_1 = require("valtio");
19
+ const platform_js_1 = require("../../platform.js");
20
+ const Box_js_1 = require("../box/Box.js");
21
+ const Button_js_1 = require("../button/Button.js");
22
+ const Dialog_js_1 = require("../dialog/Dialog.js");
23
+ const Icon_js_1 = require("../icon/Icon.js");
24
+ const Lightbox_js_1 = require("../lightbox/Lightbox.js");
25
+ const lists_js_1 = require("../lists/lists.js");
26
+ const typography_js_1 = require("../typography/typography.js");
27
+ const PlatformIcons_js_1 = require("./PlatformIcons.js");
28
+ const state_js_1 = require("./state.js");
29
+ const useIsInstallReady_js_1 = require("./useIsInstallReady.js");
30
+ const useWebManifest_js_1 = require("./useWebManifest.js");
31
+ function PwaInstall(_a) {
32
+ var _b, _c, _d, _e, _f, _g;
33
+ var { children, manifestPath, asChild: _ } = _a, rest = __rest(_a, ["children", "manifestPath", "asChild"]);
34
+ const installed = (0, useIsInstallReady_js_1.useIsInstalled)();
35
+ const manifest = (0, useWebManifest_js_1.useWebManifest)(manifestPath);
36
+ const { open } = (0, valtio_1.useSnapshot)(state_js_1.pwaInstallerState);
37
+ const [showInstructions, setShowInstructions] = (0, react_1.useState)(false);
38
+ if (installed) {
39
+ return null;
40
+ }
41
+ const primaryIcon = (_b = manifest === null || manifest === void 0 ? void 0 : manifest.icons) === null || _b === void 0 ? void 0 : _b[0];
42
+ return ((0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog, { open: open, onOpenChange: (isOpen) => {
43
+ state_js_1.pwaInstallerState.open = isOpen;
44
+ }, children: (0, jsx_runtime_1.jsxs)(Dialog_js_1.Dialog.Content, { className: "flex flex-col gap-xs", id: "pwa-install-dialog", children: [(0, jsx_runtime_1.jsxs)(Dialog_js_1.Dialog.Title, { className: "flex flex-row gap-md items-center", children: [primaryIcon && ((0, jsx_runtime_1.jsx)("img", { src: primaryIcon.src, alt: (_e = (_d = (_c = primaryIcon.label) !== null && _c !== void 0 ? _c : manifest === null || manifest === void 0 ? void 0 : manifest.short_name) !== null && _d !== void 0 ? _d : manifest === null || manifest === void 0 ? void 0 : manifest.name) !== null && _e !== void 0 ? _e : 'App Icon', className: "inline-block w-1em h-1em rounded" })), "Install ", (_g = (_f = manifest === null || manifest === void 0 ? void 0 : manifest.short_name) !== null && _f !== void 0 ? _f : manifest === null || manifest === void 0 ? void 0 : manifest.name) !== null && _g !== void 0 ? _g : 'App'] }), showInstructions ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog.Description, { children: "Follow the instructions below to install this app on your device." }), (0, jsx_runtime_1.jsx)(InstallInstructions, {}), (0, jsx_runtime_1.jsxs)(Dialog_js_1.Dialog.Actions, { children: [(0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog.Close, { asChild: true, children: (0, jsx_runtime_1.jsx)(Button_js_1.Button, { emphasis: "ghost", children: "Close" }) }), (0, jsx_runtime_1.jsxs)(Button_js_1.Button, { onClick: () => setShowInstructions(false), children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "arrowLeft" }), " Back"] })] })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog.Description, { children: "This site is also an app. You can install it right now for easier access and more features." }), (manifest === null || manifest === void 0 ? void 0 : manifest.description) && ((0, jsx_runtime_1.jsx)(typography_js_1.P, { className: "mb-sm", children: manifest.description })), (0, jsx_runtime_1.jsx)(ManifestImageGallery, { manifestPath: manifestPath }), (0, jsx_runtime_1.jsxs)(Dialog_js_1.Dialog.Actions, { children: [(0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog.Close, { asChild: true, children: (0, jsx_runtime_1.jsx)(Button_js_1.Button, { emphasis: "ghost", children: "Close" }) }), (0, jsx_runtime_1.jsx)(InstallDeviceActions, { showInstructions: () => setShowInstructions(true) })] })] }))] }) }));
45
+ }
46
+ const supportsDirectInstall = (0, platform_js_1.getSupportsPWAInstallPrompt)();
47
+ function InstallInstructions() {
48
+ const os = (0, platform_js_1.getOS)();
49
+ if (os === 'iOS' || os === 'Mac OS') {
50
+ if ((0, platform_js_1.getIsSafari)()) {
51
+ if (os === 'iOS') {
52
+ return ((0, jsx_runtime_1.jsxs)(lists_js_1.Ol, { children: [(0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariShareIcon, {}), " Tap the Share button in the toolbar."] }), (0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariPlusSquareIcon, {}), " Scroll down and tap \"Add to Home Screen\"."] })] }));
53
+ }
54
+ else {
55
+ return ((0, jsx_runtime_1.jsxs)(lists_js_1.Ol, { children: [(0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariShareIcon, {}), " Tap the Share button in the toolbar."] }), (0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariAddToDockIcon, {}), " Tap \"Add to Dock\"."] })] }));
56
+ }
57
+ }
58
+ else {
59
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lists_js_1.Ol, { children: (0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariIcon, {}), " Open this site in Safari to continue."] }) }), (0, jsx_runtime_1.jsx)(Box_js_1.Box, { surface: true, p: true, children: "Apple does not allow non-Safari browsers to install web apps." })] }));
60
+ }
61
+ }
62
+ return ((0, jsx_runtime_1.jsxs)(lists_js_1.Ol, { children: [(0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "dots", className: "rotate-90" }), " Tap the menu button in the toolbar."] }), (0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.AndroidAddToHomeIcon, {}), " Tap \"Add to Home Screen.\""] })] }));
63
+ }
64
+ function ManifestImageGallery({ manifestPath }) {
65
+ var _a, _b;
66
+ const manifest = (0, useWebManifest_js_1.useWebManifest)(manifestPath);
67
+ if (!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.screenshots) === null || _a === void 0 ? void 0 : _a.length)) {
68
+ return null;
69
+ }
70
+ return ((0, jsx_runtime_1.jsx)(Box_js_1.Box, { overflow: "auto-x", p: "sm", gap: true, className: "h-240px", children: (_b = manifest.screenshots) === null || _b === void 0 ? void 0 : _b.map((screenshot, index) => ((0, jsx_runtime_1.jsxs)(Lightbox_js_1.Lightbox.Root, { children: [(0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Trigger, { asChild: true, children: (0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Image, { tabIndex: 0, src: screenshot.src, alt: screenshot.label || `Screenshot ${index + 1}`, className: "border border-default rounded-xs" }, index) }), (0, jsx_runtime_1.jsxs)(Lightbox_js_1.Lightbox.Portal, { children: [(0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Overlay, { className: "z-10000" }), (0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Content, { className: "z-10001", children: (0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Image, { src: screenshot.src, alt: screenshot.label || `Screenshot ${index + 1}` }) })] })] }, screenshot.src))) }));
71
+ }
72
+ function InstallDeviceActions({ showInstructions, }) {
73
+ const ready = (0, useIsInstallReady_js_1.useIsInstallReady)();
74
+ if (supportsDirectInstall && ready) {
75
+ return ((0, jsx_runtime_1.jsxs)(Button_js_1.Button, { onClick: () => (0, useIsInstallReady_js_1.triggerDeferredInstall)(), emphasis: "primary", children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "download" }), " Install now"] }));
76
+ }
77
+ return ((0, jsx_runtime_1.jsxs)(Button_js_1.Button, { onClick: () => showInstructions(), emphasis: "primary", children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "arrowRight" }), " Add to Home"] }));
78
+ }
79
+ //# sourceMappingURL=PwaInstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PwaInstall.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/PwaInstall.tsx"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- import { DialogTriggerProps } from '@radix-ui/react-dialog';
2
- export interface PwaInstallTriggerProps extends DialogTriggerProps {
3
- manifestPath?: string;
1
+ import { ButtonProps } from '../button/Button.js';
2
+ export interface PwaInstallTriggerProps extends ButtonProps {
4
3
  }
5
- export declare function PwaInstallTrigger({ children, manifestPath, asChild: _, ...rest }: PwaInstallTriggerProps): import("react/jsx-runtime.js").JSX.Element | null;
4
+ export declare function PwaInstallTrigger({ children, ...rest }: PwaInstallTriggerProps): import("react/jsx-runtime.js").JSX.Element | null;
@@ -14,61 +14,18 @@ var __rest = (this && this.__rest) || function (s, e) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.PwaInstallTrigger = PwaInstallTrigger;
16
16
  const jsx_runtime_1 = require("react/jsx-runtime");
17
- const react_1 = require("react");
18
- const platform_js_1 = require("../../platform.js");
19
- const Box_js_1 = require("../box/Box.js");
20
17
  const Button_js_1 = require("../button/Button.js");
21
- const Dialog_js_1 = require("../dialog/Dialog.js");
22
18
  const Icon_js_1 = require("../icon/Icon.js");
23
- const Lightbox_js_1 = require("../lightbox/Lightbox.js");
24
- const lists_js_1 = require("../lists/lists.js");
25
- const typography_js_1 = require("../typography/typography.js");
26
- const PlatformIcons_js_1 = require("./PlatformIcons.js");
19
+ const state_js_1 = require("./state.js");
27
20
  const useIsInstallReady_js_1 = require("./useIsInstallReady.js");
28
- const useWebManifest_js_1 = require("./useWebManifest.js");
29
21
  function PwaInstallTrigger(_a) {
30
- var _b, _c, _d, _e, _f, _g;
31
- var { children, manifestPath, asChild: _ } = _a, rest = __rest(_a, ["children", "manifestPath", "asChild"]);
22
+ var { children } = _a, rest = __rest(_a, ["children"]);
32
23
  const installed = (0, useIsInstallReady_js_1.useIsInstalled)();
33
- const manifest = (0, useWebManifest_js_1.useWebManifest)(manifestPath);
34
- const [showInstructions, setShowInstructions] = (0, react_1.useState)(false);
35
24
  if (installed) {
36
25
  return null;
37
26
  }
38
- const primaryIcon = (_b = manifest === null || manifest === void 0 ? void 0 : manifest.icons) === null || _b === void 0 ? void 0 : _b[0];
39
- return ((0, jsx_runtime_1.jsxs)(Dialog_js_1.Dialog, { children: [(0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog.Trigger, Object.assign({}, rest, { asChild: true, children: children !== null && children !== void 0 ? children : ((0, jsx_runtime_1.jsxs)(Button_js_1.Button, { color: "primary", emphasis: "light", children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "star" }), " Install"] })) })), (0, jsx_runtime_1.jsxs)(Dialog_js_1.Dialog.Content, { className: "flex flex-col gap-xs", children: [(0, jsx_runtime_1.jsxs)(Dialog_js_1.Dialog.Title, { className: "flex flex-row gap-md items-center", children: [primaryIcon && ((0, jsx_runtime_1.jsx)("img", { src: primaryIcon.src, alt: (_e = (_d = (_c = primaryIcon.label) !== null && _c !== void 0 ? _c : manifest === null || manifest === void 0 ? void 0 : manifest.short_name) !== null && _d !== void 0 ? _d : manifest === null || manifest === void 0 ? void 0 : manifest.name) !== null && _e !== void 0 ? _e : 'App Icon', className: "inline-block w-1em h-1em rounded" })), "Install ", (_g = (_f = manifest === null || manifest === void 0 ? void 0 : manifest.short_name) !== null && _f !== void 0 ? _f : manifest === null || manifest === void 0 ? void 0 : manifest.name) !== null && _g !== void 0 ? _g : 'App'] }), showInstructions ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog.Description, { children: "Follow the instructions below to install this app on your device." }), (0, jsx_runtime_1.jsx)(InstallInstructions, {}), (0, jsx_runtime_1.jsxs)(Dialog_js_1.Dialog.Actions, { children: [(0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog.Close, { asChild: true, children: (0, jsx_runtime_1.jsx)(Button_js_1.Button, { emphasis: "ghost", children: "Close" }) }), (0, jsx_runtime_1.jsxs)(Button_js_1.Button, { onClick: () => setShowInstructions(false), children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "arrowLeft" }), " Back"] })] })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog.Description, { children: "This site is also an app. You can install it right now for easier access and more features." }), (manifest === null || manifest === void 0 ? void 0 : manifest.description) && ((0, jsx_runtime_1.jsx)(typography_js_1.P, { className: "mb-sm", children: manifest.description })), (0, jsx_runtime_1.jsx)(ManifestImageGallery, { manifestPath: manifestPath }), (0, jsx_runtime_1.jsxs)(Dialog_js_1.Dialog.Actions, { children: [(0, jsx_runtime_1.jsx)(Dialog_js_1.Dialog.Close, { asChild: true, children: (0, jsx_runtime_1.jsx)(Button_js_1.Button, { emphasis: "ghost", children: "Close" }) }), (0, jsx_runtime_1.jsx)(InstallDeviceActions, { showInstructions: () => setShowInstructions(true) })] })] }))] })] }));
40
- }
41
- const supportsDirectInstall = (0, platform_js_1.getSupportsPWAInstallPrompt)();
42
- function InstallInstructions() {
43
- const os = (0, platform_js_1.getOS)();
44
- if (os === 'iOS' || os === 'Mac OS') {
45
- if ((0, platform_js_1.getIsSafari)()) {
46
- if (os === 'iOS') {
47
- return ((0, jsx_runtime_1.jsxs)(lists_js_1.Ol, { children: [(0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariShareIcon, {}), " Tap the Share button in the toolbar."] }), (0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariPlusSquareIcon, {}), " Scroll down and tap \"Add to Home Screen\"."] })] }));
48
- }
49
- else {
50
- return ((0, jsx_runtime_1.jsxs)(lists_js_1.Ol, { children: [(0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariShareIcon, {}), " Tap the Share button in the toolbar."] }), (0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariAddToDockIcon, {}), " Tap \"Add to Dock\"."] })] }));
51
- }
52
- }
53
- else {
54
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lists_js_1.Ol, { children: (0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.SafariIcon, {}), " Open this site in Safari to continue."] }) }), (0, jsx_runtime_1.jsx)(Box_js_1.Box, { surface: true, p: true, children: "Apple does not allow non-Safari browsers to install web apps." })] }));
55
- }
56
- }
57
- return ((0, jsx_runtime_1.jsxs)(lists_js_1.Ol, { children: [(0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "dots", className: "rotate-90" }), " Tap the menu button in the toolbar."] }), (0, jsx_runtime_1.jsxs)(lists_js_1.Ol.Item, { children: [(0, jsx_runtime_1.jsx)(PlatformIcons_js_1.AndroidAddToHomeIcon, {}), " Tap \"Add to Home Screen.\""] })] }));
58
- }
59
- function ManifestImageGallery({ manifestPath }) {
60
- var _a, _b;
61
- const manifest = (0, useWebManifest_js_1.useWebManifest)(manifestPath);
62
- if (!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.screenshots) === null || _a === void 0 ? void 0 : _a.length)) {
63
- return null;
64
- }
65
- return ((0, jsx_runtime_1.jsx)(Box_js_1.Box, { overflow: "auto-x", p: "sm", gap: true, className: "h-240px", children: (_b = manifest.screenshots) === null || _b === void 0 ? void 0 : _b.map((screenshot, index) => ((0, jsx_runtime_1.jsxs)(Lightbox_js_1.Lightbox.Root, { children: [(0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Trigger, { asChild: true, children: (0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Image, { tabIndex: 0, src: screenshot.src, alt: screenshot.label || `Screenshot ${index + 1}`, className: "border border-default rounded-xs" }, index) }), (0, jsx_runtime_1.jsxs)(Lightbox_js_1.Lightbox.Portal, { children: [(0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Overlay, { className: "z-10000" }), (0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Content, { className: "z-10001", children: (0, jsx_runtime_1.jsx)(Lightbox_js_1.Lightbox.Image, { src: screenshot.src, alt: screenshot.label || `Screenshot ${index + 1}` }) })] })] }, screenshot.src))) }));
66
- }
67
- function InstallDeviceActions({ showInstructions, }) {
68
- const ready = (0, useIsInstallReady_js_1.useIsInstallReady)();
69
- if (supportsDirectInstall && ready) {
70
- return ((0, jsx_runtime_1.jsxs)(Button_js_1.Button, { onClick: () => (0, useIsInstallReady_js_1.triggerDeferredInstall)(), emphasis: "primary", children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "download" }), " Install now"] }));
71
- }
72
- return ((0, jsx_runtime_1.jsxs)(Button_js_1.Button, { onClick: () => showInstructions(), emphasis: "primary", children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "arrowRight" }), " Add to Home"] }));
27
+ return ((0, jsx_runtime_1.jsx)(Button_js_1.Button, Object.assign({ color: "primary", emphasis: "light" }, rest, { onClick: () => {
28
+ state_js_1.pwaInstallerState.open = true;
29
+ }, children: children !== null && children !== void 0 ? children : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Icon_js_1.Icon, { name: "star" }), " Install"] })) })));
73
30
  }
74
31
  //# sourceMappingURL=PwaInstallTrigger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PwaInstallTrigger.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/PwaInstallTrigger.tsx"],"names":[],"mappings":";;;;;;;;;;;;;AAgCA,8CAgFC;;AA/GD,iCAAiC;AACjC,mDAI2B;AAC3B,0CAAoC;AACpC,mDAA6C;AAC7C,mDAA6C;AAC7C,6CAAuC;AACvC,yDAAmD;AACnD,gDAAuC;AACvC,+DAAgD;AAChD,yDAM4B;AAC5B,iEAIgC;AAChC,2DAAqD;AAMrD,SAAgB,iBAAiB,CAAC,EAKT;;QALS,EACjC,QAAQ,EACR,YAAY,EACZ,OAAO,EAAE,CAAC,OAEc,EADrB,IAAI,cAJ0B,uCAKjC,CADO;IAEP,MAAM,SAAS,GAAG,IAAA,qCAAc,GAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAA,kCAAc,EAAC,YAAY,CAAC,CAAC;IAE9C,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAEhE,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,WAAW,GAAG,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,0CAAG,CAAC,CAAC,CAAC;IAEzC,OAAO,CACN,wBAAC,kBAAM,eACN,uBAAC,kBAAM,CAAC,OAAO,oBAAK,IAAI,IAAE,OAAO,kBAC/B,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,CACZ,wBAAC,kBAAM,IAAC,KAAK,EAAC,SAAS,EAAC,QAAQ,EAAC,OAAO,aACvC,uBAAC,cAAI,IAAC,IAAI,EAAC,MAAM,GAAG,gBACZ,CACT,IACe,EACjB,wBAAC,kBAAM,CAAC,OAAO,IAAC,SAAS,EAAC,sBAAsB,aAC/C,wBAAC,kBAAM,CAAC,KAAK,IAAC,SAAS,EAAC,mCAAmC,aACzD,WAAW,IAAI,CACf,gCACC,GAAG,EAAE,WAAW,CAAC,GAAG,EACpB,GAAG,EACF,MAAA,MAAA,MAAA,WAAW,CAAC,KAAK,mCACjB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,UAAU,mCACpB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,mCACd,UAAU,EAEX,SAAS,EAAC,kCAAkC,GAC3C,CACF,cACQ,MAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,UAAU,mCAAI,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,mCAAI,KAAK,IAC1C,EACd,gBAAgB,CAAC,CAAC,CAAC,CACnB,6DACC,uBAAC,kBAAM,CAAC,WAAW,oFAEE,EACrB,uBAAC,mBAAmB,KAAG,EACvB,wBAAC,kBAAM,CAAC,OAAO,eACd,uBAAC,kBAAM,CAAC,KAAK,IAAC,OAAO,kBACpB,uBAAC,kBAAM,IAAC,QAAQ,EAAC,OAAO,sBAAe,GACzB,EACf,wBAAC,kBAAM,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,aAChD,uBAAC,cAAI,IAAC,IAAI,EAAC,WAAW,GAAG,aACjB,IACO,IACf,CACH,CAAC,CAAC,CAAC,CACH,6DACC,uBAAC,kBAAM,CAAC,WAAW,8GAGE,EACpB,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,WAAW,KAAI,CACzB,uBAAC,iBAAC,IAAC,SAAS,EAAC,OAAO,YAAE,QAAQ,CAAC,WAAW,GAAK,CAC/C,EACD,uBAAC,oBAAoB,IAAC,YAAY,EAAE,YAAY,GAAI,EACpD,wBAAC,kBAAM,CAAC,OAAO,eACd,uBAAC,kBAAM,CAAC,KAAK,IAAC,OAAO,kBACpB,uBAAC,kBAAM,IAAC,QAAQ,EAAC,OAAO,sBAAe,GACzB,EACf,uBAAC,oBAAoB,IACpB,gBAAgB,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,GAChD,IACc,IACf,CACH,IACe,IACT,CACT,CAAC;AACH,CAAC;AAED,MAAM,qBAAqB,GAAG,IAAA,yCAA2B,GAAE,CAAC;AAE5D,SAAS,mBAAmB;IAC3B,MAAM,EAAE,GAAG,IAAA,mBAAK,GAAE,CAAC;IACnB,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;QACrC,IAAI,IAAA,yBAAW,GAAE,EAAE,CAAC;YACnB,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;gBAClB,OAAO,CACN,wBAAC,aAAE,eACF,wBAAC,aAAE,CAAC,IAAI,eACP,uBAAC,kCAAe,KAAG,6CACV,EACV,wBAAC,aAAE,CAAC,IAAI,eACP,uBAAC,uCAAoB,KAAG,oDACf,IACN,CACL,CAAC;YACH,CAAC;iBAAM,CAAC;gBACP,OAAO,CACN,wBAAC,aAAE,eACF,wBAAC,aAAE,CAAC,IAAI,eACP,uBAAC,kCAAe,KAAG,6CACV,EACV,wBAAC,aAAE,CAAC,IAAI,eACP,uBAAC,sCAAmB,KAAG,6BACd,IACN,CACL,CAAC;YACH,CAAC;QACF,CAAC;aAAM,CAAC;YACP,OAAO,CACN,6DACC,uBAAC,aAAE,cACF,wBAAC,aAAE,CAAC,IAAI,eACP,uBAAC,6BAAU,KAAG,8CACL,GACN,EACL,uBAAC,YAAG,IAAC,OAAO,QAAC,CAAC,oFAER,IACJ,CACH,CAAC;QACH,CAAC;IACF,CAAC;IAED,OAAO,CACN,wBAAC,aAAE,eACF,wBAAC,aAAE,CAAC,IAAI,eACP,uBAAC,cAAI,IAAC,IAAI,EAAC,MAAM,EAAC,SAAS,EAAC,WAAW,GAAG,4CAEjC,EACV,wBAAC,aAAE,CAAC,IAAI,eACP,uBAAC,uCAAoB,KAAG,oCACf,IACN,CACL,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,EAAE,YAAY,EAA6B;;IACxE,MAAM,QAAQ,GAAG,IAAA,kCAAc,EAAC,YAAY,CAAC,CAAC;IAE9C,IAAI,CAAC,CAAA,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,WAAW,0CAAE,MAAM,CAAA,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,CACN,uBAAC,YAAG,IAAC,QAAQ,EAAC,QAAQ,EAAC,CAAC,EAAC,IAAI,EAAC,GAAG,QAAC,SAAS,EAAC,SAAS,YACnD,MAAA,QAAQ,CAAC,WAAW,0CAAE,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC,CACjD,wBAAC,sBAAQ,CAAC,IAAI,eACb,uBAAC,sBAAQ,CAAC,OAAO,IAAC,OAAO,kBACxB,uBAAC,sBAAQ,CAAC,KAAK,IACd,QAAQ,EAAE,CAAC,EAEX,GAAG,EAAE,UAAU,CAAC,GAAG,EACnB,GAAG,EAAE,UAAU,CAAC,KAAK,IAAI,cAAc,KAAK,GAAG,CAAC,EAAE,EAClD,SAAS,EAAC,kCAAkC,IAHvC,KAAK,CAIT,GACgB,EACnB,wBAAC,sBAAQ,CAAC,MAAM,eACf,uBAAC,sBAAQ,CAAC,OAAO,IAAC,SAAS,EAAC,SAAS,GAAG,EACxC,uBAAC,sBAAQ,CAAC,OAAO,IAAC,SAAS,EAAC,SAAS,YACpC,uBAAC,sBAAQ,CAAC,KAAK,IACd,GAAG,EAAE,UAAU,CAAC,GAAG,EACnB,GAAG,EAAE,UAAU,CAAC,KAAK,IAAI,cAAc,KAAK,GAAG,CAAC,EAAE,GACjD,GACgB,IACF,KAlBC,UAAU,CAAC,GAAG,CAmBlB,CAChB,CAAC,GACG,CACN,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,EAC7B,gBAAgB,GAGhB;IACA,MAAM,KAAK,GAAG,IAAA,wCAAiB,GAAE,CAAC;IAClC,IAAI,qBAAqB,IAAI,KAAK,EAAE,CAAC;QACpC,OAAO,CACN,wBAAC,kBAAM,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAA,6CAAsB,GAAE,EAAE,QAAQ,EAAC,SAAS,aAClE,uBAAC,cAAI,IAAC,IAAI,EAAC,UAAU,GAAG,oBAChB,CACT,CAAC;IACH,CAAC;IAED,OAAO,CACN,wBAAC,kBAAM,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,EAAE,EAAE,QAAQ,EAAC,SAAS,aAC5D,uBAAC,cAAI,IAAC,IAAI,EAAC,YAAY,GAAG,oBAClB,CACT,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"PwaInstallTrigger.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/PwaInstallTrigger.tsx"],"names":[],"mappings":";;;;;;;;;;;;;AAOA,8CAyBC;;AAhCD,mDAA0D;AAC1D,6CAAuC;AACvC,yCAA+C;AAC/C,iEAAwD;AAIxD,SAAgB,iBAAiB,CAAC,EAGT;QAHS,EACjC,QAAQ,OAEgB,EADrB,IAAI,cAF0B,YAGjC,CADO;IAEP,MAAM,SAAS,GAAG,IAAA,qCAAc,GAAE,CAAC;IACnC,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,CACN,uBAAC,kBAAM,kBACN,KAAK,EAAC,SAAS,EACf,QAAQ,EAAC,OAAO,IACZ,IAAI,IACR,OAAO,EAAE,GAAG,EAAE;YACb,4BAAiB,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC,YAEA,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,CACZ,6DACC,uBAAC,cAAI,IAAC,IAAI,EAAC,MAAM,GAAG,gBAClB,CACH,IACO,CACT,CAAC;AACH,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export * from './PwaInstallTrigger.js';
2
+ export * from './state.js';
2
3
  export * from './useIsInstallReady.js';
3
4
  export * from './useWebManifest.js';
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  __exportStar(require("./PwaInstallTrigger.js"), exports);
19
+ __exportStar(require("./state.js"), exports);
19
20
  __exportStar(require("./useIsInstallReady.js"), exports);
20
21
  __exportStar(require("./useWebManifest.js"), exports);
21
22
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,yDAAuC;AACvC,sDAAoC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC;AACvC,6CAA2B;AAC3B,yDAAuC;AACvC,sDAAoC"}
@@ -0,0 +1,4 @@
1
+ export declare const pwaInstallerState: {
2
+ open: boolean;
3
+ };
4
+ export declare function showPwaInstall(): void;
@@ -0,0 +1,13 @@
1
+ // @unocss-include
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.pwaInstallerState = void 0;
5
+ exports.showPwaInstall = showPwaInstall;
6
+ const valtio_1 = require("valtio");
7
+ exports.pwaInstallerState = (0, valtio_1.proxy)({
8
+ open: false,
9
+ });
10
+ function showPwaInstall() {
11
+ exports.pwaInstallerState.open = true;
12
+ }
13
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/state.ts"],"names":[],"mappings":";;;AAMA,wCAEC;AARD,mCAA+B;AAElB,QAAA,iBAAiB,GAAG,IAAA,cAAK,EAAC;IACtC,IAAI,EAAE,KAAK;CACX,CAAC,CAAC;AAEH,SAAgB,cAAc;IAC7B,yBAAiB,CAAC,IAAI,GAAG,IAAI,CAAC;AAC/B,CAAC"}
@@ -5,11 +5,12 @@ export interface ProviderProps {
5
5
  disableViewportOffset?: boolean;
6
6
  virtualKeyboardBehavior?: 'overlay' | 'displace';
7
7
  disableTitleBarColor?: boolean;
8
+ manifestPath?: string;
8
9
  }
9
10
  /**
10
11
  * Provides all the stuff for all global junk.
11
12
  */
12
- export declare function Provider({ children, disableParticles, disableViewportOffset, virtualKeyboardBehavior, disableTitleBarColor, }: ProviderProps): import("react/jsx-runtime").JSX.Element;
13
+ export declare function Provider({ children, disableParticles, disableViewportOffset, virtualKeyboardBehavior, disableTitleBarColor, manifestPath, }: ProviderProps): import("react/jsx-runtime").JSX.Element;
13
14
  export declare const ConfigContext: import("react").Context<{
14
15
  virtualKeyboardBehavior: "overlay" | "displace";
15
16
  }>;
@@ -5,19 +5,20 @@ import { useThemedTitleBar, useVisualViewportOffset } from '../../hooks.js';
5
5
  import { useVirtualKeyboardBehavior } from '../../hooks/useVirtualKeyboardBehavior.js';
6
6
  import { IconSpritesheet } from '../icon/index.js';
7
7
  import { ParticleLayer } from '../particles/index.js';
8
+ import { PwaInstall } from '../pwaInstall/PwaInstall.js';
8
9
  import { Toaster } from '../toasts/toasts.js';
9
10
  import { TooltipProvider } from '../tooltip/index.js';
10
11
  /**
11
12
  * Provides all the stuff for all global junk.
12
13
  */
13
- export function Provider({ children, disableParticles, disableViewportOffset, virtualKeyboardBehavior = 'displace', disableTitleBarColor, }) {
14
+ export function Provider({ children, disableParticles, disableViewportOffset, virtualKeyboardBehavior = 'displace', disableTitleBarColor, manifestPath, }) {
14
15
  useVisualViewportOffset(disableViewportOffset);
15
16
  const supportedVirtualKeyboardBehavior = typeof navigator !== 'undefined' && 'virtualKeyboard' in navigator
16
17
  ? virtualKeyboardBehavior
17
18
  : 'displace';
18
19
  useVirtualKeyboardBehavior(supportedVirtualKeyboardBehavior);
19
20
  useThemedTitleBar('gray', 'wash', undefined, disableTitleBarColor);
20
- const otherStuff = (_jsxs(_Fragment, { children: [_jsx(IconSpritesheet, {}), _jsx(Toaster, {})] }));
21
+ const otherStuff = (_jsxs(_Fragment, { children: [_jsx(IconSpritesheet, {}), _jsx(Toaster, {}), _jsx(PwaInstall, { manifestPath: manifestPath })] }));
21
22
  if (disableParticles)
22
23
  return (_jsx(ConfigContext.Provider, { value: { virtualKeyboardBehavior: supportedVirtualKeyboardBehavior }, children: _jsxs(TooltipProvider, { children: [children, otherStuff] }) }));
23
24
  return (_jsx(ConfigContext.Provider, { value: { virtualKeyboardBehavior: supportedVirtualKeyboardBehavior }, children: _jsx(TooltipProvider, { children: _jsxs(ParticleLayer, { children: [children, otherStuff] }) }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"Provider.js","sourceRoot":"","sources":["../../../../src/components/provider/Provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAa,UAAU,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAUtD;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,EACxB,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,GAAG,UAAU,EACpC,oBAAoB,GACL;IACf,uBAAuB,CAAC,qBAAqB,CAAC,CAAC;IAC/C,MAAM,gCAAgC,GACrC,OAAO,SAAS,KAAK,WAAW,IAAI,iBAAiB,IAAI,SAAS;QACjE,CAAC,CAAC,uBAAuB;QACzB,CAAC,CAAC,UAAU,CAAC;IACf,0BAA0B,CAAC,gCAAgC,CAAC,CAAC;IAC7D,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,CAClB,8BACC,KAAC,eAAe,KAAG,EACnB,KAAC,OAAO,KAAG,IACT,CACH,CAAC;IAEF,IAAI,gBAAgB;QACnB,OAAO,CACN,KAAC,aAAa,CAAC,QAAQ,IACtB,KAAK,EAAE,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,YAEpE,MAAC,eAAe,eACd,QAAQ,EACR,UAAU,IACM,GACM,CACzB,CAAC;IAEH,OAAO,CACN,KAAC,aAAa,CAAC,QAAQ,IACtB,KAAK,EAAE,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,YAEpE,KAAC,eAAe,cACf,MAAC,aAAa,eACZ,QAAQ,EACR,UAAU,IACI,GACC,GACM,CACzB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAEvC;IACF,uBAAuB,EAAE,UAAU;CACnC,CAAC,CAAC;AAEH,MAAM,UAAU,SAAS;IACxB,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"Provider.js","sourceRoot":"","sources":["../../../../src/components/provider/Provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAa,UAAU,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAWtD;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,EACxB,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,GAAG,UAAU,EACpC,oBAAoB,EACpB,YAAY,GACG;IACf,uBAAuB,CAAC,qBAAqB,CAAC,CAAC;IAC/C,MAAM,gCAAgC,GACrC,OAAO,SAAS,KAAK,WAAW,IAAI,iBAAiB,IAAI,SAAS;QACjE,CAAC,CAAC,uBAAuB;QACzB,CAAC,CAAC,UAAU,CAAC;IACf,0BAA0B,CAAC,gCAAgC,CAAC,CAAC;IAC7D,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,CAClB,8BACC,KAAC,eAAe,KAAG,EACnB,KAAC,OAAO,KAAG,EACX,KAAC,UAAU,IAAC,YAAY,EAAE,YAAY,GAAI,IACxC,CACH,CAAC;IAEF,IAAI,gBAAgB;QACnB,OAAO,CACN,KAAC,aAAa,CAAC,QAAQ,IACtB,KAAK,EAAE,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,YAEpE,MAAC,eAAe,eACd,QAAQ,EACR,UAAU,IACM,GACM,CACzB,CAAC;IAEH,OAAO,CACN,KAAC,aAAa,CAAC,QAAQ,IACtB,KAAK,EAAE,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,YAEpE,KAAC,eAAe,cACf,MAAC,aAAa,eACZ,QAAQ,EACR,UAAU,IACI,GACC,GACM,CACzB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAEvC;IACF,uBAAuB,EAAE,UAAU;CACnC,CAAC,CAAC;AAEH,MAAM,UAAU,SAAS;IACxB,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { DialogTriggerProps } from '@radix-ui/react-dialog';
2
+ export interface PwaInstall extends DialogTriggerProps {
3
+ manifestPath?: string;
4
+ }
5
+ export declare function PwaInstall({ children, manifestPath, asChild: _, ...rest }: PwaInstall): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,76 @@
1
+ // @unocss-include
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
+ import { useState } from 'react';
15
+ import { useSnapshot } from 'valtio';
16
+ import { getIsSafari, getOS, getSupportsPWAInstallPrompt, } from '../../platform.js';
17
+ import { Box } from '../box/Box.js';
18
+ import { Button } from '../button/Button.js';
19
+ import { Dialog } from '../dialog/Dialog.js';
20
+ import { Icon } from '../icon/Icon.js';
21
+ import { Lightbox } from '../lightbox/Lightbox.js';
22
+ import { Ol } from '../lists/lists.js';
23
+ import { P } from '../typography/typography.js';
24
+ import { AndroidAddToHomeIcon, SafariAddToDockIcon, SafariIcon, SafariPlusSquareIcon, SafariShareIcon, } from './PlatformIcons.js';
25
+ import { pwaInstallerState } from './state.js';
26
+ import { triggerDeferredInstall, useIsInstalled, useIsInstallReady, } from './useIsInstallReady.js';
27
+ import { useWebManifest } from './useWebManifest.js';
28
+ export function PwaInstall(_a) {
29
+ var _b, _c, _d, _e, _f, _g;
30
+ var { children, manifestPath, asChild: _ } = _a, rest = __rest(_a, ["children", "manifestPath", "asChild"]);
31
+ const installed = useIsInstalled();
32
+ const manifest = useWebManifest(manifestPath);
33
+ const { open } = useSnapshot(pwaInstallerState);
34
+ const [showInstructions, setShowInstructions] = useState(false);
35
+ if (installed) {
36
+ return null;
37
+ }
38
+ const primaryIcon = (_b = manifest === null || manifest === void 0 ? void 0 : manifest.icons) === null || _b === void 0 ? void 0 : _b[0];
39
+ return (_jsx(Dialog, { open: open, onOpenChange: (isOpen) => {
40
+ pwaInstallerState.open = isOpen;
41
+ }, children: _jsxs(Dialog.Content, { className: "flex flex-col gap-xs", id: "pwa-install-dialog", children: [_jsxs(Dialog.Title, { className: "flex flex-row gap-md items-center", children: [primaryIcon && (_jsx("img", { src: primaryIcon.src, alt: (_e = (_d = (_c = primaryIcon.label) !== null && _c !== void 0 ? _c : manifest === null || manifest === void 0 ? void 0 : manifest.short_name) !== null && _d !== void 0 ? _d : manifest === null || manifest === void 0 ? void 0 : manifest.name) !== null && _e !== void 0 ? _e : 'App Icon', className: "inline-block w-1em h-1em rounded" })), "Install ", (_g = (_f = manifest === null || manifest === void 0 ? void 0 : manifest.short_name) !== null && _f !== void 0 ? _f : manifest === null || manifest === void 0 ? void 0 : manifest.name) !== null && _g !== void 0 ? _g : 'App'] }), showInstructions ? (_jsxs(_Fragment, { children: [_jsx(Dialog.Description, { children: "Follow the instructions below to install this app on your device." }), _jsx(InstallInstructions, {}), _jsxs(Dialog.Actions, { children: [_jsx(Dialog.Close, { asChild: true, children: _jsx(Button, { emphasis: "ghost", children: "Close" }) }), _jsxs(Button, { onClick: () => setShowInstructions(false), children: [_jsx(Icon, { name: "arrowLeft" }), " Back"] })] })] })) : (_jsxs(_Fragment, { children: [_jsx(Dialog.Description, { children: "This site is also an app. You can install it right now for easier access and more features." }), (manifest === null || manifest === void 0 ? void 0 : manifest.description) && (_jsx(P, { className: "mb-sm", children: manifest.description })), _jsx(ManifestImageGallery, { manifestPath: manifestPath }), _jsxs(Dialog.Actions, { children: [_jsx(Dialog.Close, { asChild: true, children: _jsx(Button, { emphasis: "ghost", children: "Close" }) }), _jsx(InstallDeviceActions, { showInstructions: () => setShowInstructions(true) })] })] }))] }) }));
42
+ }
43
+ const supportsDirectInstall = getSupportsPWAInstallPrompt();
44
+ function InstallInstructions() {
45
+ const os = getOS();
46
+ if (os === 'iOS' || os === 'Mac OS') {
47
+ if (getIsSafari()) {
48
+ if (os === 'iOS') {
49
+ return (_jsxs(Ol, { children: [_jsxs(Ol.Item, { children: [_jsx(SafariShareIcon, {}), " Tap the Share button in the toolbar."] }), _jsxs(Ol.Item, { children: [_jsx(SafariPlusSquareIcon, {}), " Scroll down and tap \"Add to Home Screen\"."] })] }));
50
+ }
51
+ else {
52
+ return (_jsxs(Ol, { children: [_jsxs(Ol.Item, { children: [_jsx(SafariShareIcon, {}), " Tap the Share button in the toolbar."] }), _jsxs(Ol.Item, { children: [_jsx(SafariAddToDockIcon, {}), " Tap \"Add to Dock\"."] })] }));
53
+ }
54
+ }
55
+ else {
56
+ return (_jsxs(_Fragment, { children: [_jsx(Ol, { children: _jsxs(Ol.Item, { children: [_jsx(SafariIcon, {}), " Open this site in Safari to continue."] }) }), _jsx(Box, { surface: true, p: true, children: "Apple does not allow non-Safari browsers to install web apps." })] }));
57
+ }
58
+ }
59
+ return (_jsxs(Ol, { children: [_jsxs(Ol.Item, { children: [_jsx(Icon, { name: "dots", className: "rotate-90" }), " Tap the menu button in the toolbar."] }), _jsxs(Ol.Item, { children: [_jsx(AndroidAddToHomeIcon, {}), " Tap \"Add to Home Screen.\""] })] }));
60
+ }
61
+ function ManifestImageGallery({ manifestPath }) {
62
+ var _a, _b;
63
+ const manifest = useWebManifest(manifestPath);
64
+ if (!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.screenshots) === null || _a === void 0 ? void 0 : _a.length)) {
65
+ return null;
66
+ }
67
+ return (_jsx(Box, { overflow: "auto-x", p: "sm", gap: true, className: "h-240px", children: (_b = manifest.screenshots) === null || _b === void 0 ? void 0 : _b.map((screenshot, index) => (_jsxs(Lightbox.Root, { children: [_jsx(Lightbox.Trigger, { asChild: true, children: _jsx(Lightbox.Image, { tabIndex: 0, src: screenshot.src, alt: screenshot.label || `Screenshot ${index + 1}`, className: "border border-default rounded-xs" }, index) }), _jsxs(Lightbox.Portal, { children: [_jsx(Lightbox.Overlay, { className: "z-10000" }), _jsx(Lightbox.Content, { className: "z-10001", children: _jsx(Lightbox.Image, { src: screenshot.src, alt: screenshot.label || `Screenshot ${index + 1}` }) })] })] }, screenshot.src))) }));
68
+ }
69
+ function InstallDeviceActions({ showInstructions, }) {
70
+ const ready = useIsInstallReady();
71
+ if (supportsDirectInstall && ready) {
72
+ return (_jsxs(Button, { onClick: () => triggerDeferredInstall(), emphasis: "primary", children: [_jsx(Icon, { name: "download" }), " Install now"] }));
73
+ }
74
+ return (_jsxs(Button, { onClick: () => showInstructions(), emphasis: "primary", children: [_jsx(Icon, { name: "arrowRight" }), " Add to Home"] }));
75
+ }
76
+ //# sourceMappingURL=PwaInstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PwaInstall.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/PwaInstall.tsx"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- import { DialogTriggerProps } from '@radix-ui/react-dialog';
2
- export interface PwaInstallTriggerProps extends DialogTriggerProps {
3
- manifestPath?: string;
1
+ import { ButtonProps } from '../button/Button.js';
2
+ export interface PwaInstallTriggerProps extends ButtonProps {
4
3
  }
5
- export declare function PwaInstallTrigger({ children, manifestPath, asChild: _, ...rest }: PwaInstallTriggerProps): import("react/jsx-runtime").JSX.Element | null;
4
+ export declare function PwaInstallTrigger({ children, ...rest }: PwaInstallTriggerProps): import("react/jsx-runtime").JSX.Element | null;
@@ -10,62 +10,19 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  }
11
11
  return t;
12
12
  };
13
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
- import { useState } from 'react';
15
- import { getIsSafari, getOS, getSupportsPWAInstallPrompt, } from '../../platform.js';
16
- import { Box } from '../box/Box.js';
13
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
17
14
  import { Button } from '../button/Button.js';
18
- import { Dialog } from '../dialog/Dialog.js';
19
15
  import { Icon } from '../icon/Icon.js';
20
- import { Lightbox } from '../lightbox/Lightbox.js';
21
- import { Ol } from '../lists/lists.js';
22
- import { P } from '../typography/typography.js';
23
- import { AndroidAddToHomeIcon, SafariAddToDockIcon, SafariIcon, SafariPlusSquareIcon, SafariShareIcon, } from './PlatformIcons.js';
24
- import { triggerDeferredInstall, useIsInstalled, useIsInstallReady, } from './useIsInstallReady.js';
25
- import { useWebManifest } from './useWebManifest.js';
16
+ import { pwaInstallerState } from './state.js';
17
+ import { useIsInstalled } from './useIsInstallReady.js';
26
18
  export function PwaInstallTrigger(_a) {
27
- var _b, _c, _d, _e, _f, _g;
28
- var { children, manifestPath, asChild: _ } = _a, rest = __rest(_a, ["children", "manifestPath", "asChild"]);
19
+ var { children } = _a, rest = __rest(_a, ["children"]);
29
20
  const installed = useIsInstalled();
30
- const manifest = useWebManifest(manifestPath);
31
- const [showInstructions, setShowInstructions] = useState(false);
32
21
  if (installed) {
33
22
  return null;
34
23
  }
35
- const primaryIcon = (_b = manifest === null || manifest === void 0 ? void 0 : manifest.icons) === null || _b === void 0 ? void 0 : _b[0];
36
- return (_jsxs(Dialog, { children: [_jsx(Dialog.Trigger, Object.assign({}, rest, { asChild: true, children: children !== null && children !== void 0 ? children : (_jsxs(Button, { color: "primary", emphasis: "light", children: [_jsx(Icon, { name: "star" }), " Install"] })) })), _jsxs(Dialog.Content, { className: "flex flex-col gap-xs", children: [_jsxs(Dialog.Title, { className: "flex flex-row gap-md items-center", children: [primaryIcon && (_jsx("img", { src: primaryIcon.src, alt: (_e = (_d = (_c = primaryIcon.label) !== null && _c !== void 0 ? _c : manifest === null || manifest === void 0 ? void 0 : manifest.short_name) !== null && _d !== void 0 ? _d : manifest === null || manifest === void 0 ? void 0 : manifest.name) !== null && _e !== void 0 ? _e : 'App Icon', className: "inline-block w-1em h-1em rounded" })), "Install ", (_g = (_f = manifest === null || manifest === void 0 ? void 0 : manifest.short_name) !== null && _f !== void 0 ? _f : manifest === null || manifest === void 0 ? void 0 : manifest.name) !== null && _g !== void 0 ? _g : 'App'] }), showInstructions ? (_jsxs(_Fragment, { children: [_jsx(Dialog.Description, { children: "Follow the instructions below to install this app on your device." }), _jsx(InstallInstructions, {}), _jsxs(Dialog.Actions, { children: [_jsx(Dialog.Close, { asChild: true, children: _jsx(Button, { emphasis: "ghost", children: "Close" }) }), _jsxs(Button, { onClick: () => setShowInstructions(false), children: [_jsx(Icon, { name: "arrowLeft" }), " Back"] })] })] })) : (_jsxs(_Fragment, { children: [_jsx(Dialog.Description, { children: "This site is also an app. You can install it right now for easier access and more features." }), (manifest === null || manifest === void 0 ? void 0 : manifest.description) && (_jsx(P, { className: "mb-sm", children: manifest.description })), _jsx(ManifestImageGallery, { manifestPath: manifestPath }), _jsxs(Dialog.Actions, { children: [_jsx(Dialog.Close, { asChild: true, children: _jsx(Button, { emphasis: "ghost", children: "Close" }) }), _jsx(InstallDeviceActions, { showInstructions: () => setShowInstructions(true) })] })] }))] })] }));
37
- }
38
- const supportsDirectInstall = getSupportsPWAInstallPrompt();
39
- function InstallInstructions() {
40
- const os = getOS();
41
- if (os === 'iOS' || os === 'Mac OS') {
42
- if (getIsSafari()) {
43
- if (os === 'iOS') {
44
- return (_jsxs(Ol, { children: [_jsxs(Ol.Item, { children: [_jsx(SafariShareIcon, {}), " Tap the Share button in the toolbar."] }), _jsxs(Ol.Item, { children: [_jsx(SafariPlusSquareIcon, {}), " Scroll down and tap \"Add to Home Screen\"."] })] }));
45
- }
46
- else {
47
- return (_jsxs(Ol, { children: [_jsxs(Ol.Item, { children: [_jsx(SafariShareIcon, {}), " Tap the Share button in the toolbar."] }), _jsxs(Ol.Item, { children: [_jsx(SafariAddToDockIcon, {}), " Tap \"Add to Dock\"."] })] }));
48
- }
49
- }
50
- else {
51
- return (_jsxs(_Fragment, { children: [_jsx(Ol, { children: _jsxs(Ol.Item, { children: [_jsx(SafariIcon, {}), " Open this site in Safari to continue."] }) }), _jsx(Box, { surface: true, p: true, children: "Apple does not allow non-Safari browsers to install web apps." })] }));
52
- }
53
- }
54
- return (_jsxs(Ol, { children: [_jsxs(Ol.Item, { children: [_jsx(Icon, { name: "dots", className: "rotate-90" }), " Tap the menu button in the toolbar."] }), _jsxs(Ol.Item, { children: [_jsx(AndroidAddToHomeIcon, {}), " Tap \"Add to Home Screen.\""] })] }));
55
- }
56
- function ManifestImageGallery({ manifestPath }) {
57
- var _a, _b;
58
- const manifest = useWebManifest(manifestPath);
59
- if (!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.screenshots) === null || _a === void 0 ? void 0 : _a.length)) {
60
- return null;
61
- }
62
- return (_jsx(Box, { overflow: "auto-x", p: "sm", gap: true, className: "h-240px", children: (_b = manifest.screenshots) === null || _b === void 0 ? void 0 : _b.map((screenshot, index) => (_jsxs(Lightbox.Root, { children: [_jsx(Lightbox.Trigger, { asChild: true, children: _jsx(Lightbox.Image, { tabIndex: 0, src: screenshot.src, alt: screenshot.label || `Screenshot ${index + 1}`, className: "border border-default rounded-xs" }, index) }), _jsxs(Lightbox.Portal, { children: [_jsx(Lightbox.Overlay, { className: "z-10000" }), _jsx(Lightbox.Content, { className: "z-10001", children: _jsx(Lightbox.Image, { src: screenshot.src, alt: screenshot.label || `Screenshot ${index + 1}` }) })] })] }, screenshot.src))) }));
63
- }
64
- function InstallDeviceActions({ showInstructions, }) {
65
- const ready = useIsInstallReady();
66
- if (supportsDirectInstall && ready) {
67
- return (_jsxs(Button, { onClick: () => triggerDeferredInstall(), emphasis: "primary", children: [_jsx(Icon, { name: "download" }), " Install now"] }));
68
- }
69
- return (_jsxs(Button, { onClick: () => showInstructions(), emphasis: "primary", children: [_jsx(Icon, { name: "arrowRight" }), " Add to Home"] }));
24
+ return (_jsx(Button, Object.assign({ color: "primary", emphasis: "light" }, rest, { onClick: () => {
25
+ pwaInstallerState.open = true;
26
+ }, children: children !== null && children !== void 0 ? children : (_jsxs(_Fragment, { children: [_jsx(Icon, { name: "star" }), " Install"] })) })));
70
27
  }
71
28
  //# sourceMappingURL=PwaInstallTrigger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PwaInstallTrigger.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/PwaInstallTrigger.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PwaInstallTrigger.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/PwaInstallTrigger.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAIxD,MAAM,UAAU,iBAAiB,CAAC,EAGT;QAHS,EACjC,QAAQ,OAEgB,EADrB,IAAI,cAF0B,YAGjC,CADO;IAEP,MAAM,SAAS,GAAG,cAAc,EAAE,CAAC;IACnC,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,CACN,KAAC,MAAM,kBACN,KAAK,EAAC,SAAS,EACf,QAAQ,EAAC,OAAO,IACZ,IAAI,IACR,OAAO,EAAE,GAAG,EAAE;YACb,iBAAiB,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC,YAEA,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,CACZ,8BACC,KAAC,IAAI,IAAC,IAAI,EAAC,MAAM,GAAG,gBAClB,CACH,IACO,CACT,CAAC;AACH,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export * from './PwaInstallTrigger.js';
2
+ export * from './state.js';
2
3
  export * from './useIsInstallReady.js';
3
4
  export * from './useWebManifest.js';
@@ -1,5 +1,6 @@
1
1
  // @unocss-include
2
2
  export * from './PwaInstallTrigger.js';
3
+ export * from './state.js';
3
4
  export * from './useIsInstallReady.js';
4
5
  export * from './useWebManifest.js';
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare const pwaInstallerState: {
2
+ open: boolean;
3
+ };
4
+ export declare function showPwaInstall(): void;
@@ -0,0 +1,9 @@
1
+ // @unocss-include
2
+ import { proxy } from 'valtio';
3
+ export const pwaInstallerState = proxy({
4
+ open: false,
5
+ });
6
+ export function showPwaInstall() {
7
+ pwaInstallerState.open = true;
8
+ }
9
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../src/components/pwaInstall/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE/B,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;IACtC,IAAI,EAAE,KAAK;CACX,CAAC,CAAC;AAEH,MAAM,UAAU,cAAc;IAC7B,iBAAiB,CAAC,IAAI,GAAG,IAAI,CAAC;AAC/B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a-type/ui",
3
- "version": "3.0.36",
3
+ "version": "3.0.37",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "url": "https://github.com/a-type/ui"
@@ -3,6 +3,7 @@ import { useThemedTitleBar, useVisualViewportOffset } from '../../hooks.js';
3
3
  import { useVirtualKeyboardBehavior } from '../../hooks/useVirtualKeyboardBehavior.js';
4
4
  import { IconSpritesheet } from '../icon/index.js';
5
5
  import { ParticleLayer } from '../particles/index.js';
6
+ import { PwaInstall } from '../pwaInstall/PwaInstall.js';
6
7
  import { Toaster } from '../toasts/toasts.js';
7
8
  import { TooltipProvider } from '../tooltip/index.js';
8
9
 
@@ -12,6 +13,7 @@ export interface ProviderProps {
12
13
  disableViewportOffset?: boolean;
13
14
  virtualKeyboardBehavior?: 'overlay' | 'displace';
14
15
  disableTitleBarColor?: boolean;
16
+ manifestPath?: string;
15
17
  }
16
18
 
17
19
  /**
@@ -23,6 +25,7 @@ export function Provider({
23
25
  disableViewportOffset,
24
26
  virtualKeyboardBehavior = 'displace',
25
27
  disableTitleBarColor,
28
+ manifestPath,
26
29
  }: ProviderProps) {
27
30
  useVisualViewportOffset(disableViewportOffset);
28
31
  const supportedVirtualKeyboardBehavior =
@@ -35,6 +38,7 @@ export function Provider({
35
38
  <>
36
39
  <IconSpritesheet />
37
40
  <Toaster />
41
+ <PwaInstall manifestPath={manifestPath} />
38
42
  </>
39
43
  );
40
44
 
@@ -0,0 +1,228 @@
1
+ import { DialogTriggerProps } from '@radix-ui/react-dialog';
2
+ import { useState } from 'react';
3
+ import { useSnapshot } from 'valtio';
4
+ import {
5
+ getIsSafari,
6
+ getOS,
7
+ getSupportsPWAInstallPrompt,
8
+ } from '../../platform.js';
9
+ import { Box } from '../box/Box.js';
10
+ import { Button } from '../button/Button.js';
11
+ import { Dialog } from '../dialog/Dialog.js';
12
+ import { Icon } from '../icon/Icon.js';
13
+ import { Lightbox } from '../lightbox/Lightbox.js';
14
+ import { Ol } from '../lists/lists.js';
15
+ import { P } from '../typography/typography.js';
16
+ import {
17
+ AndroidAddToHomeIcon,
18
+ SafariAddToDockIcon,
19
+ SafariIcon,
20
+ SafariPlusSquareIcon,
21
+ SafariShareIcon,
22
+ } from './PlatformIcons.js';
23
+ import { pwaInstallerState } from './state.js';
24
+ import {
25
+ triggerDeferredInstall,
26
+ useIsInstalled,
27
+ useIsInstallReady,
28
+ } from './useIsInstallReady.js';
29
+ import { useWebManifest } from './useWebManifest.js';
30
+
31
+ export interface PwaInstall extends DialogTriggerProps {
32
+ manifestPath?: string;
33
+ }
34
+
35
+ export function PwaInstall({
36
+ children,
37
+ manifestPath,
38
+ asChild: _,
39
+ ...rest
40
+ }: PwaInstall) {
41
+ const installed = useIsInstalled();
42
+ const manifest = useWebManifest(manifestPath);
43
+ const { open } = useSnapshot(pwaInstallerState);
44
+
45
+ const [showInstructions, setShowInstructions] = useState(false);
46
+
47
+ if (installed) {
48
+ return null;
49
+ }
50
+
51
+ const primaryIcon = manifest?.icons?.[0];
52
+
53
+ return (
54
+ <Dialog
55
+ open={open}
56
+ onOpenChange={(isOpen) => {
57
+ pwaInstallerState.open = isOpen;
58
+ }}
59
+ >
60
+ <Dialog.Content className="flex flex-col gap-xs" id="pwa-install-dialog">
61
+ <Dialog.Title className="flex flex-row gap-md items-center">
62
+ {primaryIcon && (
63
+ <img
64
+ src={primaryIcon.src}
65
+ alt={
66
+ primaryIcon.label ??
67
+ manifest?.short_name ??
68
+ manifest?.name ??
69
+ 'App Icon'
70
+ }
71
+ className="inline-block w-1em h-1em rounded"
72
+ />
73
+ )}
74
+ Install {manifest?.short_name ?? manifest?.name ?? 'App'}
75
+ </Dialog.Title>
76
+ {showInstructions ? (
77
+ <>
78
+ <Dialog.Description>
79
+ Follow the instructions below to install this app on your device.
80
+ </Dialog.Description>
81
+ <InstallInstructions />
82
+ <Dialog.Actions>
83
+ <Dialog.Close asChild>
84
+ <Button emphasis="ghost">Close</Button>
85
+ </Dialog.Close>
86
+ <Button onClick={() => setShowInstructions(false)}>
87
+ <Icon name="arrowLeft" /> Back
88
+ </Button>
89
+ </Dialog.Actions>
90
+ </>
91
+ ) : (
92
+ <>
93
+ <Dialog.Description>
94
+ This site is also an app. You can install it right now for easier
95
+ access and more features.
96
+ </Dialog.Description>
97
+ {manifest?.description && (
98
+ <P className="mb-sm">{manifest.description}</P>
99
+ )}
100
+ <ManifestImageGallery manifestPath={manifestPath} />
101
+ <Dialog.Actions>
102
+ <Dialog.Close asChild>
103
+ <Button emphasis="ghost">Close</Button>
104
+ </Dialog.Close>
105
+ <InstallDeviceActions
106
+ showInstructions={() => setShowInstructions(true)}
107
+ />
108
+ </Dialog.Actions>
109
+ </>
110
+ )}
111
+ </Dialog.Content>
112
+ </Dialog>
113
+ );
114
+ }
115
+
116
+ const supportsDirectInstall = getSupportsPWAInstallPrompt();
117
+
118
+ function InstallInstructions() {
119
+ const os = getOS();
120
+ if (os === 'iOS' || os === 'Mac OS') {
121
+ if (getIsSafari()) {
122
+ if (os === 'iOS') {
123
+ return (
124
+ <Ol>
125
+ <Ol.Item>
126
+ <SafariShareIcon /> Tap the Share button in the toolbar.
127
+ </Ol.Item>
128
+ <Ol.Item>
129
+ <SafariPlusSquareIcon /> Scroll down and tap "Add to Home Screen".
130
+ </Ol.Item>
131
+ </Ol>
132
+ );
133
+ } else {
134
+ return (
135
+ <Ol>
136
+ <Ol.Item>
137
+ <SafariShareIcon /> Tap the Share button in the toolbar.
138
+ </Ol.Item>
139
+ <Ol.Item>
140
+ <SafariAddToDockIcon /> Tap "Add to Dock".
141
+ </Ol.Item>
142
+ </Ol>
143
+ );
144
+ }
145
+ } else {
146
+ return (
147
+ <>
148
+ <Ol>
149
+ <Ol.Item>
150
+ <SafariIcon /> Open this site in Safari to continue.
151
+ </Ol.Item>
152
+ </Ol>
153
+ <Box surface p>
154
+ Apple does not allow non-Safari browsers to install web apps.
155
+ </Box>
156
+ </>
157
+ );
158
+ }
159
+ }
160
+
161
+ return (
162
+ <Ol>
163
+ <Ol.Item>
164
+ <Icon name="dots" className="rotate-90" /> Tap the menu button in the
165
+ toolbar.
166
+ </Ol.Item>
167
+ <Ol.Item>
168
+ <AndroidAddToHomeIcon /> Tap "Add to Home Screen."
169
+ </Ol.Item>
170
+ </Ol>
171
+ );
172
+ }
173
+
174
+ function ManifestImageGallery({ manifestPath }: { manifestPath?: string }) {
175
+ const manifest = useWebManifest(manifestPath);
176
+
177
+ if (!manifest?.screenshots?.length) {
178
+ return null;
179
+ }
180
+
181
+ return (
182
+ <Box overflow="auto-x" p="sm" gap className="h-240px">
183
+ {manifest.screenshots?.map((screenshot, index) => (
184
+ <Lightbox.Root key={screenshot.src}>
185
+ <Lightbox.Trigger asChild>
186
+ <Lightbox.Image
187
+ tabIndex={0}
188
+ key={index}
189
+ src={screenshot.src}
190
+ alt={screenshot.label || `Screenshot ${index + 1}`}
191
+ className="border border-default rounded-xs"
192
+ />
193
+ </Lightbox.Trigger>
194
+ <Lightbox.Portal>
195
+ <Lightbox.Overlay className="z-10000" />
196
+ <Lightbox.Content className="z-10001">
197
+ <Lightbox.Image
198
+ src={screenshot.src}
199
+ alt={screenshot.label || `Screenshot ${index + 1}`}
200
+ />
201
+ </Lightbox.Content>
202
+ </Lightbox.Portal>
203
+ </Lightbox.Root>
204
+ ))}
205
+ </Box>
206
+ );
207
+ }
208
+
209
+ function InstallDeviceActions({
210
+ showInstructions,
211
+ }: {
212
+ showInstructions: () => void;
213
+ }) {
214
+ const ready = useIsInstallReady();
215
+ if (supportsDirectInstall && ready) {
216
+ return (
217
+ <Button onClick={() => triggerDeferredInstall()} emphasis="primary">
218
+ <Icon name="download" /> Install now
219
+ </Button>
220
+ );
221
+ }
222
+
223
+ return (
224
+ <Button onClick={() => showInstructions()} emphasis="primary">
225
+ <Icon name="arrowRight" /> Add to Home
226
+ </Button>
227
+ );
228
+ }
@@ -1,227 +1,33 @@
1
- import { DialogTriggerProps } from '@radix-ui/react-dialog';
2
- import { useState } from 'react';
3
- import {
4
- getIsSafari,
5
- getOS,
6
- getSupportsPWAInstallPrompt,
7
- } from '../../platform.js';
8
- import { Box } from '../box/Box.js';
9
- import { Button } from '../button/Button.js';
10
- import { Dialog } from '../dialog/Dialog.js';
1
+ import { Button, ButtonProps } from '../button/Button.js';
11
2
  import { Icon } from '../icon/Icon.js';
12
- import { Lightbox } from '../lightbox/Lightbox.js';
13
- import { Ol } from '../lists/lists.js';
14
- import { P } from '../typography/typography.js';
15
- import {
16
- AndroidAddToHomeIcon,
17
- SafariAddToDockIcon,
18
- SafariIcon,
19
- SafariPlusSquareIcon,
20
- SafariShareIcon,
21
- } from './PlatformIcons.js';
22
- import {
23
- triggerDeferredInstall,
24
- useIsInstalled,
25
- useIsInstallReady,
26
- } from './useIsInstallReady.js';
27
- import { useWebManifest } from './useWebManifest.js';
3
+ import { pwaInstallerState } from './state.js';
4
+ import { useIsInstalled } from './useIsInstallReady.js';
28
5
 
29
- export interface PwaInstallTriggerProps extends DialogTriggerProps {
30
- manifestPath?: string;
31
- }
6
+ export interface PwaInstallTriggerProps extends ButtonProps {}
32
7
 
33
8
  export function PwaInstallTrigger({
34
9
  children,
35
- manifestPath,
36
- asChild: _,
37
10
  ...rest
38
11
  }: PwaInstallTriggerProps) {
39
12
  const installed = useIsInstalled();
40
- const manifest = useWebManifest(manifestPath);
41
-
42
- const [showInstructions, setShowInstructions] = useState(false);
43
-
44
13
  if (installed) {
45
14
  return null;
46
15
  }
47
16
 
48
- const primaryIcon = manifest?.icons?.[0];
49
-
50
17
  return (
51
- <Dialog>
52
- <Dialog.Trigger {...rest} asChild>
53
- {children ?? (
54
- <Button color="primary" emphasis="light">
55
- <Icon name="star" /> Install
56
- </Button>
57
- )}
58
- </Dialog.Trigger>
59
- <Dialog.Content className="flex flex-col gap-xs">
60
- <Dialog.Title className="flex flex-row gap-md items-center">
61
- {primaryIcon && (
62
- <img
63
- src={primaryIcon.src}
64
- alt={
65
- primaryIcon.label ??
66
- manifest?.short_name ??
67
- manifest?.name ??
68
- 'App Icon'
69
- }
70
- className="inline-block w-1em h-1em rounded"
71
- />
72
- )}
73
- Install {manifest?.short_name ?? manifest?.name ?? 'App'}
74
- </Dialog.Title>
75
- {showInstructions ? (
76
- <>
77
- <Dialog.Description>
78
- Follow the instructions below to install this app on your device.
79
- </Dialog.Description>
80
- <InstallInstructions />
81
- <Dialog.Actions>
82
- <Dialog.Close asChild>
83
- <Button emphasis="ghost">Close</Button>
84
- </Dialog.Close>
85
- <Button onClick={() => setShowInstructions(false)}>
86
- <Icon name="arrowLeft" /> Back
87
- </Button>
88
- </Dialog.Actions>
89
- </>
90
- ) : (
91
- <>
92
- <Dialog.Description>
93
- This site is also an app. You can install it right now for easier
94
- access and more features.
95
- </Dialog.Description>
96
- {manifest?.description && (
97
- <P className="mb-sm">{manifest.description}</P>
98
- )}
99
- <ManifestImageGallery manifestPath={manifestPath} />
100
- <Dialog.Actions>
101
- <Dialog.Close asChild>
102
- <Button emphasis="ghost">Close</Button>
103
- </Dialog.Close>
104
- <InstallDeviceActions
105
- showInstructions={() => setShowInstructions(true)}
106
- />
107
- </Dialog.Actions>
108
- </>
109
- )}
110
- </Dialog.Content>
111
- </Dialog>
112
- );
113
- }
114
-
115
- const supportsDirectInstall = getSupportsPWAInstallPrompt();
116
-
117
- function InstallInstructions() {
118
- const os = getOS();
119
- if (os === 'iOS' || os === 'Mac OS') {
120
- if (getIsSafari()) {
121
- if (os === 'iOS') {
122
- return (
123
- <Ol>
124
- <Ol.Item>
125
- <SafariShareIcon /> Tap the Share button in the toolbar.
126
- </Ol.Item>
127
- <Ol.Item>
128
- <SafariPlusSquareIcon /> Scroll down and tap "Add to Home Screen".
129
- </Ol.Item>
130
- </Ol>
131
- );
132
- } else {
133
- return (
134
- <Ol>
135
- <Ol.Item>
136
- <SafariShareIcon /> Tap the Share button in the toolbar.
137
- </Ol.Item>
138
- <Ol.Item>
139
- <SafariAddToDockIcon /> Tap "Add to Dock".
140
- </Ol.Item>
141
- </Ol>
142
- );
143
- }
144
- } else {
145
- return (
18
+ <Button
19
+ color="primary"
20
+ emphasis="light"
21
+ {...rest}
22
+ onClick={() => {
23
+ pwaInstallerState.open = true;
24
+ }}
25
+ >
26
+ {children ?? (
146
27
  <>
147
- <Ol>
148
- <Ol.Item>
149
- <SafariIcon /> Open this site in Safari to continue.
150
- </Ol.Item>
151
- </Ol>
152
- <Box surface p>
153
- Apple does not allow non-Safari browsers to install web apps.
154
- </Box>
28
+ <Icon name="star" /> Install
155
29
  </>
156
- );
157
- }
158
- }
159
-
160
- return (
161
- <Ol>
162
- <Ol.Item>
163
- <Icon name="dots" className="rotate-90" /> Tap the menu button in the
164
- toolbar.
165
- </Ol.Item>
166
- <Ol.Item>
167
- <AndroidAddToHomeIcon /> Tap "Add to Home Screen."
168
- </Ol.Item>
169
- </Ol>
170
- );
171
- }
172
-
173
- function ManifestImageGallery({ manifestPath }: { manifestPath?: string }) {
174
- const manifest = useWebManifest(manifestPath);
175
-
176
- if (!manifest?.screenshots?.length) {
177
- return null;
178
- }
179
-
180
- return (
181
- <Box overflow="auto-x" p="sm" gap className="h-240px">
182
- {manifest.screenshots?.map((screenshot, index) => (
183
- <Lightbox.Root key={screenshot.src}>
184
- <Lightbox.Trigger asChild>
185
- <Lightbox.Image
186
- tabIndex={0}
187
- key={index}
188
- src={screenshot.src}
189
- alt={screenshot.label || `Screenshot ${index + 1}`}
190
- className="border border-default rounded-xs"
191
- />
192
- </Lightbox.Trigger>
193
- <Lightbox.Portal>
194
- <Lightbox.Overlay className="z-10000" />
195
- <Lightbox.Content className="z-10001">
196
- <Lightbox.Image
197
- src={screenshot.src}
198
- alt={screenshot.label || `Screenshot ${index + 1}`}
199
- />
200
- </Lightbox.Content>
201
- </Lightbox.Portal>
202
- </Lightbox.Root>
203
- ))}
204
- </Box>
205
- );
206
- }
207
-
208
- function InstallDeviceActions({
209
- showInstructions,
210
- }: {
211
- showInstructions: () => void;
212
- }) {
213
- const ready = useIsInstallReady();
214
- if (supportsDirectInstall && ready) {
215
- return (
216
- <Button onClick={() => triggerDeferredInstall()} emphasis="primary">
217
- <Icon name="download" /> Install now
218
- </Button>
219
- );
220
- }
221
-
222
- return (
223
- <Button onClick={() => showInstructions()} emphasis="primary">
224
- <Icon name="arrowRight" /> Add to Home
30
+ )}
225
31
  </Button>
226
32
  );
227
33
  }
@@ -1,3 +1,4 @@
1
1
  export * from './PwaInstallTrigger.js';
2
+ export * from './state.js';
2
3
  export * from './useIsInstallReady.js';
3
4
  export * from './useWebManifest.js';
@@ -0,0 +1,9 @@
1
+ import { proxy } from 'valtio';
2
+
3
+ export const pwaInstallerState = proxy({
4
+ open: false,
5
+ });
6
+
7
+ export function showPwaInstall() {
8
+ pwaInstallerState.open = true;
9
+ }