@mx-cartographer/experiences 9.6.0 → 9.6.2

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 (73) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/common/components/ConnectDrawer.es.js +17 -44
  3. package/dist/common/components/ConnectDrawer.es.js.map +1 -1
  4. package/dist/common/components/ConnectWidgetPanel.d.ts +8 -0
  5. package/dist/common/components/ConnectWidgetPanel.es.js +44 -0
  6. package/dist/common/components/ConnectWidgetPanel.es.js.map +1 -0
  7. package/dist/common/components/dialog/Dialog.d.ts +2 -0
  8. package/dist/common/components/dialog/Dialog.es.js +30 -30
  9. package/dist/common/components/dialog/Dialog.es.js.map +1 -1
  10. package/dist/common/components/index.d.ts +1 -0
  11. package/dist/common/index.es.js +67 -65
  12. package/dist/core/types/InsightsInstanceSlotData.d.ts +0 -1
  13. package/dist/core/types/InsightsInstanceSlotData.es.js.map +1 -1
  14. package/dist/core/types/localization/InsightsFeedCopy.d.ts +87 -0
  15. package/dist/insights-v2/actionBlocks/ActionBlockLayer.es.js +19 -19
  16. package/dist/insights-v2/actionBlocks/ActionBlockLayer.es.js.map +1 -1
  17. package/dist/insights-v2/actionBlocks/ConnectWidgetActionBlock.d.ts +21 -0
  18. package/dist/insights-v2/actionBlocks/ConnectWidgetActionBlock.es.js +16 -0
  19. package/dist/insights-v2/actionBlocks/ConnectWidgetActionBlock.es.js.map +1 -0
  20. package/dist/insights-v2/actionBlocks/ConnectionDetailActionBlock.d.ts +12 -0
  21. package/dist/insights-v2/actionBlocks/ConnectionDetailActionBlock.es.js +25 -0
  22. package/dist/insights-v2/actionBlocks/ConnectionDetailActionBlock.es.js.map +1 -0
  23. package/dist/insights-v2/actionBlocks/FeedbackModalActionBlock.d.ts +17 -0
  24. package/dist/insights-v2/actionBlocks/FeedbackModalActionBlock.es.js +39 -0
  25. package/dist/insights-v2/actionBlocks/FeedbackModalActionBlock.es.js.map +1 -0
  26. package/dist/insights-v2/actionBlocks/SurveyModalActionBlock.d.ts +16 -0
  27. package/dist/insights-v2/actionBlocks/SurveyModalActionBlock.es.js +47 -0
  28. package/dist/insights-v2/actionBlocks/SurveyModalActionBlock.es.js.map +1 -0
  29. package/dist/insights-v2/beatActions.d.ts +2 -2
  30. package/dist/insights-v2/beatActions.es.js.map +1 -1
  31. package/dist/insights-v2/blocks/ComponentBlocks/AccountSwitchBlock/AccountSwitchBlock.d.ts +2 -4
  32. package/dist/insights-v2/blocks/ComponentBlocks/AccountSwitchBlock/AccountSwitchBlock.es.js +24 -33
  33. package/dist/insights-v2/blocks/ComponentBlocks/AccountSwitchBlock/AccountSwitchBlock.es.js.map +1 -1
  34. package/dist/insights-v2/blocks/ComponentBlocks/AccountSwitchBlock/layout.d.ts +36 -0
  35. package/dist/insights-v2/blocks/ComponentBlocks/AccountSwitchBlock/layout.es.js +40 -0
  36. package/dist/insights-v2/blocks/ComponentBlocks/AccountSwitchBlock/layout.es.js.map +1 -0
  37. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.d.ts +8 -18
  38. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js +43 -42
  39. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js.map +1 -1
  40. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/index.d.ts +2 -1
  41. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.d.ts +30 -0
  42. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.es.js +29 -0
  43. package/dist/insights-v2/blocks/ComponentBlocks/TransactionBlock/layout.es.js.map +1 -0
  44. package/dist/insights-v2/blocks/resolveVariantConfig.d.ts +10 -0
  45. package/dist/insights-v2/blocks/resolveVariantConfig.es.js +6 -0
  46. package/dist/insights-v2/blocks/resolveVariantConfig.es.js.map +1 -0
  47. package/dist/insights-v2/components/BaseLayout.es.js +14 -14
  48. package/dist/insights-v2/components/ConnectionDetailDrillDown.d.ts +32 -0
  49. package/dist/insights-v2/components/ConnectionDetailDrillDown.es.js +148 -0
  50. package/dist/insights-v2/components/ConnectionDetailDrillDown.es.js.map +1 -0
  51. package/dist/insights-v2/components/FeedbackDialog.d.ts +3 -1
  52. package/dist/insights-v2/components/FeedbackDialog.es.js +80 -72
  53. package/dist/insights-v2/components/FeedbackDialog.es.js.map +1 -1
  54. package/dist/insights-v2/components/FeedbackModal.d.ts +60 -0
  55. package/dist/insights-v2/components/FeedbackModal.es.js +61 -0
  56. package/dist/insights-v2/components/FeedbackModal.es.js.map +1 -0
  57. package/dist/insights-v2/components/SurveyModal.d.ts +65 -0
  58. package/dist/insights-v2/components/SurveyModal.es.js +138 -0
  59. package/dist/insights-v2/components/SurveyModal.es.js.map +1 -0
  60. package/dist/insights-v2/components/celebrationGradients.d.ts +19 -7
  61. package/dist/insights-v2/components/celebrationGradients.es.js +7 -4
  62. package/dist/insights-v2/components/celebrationGradients.es.js.map +1 -1
  63. package/dist/insights-v2/components/shared/StatusSnackbar.d.ts +28 -0
  64. package/dist/insights-v2/components/shared/StatusSnackbar.es.js +19 -0
  65. package/dist/insights-v2/components/shared/StatusSnackbar.es.js.map +1 -0
  66. package/dist/insights-v2/index.d.ts +4 -0
  67. package/dist/insights-v2/index.es.js +78 -69
  68. package/dist/insights-v2/mappings/actionBlocksKey.d.ts +4 -0
  69. package/dist/insights-v2/mappings/actionBlocksKey.es.js +4 -0
  70. package/dist/insights-v2/mappings/actionBlocksKey.es.js.map +1 -1
  71. package/dist/insights-v2/mappings/blocks.es.js +79 -56
  72. package/dist/insights-v2/mappings/blocks.es.js.map +1 -1
  73. package/package.json +1 -1
@@ -132,6 +132,87 @@ export interface FeedbackCopy {
132
132
  /** ARIA label for the close button. */
133
133
  close_aria: string;
134
134
  }
