@flipdish/ui-library 0.38.0 → 0.39.1

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 (40) hide show
  1. package/README.md +9 -9
  2. package/dist/components/templates/WidgetLayout/index.cjs +36 -0
  3. package/dist/components/templates/WidgetLayout/index.cjs.map +1 -0
  4. package/dist/components/templates/WidgetLayout/index.d.ts +54 -0
  5. package/dist/components/templates/WidgetLayout/index.d.ts.map +1 -0
  6. package/dist/components/templates/WidgetLayout/index.js +34 -0
  7. package/dist/components/templates/WidgetLayout/index.js.map +1 -0
  8. package/dist/native/components/templates/WidgetLayout/index.d.ts +12 -0
  9. package/dist/providers/PortalContainer/index.d.ts +1 -1
  10. package/dist/providers/ThemeProvider/index.cjs +36 -14
  11. package/dist/providers/ThemeProvider/index.cjs.map +1 -1
  12. package/dist/providers/ThemeProvider/index.d.ts +19 -5
  13. package/dist/providers/ThemeProvider/index.d.ts.map +1 -1
  14. package/dist/providers/ThemeProvider/index.js +36 -14
  15. package/dist/providers/ThemeProvider/index.js.map +1 -1
  16. package/dist/providers/UIProvider/hooks/usePortalAnchor.cjs +137 -0
  17. package/dist/providers/UIProvider/hooks/usePortalAnchor.cjs.map +1 -0
  18. package/dist/providers/UIProvider/hooks/usePortalAnchor.d.ts +60 -0
  19. package/dist/providers/UIProvider/hooks/usePortalAnchor.d.ts.map +1 -0
  20. package/dist/providers/UIProvider/hooks/usePortalAnchor.js +131 -0
  21. package/dist/providers/UIProvider/hooks/usePortalAnchor.js.map +1 -0
  22. package/dist/providers/UIProvider/index.cjs +7 -64
  23. package/dist/providers/UIProvider/index.cjs.map +1 -1
  24. package/dist/providers/UIProvider/index.d.ts +16 -11
  25. package/dist/providers/UIProvider/index.d.ts.map +1 -1
  26. package/dist/providers/UIProvider/index.js +7 -64
  27. package/dist/providers/UIProvider/index.js.map +1 -1
  28. package/dist/utilities/cssScopeUtils/index.cjs +22 -11
  29. package/dist/utilities/cssScopeUtils/index.cjs.map +1 -1
  30. package/dist/utilities/cssScopeUtils/index.d.ts +20 -9
  31. package/dist/utilities/cssScopeUtils/index.d.ts.map +1 -1
  32. package/dist/utilities/cssScopeUtils/index.js +22 -11
  33. package/dist/utilities/cssScopeUtils/index.js.map +1 -1
  34. package/dist/utilities/renderUtils/index.cjs +36 -7
  35. package/dist/utilities/renderUtils/index.cjs.map +1 -1
  36. package/dist/utilities/renderUtils/index.d.ts +23 -2
  37. package/dist/utilities/renderUtils/index.d.ts.map +1 -1
  38. package/dist/utilities/renderUtils/index.js +35 -8
  39. package/dist/utilities/renderUtils/index.js.map +1 -1
  40. package/package.json +2 -2
