@arbidocs/blocks 0.4.4 → 0.4.6

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 (149) hide show
  1. package/README.md +71 -6
  2. package/dist/agents/index.cjs +163 -162
  3. package/dist/agents/index.js +6 -5
  4. package/dist/artifacts/ArtifactCompareBar.d.ts +33 -0
  5. package/dist/artifacts/ArtifactEditor.d.ts +64 -0
  6. package/dist/artifacts/ArtifactEditorBody.d.ts +34 -0
  7. package/dist/artifacts/ArtifactRedlineView.d.ts +57 -0
  8. package/dist/artifacts/ArtifactToolbar.d.ts +53 -0
  9. package/dist/artifacts/ArtifactVersionBar.d.ts +42 -0
  10. package/dist/{files → artifacts}/RedlineParts.d.ts +4 -0
  11. package/dist/artifacts/editor/ArtifactMarkdownEditor.d.ts +39 -0
  12. package/dist/artifacts/editor/index.cjs +89 -0
  13. package/dist/artifacts/editor/index.cjs.map +1 -0
  14. package/dist/artifacts/editor/index.d.ts +1 -0
  15. package/dist/artifacts/editor/index.js +86 -0
  16. package/dist/artifacts/editor/index.js.map +1 -0
  17. package/dist/artifacts/index.cjs +807 -0
  18. package/dist/artifacts/index.cjs.map +1 -0
  19. package/dist/artifacts/index.d.ts +8 -0
  20. package/dist/artifacts/index.js +787 -0
  21. package/dist/artifacts/index.js.map +1 -0
  22. package/dist/chat/ChatMessageContent.d.ts +16 -0
  23. package/dist/chat/ChatPage.d.ts +11 -8
  24. package/dist/chat/ChatThreads.d.ts +3 -1
  25. package/dist/chat/CitationMark.d.ts +18 -0
  26. package/dist/chat/chat-page-types.d.ts +75 -1
  27. package/dist/chat/index.cjs +125 -116
  28. package/dist/chat/index.d.ts +3 -1
  29. package/dist/chat/index.js +4 -3
  30. package/dist/{chunk-XKKGGUU2.cjs → chunk-23XL6SVZ.cjs} +39 -19
  31. package/dist/chunk-23XL6SVZ.cjs.map +1 -0
  32. package/dist/{chunk-ULWRNGGE.cjs → chunk-2ZTONLT5.cjs} +4 -25
  33. package/dist/chunk-2ZTONLT5.cjs.map +1 -0
  34. package/dist/{chunk-O637DUKS.cjs → chunk-56BUD74K.cjs} +28 -28
  35. package/dist/{chunk-O637DUKS.cjs.map → chunk-56BUD74K.cjs.map} +1 -1
  36. package/dist/{chunk-ATXPAD6S.cjs → chunk-5SLLMK5K.cjs} +420 -114
  37. package/dist/chunk-5SLLMK5K.cjs.map +1 -0
  38. package/dist/{chunk-SS23F63U.cjs → chunk-5ZBP7TCD.cjs} +55 -3
  39. package/dist/chunk-5ZBP7TCD.cjs.map +1 -0
  40. package/dist/{chunk-DGVKBOY5.cjs → chunk-67HGXV4I.cjs} +6 -6
  41. package/dist/{chunk-DGVKBOY5.cjs.map → chunk-67HGXV4I.cjs.map} +1 -1
  42. package/dist/{chunk-RCP6THBS.js → chunk-7OCFHEE6.js} +3 -3
  43. package/dist/{chunk-RCP6THBS.js.map → chunk-7OCFHEE6.js.map} +1 -1
  44. package/dist/{chunk-TX2ZICS7.js → chunk-CPMNAJLF.js} +4 -24
  45. package/dist/chunk-CPMNAJLF.js.map +1 -0
  46. package/dist/{chunk-BBEMPS6C.js → chunk-CVFBSUXL.js} +5 -5
  47. package/dist/{chunk-BBEMPS6C.js.map → chunk-CVFBSUXL.js.map} +1 -1
  48. package/dist/chunk-DCDVWPMB.cjs +29 -0
  49. package/dist/chunk-DCDVWPMB.cjs.map +1 -0
  50. package/dist/{chunk-TI4UTYRL.js → chunk-EY2RJW27.js} +258 -10
  51. package/dist/chunk-EY2RJW27.js.map +1 -0
  52. package/dist/{chunk-7YADKWZT.js → chunk-G2E3O3HI.js} +3 -3
  53. package/dist/{chunk-7YADKWZT.js.map → chunk-G2E3O3HI.js.map} +1 -1
  54. package/dist/{chunk-JPO3F4J7.js → chunk-G2T3KTZ3.js} +418 -114
  55. package/dist/chunk-G2T3KTZ3.js.map +1 -0
  56. package/dist/{chunk-2NNTQLBY.js → chunk-IAKUTBPX.js} +4 -4
  57. package/dist/{chunk-2NNTQLBY.js.map → chunk-IAKUTBPX.js.map} +1 -1
  58. package/dist/{chunk-IZHWP6WQ.cjs → chunk-JG4TFS3Z.cjs} +6 -6
  59. package/dist/{chunk-IZHWP6WQ.cjs.map → chunk-JG4TFS3Z.cjs.map} +1 -1
  60. package/dist/chunk-JLOYWXRB.js +1156 -0
  61. package/dist/chunk-JLOYWXRB.js.map +1 -0
  62. package/dist/{chunk-WJZBJUPX.js → chunk-KXMDOTGW.js} +56 -4
  63. package/dist/chunk-KXMDOTGW.js.map +1 -0
  64. package/dist/{chunk-2VBJ763Y.js → chunk-KZJAG7T3.js} +37 -7
  65. package/dist/chunk-KZJAG7T3.js.map +1 -0
  66. package/dist/{chunk-RIL7G7AS.cjs → chunk-MGUHR3JI.cjs} +4 -4
  67. package/dist/{chunk-RIL7G7AS.cjs.map → chunk-MGUHR3JI.cjs.map} +1 -1
  68. package/dist/{chunk-DN3NFNIA.cjs → chunk-QMDLPO3M.cjs} +266 -10
  69. package/dist/chunk-QMDLPO3M.cjs.map +1 -0
  70. package/dist/chunk-TJMKFY5P.js +27 -0
  71. package/dist/chunk-TJMKFY5P.js.map +1 -0
  72. package/dist/{chunk-B673CCW5.js → chunk-UHVNYKV2.js} +38 -18
  73. package/dist/chunk-UHVNYKV2.js.map +1 -0
  74. package/dist/{chunk-6CHMNKXC.cjs → chunk-UTYQPVIW.cjs} +11 -11
  75. package/dist/chunk-UTYQPVIW.cjs.map +1 -0
  76. package/dist/{chunk-KHX2BX3S.cjs → chunk-VGOFFCMT.cjs} +37 -5
  77. package/dist/chunk-VGOFFCMT.cjs.map +1 -0
  78. package/dist/{chunk-67MKU5U7.js → chunk-YMHGF6R5.js} +8 -8
  79. package/dist/chunk-YMHGF6R5.js.map +1 -0
  80. package/dist/chunk-YVIOCITQ.cjs +1186 -0
  81. package/dist/chunk-YVIOCITQ.cjs.map +1 -0
  82. package/dist/collaboration/index.cjs +38 -37
  83. package/dist/collaboration/index.js +3 -2
  84. package/dist/connect/index.cjs +358 -19
  85. package/dist/connect/index.cjs.map +1 -1
  86. package/dist/connect/index.d.ts +1 -0
  87. package/dist/connect/index.js +341 -9
  88. package/dist/connect/index.js.map +1 -1
  89. package/dist/connection/ConnectedSettings.d.ts +64 -0
  90. package/dist/facts/index.cjs +1 -1
  91. package/dist/facts/index.js +1 -1
  92. package/dist/files/ViewerChrome.d.ts +0 -45
  93. package/dist/files/ViewerParts.d.ts +0 -19
  94. package/dist/files/index.cjs +15 -446
  95. package/dist/files/index.cjs.map +1 -1
  96. package/dist/files/index.d.ts +2 -4
  97. package/dist/files/index.js +9 -428
  98. package/dist/files/index.js.map +1 -1
  99. package/dist/home/index.cjs +1 -1
  100. package/dist/home/index.js +1 -1
  101. package/dist/index.cjs +634 -585
  102. package/dist/index.cjs.map +1 -1
  103. package/dist/index.js +19 -18
  104. package/dist/index.js.map +1 -1
  105. package/dist/lib/bottom-inset.d.ts +16 -0
  106. package/dist/lib/useElementSize.d.ts +13 -0
  107. package/dist/lib/useFillHeight.d.ts +10 -0
  108. package/dist/settings/account-views.d.ts +55 -0
  109. package/dist/settings/index.cjs +178 -1147
  110. package/dist/settings/index.cjs.map +1 -1
  111. package/dist/settings/index.d.ts +1 -0
  112. package/dist/settings/index.js +9 -1072
  113. package/dist/settings/index.js.map +1 -1
  114. package/dist/shell/InstallPrompt.d.ts +28 -0
  115. package/dist/shell/MobileBars.d.ts +1 -1
  116. package/dist/shell/index.cjs +92 -52
  117. package/dist/shell/index.d.ts +4 -0
  118. package/dist/shell/index.js +4 -4
  119. package/dist/shell/install-instructions.d.ts +19 -0
  120. package/dist/shell/types.d.ts +6 -0
  121. package/dist/shell/use-install-prompt.d.ts +49 -0
  122. package/dist/site/index.cjs +67 -67
  123. package/dist/site/index.js +3 -3
  124. package/dist/studio/index.cjs +79 -78
  125. package/dist/studio/index.cjs.map +1 -1
  126. package/dist/studio/index.js +9 -8
  127. package/dist/studio/index.js.map +1 -1
  128. package/dist/theme/ThemeEditor.d.ts +4 -2
  129. package/dist/workspaces/index.cjs +4 -3
  130. package/dist/workspaces/index.cjs.map +1 -1
  131. package/dist/workspaces/index.js +3 -2
  132. package/dist/workspaces/index.js.map +1 -1
  133. package/package.json +30 -5
  134. package/src/blocks.css +30 -0
  135. package/dist/chunk-2VBJ763Y.js.map +0 -1
  136. package/dist/chunk-67MKU5U7.js.map +0 -1
  137. package/dist/chunk-6CHMNKXC.cjs.map +0 -1
  138. package/dist/chunk-ATXPAD6S.cjs.map +0 -1
  139. package/dist/chunk-B673CCW5.js.map +0 -1
  140. package/dist/chunk-DN3NFNIA.cjs.map +0 -1
  141. package/dist/chunk-JPO3F4J7.js.map +0 -1
  142. package/dist/chunk-KHX2BX3S.cjs.map +0 -1
  143. package/dist/chunk-SS23F63U.cjs.map +0 -1
  144. package/dist/chunk-TI4UTYRL.js.map +0 -1
  145. package/dist/chunk-TX2ZICS7.js.map +0 -1
  146. package/dist/chunk-ULWRNGGE.cjs.map +0 -1
  147. package/dist/chunk-WJZBJUPX.js.map +0 -1
  148. package/dist/chunk-XKKGGUU2.cjs.map +0 -1
  149. /package/dist/{files → artifacts}/VersionTimeline.d.ts +0 -0