135
+ /** Confirmation survey drilldown (`survey_modal_block`), e.g. "Does this look right?". */
136
+ export interface SurveyModalCopy {
137
+ /** Dialog title, e.g. "Does this look right?". */
138
+ title: string;
139
+ /** Overline above the positive row, e.g. "Yes,". */
140
+ yes_overline: string;
141
+ /** Positive row label, e.g. "This looks correct.". */
142
+ yes_label: string;
143
+ /** Overline above the negative row, e.g. "No,". */
144
+ no_overline: string;
145
+ /** Negative row label, e.g. "This looks wrong.". */
146
+ no_label: string;
147
+ /** Primary (Submit) button label. */
148
+ submit: string;
149
+ /** ARIA label for the dialog close button. */
150
+ close_aria: string;
151
+ /** Reasons dialog title (negative path), e.g. "This looks wrong". */
152
+ reasons_title: string;
153
+ /** Reasons dialog options; the last one reveals the detail text field. */
154
+ reason_options: DynamicKeyValue;
155
+ /** Reasons dialog secondary (Back) button label. */
156
+ back: string;
157
+ /** Helper text under the reasons detail field. */
158
+ character_limit: string;
159
+ /** Success snackbar message. */
160
+ success_message: string;
161
+ /** Error snackbar message. */
162
+ error_message: string;
163
+ /** Error snackbar retry action label. */
164
+ try_again: string;
165
+ /** ARIA label for the snackbar close button. */
166
+ toast_close_aria: string;
167
+ }
168
+ /** Connection-details education drilldown (`connection_detail_block`). */
169
+ export interface ConnectionDetailsCopy {
170
+ aria_label_thumbs_down: string;
171
+ aria_label_thumbs_up: string;
172
+ /** Bullet list under the header. */
173
+ benefits_list: DynamicKeyValue;
174
+ /** Drawer title (used by the registry entry's `title`). */
175
+ connection_details_drawer_title: string;
176
+ description: string;
177
+ /** "Was this helpful?" footer label. */
178
+ footer_title: string;
179
+ header_text: string;
180
+ shared_info_description: string;
181
+ shared_info_header_text: string;
182
+ /** Shared-info cards, numeric-keyed like other list copy. */
183
+ shared_info_list: {
184
+ [key: string]: {
185
+ content: string;
186
+ icon_name: string;
187
+ title: string;
188
+ };
189
+ };
190
+ }
191
+ /** CTA feedback drilldown (`feedback_modal_block`): survey dialog + success snackbar. */
192
+ export interface FeedbackModalCopy {
193
+ /** Dialog title, e.g. "Can you tell us why?". */
194
+ title: string;
195
+ /** Paragraph under the title; interpolates `_1{account_name}`. */
196
+ description: string;
197
+ /** Survey reasons; the last option reveals the detail text field. */
198
+ options: DynamicKeyValue;
199
+ /** Primary (Submit) button label. */
200
+ submit: string;
201
+ /** Secondary (No thanks) button label. */
202
+ no_thanks: string;
203
+ /** ARIA label for the dialog close button. */
204
+ close_aria: string;
205
+ /** Success snackbar message. */
206
+ success_message: string;
207
+ /** Error snackbar message. */
208
+ error_message: string;
209
+ /** Error snackbar retry action label. */
210
+ try_again: string;
211
+ /** ARIA label for the snackbar close button. */
212
+ toast_close_aria: string;
213
+ /** Helper text under the detail field. */
214
+ character_limit: string;
215
+ }
135
216
  export interface RemainingCashCopy {
136
217
  title: string;
137
218
  remaining_until_payday: string;
@@ -175,6 +256,12 @@ export interface InsightsFeedCopy {
175
256
  hidden_confirmation: HiddenConfirmationCopy;
176
257
  hide_feedback: HideFeedbackCopy;
177
258
  feedback: FeedbackCopy;
259
+ /** Optional: every caller already null-guards (`copyStore.insights_feed?.feedback_modal`). */
260
+ feedback_modal?: FeedbackModalCopy;
261
+ /** Optional: every caller already null-guards (`copyStore.insights_feed?.connection_details`). */
262
+ connection_details?: ConnectionDetailsCopy;
263
+ /** Optional: every caller already null-guards (`copyStore.insights_feed?.survey_modal`). */
264
+ survey_modal?: SurveyModalCopy;
178
265
  feedback_bar: FeedbackBarCopy;
179
266
  dismiss: DismissInsightCopy;
180
267
  /** Optional until the localized-content service ships the namespace. */
@@ -1,43 +1,43 @@
1
- import { useGlobalCopyStore as C, useGlobalUiStore as h, useInsightsV2Store as B } from "../../common/context/hooks.es.js";
2
- import _ from "../../common/components/drawer/Drawer.es.js";
3
- import b from "../../common/components/Loader.es.js";
1
+ import { useGlobalCopyStore as g, useGlobalUiStore as C, useInsightsV2Store as h } from "../../common/context/hooks.es.js";
2
+ import B from "../../common/components/drawer/Drawer.es.js";
3
+ import _ from "../../common/components/Loader.es.js";
4
4
  import { getDynamicCtaBasedOnTriggers as v } from "./util.es.js";
5
5
  import { hasDrawerBlock as w } from "../mappings/hasDrawerBlock.es.js";
6
6
  import { actionBlocks as D } from "../mappings/blocks.es.js";
7
- import { observer as L } from "mobx-react-lite";
8
- import x from "@mui/material/Stack";
9
- import { Text as A } from "@mxenabled/mxui";
7
+ import { observer as b } from "mobx-react-lite";
8
+ import L from "@mui/material/Stack";
9
+ import { Text as x } from "@mxenabled/mxui";
10
10
  import { jsx as e } from "react/jsx-runtime";
11
11
  var m = ({ actionBlock: s, ...o }) => {
12
12
  const { Component: i, usePrepare: n } = s;
13
13
  return n(o), /* @__PURE__ */ e(i, { ...o });
14
- }, q = L(function({ beat: o }) {
15
- const i = C(), n = i.common, { isCopyLoaded: p } = h(), { actionDrawer: c, closeActionDrawer: u } = B();
14
+ }, $ = b(function({ beat: o }) {
15
+ const i = g(), n = i.common, { isCopyLoaded: p } = C(), { actionDrawer: c, closeActionDrawer: u } = h();
16
16
  if (!o.insights_payload) return null;
17
- const { primary_cta: d, secondary_cta: f, guid: k } = o.insights_payload, a = c.isDrawerOpen && c.guid === k;
18
- if (!p) return a ? /* @__PURE__ */ e(b, {}) : null;
19
- const r = v(c, d, f), l = w(r?.block), t = l ? D[r?.block] : void 0;
20
- if (t?.presentation === "modal") return a ? /* @__PURE__ */ e(m, {
17
+ const { primary_cta: d, secondary_cta: f } = o.insights_payload, l = c.isDrawerOpen && c.guid === o.guid;
18
+ if (!p) return l ? /* @__PURE__ */ e(_, {}) : null;
19
+ const r = v(c, d, f), a = w(r?.block), t = a ? D[r?.block] : void 0;
20
+ if (t?.presentation === "modal") return l ? /* @__PURE__ */ e(m, {
21
21
  actionBlock: t,
22
22
  beat: o
23
23
  }, r?.block) : null;
24
- const y = t?.title?.(r?.variant, i, o), g = t ? y || r?.label || "" : l ? n.error_heading : r?.label ?? "";
25
- return /* @__PURE__ */ e(_, {
24
+ const k = t?.title?.(r?.variant, i, o), y = t ? k || r?.label || "" : a ? n.error_heading : r?.label ?? "";
25
+ return /* @__PURE__ */ e(B, {
26
26
  ariaLabelClose: n.close_aria,
27
- isOpen: a,
27
+ isOpen: l,
28
28
  onClose: u,
29
- title: g,
29
+ title: y,
30
30
  children: t ? /* @__PURE__ */ e(m, {
31
31
  actionBlock: t,
32
32
  beat: o
33
- }, r?.block) : l ? /* @__PURE__ */ e(x, {
33
+ }, r?.block) : a ? /* @__PURE__ */ e(L, {
34
34
  sx: { p: 24 },
35
- children: /* @__PURE__ */ e(A, { children: n.error_message })
35
+ children: /* @__PURE__ */ e(x, { children: n.error_message })
36
36
  }) : null
37
37
  });
38
38
  });
39
39
  export {
40
- q as ActionBlockLayer
40
+ $ as ActionBlockLayer
41
41
  };
42
42
 
43
43
  //# sourceMappingURL=ActionBlockLayer.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ActionBlockLayer.es.js","names":[],"sources":["../../../src/insights-v2/actionBlocks/ActionBlockLayer.tsx"],"sourcesContent":["import Stack from '@mui/material/Stack'\n\nimport { Text } from '@mxenabled/mxui'\nimport { observer } from 'mobx-react-lite'\n\nimport {\n Drawer,\n Loader,\n useGlobalCopyStore,\n useGlobalUiStore,\n useInsightsV2Store,\n} from '../../common'\nimport { type Beat } from '../../core'\nimport {\n actionBlocks,\n hasDrawerBlock,\n type ActionBlockEntry,\n type ActionBlockProps,\n} from '../mappings/blocks'\nimport { getDynamicCtaBasedOnTriggers } from './util'\n\ninterface ActionBlockLayerProps {\n beat: Beat\n}\n\n/**\n * Renders a registered action block. Callers MUST key this per block name — a\n * block with `usePrepare` and one without run a different number of hooks, so\n * reusing the same fiber across a block switch violates the rules of hooks.\n */\nconst ActionBlockRunner = ({\n actionBlock,\n ...blockProps\n}: ActionBlockProps & { actionBlock: ActionBlockEntry }) => {\n const { Component, usePrepare } = actionBlock\n\n usePrepare(blockProps)\n\n return <Component {...blockProps} />\n}\n\n// `observer` is required: this reads `isCopyLoaded` off GlobalUiStore and the\n// action drawer off InsightsV2Store. Without it the component never re-renders\n// and stays stuck on <Loader /> forever.\nexport const ActionBlockLayer = observer(function ActionBlockLayer({\n beat,\n}: ActionBlockLayerProps) {\n const copy = useGlobalCopyStore()\n const commonCopy = copy.common\n const { isCopyLoaded } = useGlobalUiStore()\n const { actionDrawer, closeActionDrawer } = useInsightsV2Store()\n\n // Mirrors BaseLayout's guard — the layer is exported, so callers are not\n // guaranteed to have narrowed this already.\n if (!beat.insights_payload) return null\n\n const { primary_cta, secondary_cta, guid } = beat.insights_payload\n\n // Every card in the feed renders its own layer against the shared store, so\n // this card's drawer only opens when its beat is the one that triggered it.\n const isCurrentBeatOpen = actionDrawer.isDrawerOpen && actionDrawer.guid === guid\n\n if (!isCopyLoaded) return isCurrentBeatOpen ? <Loader /> : null\n\n const currentCta = getDynamicCtaBasedOnTriggers(actionDrawer, primary_cta, secondary_cta)\n\n // A CTA without a real block never opens a drawer (BaseLayout won't trigger it);\n // a real-but-unknown block shows the error (\"oops\") content.\n const blockValid = hasDrawerBlock(currentCta?.block)\n const actionBlock = blockValid\n ? actionBlocks[currentCta?.block as keyof typeof actionBlocks]\n : undefined\n\n // A modal block owns its dialog: no drawer behind it, and nothing mounted until it is opened.\n if (actionBlock?.presentation === 'modal') {\n return isCurrentBeatOpen ? (\n <ActionBlockRunner actionBlock={actionBlock} beat={beat} key={currentCta?.block} />\n ) : null\n }\n\n const resolvedTitle = actionBlock?.title?.(currentCta?.variant, copy, beat)\n const drawerTitle = actionBlock\n ? resolvedTitle || currentCta?.label || ''\n : blockValid\n ? commonCopy.error_heading\n : (currentCta?.label ?? '')\n\n return (\n <Drawer\n ariaLabelClose={commonCopy.close_aria}\n isOpen={isCurrentBeatOpen}\n onClose={closeActionDrawer}\n title={drawerTitle}\n >\n {actionBlock ? (\n <ActionBlockRunner actionBlock={actionBlock} beat={beat} key={currentCta?.block} />\n ) : blockValid ? (\n <Stack sx={{ p: 24 }}>\n <Text>{commonCopy.error_message}</Text>\n </Stack>\n ) : null}\n </Drawer>\n )\n})\n"],"mappings":";;;;;;;;;;AA8BA,IAAM,IAAA,CAAqB,EACzB,aAAA,GACA,GAAG,EAAA,MACuD;AAC1D,QAAM,EAAE,WAAA,GAAW,YAAA,EAAA,IAAe;AAElC,SAAA,EAAW,CAAU,GAEd,gBAAA,EAAC,GAAD,EAAW,GAAI,EAAa,CAAA;AACrC,GAKa,IAAmB,EAAS,SAA0B,EACjE,MAAA,EAAA,GACwB;AACxB,QAAM,IAAO,EAAmB,GAC1B,IAAa,EAAK,QAClB,EAAE,cAAA,EAAA,IAAiB,EAAiB,GACpC,EAAE,cAAA,GAAc,mBAAA,EAAA,IAAsB,EAAmB;AAI/D,MAAI,CAAC,EAAK,iBAAkB,QAAO;AAEnC,QAAM,EAAE,aAAA,GAAa,eAAA,GAAe,MAAA,EAAA,IAAS,EAAK,kBAI5C,IAAoB,EAAa,gBAAgB,EAAa,SAAS;AAE7E,MAAI,CAAC,EAAc,QAAO,IAAoB,gBAAA,EAAC,GAAD,CAAS,CAAA,IAAI;AAE3D,QAAM,IAAa,EAA6B,GAAc,GAAa,CAAa,GAIlF,IAAa,EAAe,GAAY,KAAK,GAC7C,IAAc,IAChB,EAAa,GAAY,KAAA,IACzB;AAGJ,MAAI,GAAa,iBAAiB,QAChC,QAAO,IACL,gBAAA,EAAC,GAAD;AAAA,IAAgC,aAAA;AAAA,IAAmB,MAAA;AAAA,EAA+B,GAApB,GAAY,KAAQ,IAChF;AAGN,QAAM,IAAgB,GAAa,QAAQ,GAAY,SAAS,GAAM,CAAI,GACpE,IAAc,IAChB,KAAiB,GAAY,SAAS,KACtC,IACE,EAAW,gBACV,GAAY,SAAS;AAE5B,SACE,gBAAA,EAAC,GAAD;AAAA,IACE,gBAAgB,EAAW;AAAA,IAC3B,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IAEN,UAAA,IACC,gBAAA,EAAC,GAAD;AAAA,MAAgC,aAAA;AAAA,MAAmB,MAAA;AAAA,IAA+B,GAApB,GAAY,KAAQ,IAChF,IACF,gBAAA,EAAC,GAAD;AAAA,MAAO,IAAI,EAAE,GAAG,GAAG;AAAA,MACjB,UAAA,gBAAA,EAAC,GAAD,EAAA,UAAO,EAAW,cAAoB,CAAA;AAAA,IACjC,CAAA,IACL;AAAA,EACE,CAAA;AAEZ,CAAC"}
1
+ {"version":3,"file":"ActionBlockLayer.es.js","names":[],"sources":["../../../src/insights-v2/actionBlocks/ActionBlockLayer.tsx"],"sourcesContent":["import Stack from '@mui/material/Stack'\n\nimport { Text } from '@mxenabled/mxui'\nimport { observer } from 'mobx-react-lite'\n\nimport {\n Drawer,\n Loader,\n useGlobalCopyStore,\n useGlobalUiStore,\n useInsightsV2Store,\n} from '../../common'\nimport { type Beat } from '../../core'\nimport {\n actionBlocks,\n hasDrawerBlock,\n type ActionBlockEntry,\n type ActionBlockProps,\n} from '../mappings/blocks'\nimport { getDynamicCtaBasedOnTriggers } from './util'\n\ninterface ActionBlockLayerProps {\n beat: Beat\n}\n\n/**\n * Renders a registered action block. Callers MUST key this per block name — a\n * block with `usePrepare` and one without run a different number of hooks, so\n * reusing the same fiber across a block switch violates the rules of hooks.\n */\nconst ActionBlockRunner = ({\n actionBlock,\n ...blockProps\n}: ActionBlockProps & { actionBlock: ActionBlockEntry }) => {\n const { Component, usePrepare } = actionBlock\n\n usePrepare(blockProps)\n\n return <Component {...blockProps} />\n}\n\n// `observer` is required: this reads `isCopyLoaded` off GlobalUiStore and the\n// action drawer off InsightsV2Store. Without it the component never re-renders\n// and stays stuck on <Loader /> forever.\nexport const ActionBlockLayer = observer(function ActionBlockLayer({\n beat,\n}: ActionBlockLayerProps) {\n const copy = useGlobalCopyStore()\n const commonCopy = copy.common\n const { isCopyLoaded } = useGlobalUiStore()\n const { actionDrawer, closeActionDrawer } = useInsightsV2Store()\n\n // Mirrors BaseLayout's guard — the layer is exported, so callers are not\n // guaranteed to have narrowed this already.\n if (!beat.insights_payload) return null\n\n const { primary_cta, secondary_cta } = beat.insights_payload\n\n // Every card in the feed renders its own layer against the shared store, so\n // this card's drawer only opens when its beat is the one that triggered it.\n const isCurrentBeatOpen = actionDrawer.isDrawerOpen && actionDrawer.guid === beat.guid\n\n if (!isCopyLoaded) return isCurrentBeatOpen ? <Loader /> : null\n\n const currentCta = getDynamicCtaBasedOnTriggers(actionDrawer, primary_cta, secondary_cta)\n\n // A CTA without a real block never opens a drawer (BaseLayout won't trigger it);\n // a real-but-unknown block shows the error (\"oops\") content.\n const blockValid = hasDrawerBlock(currentCta?.block)\n const actionBlock = blockValid\n ? actionBlocks[currentCta?.block as keyof typeof actionBlocks]\n : undefined\n\n // A modal block owns its dialog: no drawer behind it, and nothing mounted until it is opened.\n if (actionBlock?.presentation === 'modal') {\n return isCurrentBeatOpen ? (\n <ActionBlockRunner actionBlock={actionBlock} beat={beat} key={currentCta?.block} />\n ) : null\n }\n\n const resolvedTitle = actionBlock?.title?.(currentCta?.variant, copy, beat)\n const drawerTitle = actionBlock\n ? resolvedTitle || currentCta?.label || ''\n : blockValid\n ? commonCopy.error_heading\n : (currentCta?.label ?? '')\n\n return (\n <Drawer\n ariaLabelClose={commonCopy.close_aria}\n isOpen={isCurrentBeatOpen}\n onClose={closeActionDrawer}\n title={drawerTitle}\n >\n {actionBlock ? (\n <ActionBlockRunner actionBlock={actionBlock} beat={beat} key={currentCta?.block} />\n ) : blockValid ? (\n <Stack sx={{ p: 24 }}>\n <Text>{commonCopy.error_message}</Text>\n </Stack>\n ) : null}\n </Drawer>\n )\n})\n"],"mappings":";;;;;;;;;;AA8BA,IAAM,IAAA,CAAqB,EACzB,aAAA,GACA,GAAG,EAAA,MACuD;AAC1D,QAAM,EAAE,WAAA,GAAW,YAAA,EAAA,IAAe;AAElC,SAAA,EAAW,CAAU,GAEd,gBAAA,EAAC,GAAD,EAAW,GAAI,EAAa,CAAA;AACrC,GAKa,IAAmB,EAAS,SAA0B,EACjE,MAAA,EAAA,GACwB;AACxB,QAAM,IAAO,EAAmB,GAC1B,IAAa,EAAK,QAClB,EAAE,cAAA,EAAA,IAAiB,EAAiB,GACpC,EAAE,cAAA,GAAc,mBAAA,EAAA,IAAsB,EAAmB;AAI/D,MAAI,CAAC,EAAK,iBAAkB,QAAO;AAEnC,QAAM,EAAE,aAAA,GAAa,eAAA,EAAA,IAAkB,EAAK,kBAItC,IAAoB,EAAa,gBAAgB,EAAa,SAAS,EAAK;AAElF,MAAI,CAAC,EAAc,QAAO,IAAoB,gBAAA,EAAC,GAAD,CAAS,CAAA,IAAI;AAE3D,QAAM,IAAa,EAA6B,GAAc,GAAa,CAAa,GAIlF,IAAa,EAAe,GAAY,KAAK,GAC7C,IAAc,IAChB,EAAa,GAAY,KAAA,IACzB;AAGJ,MAAI,GAAa,iBAAiB,QAChC,QAAO,IACL,gBAAA,EAAC,GAAD;AAAA,IAAgC,aAAA;AAAA,IAAmB,MAAA;AAAA,EAA+B,GAApB,GAAY,KAAQ,IAChF;AAGN,QAAM,IAAgB,GAAa,QAAQ,GAAY,SAAS,GAAM,CAAI,GACpE,IAAc,IAChB,KAAiB,GAAY,SAAS,KACtC,IACE,EAAW,gBACV,GAAY,SAAS;AAE5B,SACE,gBAAA,EAAC,GAAD;AAAA,IACE,gBAAgB,EAAW;AAAA,IAC3B,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IAEN,UAAA,IACC,gBAAA,EAAC,GAAD;AAAA,MAAgC,aAAA;AAAA,MAAmB,MAAA;AAAA,IAA+B,GAApB,GAAY,KAAQ,IAChF,IACF,gBAAA,EAAC,GAAD;AAAA,MAAO,IAAI,EAAE,GAAG,GAAG;AAAA,MACjB,UAAA,gBAAA,EAAC,GAAD,EAAA,UAAO,EAAW,cAAoB,CAAA;AAAA,IACjC,CAAA,IACL;AAAA,EACE,CAAA;AAEZ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { ActionBlockProps } from '../mappings/blocks';
2
+ /**
3
+ * `connect_widget_block` — opens MX's Connect widget itself via the shared
4
+ * `ConnectWidgetPanel` (src/common): SSO url via ConnectStore and the
5
+ * iframe-based `@mxenabled/web-widget-sdk` ConnectWidget, with loading/error
6
+ * statuses.
7
+ *
8
+ * Renders the panel directly (not `ConnectDrawer`, which wraps it in its own
9
+ * `Drawer`) — `ActionBlockLayer` already supplies the action drawer's chrome
10
+ * (title from the CTA label, close button), so a second nested `Drawer` here
11
+ * would produce two stacked drawers with two headers and two close buttons.
12
+ *
13
+ * `ActionBlockLayer` does not unmount a drawer-presentation block when the
14
+ * drawer closes — it only toggles the `Drawer`'s `isOpen` — so the account
15
+ * refresh (parity with `ConnectDrawer`'s own `onClose`) is driven by watching
16
+ * this beat's `actionDrawer.isDrawerOpen` transition from true to false,
17
+ * rather than an unmount effect, which would never fire.
18
+ */
19
+ export declare const ConnectWidgetActionBlock: (({ beat, }: ActionBlockProps) => import("react/jsx-runtime").JSX.Element) & {
20
+ displayName: string;
21
+ };
@@ -0,0 +1,16 @@
1
+ import { useAccountStore as c, useInsightsV2Store as i } from "../../common/context/hooks.es.js";
2
+ import s from "../../common/components/ConnectWidgetPanel.es.js";
3
+ import { useEffect as u, useRef as f } from "react";
4
+ import { observer as m } from "mobx-react-lite";
5
+ import { jsx as p } from "react/jsx-runtime";
6
+ var v = m(function({ beat: o }) {
7
+ const { actionDrawer: e } = i(), { refreshAccounts: n } = c(), t = e.isDrawerOpen && e.guid === o.guid, r = f(t);
8
+ return u(() => {
9
+ r.current && !t && n(), r.current = t;
10
+ }, [t]), /* @__PURE__ */ p(s, { isActive: t });
11
+ });
12
+ export {
13
+ v as ConnectWidgetActionBlock
14
+ };
15
+
16
+ //# sourceMappingURL=ConnectWidgetActionBlock.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectWidgetActionBlock.es.js","names":[],"sources":["../../../src/insights-v2/actionBlocks/ConnectWidgetActionBlock.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react'\nimport { observer } from 'mobx-react-lite'\n\nimport { ConnectWidgetPanel, useAccountStore, useInsightsV2Store } from '../../common'\nimport type { ActionBlockProps } from '../mappings/blocks'\n\n/**\n * `connect_widget_block` — opens MX's Connect widget itself via the shared\n * `ConnectWidgetPanel` (src/common): SSO url via ConnectStore and the\n * iframe-based `@mxenabled/web-widget-sdk` ConnectWidget, with loading/error\n * statuses.\n *\n * Renders the panel directly (not `ConnectDrawer`, which wraps it in its own\n * `Drawer`) — `ActionBlockLayer` already supplies the action drawer's chrome\n * (title from the CTA label, close button), so a second nested `Drawer` here\n * would produce two stacked drawers with two headers and two close buttons.\n *\n * `ActionBlockLayer` does not unmount a drawer-presentation block when the\n * drawer closes — it only toggles the `Drawer`'s `isOpen` — so the account\n * refresh (parity with `ConnectDrawer`'s own `onClose`) is driven by watching\n * this beat's `actionDrawer.isDrawerOpen` transition from true to false,\n * rather than an unmount effect, which would never fire.\n */\nexport const ConnectWidgetActionBlock = observer(function ConnectWidgetActionBlock({\n beat,\n}: ActionBlockProps) {\n const { actionDrawer } = useInsightsV2Store()\n const { refreshAccounts } = useAccountStore()\n\n const isCurrentBeatOpen = actionDrawer.isDrawerOpen && actionDrawer.guid === beat.guid\n const wasOpen = useRef(isCurrentBeatOpen)\n\n useEffect(() => {\n if (wasOpen.current && !isCurrentBeatOpen) {\n void refreshAccounts()\n }\n wasOpen.current = isCurrentBeatOpen\n }, [isCurrentBeatOpen])\n\n return <ConnectWidgetPanel isActive={isCurrentBeatOpen} />\n})\n"],"mappings":";;;;;AAuBA,IAAa,IAA2B,EAAS,SAAkC,EACjF,MAAA,EAAA,GACmB;AACnB,QAAM,EAAE,cAAA,EAAA,IAAiB,EAAmB,GACtC,EAAE,iBAAA,EAAA,IAAoB,EAAgB,GAEtC,IAAoB,EAAa,gBAAgB,EAAa,SAAS,EAAK,MAC5E,IAAU,EAAO,CAAiB;AAExC,SAAA,EAAA,MAAgB;AACd,IAAI,EAAQ,WAAW,CAAC,KACtB,EAAqB,GAEvB,EAAQ,UAAU;AAAA,EACpB,GAAG,CAAC,CAAiB,CAAC,GAEf,gBAAA,EAAC,GAAD,EAAoB,UAAU,EAAoB,CAAA;AAC3D,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { ActionBlockProps } from '../mappings/blocks';
2
+ /**
3
+ * `connection_detail_block` — the connection-details education drilldown
4
+ * (ported from V1's `insights/components/shared/ConnectionDetailDrillDown`).
5
+ * Renders inside the standard action drawer; the drawer title comes from the
6
+ * registry entry's `title` (copy `connection_details_drawer_title`).
7
+ *
8
+ * Copy comes from `insights_feed.connection_details` in GlobalCopy.
9
+ */
10
+ export declare const ConnectionDetailActionBlock: ((_props: ActionBlockProps) => import("react/jsx-runtime").JSX.Element | null) & {
11
+ displayName: string;
12
+ };
@@ -0,0 +1,25 @@
1
+ import { useGlobalCopyStore as o } from "../../common/context/hooks.es.js";
2
+ import i from "../components/ConnectionDetailDrillDown.es.js";
3
+ import { observer as r } from "mobx-react-lite";
4
+ import { jsx as n } from "react/jsx-runtime";
5
+ var f = r(function(a) {
6
+ const e = o().insights_feed?.connection_details;
7
+ if (!e) return null;
8
+ const t = {
9
+ aria_label_thumbs_down: e.aria_label_thumbs_down,
10
+ aria_label_thumbs_up: e.aria_label_thumbs_up,
11
+ benefits: Object.values(e.benefits_list ?? {}),
12
+ description: e.description,
13
+ footer_title: e.footer_title,
14
+ header_text: e.header_text,
15
+ shared_info_description: e.shared_info_description,
16
+ shared_info_header_text: e.shared_info_header_text,
17
+ shared_info_items: Object.values(e.shared_info_list ?? {})
18
+ };
19
+ return /* @__PURE__ */ n(i, { copy: t });
20
+ });
21
+ export {
22
+ f as ConnectionDetailActionBlock
23
+ };
24
+
25
+ //# sourceMappingURL=ConnectionDetailActionBlock.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectionDetailActionBlock.es.js","names":[],"sources":["../../../src/insights-v2/actionBlocks/ConnectionDetailActionBlock.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport { useGlobalCopyStore } from '../../common'\nimport ConnectionDetailDrillDown, {\n type ConnectionDetailContent,\n} from '../components/ConnectionDetailDrillDown'\nimport type { ActionBlockProps } from '../mappings/blocks'\n\n/**\n * `connection_detail_block` — the connection-details education drilldown\n * (ported from V1's `insights/components/shared/ConnectionDetailDrillDown`).\n * Renders inside the standard action drawer; the drawer title comes from the\n * registry entry's `title` (copy `connection_details_drawer_title`).\n *\n * Copy comes from `insights_feed.connection_details` in GlobalCopy.\n */\nexport const ConnectionDetailActionBlock = observer(function ConnectionDetailActionBlock(\n _props: ActionBlockProps,\n) {\n const copyStore = useGlobalCopyStore()\n const detailsCopy = copyStore.insights_feed?.connection_details\n\n if (!detailsCopy) return null\n\n const copy: ConnectionDetailContent = {\n aria_label_thumbs_down: detailsCopy.aria_label_thumbs_down,\n aria_label_thumbs_up: detailsCopy.aria_label_thumbs_up,\n benefits: Object.values(detailsCopy.benefits_list ?? {}),\n description: detailsCopy.description,\n footer_title: detailsCopy.footer_title,\n header_text: detailsCopy.header_text,\n shared_info_description: detailsCopy.shared_info_description,\n shared_info_header_text: detailsCopy.shared_info_header_text,\n shared_info_items: Object.values(detailsCopy.shared_info_list ?? {}),\n }\n\n // TODO(analytics): forward the thumbs response once the host contract for\n // connection-details feedback lands (V1 posted it via sendResponseAnalytics).\n return <ConnectionDetailDrillDown copy={copy} />\n})\n"],"mappings":";;;;AAgBA,IAAa,IAA8B,EAAS,SAClD,GACA;AAEA,QAAM,IADY,EACE,EAAU,eAAe;AAE7C,MAAI,CAAC,EAAa,QAAO;AAEzB,QAAM,IAAgC;AAAA,IACpC,wBAAwB,EAAY;AAAA,IACpC,sBAAsB,EAAY;AAAA,IAClC,UAAU,OAAO,OAAO,EAAY,iBAAiB,CAAC,CAAC;AAAA,IACvD,aAAa,EAAY;AAAA,IACzB,cAAc,EAAY;AAAA,IAC1B,aAAa,EAAY;AAAA,IACzB,yBAAyB,EAAY;AAAA,IACrC,yBAAyB,EAAY;AAAA,IACrC,mBAAmB,OAAO,OAAO,EAAY,oBAAoB,CAAC,CAAC;AAAA,EACrE;AAIA,SAAO,gBAAA,EAAC,GAAD,EAAiC,MAAA,EAAO,CAAA;AACjD,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { ActionBlockProps } from '../mappings/blocks';
2
+ /**
3
+ * `feedback_modal_block` — a CTA drilldown registered like any other drawer
4
+ * block; its content is a MODAL (the dialog portals over the drawer).
5
+ *
6
+ * Flow: the CTA (e.g. Set Up Direct Deposit's "Not Interested") opens the
7
+ * "Can you tell us why?" survey (Figma `1941:192803`). Submit forwards the
8
+ * selection to the host via `beatActions.onSubmitFeedback` (source `cta`) and
9
+ * swaps the dialog for the success snackbar (Figma `1941:167636`); closing the
10
+ * snackbar — or dismissing the dialog — ends the action-drawer session.
11
+ *
12
+ * Copy comes from `insights_feed.feedback_modal` in GlobalCopy; the
13
+ * description interpolates the beat's account name (`_1{account_name}`).
14
+ */
15
+ export declare const FeedbackModalActionBlock: (({ beat, }: ActionBlockProps) => import("react/jsx-runtime").JSX.Element | null) & {
16
+ displayName: string;
17
+ };
@@ -0,0 +1,39 @@
1
+ import { buildDynamicCopy as l } from "../../core/utils/Localization.es.js";
2
+ import { useGlobalCopyStore as m, useInsightsV2Store as u } from "../../common/context/hooks.es.js";
3
+ import { useBeatActions as d } from "../beatActions.es.js";
4
+ import b from "../components/FeedbackModal.es.js";
5
+ import { observer as p } from "mobx-react-lite";
6
+ import { jsx as _ } from "react/jsx-runtime";
7
+ var C = p(function({ beat: t }) {
8
+ const { closeActionDrawer: s } = u(), { onSubmitFeedback: a } = d(), i = m(), e = t.insights_payload, o = i.insights_feed?.feedback_modal;
9
+ if (!e || !o) return null;
10
+ const r = {
11
+ title: o.title,
12
+ description: l(o.description, e.instance_slot?.account_name ?? ""),
13
+ options: Object.values(o.options ?? {}),
14
+ submitText: o.submit,
15
+ cancelText: o.no_thanks,
16
+ closeAriaLabel: o.close_aria,
17
+ characterLimitLabel: o.character_limit,
18
+ successMessage: o.success_message,
19
+ errorMessage: o.error_message,
20
+ tryAgainText: o.try_again,
21
+ toastCloseAriaLabel: o.toast_close_aria
22
+ };
23
+ return /* @__PURE__ */ _(b, {
24
+ copy: r,
25
+ isOpen: !0,
26
+ onClose: () => s(),
27
+ onSubmit: (c, n) => a?.({
28
+ beatGuid: e.guid,
29
+ source: "cta",
30
+ option: c,
31
+ detail: n
32
+ })
33
+ });
34
+ });
35
+ export {
36
+ C as FeedbackModalActionBlock
37
+ };
38
+
39
+ //# sourceMappingURL=FeedbackModalActionBlock.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeedbackModalActionBlock.es.js","names":[],"sources":["../../../src/insights-v2/actionBlocks/FeedbackModalActionBlock.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport { useGlobalCopyStore, useInsightsV2Store } from '../../common'\nimport { buildDynamicCopy } from '../../core/utils/Localization'\nimport FeedbackModal, { type FeedbackModalContent } from '../components/FeedbackModal'\nimport { useBeatActions } from '../beatActions'\nimport type { ActionBlockProps } from '../mappings/blocks'\n\n/**\n * `feedback_modal_block` — a CTA drilldown registered like any other drawer\n * block; its content is a MODAL (the dialog portals over the drawer).\n *\n * Flow: the CTA (e.g. Set Up Direct Deposit's \"Not Interested\") opens the\n * \"Can you tell us why?\" survey (Figma `1941:192803`). Submit forwards the\n * selection to the host via `beatActions.onSubmitFeedback` (source `cta`) and\n * swaps the dialog for the success snackbar (Figma `1941:167636`); closing the\n * snackbar — or dismissing the dialog — ends the action-drawer session.\n *\n * Copy comes from `insights_feed.feedback_modal` in GlobalCopy; the\n * description interpolates the beat's account name (`_1{account_name}`).\n */\nexport const FeedbackModalActionBlock = observer(function FeedbackModalActionBlock({\n beat,\n}: ActionBlockProps) {\n const { closeActionDrawer } = useInsightsV2Store()\n const { onSubmitFeedback } = useBeatActions()\n const copyStore = useGlobalCopyStore()\n\n const insights_payload = beat.insights_payload\n const modalCopy = copyStore.insights_feed?.feedback_modal\n\n if (!insights_payload || !modalCopy) return null\n\n const copy: FeedbackModalContent = {\n title: modalCopy.title,\n description: buildDynamicCopy(\n modalCopy.description,\n // `account_name` lands on InstanceSlot with the Direct Deposit block (WEC-1875);\n // narrow-cast until that merges so the modal stays beat-agnostic.\n (insights_payload.instance_slot as { account_name?: string })?.account_name ?? '',\n ) as string,\n options: Object.values(modalCopy.options ?? {}),\n submitText: modalCopy.submit,\n cancelText: modalCopy.no_thanks,\n closeAriaLabel: modalCopy.close_aria,\n characterLimitLabel: modalCopy.character_limit,\n successMessage: modalCopy.success_message,\n errorMessage: modalCopy.error_message,\n tryAgainText: modalCopy.try_again,\n toastCloseAriaLabel: modalCopy.toast_close_aria,\n }\n\n // Returned (not just fired): a host promise rejection drives the modal's\n // error snackbar + Try Again retry.\n\n //TODO: Need to update the onSubmit functionality as per pulse. This function is mis-matching with the current approach of switchdirectdeposit and setupdirectdeposit\n\n const handleSubmit = (option: string, detail?: string) =>\n onSubmitFeedback?.({\n beatGuid: insights_payload.guid,\n source: 'cta',\n option,\n detail,\n })\n\n return (\n <FeedbackModal\n copy={copy}\n isOpen={true}\n onClose={() => closeActionDrawer()}\n onSubmit={handleSubmit}\n />\n )\n})\n"],"mappings":";;;;;;AAqBA,IAAa,IAA2B,EAAS,SAAkC,EACjF,MAAA,EAAA,GACmB;AACnB,QAAM,EAAE,mBAAA,EAAA,IAAsB,EAAmB,GAC3C,EAAE,kBAAA,EAAA,IAAqB,EAAe,GACtC,IAAY,EAAmB,GAE/B,IAAmB,EAAK,kBACxB,IAAY,EAAU,eAAe;AAE3C,MAAI,CAAC,KAAoB,CAAC,EAAW,QAAO;AAE5C,QAAM,IAA6B;AAAA,IACjC,OAAO,EAAU;AAAA,IACjB,aAAa,EACX,EAAU,aAGT,EAAiB,eAA6C,gBAAgB,EACjF;AAAA,IACA,SAAS,OAAO,OAAO,EAAU,WAAW,CAAC,CAAC;AAAA,IAC9C,YAAY,EAAU;AAAA,IACtB,YAAY,EAAU;AAAA,IACtB,gBAAgB,EAAU;AAAA,IAC1B,qBAAqB,EAAU;AAAA,IAC/B,gBAAgB,EAAU;AAAA,IAC1B,cAAc,EAAU;AAAA,IACxB,cAAc,EAAU;AAAA,IACxB,qBAAqB,EAAU;AAAA,EACjC;AAeA,SACE,gBAAA,EAAC,GAAD;AAAA,IACQ,MAAA;AAAA,IACN,QAAQ;AAAA,IACR,SAAA,MAAe,EAAkB;AAAA,IACjC,UAbE,CAAgB,GAAgB,MACpC,IAAmB;AAAA,MACjB,UAAU,EAAiB;AAAA,MAC3B,QAAQ;AAAA,MACR,QAAA;AAAA,MACA,QAAA;AAAA,IACF,CAAC;AAAA,EAQA,CAAA;AAEL,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { ActionBlockProps } from '../mappings/blocks';
2
+ /**
3
+ * `survey_modal_block` — the "Does this look right?" confirmation survey
4
+ * (Figma `1941:212640`). Registered like any other drawer block; its content
5
+ * is a MODAL (the dialog portals over the drawer).
6
+ *
7
+ * The survey has no action buttons — its rows act: the positive row submits
8
+ * to the host via `beatActions.onSubmitFeedback` (source `cta`) and shows the
9
+ * status snackbar; the negative row opens the FeedbackModal reasons dialog.
10
+ * The session ends when the flow does (snackbar dismissed or dialogs closed).
11
+ *
12
+ * Copy comes from `insights_feed.survey_modal` in GlobalCopy.
13
+ */
14
+ export declare const SurveyModalActionBlock: (({ beat, }: ActionBlockProps) => import("react/jsx-runtime").JSX.Element | null) & {
15
+ displayName: string;
16
+ };
@@ -0,0 +1,47 @@
1
+ import { useGlobalCopyStore as c, useInsightsV2Store as u } from "../../common/context/hooks.es.js";
2
+ import { useBeatActions as m } from "../beatActions.es.js";
3
+ import b from "../components/SurveyModal.es.js";
4
+ import { observer as p } from "mobx-react-lite";
5
+ import { jsx as _ } from "react/jsx-runtime";
6
+ var A = p(function({ beat: t }) {
7
+ const { closeActionDrawer: s } = u(), { onSubmitFeedback: r } = m(), a = c(), o = t.insights_payload, e = a.insights_feed?.survey_modal;
8
+ if (!o || !e) return null;
9
+ const i = {
10
+ title: e.title,
11
+ options: [{
12
+ overline: e.yes_overline,
13
+ label: e.yes_label,
14
+ tone: "positive"
15
+ }, {
16
+ overline: e.no_overline,
17
+ label: e.no_label,
18
+ tone: "negative"
19
+ }],
20
+ submitText: e.submit,
21
+ closeAriaLabel: e.close_aria,
22
+ reasonsTitle: e.reasons_title,
23
+ reasonOptions: Object.values(e.reason_options ?? {}),
24
+ backText: e.back,
25
+ characterLimitLabel: e.character_limit,
26
+ successMessage: e.success_message,
27
+ errorMessage: e.error_message,
28
+ tryAgainText: e.try_again,
29
+ toastCloseAriaLabel: e.toast_close_aria
30
+ };
31
+ return /* @__PURE__ */ _(b, {
32
+ copy: i,
33
+ isOpen: !0,
34
+ onClose: () => s(),
35
+ onSubmit: (n, l) => r?.({
36
+ beatGuid: o.guid,
37
+ source: "cta",
38
+ option: n,
39
+ detail: l
40
+ })
41
+ });
42
+ });
43
+ export {
44
+ A as SurveyModalActionBlock
45
+ };
46
+
47
+ //# sourceMappingURL=SurveyModalActionBlock.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SurveyModalActionBlock.es.js","names":[],"sources":["../../../src/insights-v2/actionBlocks/SurveyModalActionBlock.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport { useGlobalCopyStore, useInsightsV2Store } from '../../common'\nimport SurveyModal, { type SurveyModalContent } from '../components/SurveyModal'\nimport { useBeatActions } from '../beatActions'\nimport type { ActionBlockProps } from '../mappings/blocks'\n\n/**\n * `survey_modal_block` — the \"Does this look right?\" confirmation survey\n * (Figma `1941:212640`). Registered like any other drawer block; its content\n * is a MODAL (the dialog portals over the drawer).\n *\n * The survey has no action buttons — its rows act: the positive row submits\n * to the host via `beatActions.onSubmitFeedback` (source `cta`) and shows the\n * status snackbar; the negative row opens the FeedbackModal reasons dialog.\n * The session ends when the flow does (snackbar dismissed or dialogs closed).\n *\n * Copy comes from `insights_feed.survey_modal` in GlobalCopy.\n */\nexport const SurveyModalActionBlock = observer(function SurveyModalActionBlock({\n beat,\n}: ActionBlockProps) {\n const { closeActionDrawer } = useInsightsV2Store()\n const { onSubmitFeedback } = useBeatActions()\n const copyStore = useGlobalCopyStore()\n\n const insights_payload = beat.insights_payload\n const surveyCopy = copyStore.insights_feed?.survey_modal\n\n if (!insights_payload || !surveyCopy) return null\n\n const copy: SurveyModalContent = {\n title: surveyCopy.title,\n options: [\n { overline: surveyCopy.yes_overline, label: surveyCopy.yes_label, tone: 'positive' },\n { overline: surveyCopy.no_overline, label: surveyCopy.no_label, tone: 'negative' },\n ],\n submitText: surveyCopy.submit,\n\n closeAriaLabel: surveyCopy.close_aria,\n reasonsTitle: surveyCopy.reasons_title,\n reasonOptions: Object.values(surveyCopy.reason_options ?? {}),\n backText: surveyCopy.back,\n characterLimitLabel: surveyCopy.character_limit,\n successMessage: surveyCopy.success_message,\n errorMessage: surveyCopy.error_message,\n tryAgainText: surveyCopy.try_again,\n toastCloseAriaLabel: surveyCopy.toast_close_aria,\n }\n\n // Returned (not just fired): a host promise rejection drives the modal's\n // error snackbar + Try Again retry. The session closes when the flow ends\n // (snackbar dismissed), not on submit.\n\n //TODO: Need to update the onSubmit functionality as per pulse. This function is mis-matching with the current approach of switchdirectdeposit and setupdirectdeposit\n const handleSubmit = (option: string, detail?: string) =>\n onSubmitFeedback?.({\n beatGuid: insights_payload.guid,\n source: 'cta',\n option,\n detail,\n })\n\n return (\n <SurveyModal\n copy={copy}\n isOpen={true}\n onClose={() => closeActionDrawer()}\n onSubmit={handleSubmit}\n />\n )\n})\n"],"mappings":";;;;;AAmBA,IAAa,IAAyB,EAAS,SAAgC,EAC7E,MAAA,EAAA,GACmB;AACnB,QAAM,EAAE,mBAAA,EAAA,IAAsB,EAAmB,GAC3C,EAAE,kBAAA,EAAA,IAAqB,EAAe,GACtC,IAAY,EAAmB,GAE/B,IAAmB,EAAK,kBACxB,IAAa,EAAU,eAAe;AAE5C,MAAI,CAAC,KAAoB,CAAC,EAAY,QAAO;AAE7C,QAAM,IAA2B;AAAA,IAC/B,OAAO,EAAW;AAAA,IAClB,SAAS,CACP;AAAA,MAAE,UAAU,EAAW;AAAA,MAAc,OAAO,EAAW;AAAA,MAAW,MAAM;AAAA,IAAW,GACnF;AAAA,MAAE,UAAU,EAAW;AAAA,MAAa,OAAO,EAAW;AAAA,MAAU,MAAM;AAAA,IAAW,CACnF;AAAA,IACA,YAAY,EAAW;AAAA,IAEvB,gBAAgB,EAAW;AAAA,IAC3B,cAAc,EAAW;AAAA,IACzB,eAAe,OAAO,OAAO,EAAW,kBAAkB,CAAC,CAAC;AAAA,IAC5D,UAAU,EAAW;AAAA,IACrB,qBAAqB,EAAW;AAAA,IAChC,gBAAgB,EAAW;AAAA,IAC3B,cAAc,EAAW;AAAA,IACzB,cAAc,EAAW;AAAA,IACzB,qBAAqB,EAAW;AAAA,EAClC;AAeA,SACE,gBAAA,EAAC,GAAD;AAAA,IACQ,MAAA;AAAA,IACN,QAAQ;AAAA,IACR,SAAA,MAAe,EAAkB;AAAA,IACjC,UAbE,CAAgB,GAAgB,MACpC,IAAmB;AAAA,MACjB,UAAU,EAAiB;AAAA,MAC3B,QAAQ;AAAA,MACR,QAAA;AAAA,MACA,QAAA;AAAA,IACF,CAAC;AAAA,EAQA,CAAA;AAEL,CAAC"}
@@ -13,7 +13,7 @@ export interface UpdateParams {
13
13
  }
14
14
  export interface FeedbackParams {
15
15
  beatGuid: string;
16
- source: InsightRating | 'hide';
16
+ source: InsightRating | 'hide' | 'cta';
17
17
  option: string;
18
18
  detail?: string;
19
19
  }
@@ -35,7 +35,7 @@ export interface CtaActionParams {
35
35
  export interface BeatActions {
36
36
  onMenuAction?: MenuActionHandlers;
37
37
  onUpdate?: (params: UpdateParams) => void;
38
- onSubmitFeedback?: (params: FeedbackParams) => void;
38
+ onSubmitFeedback?: (params: FeedbackParams) => void | Promise<void>;
39
39
  onDismissInsight?: (params: DismissParams) => void;
40
40
  onUndoDismiss?: (params: {
41
41
  beatGuid: string;
@@ -1 +1 @@
1
- {"version":3,"file":"beatActions.es.js","names":[],"sources":["../../src/insights-v2/beatActions.tsx"],"sourcesContent":["import { createContext, useContext, type ReactNode } from 'react'\n\nimport type { DismissType } from './components/DismissInsightDialog'\nimport type { FeedbackDialogCloseReason } from './components/FeedbackDialog'\n\nexport type InsightMenuAction = 'helpful' | 'not_helpful' | 'hide'\nexport type InsightRating = 'helpful' | 'not_helpful'\n\nexport interface MenuActionHandlers {\n onAction: (action: InsightMenuAction) => void\n onOpen?: () => void\n disabled?: boolean\n}\n\nexport interface UpdateParams {\n beatGuid: string\n}\n\nexport interface FeedbackParams {\n beatGuid: string\n source: InsightRating | 'hide'\n option: string\n detail?: string\n}\n\nexport interface DismissParams {\n beatGuid: string\n type: DismissType\n}\n\n/**\n * A CTA side effect the host must perform because experiences cannot (beat-owned endpoints,\n * spending plan items, third-party SDKs). `name` is agreed between the ctaActions table and\n * the host; see insights-v2/ctaActions/README.md for the list.\n */\nexport interface CtaActionParams {\n beatGuid: string\n name: string\n params?: Record<string, unknown>\n}\n\n/** Host callbacks for a beat card. */\nexport interface BeatActions {\n onMenuAction?: MenuActionHandlers\n onUpdate?: (params: UpdateParams) => void\n onSubmitFeedback?: (params: FeedbackParams) => void\n onDismissInsight?: (params: DismissParams) => void\n onUndoDismiss?: (params: { beatGuid: string }) => void\n onFeedbackDialogClose?: (reason: FeedbackDialogCloseReason) => void\n onFeedbackDialogBack?: () => void\n onFeedbackTextFocus?: () => void\n /**\n * Opens the host's contact-support flow for a `contact_support_block` CTA. insights-v2 cannot\n * import the help module (hosts that don't ship it stub the import), so the host supplies it:\n * the experiences Help widget wires `RequestSupport`; pulse wires its own. When absent, the CTA\n * renders disabled (see `isContactSupportCtaDisabled`).\n */\n onContactSupport?: () => void\n onCtaAction?: (params: CtaActionParams) => Promise<void> | void\n}\n\nconst BeatActionsContext = createContext<BeatActions>({})\n\nexport const BeatActionsProvider = ({\n value,\n children,\n}: {\n value: BeatActions\n children: ReactNode\n}) => <BeatActionsContext.Provider value={value}>{children}</BeatActionsContext.Provider>\n\nexport const useBeatActions = () => useContext(BeatActionsContext)\n"],"mappings":";;AA6DA,IAAM,IAAqB,EAA2B,CAAC,CAAC,GAE3C,IAAA,CAAuB,EAClC,OAAA,GACA,UAAA,EAAA,MAII,gBAAA,EAAC,EAAmB,UAApB;AAAA,EAAoC,OAAA;AAAA,EAAQ,UAAA;AAAsC,CAAA,GAE3E,IAAA,MAAuB,EAAW,CAAkB"}
1
+ {"version":3,"file":"beatActions.es.js","names":[],"sources":["../../src/insights-v2/beatActions.tsx"],"sourcesContent":["import { createContext, useContext, type ReactNode } from 'react'\n\nimport type { DismissType } from './components/DismissInsightDialog'\nimport type { FeedbackDialogCloseReason } from './components/FeedbackDialog'\n\nexport type InsightMenuAction = 'helpful' | 'not_helpful' | 'hide'\nexport type InsightRating = 'helpful' | 'not_helpful'\n\nexport interface MenuActionHandlers {\n onAction: (action: InsightMenuAction) => void\n onOpen?: () => void\n disabled?: boolean\n}\n\nexport interface UpdateParams {\n beatGuid: string\n}\n\nexport interface FeedbackParams {\n beatGuid: string\n source: InsightRating | 'hide' | 'cta'\n option: string\n detail?: string\n}\n\nexport interface DismissParams {\n beatGuid: string\n type: DismissType\n}\n\n/**\n * A CTA side effect the host must perform because experiences cannot (beat-owned endpoints,\n * spending plan items, third-party SDKs). `name` is agreed between the ctaActions table and\n * the host; see insights-v2/ctaActions/README.md for the list.\n */\nexport interface CtaActionParams {\n beatGuid: string\n name: string\n params?: Record<string, unknown>\n}\n\n/** Host callbacks for a beat card. */\nexport interface BeatActions {\n onMenuAction?: MenuActionHandlers\n onUpdate?: (params: UpdateParams) => void\n onSubmitFeedback?: (params: FeedbackParams) => void | Promise<void>\n onDismissInsight?: (params: DismissParams) => void\n onUndoDismiss?: (params: { beatGuid: string }) => void\n onFeedbackDialogClose?: (reason: FeedbackDialogCloseReason) => void\n onFeedbackDialogBack?: () => void\n onFeedbackTextFocus?: () => void\n /**\n * Opens the host's contact-support flow for a `contact_support_block` CTA. insights-v2 cannot\n * import the help module (hosts that don't ship it stub the import), so the host supplies it:\n * the experiences Help widget wires `RequestSupport`; pulse wires its own. When absent, the CTA\n * renders disabled (see `isContactSupportCtaDisabled`).\n */\n onContactSupport?: () => void\n onCtaAction?: (params: CtaActionParams) => Promise<void> | void\n}\n\nconst BeatActionsContext = createContext<BeatActions>({})\n\nexport const BeatActionsProvider = ({\n value,\n children,\n}: {\n value: BeatActions\n children: ReactNode\n}) => <BeatActionsContext.Provider value={value}>{children}</BeatActionsContext.Provider>\n\nexport const useBeatActions = () => useContext(BeatActionsContext)\n"],"mappings":";;AA6DA,IAAM,IAAqB,EAA2B,CAAC,CAAC,GAE3C,IAAA,CAAuB,EAClC,OAAA,GACA,UAAA,EAAA,MAII,gBAAA,EAAC,EAAmB,UAApB;AAAA,EAAoC,OAAA;AAAA,EAAQ,UAAA;AAAsC,CAAA,GAE3E,IAAA,MAAuB,EAAW,CAAkB"}
@@ -1,10 +1,8 @@
1
1
  import { AccountSwitchBlockData } from '../../../../core/types/InsightsInstanceSlotData';
2
2
  import { BlockProps } from '../../types';
3
3
  /**
4
- * Discovered-accounts connect visual: two institution logos on a transfer track.
5
- * The pending state (`is_connected: false`) shows a link badge on the default
6
- * slot; the connected state (`is_connected: true`) switches to a success badge
7
- * with the discovered-accounts gradient and a confetti wash.
4
+ * Two institution logos on a transfer track, shared by Discovered Accounts and Switch
5
+ * Direct Deposit. `instance_slot.variant` picks the design branch from `./layout.ts`.
8
6
  */
9
7
  declare const AccountSwitchBlock: ({ payload }: BlockProps<AccountSwitchBlockData>) => import("react/jsx-runtime").JSX.Element;
10
8
  export default AccountSwitchBlock;
@@ -1,43 +1,34 @@
1
- import "../../../components/celebrationGradients.es.js";
2
- import u from "../../../components/TransferLogoCard.es.js";
1
+ import _ from "../../../components/TransferLogoCard.es.js";
2
+ import { resolveVariantConfig as l } from "../../resolveVariantConfig.es.js";
3
+ import { accountSwitchVariant as g, getLayoutConfig as h } from "./layout.es.js";
3
4
  import { InstitutionLogo as i } from "@mxenabled/mxui";
4
- import { Icon as e } from "@mxenabled/mx-icons";
5
- import { jsx as o } from "react/jsx-runtime";
6
- var r = 64, m = /* @__PURE__ */ o(e, {
7
- "aria-hidden": !0,
8
- name: "link",
9
- size: 20,
10
- sx: { color: "primary.contrastText" }
11
- }), g = /* @__PURE__ */ o(e, {
12
- "aria-hidden": !0,
13
- name: "check_circle",
14
- size: 20,
15
- sx: { color: "common.white" }
16
- }), x = ({ payload: n }) => {
17
- const { discovered_institution_guid: a, discovered_institution_name: s, held_institution_guid: c, held_institution_name: d, is_connected: t } = n.instance_slot_data;
18
- return /* @__PURE__ */ o(u, {
19
- badgeBgColor: t ? "success.main" : "text.secondary",
20
- dotColor: "text.secondary",
21
- from: /* @__PURE__ */ o(i, {
5
+ import { Icon as p } from "@mxenabled/mx-icons";
6
+ import { jsx as t } from "react/jsx-runtime";
7
+ import { useTheme as v } from "@mui/material/styles";
8
+ var n = 64, A = ({ payload: o }) => {
9
+ const r = v(), { variant: e } = o.instance_slot, { discovered_institution_guid: c, discovered_institution_name: s, held_institution_guid: a, held_institution_name: m } = o.instance_slot_data, { badgeIcon: u, badgeIconColor: d, ...f } = l(h(r), e, g.AccountConnect, "AccountSwitchBlock");
10
+ return /* @__PURE__ */ t(_, {
11
+ ...f,
12
+ from: /* @__PURE__ */ t(i, {
22
13
  alt: s,
23
- institutionGuid: a,
24
- size: r
25
- }),
26
- icon: t ? g : m,
27
- to: /* @__PURE__ */ o(i, {
28
- alt: d,
29
14
  institutionGuid: c,
30
- size: r
15
+ size: n
31
16
  }),
32
- ...t && {
33
- backgroundImage: "linear-gradient(257deg, rgba(255, 224, 153, 0.2) 1.86%, rgba(255, 129, 230, 0.2) 101.54%)",
34
- bgcolor: "background.paper",
35
- showConfetti: !0
36
- }
17
+ icon: /* @__PURE__ */ t(p, {
18
+ "aria-hidden": !0,
19
+ name: u,
20
+ size: 20,
21
+ sx: { color: d }
22
+ }),
23
+ to: /* @__PURE__ */ t(i, {
24
+ alt: m,
25
+ institutionGuid: a,
26
+ size: n
27
+ })
37
28
  });
38
29
  };
39
30
  export {
40
- x as default
31
+ A as default
41
32
  };
42
33
 
43
34
  //# sourceMappingURL=AccountSwitchBlock.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccountSwitchBlock.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ComponentBlocks/AccountSwitchBlock/AccountSwitchBlock.tsx"],"sourcesContent":["import { InstitutionLogo } from '@mxenabled/mxui'\nimport { Icon } from '@mxenabled/mx-icons'\n\nimport type { AccountSwitchBlockData } from '../../../../core/types/InsightsInstanceSlotData'\n\nimport TransferLogoCard from '../../../components/TransferLogoCard'\nimport { ACCOUNT_CONNECTED_GRADIENT } from '../../../components/celebrationGradients'\n\nimport type { BlockProps } from '../../types'\n\nconst LOGO_SIZE = 64\n\n// Center-badge glyphs, hoisted to stable module-scope references so they aren't\n// re-created each render: `link` for the pending \"connect\" state and\n// `check_circle` for the connected success state (mirrors TransferLogoCard's\n// Discovered Accounts default/success states).\nconst linkBadge = (\n <Icon aria-hidden={true} name=\"link\" size={20} sx={{ color: 'primary.contrastText' }} />\n)\nconst successBadge = (\n <Icon aria-hidden={true} name=\"check_circle\" size={20} sx={{ color: 'common.white' }} />\n)\n\n/**\n * Discovered-accounts connect visual: two institution logos on a transfer track.\n * The pending state (`is_connected: false`) shows a link badge on the default\n * slot; the connected state (`is_connected: true`) switches to a success badge\n * with the discovered-accounts gradient and a confetti wash.\n */\nconst AccountSwitchBlock = ({ payload }: BlockProps<AccountSwitchBlockData>) => {\n const {\n discovered_institution_guid,\n discovered_institution_name,\n held_institution_guid,\n held_institution_name,\n is_connected,\n } = payload.instance_slot_data\n\n const from = (\n <InstitutionLogo\n alt={discovered_institution_name}\n institutionGuid={discovered_institution_guid}\n size={LOGO_SIZE}\n />\n )\n const to = (\n <InstitutionLogo\n alt={held_institution_name}\n institutionGuid={held_institution_guid}\n size={LOGO_SIZE}\n />\n )\n\n return (\n <TransferLogoCard\n badgeBgColor={is_connected ? 'success.main' : 'text.secondary'}\n dotColor=\"text.secondary\"\n from={from}\n icon={is_connected ? successBadge : linkBadge}\n to={to}\n {...(is_connected && {\n backgroundImage: ACCOUNT_CONNECTED_GRADIENT,\n bgcolor: 'background.paper',\n showConfetti: true,\n })}\n />\n )\n}\n\nexport default AccountSwitchBlock\n"],"mappings":";;;;;AAUA,IAAM,IAAY,IAMZ,IACJ,gBAAA,EAAC,GAAD;AAAA,EAAM,eAAa;AAAA,EAAM,MAAK;AAAA,EAAO,MAAM;AAAA,EAAI,IAAI,EAAE,OAAO,uBAAuB;AAAI,CAAA,GAEnF,IACJ,gBAAA,EAAC,GAAD;AAAA,EAAM,eAAa;AAAA,EAAM,MAAK;AAAA,EAAe,MAAM;AAAA,EAAI,IAAI,EAAE,OAAO,eAAe;AAAI,CAAA,GASnF,IAAA,CAAsB,EAAE,SAAA,EAAA,MAAkD;AAC9E,QAAM,EACJ,6BAAA,GACA,6BAAA,GACA,uBAAA,GACA,uBAAA,GACA,cAAA,EAAA,IACE,EAAQ;AAiBZ,SACE,gBAAA,EAAC,GAAD;AAAA,IACE,cAAc,IAAe,iBAAiB;AAAA,IAC9C,UAAS;AAAA,IACH,MAlBR,gBAAA,EAAC,GAAD;AAAA,MACE,KAAK;AAAA,MACL,iBAAiB;AAAA,MACjB,MAAM;AAAA,IACP,CAcO;AAAA,IACN,MAAM,IAAe,IAAe;AAAA,IAChC,IAbN,gBAAA,EAAC,GAAD;AAAA,MACE,KAAK;AAAA,MACL,iBAAiB;AAAA,MACjB,MAAM;AAAA,IACP,CASK;AAAA,IACJ,GAAK,KAAgB;AAAA,MACnB,iBAAA;AAAA,MACA,SAAS;AAAA,MACT,cAAc;AAAA,IAChB;AAAA,EACD,CAAA;AAEL"}
1
+ {"version":3,"file":"AccountSwitchBlock.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ComponentBlocks/AccountSwitchBlock/AccountSwitchBlock.tsx"],"sourcesContent":["import { useTheme } from '@mui/material/styles'\nimport { InstitutionLogo } from '@mxenabled/mxui'\nimport { Icon } from '@mxenabled/mx-icons'\n\nimport type { AccountSwitchBlockData } from '../../../../core/types/InsightsInstanceSlotData'\n\nimport TransferLogoCard from '../../../components/TransferLogoCard'\n\nimport type { BlockProps } from '../../types'\nimport { resolveVariantConfig } from '../../resolveVariantConfig'\nimport { accountSwitchVariant, getLayoutConfig } from './layout'\n\nconst LOGO_SIZE = 64\n\n/**\n * Two institution logos on a transfer track, shared by Discovered Accounts and Switch\n * Direct Deposit. `instance_slot.variant` picks the design branch from `./layout.ts`.\n */\nconst AccountSwitchBlock = ({ payload }: BlockProps<AccountSwitchBlockData>) => {\n const theme = useTheme()\n const { variant } = payload.instance_slot\n const {\n discovered_institution_guid,\n discovered_institution_name,\n held_institution_guid,\n held_institution_name,\n } = payload.instance_slot_data\n\n // Pending connect is the safe default: it promises nothing (no success badge, no confetti).\n const { badgeIcon, badgeIconColor, ...cardProps } = resolveVariantConfig(\n getLayoutConfig(theme),\n variant,\n accountSwitchVariant.AccountConnect,\n 'AccountSwitchBlock',\n )\n\n return (\n <TransferLogoCard\n {...cardProps}\n from={\n <InstitutionLogo\n alt={discovered_institution_name}\n institutionGuid={discovered_institution_guid}\n size={LOGO_SIZE}\n />\n }\n icon={<Icon aria-hidden={true} name={badgeIcon} size={20} sx={{ color: badgeIconColor }} />}\n to={\n <InstitutionLogo\n alt={held_institution_name}\n institutionGuid={held_institution_guid}\n size={LOGO_SIZE}\n />\n }\n />\n )\n}\n\nexport default AccountSwitchBlock\n"],"mappings":";;;;;;;AAYA,IAAM,IAAY,IAMZ,IAAA,CAAsB,EAAE,SAAA,EAAA,MAAkD;AAC9E,QAAM,IAAQ,EAAS,GACjB,EAAE,SAAA,EAAA,IAAY,EAAQ,eACtB,EACJ,6BAAA,GACA,6BAAA,GACA,uBAAA,GACA,uBAAA,EAAA,IACE,EAAQ,oBAGN,EAAE,WAAA,GAAW,gBAAA,GAAgB,GAAG,EAAA,IAAc,EAClD,EAAgB,CAAK,GACrB,GACA,EAAqB,gBACrB,oBACF;AAEA,SACE,gBAAA,EAAC,GAAD;AAAA,IACE,GAAI;AAAA,IACJ,MACE,gBAAA,EAAC,GAAD;AAAA,MACE,KAAK;AAAA,MACL,iBAAiB;AAAA,MACjB,MAAM;AAAA,IACP,CAAA;AAAA,IAEH,MAAM,gBAAA,EAAC,GAAD;AAAA,MAAM,eAAa;AAAA,MAAM,MAAM;AAAA,MAAW,MAAM;AAAA,MAAI,IAAI,EAAE,OAAO,EAAe;AAAA,IAAI,CAAA;AAAA,IAC1F,IACE,gBAAA,EAAC,GAAD;AAAA,MACE,KAAK;AAAA,MACL,iBAAiB;AAAA,MACjB,MAAM;AAAA,IACP,CAAA;AAAA,EAEJ,CAAA;AAEL"}
@@ -0,0 +1,36 @@
1
+ import { Theme } from '@mui/material/styles';
2
+ /**
3
+ * Account Switch block variants, keyed by the backend `instance_slot.variant`. All share
4
+ * `TransferLogoCard`; only the slot surface, center badge and connector dots differ.
5
+ *
6
+ * - `AccountConnect` — Discovered Accounts pending: blue gradient, link badge.
7
+ * - `AccountConnected` — Discovered Accounts success: pink wash, confetti, check badge.
8
+ * - `SwitchDirectDeposit` — Switch Direct Deposit pending: flat tinted slot, arrow badge.
9
+ * Its complete state is a different layout, served by `direct_deposit_block`.
10
+ */
11
+ export declare const accountSwitchVariant: {
12
+ readonly AccountConnect: "account_connect";
13
+ readonly AccountConnected: "account_connected";
14
+ readonly SwitchDirectDeposit: "switch_direct_deposit";
15
+ };
16
+ export type AccountSwitchVariant = (typeof accountSwitchVariant)[keyof typeof accountSwitchVariant];
17
+ export interface AccountSwitchLayoutConfig {
18
+ /** Slot surface color token. */
19
+ bgcolor: string;
20
+ /** Optional gradient layered over `bgcolor`. */
21
+ backgroundImage?: string;
22
+ /** Center badge background color token. */
23
+ badgeBgColor: string;
24
+ /** mx-icons glyph rendered in the center badge. */
25
+ badgeIcon: string;
26
+ /** Color token for the badge glyph. */
27
+ badgeIconColor: string;
28
+ /** Connector-dot color token. */
29
+ dotColor: string;
30
+ /** Enlarge the inner connector dots (6px vs 4px). */
31
+ hasBigDots: boolean;
32
+ /** Confetti burst filling the slot (success states). */
33
+ showConfetti?: boolean;
34
+ }
35
+ /** Per-variant `TransferLogoCard` props (mirrors DirectDepositBlock's `getLayoutConfig`). */
36
+ export declare const getLayoutConfig: (theme: Theme) => Record<AccountSwitchVariant, AccountSwitchLayoutConfig>;