@@ -10,12 +10,20 @@
10
10
  * [`postcss-prefix-selector`](https://www.npmjs.com/package/postcss-prefix-selector),
11
11
  * consolidating the scoping rules every consumer would otherwise hand-copy (and drift on):
12
12
  * scoping `:root`/`html` so `@theme` tokens and base typography cascade only within the
13
- * subtree, leaving `:host` and `@keyframes` steps alone, never double-prefixing, and
14
- * optionally scoping `body` resets or letting the scope root element match class selectors.
13
+ * subtree, leaving `:host` and `@keyframes` steps alone, never double-prefixing, letting the scope
14
+ * root element itself match class and attribute selectors (`matchRootElement`, on by default), and
15
+ * optionally scoping `body` resets.
15
16
  *
16
17
  * This is a pure function with no Node or DOM dependency, so it runs cleanly inside a
17
18
  * `postcss.config.mjs`.
18
19
  *
20
+ * **The scope must be exactly one selector that is unique to this app**, and the app must
21
+ * render it itself — `UIProvider`'s `scopeId` stamps `data-mfe-scope` on the themed root for
22
+ * exactly this. Never scope to a host container id (`#flipdish-micro-frontend`) or a union of
23
+ * ids (`:is(#a, #b)`): the host mounts other apps in those containers, so every rule leaks
24
+ * into them and the last-loaded bundle wins (`.text-xl` from one app beat `lg:text-display-xs`
25
+ * in another).
26
+ *
19
27
  * Why PostCSS (not Tailwind's own `important(#selector)`): Tailwind v4's `important(...)`
20
28
  * syntax emits non-standard `@media important(...)` blocks that lightningcss can't parse
21
29
  * during minification, so scoping is done as a PostCSS pass over Tailwind's output instead.
@@ -26,7 +34,8 @@
26
34
  * import prefixSelector from 'postcss-prefix-selector';
27
35
  * import { createScopedPrefixTransform } from '@flipdish/ui-library/utilities/cssScopeUtils';
28
36
  *
29
- * const SCOPE = '#flipdish-micro-frontend';
37
+ * // Your Portal microFrontendWindowName; must match <UIProvider scopeId="sale-service">.
38
+ * const SCOPE = '[data-mfe-scope="sale-service"]';
30
39
  *
31
40
  * export default {
32
41
  * plugins: [
@@ -46,14 +55,15 @@ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
46
55
  * Builds the `transform` callback for `postcss-prefix-selector` that scopes Tailwind v4 output
47
56
  * under `scopeSelector`.
48
57
  *
49
- * @param scopeSelector The selector every rule is scoped under, such as
50
- * `'#flipdish-micro-frontend'`; must match the `prefix` passed to `postcss-prefix-selector`.
58
+ * @param scopeSelector The single selector every rule is scoped under, such as
59
+ * `'[data-mfe-scope="sale-service"]'`; must match the `prefix` passed to `postcss-prefix-selector`
60
+ * and must be unique to this app on the page (never a host container id or a union of ids).
51
61
  * @param options Behavioural toggles; see `ScopedPrefixTransformOptions`.
52
62
  * @returns The `(prefix, selector, prefixedSelector, filePath?) => string` transform to pass
53
63
  * to the plugin.
54
64
  */
55
65
  function createScopedPrefixTransform(scopeSelector, options = {}) {
56
- const { shouldScope, scopeBody = false, matchRootElement = false } = options;
66
+ const { shouldScope, scopeBody = false, matchRootElement = true } = options;
57
67
  const normalisedScopeSelector = scopeSelector.trim();
58
68
  if (!normalisedScopeSelector) {
59
69
  throw new Error('createScopedPrefixTransform: `scopeSelector` must be a non-empty selector.');
@@ -91,13 +101,14 @@ function createScopedPrefixTransform(scopeSelector, options = {}) {
91
101
  if (KEYFRAME_STEP.test(selector.trim())) {
92
102
  return selector;
93
103
  }
94
- // Class selectors: optionally also match the scope root element itself via a compound
95
- // selector (`#scope.flex-1, #scope .flex-1`), so a utility on the mount node applies too.
96
- if (matchRootElement && selector.startsWith('.')) {
104
+ // Class and attribute selectors: also match the scope root itself via a compound selector
105
+ // (`[data-mfe-scope="x"][data-theme="dark"], [data-mfe-scope="x"] [data-theme="dark"]`); the
106
+ // scope root is the themed root, so the dark-token rule only reaches it this way.
107
+ if (matchRootElement && (selector.startsWith('.') || selector.startsWith('['))) {
97
108
  return `${prefix}${selector}, ${prefixedSelector}`;
98
109
  }
99
- // Everything else (`*`, `::before`, `::after`, `[hidden]`, element selectors, …) gets the
100
- // standard descendant-scoped selector.
110
+ // Everything else (`*`, `::before`, `::after`, element selectors, …) gets the standard
111
+ // descendant-scoped selector.
101
112
  return prefixedSelector;
102
113
  };
103
114
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/utilities/cssScopeUtils/index.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCG;AA4BH;AACA,MAAM,aAAa,GAAG,0BAA0B;AAEhD;AACA,MAAM,YAAY,GAAG,CAAC,KAAa,KAAa,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;AAE5F;;;;;;;;;AASG;SACa,2BAA2B,CACzC,aAAqB,EACrB,UAAwC,EAAE,EAAA;AAE1C,IAAA,MAAM,EAAE,WAAW,EAAE,SAAS,GAAG,KAAK,EAAE,gBAAgB,GAAG,KAAK,EAAE,GAAG,OAAO;AAE5E,IAAA,MAAM,uBAAuB,GAAG,aAAa,CAAC,IAAI,EAAE;IACpD,IAAI,CAAC,uBAAuB,EAAE;AAC5B,QAAA,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC;IAC/F;;;;;AAMA,IAAA,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,CAAA,CAAA,EAAI,YAAY,CAAC,uBAAuB,CAAC,CAAA,qBAAA,CAAuB,CAAC;IAElG,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,KAAI;;QAEtD,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE;AACzC,YAAA,OAAO,QAAQ;QACjB;;QAGA,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE;AAC5C,YAAA,OAAO,QAAQ;QACjB;;;;QAKA,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM,EAAE;AAC/C,YAAA,OAAO,MAAM;QACf;;AAGA,QAAA,IAAI,QAAQ,KAAK,OAAO,EAAE;AACxB,YAAA,OAAO,QAAQ;QACjB;;;AAIA,QAAA,IAAI,QAAQ,KAAK,MAAM,EAAE;YACvB,OAAO,SAAS,GAAG,MAAM,GAAG,QAAQ;QACtC;;QAGA,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE;AACvC,YAAA,OAAO,QAAQ;QACjB;;;QAIA,IAAI,gBAAgB,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAChD,YAAA,OAAO,GAAG,MAAM,CAAA,EAAG,QAAQ,CAAA,EAAA,EAAK,gBAAgB,EAAE;QACpD;;;AAIA,QAAA,OAAO,gBAAgB;AACzB,IAAA,CAAC;AACH;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/utilities/cssScopeUtils/index.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDG;AA6BH;AACA,MAAM,aAAa,GAAG,0BAA0B;AAEhD;AACA,MAAM,YAAY,GAAG,CAAC,KAAa,KAAa,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;AAE5F;;;;;;;;;;AAUG;SACa,2BAA2B,CACzC,aAAqB,EACrB,UAAwC,EAAE,EAAA;AAE1C,IAAA,MAAM,EAAE,WAAW,EAAE,SAAS,GAAG,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAAE,GAAG,OAAO;AAE3E,IAAA,MAAM,uBAAuB,GAAG,aAAa,CAAC,IAAI,EAAE;IACpD,IAAI,CAAC,uBAAuB,EAAE;AAC5B,QAAA,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC;IAC/F;;;;;AAMA,IAAA,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,CAAA,CAAA,EAAI,YAAY,CAAC,uBAAuB,CAAC,CAAA,qBAAA,CAAuB,CAAC;IAElG,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,KAAI;;QAEtD,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE;AACzC,YAAA,OAAO,QAAQ;QACjB;;QAGA,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE;AAC5C,YAAA,OAAO,QAAQ;QACjB;;;;QAKA,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM,EAAE;AAC/C,YAAA,OAAO,MAAM;QACf;;AAGA,QAAA,IAAI,QAAQ,KAAK,OAAO,EAAE;AACxB,YAAA,OAAO,QAAQ;QACjB;;;AAIA,QAAA,IAAI,QAAQ,KAAK,MAAM,EAAE;YACvB,OAAO,SAAS,GAAG,MAAM,GAAG,QAAQ;QACtC;;QAGA,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE;AACvC,YAAA,OAAO,QAAQ;QACjB;;;;AAKA,QAAA,IAAI,gBAAgB,KAAK,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE;AAC9E,YAAA,OAAO,GAAG,MAAM,CAAA,EAAG,QAAQ,CAAA,EAAA,EAAK,gBAAgB,EAAE;QACpD;;;AAIA,QAAA,OAAO,gBAAgB;AACzB,IAAA,CAAC;AACH;;"}
@@ -43,18 +43,45 @@ const isProductionBuild = () => {
43
43
  const viteEnv = undefined;
44
44
  return viteEnv?.PROD === true || viteEnv?.MODE === 'production';
45
45
  };
46
+ /** Id of the container Portal mounts page-level micro-frontends into; the lookup of last resort. */
47
+ const DEFAULT_MICRO_FRONTEND_CONTAINER_ID = 'flipdish-micro-frontend';
48
+ let microFrontendContainer = null;
46
49
  /**
47
- * Reads an attribute from the `#flipdish-micro-frontend` container Portal mounts the app into.
50
+ * Registers the container the host mounted this app into, so `getMicroFrontendAttribute` and the
51
+ * id getters read from it instead of `#flipdish-micro-frontend`. Call it first thing in the mount
52
+ * entry the host invokes, before anything reads `getAppId()` or `data-portal-base-url`. A resolver
53
+ * is accepted for containers that do not exist yet; pass `null` to clear the registration.
48
54
  *
49
- * @param key The attribute name, such as `data-app-id`.
50
- * @returns Its value, or an empty string when there is no document or no such attribute.
55
+ * @param container The mount element, a callback resolving it on each read, or `null` to fall
56
+ * back to `#flipdish-micro-frontend`.
57
+ * @returns Nothing.
51
58
  */
52
- const getMicroFrontendAttribute = (key) => {
59
+ const setMicroFrontendContainer = (container) => {
60
+ microFrontendContainer = container;
61
+ };
62
+ /**
63
+ * Resolves the container attributes are read from: the registered container while it is in the
64
+ * document, otherwise `#flipdish-micro-frontend`.
65
+ *
66
+ * @returns The container element, or `null` when neither source yields one.
67
+ */
68
+ const getMicroFrontendContainer = () => {
53
69
  if (typeof document === 'undefined') {
54
- return '';
70
+ return null;
55
71
  }
56
- const microFrontendDiv = document.getElementById('flipdish-micro-frontend');
57
- return microFrontendDiv?.getAttribute(key) || '';
72
+ const registered = typeof microFrontendContainer === 'function' ? microFrontendContainer() : microFrontendContainer;
73
+ // A registration left behind after the host removed the container must not serve stale attributes.
74
+ return registered?.isConnected ? registered : document.getElementById(DEFAULT_MICRO_FRONTEND_CONTAINER_ID);
75
+ };
76
+ /**
77
+ * Reads an attribute from the container the host mounted the app into: the one registered with
78
+ * `setMicroFrontendContainer`, else `#flipdish-micro-frontend`.
79
+ *
80
+ * @param key The attribute name, such as `data-app-id`.
81
+ * @returns Its value, or an empty string when there is no document, no container or no such attribute.
82
+ */
83
+ const getMicroFrontendAttribute = (key) => {
84
+ return getMicroFrontendContainer()?.getAttribute(key) || '';
58
85
  };
59
86
  /**
60
87
  * Reads the app id: the `VITE_APPID_OVERRIDE` environment variable first, then the container's
@@ -115,7 +142,9 @@ exports.getBrandId = getBrandId;
115
142
  exports.getEnvironmentVariable = getEnvironmentVariable;
116
143
  exports.getIsFlipdishStaff = getIsFlipdishStaff;
117
144
  exports.getMicroFrontendAttribute = getMicroFrontendAttribute;
145
+ exports.getMicroFrontendContainer = getMicroFrontendContainer;
118
146
  exports.getOrgId = getOrgId;
119
147
  exports.isProductionBuild = isProductionBuild;
120
148
  exports.lazyWithRetry = lazyWithRetry;
149
+ exports.setMicroFrontendContainer = setMicroFrontendContainer;
121
150
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/utilities/renderUtils/index.ts"],"sourcesContent":[null],"names":["lazy","importWithRetry"],"mappings":";;;;;AAIA;;;;;;AAMG;AACI,MAAM,sBAAsB,GAAG,CAAC,GAAW,KAAY;;AAE5D,IAAA,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;AACzF,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAW;IACnC;;;;;;AAMA,IAAA,MAAM,OAAO,GAAI,SAA6E;AAC9F,IAAA,OAAO,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE;AAC7B;AAEA;;;;;;;;AAQG;AACI,MAAM,iBAAiB,GAAG,MAAc;AAC7C,IAAA,IAAI;AACF,QAAA,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ;AAAE,YAAA,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;IAC5F;AAAE,IAAA,MAAM;;IAER;AACA,IAAA,MAAM,OAAO,GAAI,SAA4E;IAC7F,OAAO,OAAO,EAAE,IAAI,KAAK,IAAI,IAAI,OAAO,EAAE,IAAI,KAAK,YAAY;AACjE;AAEA;;;;;AAKG;AACI,MAAM,yBAAyB,GAAG,CAAC,GAAW,KAAY;AAC/D,IAAA,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;AACnC,QAAA,OAAO,EAAE;IACX;IACA,MAAM,gBAAgB,GAAG,QAAQ,CAAC,cAAc,CAAC,yBAAyB,CAAC;IAC3E,OAAO,gBAAgB,EAAE,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE;AAClD;AAEA;;;;;;AAMG;AACI,MAAM,QAAQ,GAAG,MAAa;AACnC,IAAA,OAAO,sBAAsB,CAAC,qBAAqB,CAAC,IAAI,yBAAyB,CAAC,aAAa,CAAC,IAAI,yBAAyB,CAAC,YAAY,CAAC;AAC7I;AAEA;;;;;;AAMG;AACI,MAAM,QAAQ,GAAG,MAAa;AACnC,IAAA,OAAO,sBAAsB,CAAC,qBAAqB,CAAC,IAAI,yBAAyB,CAAC,aAAa,CAAC,IAAI,yBAAyB,CAAC,YAAY,CAAC;AAC7I;AAEA;;;;;;AAMG;AACI,MAAM,UAAU,GAAG,MAAa;AACrC,IAAA,OAAO,sBAAsB,CAAC,uBAAuB,CAAC,IAAI,yBAAyB,CAAC,eAAe,CAAC,IAAI,yBAAyB,CAAC,cAAc,CAAC;AACnJ;AAEA;;;;;;;AAOG;AACI,MAAM,kBAAkB,GAAG,MAAc;AAC9C,IAAA,MAAM,WAAW,GACf,sBAAsB,CAAC,8BAA8B,CAAC;QACtD,yBAAyB,CAAC,wBAAwB,CAAC;QACnD,yBAAyB,CAAC,sBAAsB,CAAC;AACnD,IAAA,OAAO,WAAW,EAAE,QAAQ,EAAE,KAAK,MAAM;AAC3C;AAEA;;;;;;AAMG;AACH;AACO,MAAM,aAAa,GAAG,CAAC,eAA0B,KAAKA,UAAI,CAAC,MAAMC,qCAAe,CAAC,eAAe,CAAC;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/utilities/renderUtils/index.ts"],"sourcesContent":[null],"names":["lazy","importWithRetry"],"mappings":";;;;;AAIA;;;;;;AAMG;AACI,MAAM,sBAAsB,GAAG,CAAC,GAAW,KAAY;;AAE5D,IAAA,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;AACzF,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAW;IACnC;;;;;;AAMA,IAAA,MAAM,OAAO,GAAI,SAA6E;AAC9F,IAAA,OAAO,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE;AAC7B;AAEA;;;;;;;;AAQG;AACI,MAAM,iBAAiB,GAAG,MAAc;AAC7C,IAAA,IAAI;AACF,QAAA,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ;AAAE,YAAA,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;IAC5F;AAAE,IAAA,MAAM;;IAER;AACA,IAAA,MAAM,OAAO,GAAI,SAA4E;IAC7F,OAAO,OAAO,EAAE,IAAI,KAAK,IAAI,IAAI,OAAO,EAAE,IAAI,KAAK,YAAY;AACjE;AAEA;AACA,MAAM,mCAAmC,GAAG,yBAAyB;AAIrE,IAAI,sBAAsB,GAA2B,IAAI;AAEzD;;;;;;;;;AASG;AACI,MAAM,yBAAyB,GAAG,CAAC,SAAiC,KAAU;IACnF,sBAAsB,GAAG,SAAS;AACpC;AAEA;;;;;AAKG;AACI,MAAM,yBAAyB,GAAG,MAAyB;AAChE,IAAA,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;AACnC,QAAA,OAAO,IAAI;IACb;AACA,IAAA,MAAM,UAAU,GAAG,OAAO,sBAAsB,KAAK,UAAU,GAAG,sBAAsB,EAAE,GAAG,sBAAsB;;AAEnH,IAAA,OAAO,UAAU,EAAE,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,mCAAmC,CAAC;AAC5G;AAEA;;;;;;AAMG;AACI,MAAM,yBAAyB,GAAG,CAAC,GAAW,KAAY;IAC/D,OAAO,yBAAyB,EAAE,EAAE,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE;AAC7D;AAEA;;;;;;AAMG;AACI,MAAM,QAAQ,GAAG,MAAa;AACnC,IAAA,OAAO,sBAAsB,CAAC,qBAAqB,CAAC,IAAI,yBAAyB,CAAC,aAAa,CAAC,IAAI,yBAAyB,CAAC,YAAY,CAAC;AAC7I;AAEA;;;;;;AAMG;AACI,MAAM,QAAQ,GAAG,MAAa;AACnC,IAAA,OAAO,sBAAsB,CAAC,qBAAqB,CAAC,IAAI,yBAAyB,CAAC,aAAa,CAAC,IAAI,yBAAyB,CAAC,YAAY,CAAC;AAC7I;AAEA;;;;;;AAMG;AACI,MAAM,UAAU,GAAG,MAAa;AACrC,IAAA,OAAO,sBAAsB,CAAC,uBAAuB,CAAC,IAAI,yBAAyB,CAAC,eAAe,CAAC,IAAI,yBAAyB,CAAC,cAAc,CAAC;AACnJ;AAEA;;;;;;;AAOG;AACI,MAAM,kBAAkB,GAAG,MAAc;AAC9C,IAAA,MAAM,WAAW,GACf,sBAAsB,CAAC,8BAA8B,CAAC;QACtD,yBAAyB,CAAC,wBAAwB,CAAC;QACnD,yBAAyB,CAAC,sBAAsB,CAAC;AACnD,IAAA,OAAO,WAAW,EAAE,QAAQ,EAAE,KAAK,MAAM;AAC3C;AAEA;;;;;;AAMG;AACH;AACO,MAAM,aAAa,GAAG,CAAC,eAA0B,KAAKA,UAAI,CAAC,MAAMC,qCAAe,CAAC,eAAe,CAAC;;;;;;;;;;;"}
@@ -16,11 +16,31 @@ export declare const getEnvironmentVariable: (key: string) => string;
16
16
  * @returns `true` in a production build; `false` in development, tests and when nothing says otherwise.
17
17
  */
18
18
  export declare const isProductionBuild: () => boolean;
19
+ type MicroFrontendContainer = HTMLElement | (() => HTMLElement | null) | null;
19
20
  /**
20
- * Reads an attribute from the `#flipdish-micro-frontend` container Portal mounts the app into.
21
+ * Registers the container the host mounted this app into, so `getMicroFrontendAttribute` and the
22
+ * id getters read from it instead of `#flipdish-micro-frontend`. Call it first thing in the mount
23
+ * entry the host invokes, before anything reads `getAppId()` or `data-portal-base-url`. A resolver
24
+ * is accepted for containers that do not exist yet; pass `null` to clear the registration.
25
+ *
26
+ * @param container The mount element, a callback resolving it on each read, or `null` to fall
27
+ * back to `#flipdish-micro-frontend`.
28
+ * @returns Nothing.
29
+ */
30
+ export declare const setMicroFrontendContainer: (container: MicroFrontendContainer) => void;
31
+ /**
32
+ * Resolves the container attributes are read from: the registered container while it is in the
33
+ * document, otherwise `#flipdish-micro-frontend`.
34
+ *
35
+ * @returns The container element, or `null` when neither source yields one.
36
+ */
37
+ export declare const getMicroFrontendContainer: () => HTMLElement | null;
38
+ /**
39
+ * Reads an attribute from the container the host mounted the app into: the one registered with
40
+ * `setMicroFrontendContainer`, else `#flipdish-micro-frontend`.
21
41
  *
22
42
  * @param key The attribute name, such as `data-app-id`.
23
- * @returns Its value, or an empty string when there is no document or no such attribute.
43
+ * @returns Its value, or an empty string when there is no document, no container or no such attribute.
24
44
  */
25
45
  export declare const getMicroFrontendAttribute: (key: string) => string;
26
46
  /**
@@ -64,4 +84,5 @@ export declare const getIsFlipdishStaff: () => boolean;
64
84
  * @returns A lazy component to render inside `Suspense`.
65
85
  */
66
86
  export declare const lazyWithRetry: (componentImport: () => any) => import("react").LazyExoticComponent<import("react").ComponentType<any>>;
87
+ export {};
67
88
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utilities/renderUtils/index.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,KAAK,MAAM,KAAG,MAYpD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,QAAO,OAQpC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,KAAK,MAAM,KAAG,MAMvD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,QAAO,MAE3B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,QAAO,MAE3B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,QAAO,MAE7B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAO,OAMrC,CAAC;AAEF;;;;;;GAMG;AAEH,eAAO,MAAM,aAAa,GAAI,iBAAiB,MAAM,GAAG,4EAAiD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utilities/renderUtils/index.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,KAAK,MAAM,KAAG,MAYpD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,QAAO,OAQpC,CAAC;AAKF,KAAK,sBAAsB,GAAG,WAAW,GAAG,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AAI9E;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,GAAI,WAAW,sBAAsB,KAAG,IAE7E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,QAAO,WAAW,GAAG,IAO1D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,GAAI,KAAK,MAAM,KAAG,MAEvD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,QAAO,MAE3B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,QAAO,MAE3B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,QAAO,MAE7B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAO,OAMrC,CAAC;AAEF;;;;;;GAMG;AAEH,eAAO,MAAM,aAAa,GAAI,iBAAiB,MAAM,GAAG,4EAAiD,CAAC"}
@@ -41,18 +41,45 @@ const isProductionBuild = () => {
41
41
  const viteEnv = import.meta.env;
42
42
  return viteEnv?.PROD === true || viteEnv?.MODE === 'production';
43
43
  };
44
+ /** Id of the container Portal mounts page-level micro-frontends into; the lookup of last resort. */
45
+ const DEFAULT_MICRO_FRONTEND_CONTAINER_ID = 'flipdish-micro-frontend';
46
+ let microFrontendContainer = null;
44
47
  /**
45
- * Reads an attribute from the `#flipdish-micro-frontend` container Portal mounts the app into.
48
+ * Registers the container the host mounted this app into, so `getMicroFrontendAttribute` and the
49
+ * id getters read from it instead of `#flipdish-micro-frontend`. Call it first thing in the mount
50
+ * entry the host invokes, before anything reads `getAppId()` or `data-portal-base-url`. A resolver
51
+ * is accepted for containers that do not exist yet; pass `null` to clear the registration.
46
52
  *
47
- * @param key The attribute name, such as `data-app-id`.
48
- * @returns Its value, or an empty string when there is no document or no such attribute.
53
+ * @param container The mount element, a callback resolving it on each read, or `null` to fall
54
+ * back to `#flipdish-micro-frontend`.
55
+ * @returns Nothing.
49
56
  */
50
- const getMicroFrontendAttribute = (key) => {
57
+ const setMicroFrontendContainer = (container) => {
58
+ microFrontendContainer = container;
59
+ };
60
+ /**
61
+ * Resolves the container attributes are read from: the registered container while it is in the
62
+ * document, otherwise `#flipdish-micro-frontend`.
63
+ *
64
+ * @returns The container element, or `null` when neither source yields one.
65
+ */
66
+ const getMicroFrontendContainer = () => {
51
67
  if (typeof document === 'undefined') {
52
- return '';
68
+ return null;
53
69
  }
54
- const microFrontendDiv = document.getElementById('flipdish-micro-frontend');
55
- return microFrontendDiv?.getAttribute(key) || '';
70
+ const registered = typeof microFrontendContainer === 'function' ? microFrontendContainer() : microFrontendContainer;
71
+ // A registration left behind after the host removed the container must not serve stale attributes.
72
+ return registered?.isConnected ? registered : document.getElementById(DEFAULT_MICRO_FRONTEND_CONTAINER_ID);
73
+ };
74
+ /**
75
+ * Reads an attribute from the container the host mounted the app into: the one registered with
76
+ * `setMicroFrontendContainer`, else `#flipdish-micro-frontend`.
77
+ *
78
+ * @param key The attribute name, such as `data-app-id`.
79
+ * @returns Its value, or an empty string when there is no document, no container or no such attribute.
80
+ */
81
+ const getMicroFrontendAttribute = (key) => {
82
+ return getMicroFrontendContainer()?.getAttribute(key) || '';
56
83
  };
57
84
  /**
58
85
  * Reads the app id: the `VITE_APPID_OVERRIDE` environment variable first, then the container's
@@ -108,5 +135,5 @@ const getIsFlipdishStaff = () => {
108
135
  // biome-ignore lint/suspicious/noExplicitAny: dynamic import factory shape isn't expressible without `any`; preserved from portal-library implementation
109
136
  const lazyWithRetry = (componentImport) => lazy(() => importWithRetry(componentImport));
110
137
 
111
- export { getAppId, getBrandId, getEnvironmentVariable, getIsFlipdishStaff, getMicroFrontendAttribute, getOrgId, isProductionBuild, lazyWithRetry };
138
+ export { getAppId, getBrandId, getEnvironmentVariable, getIsFlipdishStaff, getMicroFrontendAttribute, getMicroFrontendContainer, getOrgId, isProductionBuild, lazyWithRetry, setMicroFrontendContainer };
112
139
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/utilities/renderUtils/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAIA;;;;;;AAMG;AACI,MAAM,sBAAsB,GAAG,CAAC,GAAW,KAAY;;AAE5D,IAAA,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;AACzF,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAW;IACnC;;;;;;AAMA,IAAA,MAAM,OAAO,GAAI,MAAM,CAAC,IAAkE,CAAC,GAAG;AAC9F,IAAA,OAAO,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE;AAC7B;AAEA;;;;;;;;AAQG;AACI,MAAM,iBAAiB,GAAG,MAAc;AAC7C,IAAA,IAAI;AACF,QAAA,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ;AAAE,YAAA,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;IAC5F;AAAE,IAAA,MAAM;;IAER;AACA,IAAA,MAAM,OAAO,GAAI,MAAM,CAAC,IAAiE,CAAC,GAAG;IAC7F,OAAO,OAAO,EAAE,IAAI,KAAK,IAAI,IAAI,OAAO,EAAE,IAAI,KAAK,YAAY;AACjE;AAEA;;;;;AAKG;AACI,MAAM,yBAAyB,GAAG,CAAC,GAAW,KAAY;AAC/D,IAAA,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;AACnC,QAAA,OAAO,EAAE;IACX;IACA,MAAM,gBAAgB,GAAG,QAAQ,CAAC,cAAc,CAAC,yBAAyB,CAAC;IAC3E,OAAO,gBAAgB,EAAE,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE;AAClD;AAEA;;;;;;AAMG;AACI,MAAM,QAAQ,GAAG,MAAa;AACnC,IAAA,OAAO,sBAAsB,CAAC,qBAAqB,CAAC,IAAI,yBAAyB,CAAC,aAAa,CAAC,IAAI,yBAAyB,CAAC,YAAY,CAAC;AAC7I;AAEA;;;;;;AAMG;AACI,MAAM,QAAQ,GAAG,MAAa;AACnC,IAAA,OAAO,sBAAsB,CAAC,qBAAqB,CAAC,IAAI,yBAAyB,CAAC,aAAa,CAAC,IAAI,yBAAyB,CAAC,YAAY,CAAC;AAC7I;AAEA;;;;;;AAMG;AACI,MAAM,UAAU,GAAG,MAAa;AACrC,IAAA,OAAO,sBAAsB,CAAC,uBAAuB,CAAC,IAAI,yBAAyB,CAAC,eAAe,CAAC,IAAI,yBAAyB,CAAC,cAAc,CAAC;AACnJ;AAEA;;;;;;;AAOG;AACI,MAAM,kBAAkB,GAAG,MAAc;AAC9C,IAAA,MAAM,WAAW,GACf,sBAAsB,CAAC,8BAA8B,CAAC;QACtD,yBAAyB,CAAC,wBAAwB,CAAC;QACnD,yBAAyB,CAAC,sBAAsB,CAAC;AACnD,IAAA,OAAO,WAAW,EAAE,QAAQ,EAAE,KAAK,MAAM;AAC3C;AAEA;;;;;;AAMG;AACH;AACO,MAAM,aAAa,GAAG,CAAC,eAA0B,KAAK,IAAI,CAAC,MAAM,eAAe,CAAC,eAAe,CAAC;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/utilities/renderUtils/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAIA;;;;;;AAMG;AACI,MAAM,sBAAsB,GAAG,CAAC,GAAW,KAAY;;AAE5D,IAAA,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE;AACzF,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAW;IACnC;;;;;;AAMA,IAAA,MAAM,OAAO,GAAI,MAAM,CAAC,IAAkE,CAAC,GAAG;AAC9F,IAAA,OAAO,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE;AAC7B;AAEA;;;;;;;;AAQG;AACI,MAAM,iBAAiB,GAAG,MAAc;AAC7C,IAAA,IAAI;AACF,QAAA,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ;AAAE,YAAA,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;IAC5F;AAAE,IAAA,MAAM;;IAER;AACA,IAAA,MAAM,OAAO,GAAI,MAAM,CAAC,IAAiE,CAAC,GAAG;IAC7F,OAAO,OAAO,EAAE,IAAI,KAAK,IAAI,IAAI,OAAO,EAAE,IAAI,KAAK,YAAY;AACjE;AAEA;AACA,MAAM,mCAAmC,GAAG,yBAAyB;AAIrE,IAAI,sBAAsB,GAA2B,IAAI;AAEzD;;;;;;;;;AASG;AACI,MAAM,yBAAyB,GAAG,CAAC,SAAiC,KAAU;IACnF,sBAAsB,GAAG,SAAS;AACpC;AAEA;;;;;AAKG;AACI,MAAM,yBAAyB,GAAG,MAAyB;AAChE,IAAA,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;AACnC,QAAA,OAAO,IAAI;IACb;AACA,IAAA,MAAM,UAAU,GAAG,OAAO,sBAAsB,KAAK,UAAU,GAAG,sBAAsB,EAAE,GAAG,sBAAsB;;AAEnH,IAAA,OAAO,UAAU,EAAE,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,mCAAmC,CAAC;AAC5G;AAEA;;;;;;AAMG;AACI,MAAM,yBAAyB,GAAG,CAAC,GAAW,KAAY;IAC/D,OAAO,yBAAyB,EAAE,EAAE,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE;AAC7D;AAEA;;;;;;AAMG;AACI,MAAM,QAAQ,GAAG,MAAa;AACnC,IAAA,OAAO,sBAAsB,CAAC,qBAAqB,CAAC,IAAI,yBAAyB,CAAC,aAAa,CAAC,IAAI,yBAAyB,CAAC,YAAY,CAAC;AAC7I;AAEA;;;;;;AAMG;AACI,MAAM,QAAQ,GAAG,MAAa;AACnC,IAAA,OAAO,sBAAsB,CAAC,qBAAqB,CAAC,IAAI,yBAAyB,CAAC,aAAa,CAAC,IAAI,yBAAyB,CAAC,YAAY,CAAC;AAC7I;AAEA;;;;;;AAMG;AACI,MAAM,UAAU,GAAG,MAAa;AACrC,IAAA,OAAO,sBAAsB,CAAC,uBAAuB,CAAC,IAAI,yBAAyB,CAAC,eAAe,CAAC,IAAI,yBAAyB,CAAC,cAAc,CAAC;AACnJ;AAEA;;;;;;;AAOG;AACI,MAAM,kBAAkB,GAAG,MAAc;AAC9C,IAAA,MAAM,WAAW,GACf,sBAAsB,CAAC,8BAA8B,CAAC;QACtD,yBAAyB,CAAC,wBAAwB,CAAC;QACnD,yBAAyB,CAAC,sBAAsB,CAAC;AACnD,IAAA,OAAO,WAAW,EAAE,QAAQ,EAAE,KAAK,MAAM;AAC3C;AAEA;;;;;;AAMG;AACH;AACO,MAAM,aAAa,GAAG,CAAC,eAA0B,KAAK,IAAI,CAAC,MAAM,eAAe,CAAC,eAAe,CAAC;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flipdish/ui-library",
3
- "version": "0.38.0",
3
+ "version": "0.39.1",
4
4
  "description": "Flipdish Design System — atomic-design component library (Tailwind v4 + UntitledUI + React Aria).",
5
5
  "type": "module",
6
6
  "imports": {
@@ -90,7 +90,7 @@
90
90
  }
91
91
  },
92
92
  "dependencies": {
93
- "@flipdish/ui-icons": "^0.6.0",
93
+ "@flipdish/ui-icons": "^0.7.0",
94
94
  "@floating-ui/dom": "^1.7.6",
95
95
  "@internationalized/date": "^3.12.2",
96
96
  "@react-aria/focus": "^3.22.1",