@@ -2,7 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkOB5F4577_cjs = require('./chunk-OB5F4577.cjs');
5
- var chunkKHX2BX3S_cjs = require('./chunk-KHX2BX3S.cjs');
5
+ var chunkVGOFFCMT_cjs = require('./chunk-VGOFFCMT.cjs');
6
6
  var chunkMHVNT4J3_cjs = require('./chunk-MHVNT4J3.cjs');
7
7
  var react = require('react');
8
8
  var lucideReact = require('lucide-react');
@@ -117,10 +117,10 @@ function SidebarRoot({
117
117
  const mergedLabels = react.useMemo(() => ({ ...DEFAULT_SIDEBAR_LABELS, ...labels }), [labels]);
118
118
  const drawerRef = react.useRef(null);
119
119
  const isDrawer = mode === "drawer";
120
- chunkKHX2BX3S_cjs.useDrawerBehavior(isDrawer, onBackdropClick ?? noop, drawerRef);
120
+ chunkVGOFFCMT_cjs.useDrawerBehavior(isDrawer, onBackdropClick ?? noop, drawerRef);
121
121
  const ariaLabel = ariaLabelProp ?? mergedLabels.mainNavigation;
122
122
  const contextValue = react.useMemo(() => ({ expanded, labels: mergedLabels }), [expanded, mergedLabels]);
123
- const navBase = "group/sidebar bg-sidebar border-r border-border text-foreground flex flex-col h-full overflow-y-auto overflow-x-hidden pb-safe pt-3 transition-all duration-300 ease-in-out";
123
+ const navBase = "group/sidebar bg-sidebar border-r border-border text-foreground scrollbar-themed flex flex-col h-full overflow-y-auto overflow-x-hidden pb-safe pt-3 transition-all duration-300 ease-in-out";
124
124
  const common = {
125
125
  "aria-label": ariaLabel,
126
126
  "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "sidebar" }),
@@ -233,7 +233,7 @@ function SidebarRoot({
233
233
  )
234
234
  ] });
235
235
  }
236
- return /* @__PURE__ */ jsxRuntime.jsx(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(chunkKHX2BX3S_cjs.BlocksTooltipProvider, { children: body }) });
236
+ return /* @__PURE__ */ jsxRuntime.jsx(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(chunkVGOFFCMT_cjs.BlocksTooltipProvider, { children: body }) });
237
237
  }
238
238
  function SidebarHeader({ children, className, "data-testid": testId }) {
239
239
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -556,7 +556,7 @@ function SidebarRowAction({
556
556
  "text-muted-foreground hover:bg-muted hover:text-foreground",
557
557
  rowHovered ? "opacity-100" : "opacity-70"
558
558
  );
559
- return /* @__PURE__ */ jsxRuntime.jsx(chunkKHX2BX3S_cjs.BlocksTooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Tooltip, { children: [
559
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkVGOFFCMT_cjs.BlocksTooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Tooltip, { children: [
560
560
  /* @__PURE__ */ jsxRuntime.jsx(ui.TooltipTrigger, { asChild: true, onFocusCapture: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxRuntime.jsx(
561
561
  "button",
562
562
  {
@@ -1056,6 +1056,15 @@ function MobileAppBar({
1056
1056
  }
1057
1057
  );
1058
1058
  }
1059
+ function TabLabel({ item }) {
1060
+ const wrap = "max-w-full text-balance px-0.5 text-center [overflow-wrap:normal] @max-[4.5rem]:text-[10px]";
1061
+ if (!item.shortLabel) return /* @__PURE__ */ jsxRuntime.jsx("span", { className: wrap, children: item.label });
1062
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1063
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-slot": "tab-short-label", "aria-hidden": "true", className: ui.cn(wrap, "@[5.5rem]:hidden"), children: item.shortLabel }),
1064
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: ui.cn(wrap, "hidden @[5.5rem]:block"), children: item.label }),
1065
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only @[5.5rem]:hidden", children: item.label })
1066
+ ] });
1067
+ }
1059
1068
  function MobileTabBar({
1060
1069
  items,
1061
1070
  label,
@@ -1064,14 +1073,17 @@ function MobileTabBar({
1064
1073
  className,
1065
1074
  "data-testid": testId
1066
1075
  }) {
1076
+ const navRef = react.useRef(null);
1077
+ chunkVGOFFCMT_cjs.useShellBottomInset(navRef);
1067
1078
  return /* @__PURE__ */ jsxRuntime.jsx(
1068
1079
  "nav",
1069
1080
  {
1081
+ ref: navRef,
1070
1082
  "aria-label": label ?? labels?.workspaceSections ?? DEFAULT_MOBILE_BARS_LABELS.workspaceSections,
1071
1083
  "data-slot": "mobile-tab-bar",
1072
1084
  "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "mobile-tab-bar" }),
1073
1085
  className: ui.cn(
1074
- "flex h-16 flex-shrink-0 items-stretch bg-sidebar px-2 pb-safe sm:hidden",
1086
+ "flex min-h-16 flex-shrink-0 items-stretch bg-sidebar px-2 pb-safe sm:hidden",
1075
1087
  className
1076
1088
  ),
1077
1089
  children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1082,13 +1094,14 @@ function MobileTabBar({
1082
1094
  disabled: item.disabled,
1083
1095
  "aria-current": item.active ? "page" : void 0,
1084
1096
  className: ui.cn(
1085
- "flex min-h-12 min-w-0 flex-1 flex-col items-center justify-center gap-0.5 rounded-md text-xs transition-colors",
1097
+ // Each tab is a size container: a `shortLabel` replaces the label when it is narrow.
1098
+ "@container flex min-h-12 min-w-0 flex-1 flex-col items-center justify-center gap-0.5 rounded-md text-[11px] leading-tight transition-colors",
1086
1099
  item.active ? "font-semibold text-primary" : "font-medium text-muted-foreground hover:text-foreground"
1087
1100
  ),
1088
1101
  "data-testid": chunkMHVNT4J3_cjs.prefixedTestId(testIdPrefix, item.id, { testId: `mobile-tab-${item.id}` }),
1089
1102
  children: [
1090
1103
  item.icon,
1091
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-full truncate px-1", children: item.label })
1104
+ /* @__PURE__ */ jsxRuntime.jsx(TabLabel, { item })
1092
1105
  ]
1093
1106
  },
1094
1107
  item.id
@@ -1096,6 +1109,241 @@ function MobileTabBar({
1096
1109
  }
1097
1110
  );
1098
1111
  }
1112
+
1113
+ // src/shell/install-instructions.ts
1114
+ function isIosDevice() {
1115
+ if (typeof navigator === "undefined") return false;
1116
+ return /iPad|iPhone|iPod/.test(navigator.userAgent) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
1117
+ }
1118
+ function getInstallInstructions({
1119
+ appName = "this app"
1120
+ } = {}) {
1121
+ if (typeof navigator === "undefined" || typeof window === "undefined") {
1122
+ return {
1123
+ heading: `Install ${appName}`,
1124
+ steps: [`Open ${appName} in Chrome, Edge, or Safari to install it.`]
1125
+ };
1126
+ }
1127
+ const ua = navigator.userAgent;
1128
+ const isChromium = "onbeforeinstallprompt" in window;
1129
+ const isFirefox = /firefox|fxios/i.test(ua);
1130
+ const isMac = /Macintosh|Mac OS X/.test(ua);
1131
+ if (isIosDevice()) {
1132
+ return {
1133
+ heading: "Install on iPhone or iPad",
1134
+ steps: [
1135
+ `Open ${appName} in Safari, then tap the Share button.`,
1136
+ "Scroll down and tap \u201CAdd to Home Screen\u201D.",
1137
+ `Tap \u201CAdd\u201D: ${appName} appears on your home screen.`
1138
+ ]
1139
+ };
1140
+ }
1141
+ if (isChromium) {
1142
+ return {
1143
+ heading: `Install ${appName}`,
1144
+ steps: [
1145
+ "Click the install icon at the right of the address bar (a small monitor with a down arrow).",
1146
+ "Choose \u201CInstall\u201D in the dialog that appears."
1147
+ ],
1148
+ note: `On a phone, open the browser menu and choose \u201CInstall app\u201D / \u201CAdd to Home screen\u201D. If you don\u2019t see the option, ${appName} may already be installed.`
1149
+ };
1150
+ }
1151
+ if (isMac && !isFirefox) {
1152
+ return {
1153
+ heading: "Install on macOS Safari",
1154
+ steps: ["In the menu bar, open the File menu.", "Choose \u201CAdd to Dock\u201D."],
1155
+ note: "Requires Safari 17 or later (macOS Sonoma). On older Safari, use Chrome or Edge to install."
1156
+ };
1157
+ }
1158
+ if (isFirefox) {
1159
+ return {
1160
+ heading: "Firefox can\u2019t install web apps",
1161
+ steps: [`Open ${appName} in Chrome, Edge, or Safari to install it as an app.`]
1162
+ };
1163
+ }
1164
+ return {
1165
+ heading: `Install ${appName}`,
1166
+ steps: [
1167
+ "Look for an \u201CInstall\u201D or \u201CAdd to Home Screen\u201D option in your browser\u2019s menu or address bar."
1168
+ ]
1169
+ };
1170
+ }
1171
+
1172
+ // src/shell/use-install-prompt.ts
1173
+ var deferredPrompt = null;
1174
+ var installed = false;
1175
+ var initialized = false;
1176
+ var autoPromptParam = null;
1177
+ var subscribers = /* @__PURE__ */ new Set();
1178
+ var notify = () => subscribers.forEach((fn) => fn());
1179
+ function isStandalone() {
1180
+ if (typeof window === "undefined") return false;
1181
+ const iosStandalone = navigator.standalone === true;
1182
+ return window.matchMedia?.("(display-mode: standalone)").matches === true || iosStandalone;
1183
+ }
1184
+ function wantsAutoPrompt() {
1185
+ if (!autoPromptParam) return false;
1186
+ return new URLSearchParams(window.location.search).get(autoPromptParam) === "true";
1187
+ }
1188
+ function onBeforeInstallPrompt(event) {
1189
+ event.preventDefault();
1190
+ deferredPrompt = event;
1191
+ notify();
1192
+ if (wantsAutoPrompt()) void promptAppInstall();
1193
+ }
1194
+ function onAppInstalled() {
1195
+ installed = true;
1196
+ deferredPrompt = null;
1197
+ notify();
1198
+ }
1199
+ function initInstallPrompt(options = {}) {
1200
+ if (options.autoPromptParam) autoPromptParam = options.autoPromptParam;
1201
+ if (initialized || typeof window === "undefined") return;
1202
+ initialized = true;
1203
+ installed = isStandalone();
1204
+ window.addEventListener("beforeinstallprompt", onBeforeInstallPrompt);
1205
+ window.addEventListener("appinstalled", onAppInstalled);
1206
+ }
1207
+ async function promptAppInstall() {
1208
+ if (!deferredPrompt) return false;
1209
+ const prompt = deferredPrompt;
1210
+ deferredPrompt = null;
1211
+ notify();
1212
+ try {
1213
+ await prompt.prompt();
1214
+ } catch {
1215
+ }
1216
+ return true;
1217
+ }
1218
+ var INSTALL_PROMPT_DISMISSED_KEY = "arbi-blocks:install-prompt-dismissed";
1219
+ var DAY_MS = 24 * 60 * 60 * 1e3;
1220
+ function readDismissedAt(key) {
1221
+ try {
1222
+ const raw = window.localStorage.getItem(key);
1223
+ const at = raw ? Number(raw) : NaN;
1224
+ return Number.isFinite(at) ? at : null;
1225
+ } catch {
1226
+ return null;
1227
+ }
1228
+ }
1229
+ function useInstallPrompt({
1230
+ storageKey = INSTALL_PROMPT_DISMISSED_KEY,
1231
+ dismissDays = 30,
1232
+ autoPromptParam: autoParam,
1233
+ appName
1234
+ } = {}) {
1235
+ const [, forceRender] = react.useState(0);
1236
+ const [dismissedAt, setDismissedAt] = react.useState(
1237
+ () => typeof window === "undefined" ? null : readDismissedAt(storageKey)
1238
+ );
1239
+ react.useEffect(() => {
1240
+ initInstallPrompt({ autoPromptParam: autoParam });
1241
+ const onChange = () => forceRender((n) => n + 1);
1242
+ subscribers.add(onChange);
1243
+ onChange();
1244
+ return () => {
1245
+ subscribers.delete(onChange);
1246
+ };
1247
+ }, [autoParam]);
1248
+ const dismiss = react.useCallback(() => {
1249
+ const now = Date.now();
1250
+ setDismissedAt(now);
1251
+ try {
1252
+ window.localStorage.setItem(storageKey, String(now));
1253
+ } catch {
1254
+ }
1255
+ }, [storageKey]);
1256
+ const isDismissed = dismissedAt !== null && Date.now() - dismissedAt < dismissDays * DAY_MS;
1257
+ const isInstalled = installed || isStandalone();
1258
+ return {
1259
+ canPrompt: !isInstalled && deferredPrompt !== null,
1260
+ isInstalled,
1261
+ isIos: isIosDevice(),
1262
+ isDismissed,
1263
+ promptInstall: promptAppInstall,
1264
+ dismiss,
1265
+ instructions: getInstallInstructions({ appName })
1266
+ };
1267
+ }
1268
+ var DEFAULT_INSTALL_PROMPT_LABELS = {
1269
+ install: "Install app",
1270
+ dismiss: "Dismiss install prompt",
1271
+ installAs: "Install {app} as an app"
1272
+ };
1273
+ function InstallPrompt({
1274
+ placement = "start",
1275
+ labels,
1276
+ className,
1277
+ "data-testid": testId,
1278
+ ...options
1279
+ }) {
1280
+ const l = { ...DEFAULT_INSTALL_PROMPT_LABELS, ...labels };
1281
+ const install = useInstallPrompt(options);
1282
+ const [showSteps, setShowSteps] = react.useState(false);
1283
+ const isOffer = install.canPrompt || install.isIos;
1284
+ if (install.isInstalled || install.isDismissed || !isOffer) return null;
1285
+ const appName = options.appName ?? "this app";
1286
+ const onInstall = async () => {
1287
+ if (install.canPrompt) await install.promptInstall();
1288
+ else setShowSteps((open) => !open);
1289
+ };
1290
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1291
+ "div",
1292
+ {
1293
+ "data-slot": "install-prompt",
1294
+ "data-testid": chunkMHVNT4J3_cjs.testIdOr(testId, { testId: "install-app-prompt" }),
1295
+ className: ui.cn(
1296
+ "fixed z-30 flex max-w-[calc(100vw-1.5rem)] flex-col gap-2",
1297
+ // Above the bottom bars (tab bar / composer) and the home indicator on a phone, a plain
1298
+ // corner offset from `sm` up where the tab bar is gone.
1299
+ "bottom-[calc(max(var(--shell-bottom-inset,0px),env(safe-area-inset-bottom,0px))+0.75rem)] sm:bottom-[calc(env(safe-area-inset-bottom,0px)+0.75rem)]",
1300
+ placement === "start" ? "left-3 items-start" : "right-3 items-end",
1301
+ className
1302
+ ),
1303
+ children: [
1304
+ showSteps && /* @__PURE__ */ jsxRuntime.jsxs(
1305
+ "div",
1306
+ {
1307
+ "data-slot": "install-prompt-steps",
1308
+ className: "w-72 max-w-full rounded-lg border border-border bg-card p-3 text-sm text-card-foreground shadow-lg",
1309
+ children: [
1310
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: install.instructions.heading }),
1311
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "mt-2 list-decimal space-y-1 pl-5 text-muted-foreground", children: install.instructions.steps.map((step) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: step }, step)) })
1312
+ ]
1313
+ }
1314
+ ),
1315
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center rounded-full border border-border bg-card/95 text-foreground shadow-sm backdrop-blur", children: [
1316
+ /* @__PURE__ */ jsxRuntime.jsxs(
1317
+ "button",
1318
+ {
1319
+ type: "button",
1320
+ onClick: () => void onInstall(),
1321
+ "aria-label": l.installAs.replace("{app}", appName),
1322
+ "aria-expanded": install.canPrompt ? void 0 : showSteps,
1323
+ "data-slot": "install-prompt-action",
1324
+ className: "inline-flex min-h-11 items-center gap-1.5 rounded-full pl-4 pr-2 text-xs font-medium transition-colors hover:bg-accent sm:min-h-9 sm:pl-3",
1325
+ children: [
1326
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "size-3.5", "aria-hidden": "true" }),
1327
+ l.install
1328
+ ]
1329
+ }
1330
+ ),
1331
+ /* @__PURE__ */ jsxRuntime.jsx(
1332
+ "button",
1333
+ {
1334
+ type: "button",
1335
+ onClick: install.dismiss,
1336
+ "aria-label": l.dismiss,
1337
+ "data-slot": "install-prompt-dismiss",
1338
+ className: "inline-flex size-11 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground sm:size-9",
1339
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3.5", "aria-hidden": "true" })
1340
+ }
1341
+ )
1342
+ ] })
1343
+ ]
1344
+ }
1345
+ );
1346
+ }
1099
1347
  function ActionCluster({
1100
1348
  layout = "bar",
1101
1349
  status,
@@ -1585,6 +1833,7 @@ exports.AskField = AskField;
1585
1833
  exports.AskRow = AskRow;
1586
1834
  exports.AskTrigger = AskTrigger;
1587
1835
  exports.DEFAULT_ASK_FIELD_LABELS = DEFAULT_ASK_FIELD_LABELS;
1836
+ exports.DEFAULT_INSTALL_PROMPT_LABELS = DEFAULT_INSTALL_PROMPT_LABELS;
1588
1837
  exports.DEFAULT_MOBILE_BARS_LABELS = DEFAULT_MOBILE_BARS_LABELS;
1589
1838
  exports.DEFAULT_OFFLINE_PILL_LABELS = DEFAULT_OFFLINE_PILL_LABELS;
1590
1839
  exports.DEFAULT_REMOTE_CONTROL_PILL_LABELS = DEFAULT_REMOTE_CONTROL_PILL_LABELS;
@@ -1592,7 +1841,9 @@ exports.DEFAULT_SIDEBAR_LABELS = DEFAULT_SIDEBAR_LABELS;
1592
1841
  exports.DEFAULT_TIP_CARD_LABELS = DEFAULT_TIP_CARD_LABELS;
1593
1842
  exports.DEFAULT_WORKSPACE_KIND_LABELS = DEFAULT_WORKSPACE_KIND_LABELS;
1594
1843
  exports.DEFAULT_WORKSPACE_SWITCHER_LABELS = DEFAULT_WORKSPACE_SWITCHER_LABELS;
1844
+ exports.INSTALL_PROMPT_DISMISSED_KEY = INSTALL_PROMPT_DISMISSED_KEY;
1595
1845
  exports.InfoBar = InfoBar;
1846
+ exports.InstallPrompt = InstallPrompt;
1596
1847
  exports.MobileAppBar = MobileAppBar;
1597
1848
  exports.MobileTabBar = MobileTabBar;
1598
1849
  exports.OfflinePill = OfflinePill;
@@ -1606,10 +1857,15 @@ exports.StatusRow = StatusRow;
1606
1857
  exports.TipCard = TipCard;
1607
1858
  exports.WorkspaceIdentity = WorkspaceIdentity;
1608
1859
  exports.WorkspaceSwitcher = WorkspaceSwitcher;
1860
+ exports.getInstallInstructions = getInstallInstructions;
1861
+ exports.initInstallPrompt = initInstallPrompt;
1862
+ exports.isIosDevice = isIosDevice;
1863
+ exports.promptAppInstall = promptAppInstall;
1609
1864
  exports.resolveSidebarLayout = resolveSidebarLayout;
1865
+ exports.useInstallPrompt = useInstallPrompt;
1610
1866
  exports.useSidebarContext = useSidebarContext;
1611
1867
  exports.useSidebarSettle = useSidebarSettle;
1612
1868
  exports.workspaceKindColor = workspaceKindColor;
1613
1869
  exports.workspaceKindMeta = workspaceKindMeta;
1614
- //# sourceMappingURL=chunk-DN3NFNIA.cjs.map
1615
- //# sourceMappingURL=chunk-DN3NFNIA.cjs.map
1870
+ //# sourceMappingURL=chunk-QMDLPO3M.cjs.map
1871
+ //# sourceMappingURL=chunk-QMDLPO3M.cjs.map