@flamingo-stack/openframe-frontend-core 0.0.404 → 0.0.405-snapshot.20260711081601

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 (148) hide show
  1. package/dist/{chunk-HBO2DMX4.js → chunk-3KZXOLFK.js} +3 -3
  2. package/dist/{chunk-RNKXG55J.js → chunk-6WMVBCNA.js} +4 -4
  3. package/dist/{chunk-A636Y7GU.js → chunk-7RVSGGO6.js} +5 -5
  4. package/dist/{chunk-YXOWUHGQ.js → chunk-AYFWYOL6.js} +6 -6
  5. package/dist/{chunk-GA5AN24T.cjs → chunk-BX3R44MR.cjs} +2 -2
  6. package/dist/chunk-BX3R44MR.cjs.map +1 -0
  7. package/dist/{chunk-GYFUGMNM.js → chunk-C3NPMZBI.js} +2 -2
  8. package/dist/{chunk-J4XR6YYZ.cjs → chunk-CCIBZ7TO.cjs} +10 -6
  9. package/dist/chunk-CCIBZ7TO.cjs.map +1 -0
  10. package/dist/{chunk-6MO5HF6P.cjs → chunk-CF3LBCNI.cjs} +32 -32
  11. package/dist/{chunk-6MO5HF6P.cjs.map → chunk-CF3LBCNI.cjs.map} +1 -1
  12. package/dist/{chunk-S4ZHBKGS.cjs → chunk-COERBDG4.cjs} +73 -73
  13. package/dist/{chunk-S4ZHBKGS.cjs.map → chunk-COERBDG4.cjs.map} +1 -1
  14. package/dist/{chunk-DH6HTYOV.js → chunk-E6YHDT3D.js} +6 -2
  15. package/dist/chunk-E6YHDT3D.js.map +1 -0
  16. package/dist/{chunk-OJ4HFM3I.cjs → chunk-GNS65HNC.cjs} +18 -18
  17. package/dist/{chunk-OJ4HFM3I.cjs.map → chunk-GNS65HNC.cjs.map} +1 -1
  18. package/dist/{chunk-G4YLKA7O.cjs → chunk-HJJXNMM7.cjs} +5 -5
  19. package/dist/{chunk-G4YLKA7O.cjs.map → chunk-HJJXNMM7.cjs.map} +1 -1
  20. package/dist/{chunk-TBXE5S6P.cjs → chunk-ISYVNPRT.cjs} +40 -40
  21. package/dist/{chunk-TBXE5S6P.cjs.map → chunk-ISYVNPRT.cjs.map} +1 -1
  22. package/dist/{chunk-CRUPO3MR.cjs → chunk-JAPP2F4M.cjs} +93 -93
  23. package/dist/{chunk-CRUPO3MR.cjs.map → chunk-JAPP2F4M.cjs.map} +1 -1
  24. package/dist/{chunk-G3QYCV63.cjs → chunk-LL4QQSAD.cjs} +500 -441
  25. package/dist/chunk-LL4QQSAD.cjs.map +1 -0
  26. package/dist/{chunk-YORONSXG.js → chunk-LSPBPUQM.js} +3 -3
  27. package/dist/{chunk-AMPQKNAX.js → chunk-OATWTTCI.js} +6 -6
  28. package/dist/{chunk-FFWIUNOT.cjs → chunk-P43ZHPM6.cjs} +40 -40
  29. package/dist/{chunk-FFWIUNOT.cjs.map → chunk-P43ZHPM6.cjs.map} +1 -1
  30. package/dist/{chunk-MTBFE3JF.js → chunk-PNJ5LMVK.js} +16 -2
  31. package/dist/chunk-PNJ5LMVK.js.map +1 -0
  32. package/dist/{chunk-R6SMQ2CO.js → chunk-PQN5R5II.js} +6 -6
  33. package/dist/{chunk-Q3AO2QWK.cjs → chunk-QAFRLO5N.cjs} +18 -4
  34. package/dist/chunk-QAFRLO5N.cjs.map +1 -0
  35. package/dist/{chunk-PFQQ5H6G.cjs → chunk-SF4G7M6U.cjs} +19 -19
  36. package/dist/{chunk-PFQQ5H6G.cjs.map → chunk-SF4G7M6U.cjs.map} +1 -1
  37. package/dist/{chunk-TTUQSOBL.js → chunk-SOK32D6C.js} +62 -3
  38. package/dist/chunk-SOK32D6C.js.map +1 -0
  39. package/dist/{chunk-5Z5GXXRU.js → chunk-TFDNJTBX.js} +4 -4
  40. package/dist/{chunk-QXAHXMPD.cjs → chunk-VANFD4FX.cjs} +12 -12
  41. package/dist/{chunk-QXAHXMPD.cjs.map → chunk-VANFD4FX.cjs.map} +1 -1
  42. package/dist/{chunk-KVB7SHXY.cjs → chunk-VIB4SGCD.cjs} +12 -12
  43. package/dist/{chunk-KVB7SHXY.cjs.map → chunk-VIB4SGCD.cjs.map} +1 -1
  44. package/dist/{chunk-M7LIGEAX.cjs → chunk-VZGU4BV6.cjs} +33 -33
  45. package/dist/{chunk-M7LIGEAX.cjs.map → chunk-VZGU4BV6.cjs.map} +1 -1
  46. package/dist/{chunk-HGKWTKW7.js → chunk-WJRPMULP.js} +2 -2
  47. package/dist/chunk-WJRPMULP.js.map +1 -0
  48. package/dist/{chunk-NOWXUQWF.js → chunk-XXG2Z2JT.js} +3 -3
  49. package/dist/{chunk-3I4IZYHM.js → chunk-ZVUR3A33.js} +3 -3
  50. package/dist/components/announcement-bar.d.ts +27 -1
  51. package/dist/components/announcement-bar.d.ts.map +1 -1
  52. package/dist/components/case-studies/index.cjs +10 -10
  53. package/dist/components/case-studies/index.js +4 -4
  54. package/dist/components/chat/index.cjs +4 -4
  55. package/dist/components/chat/index.js +3 -3
  56. package/dist/components/contact/index.cjs +5 -5
  57. package/dist/components/contact/index.js +4 -4
  58. package/dist/components/docs/index.cjs +7 -7
  59. package/dist/components/docs/index.js +6 -6
  60. package/dist/components/embeds/index.cjs +5 -5
  61. package/dist/components/embeds/index.js +4 -4
  62. package/dist/components/faq/index.cjs +6 -6
  63. package/dist/components/faq/index.js +5 -5
  64. package/dist/components/features/index.cjs +4 -4
  65. package/dist/components/features/index.js +3 -3
  66. package/dist/components/help-center-pages/index.cjs +23 -23
  67. package/dist/components/help-center-pages/index.js +14 -14
  68. package/dist/components/index.cjs +274 -299
  69. package/dist/components/index.cjs.map +1 -1
  70. package/dist/components/index.js +110 -135
  71. package/dist/components/index.js.map +1 -1
  72. package/dist/components/navigation/index.cjs +4 -4
  73. package/dist/components/navigation/index.js +3 -3
  74. package/dist/components/onboarding-guides/index.cjs +8 -8
  75. package/dist/components/onboarding-guides/index.js +7 -7
  76. package/dist/components/related-content/index.cjs +6 -6
  77. package/dist/components/related-content/index.js +5 -5
  78. package/dist/components/tickets/index.cjs +7 -7
  79. package/dist/components/tickets/index.js +6 -6
  80. package/dist/components/ui/file-manager/index.cjs +50 -50
  81. package/dist/components/ui/file-manager/index.js +1 -1
  82. package/dist/components/ui/index.cjs +4 -4
  83. package/dist/components/ui/index.js +3 -3
  84. package/dist/hooks/api-hooks.d.ts +0 -4
  85. package/dist/hooks/api-hooks.d.ts.map +1 -1
  86. package/dist/hooks/index.cjs +2 -2
  87. package/dist/hooks/index.js +1 -1
  88. package/dist/hooks/use-self-fetch.d.ts +7 -0
  89. package/dist/hooks/use-self-fetch.d.ts.map +1 -1
  90. package/dist/index.cjs +20 -4
  91. package/dist/index.cjs.map +1 -1
  92. package/dist/index.js +19 -3
  93. package/dist/types/announcement.cjs +5 -0
  94. package/dist/types/announcement.cjs.map +1 -1
  95. package/dist/types/announcement.d.ts +37 -7
  96. package/dist/types/announcement.d.ts.map +1 -1
  97. package/dist/types/announcement.js +5 -1
  98. package/dist/types/announcement.js.map +1 -1
  99. package/dist/types/index.cjs +5 -0
  100. package/dist/types/index.cjs.map +1 -1
  101. package/dist/types/index.js +5 -1
  102. package/dist/types/index.js.map +1 -1
  103. package/dist/utils/announcement-storage.d.ts +39 -7
  104. package/dist/utils/announcement-storage.d.ts.map +1 -1
  105. package/dist/utils/app-config.d.ts.map +1 -1
  106. package/dist/utils/color-analysis.d.ts +13 -0
  107. package/dist/utils/color-analysis.d.ts.map +1 -1
  108. package/dist/utils/index.cjs +58 -1
  109. package/dist/utils/index.cjs.map +1 -1
  110. package/dist/utils/index.d.ts +1 -0
  111. package/dist/utils/index.d.ts.map +1 -1
  112. package/dist/utils/index.js +52 -2
  113. package/dist/utils/index.js.map +1 -1
  114. package/package.json +1 -1
  115. package/src/components/.announcement-bar.md +32 -30
  116. package/src/components/announcement-bar.tsx +227 -182
  117. package/src/components/features/video.tsx +8 -0
  118. package/src/components/ui/button/button.tsx +1 -1
  119. package/src/hooks/.api-hooks.md +1 -4
  120. package/src/hooks/api-hooks.ts +0 -7
  121. package/src/hooks/use-self-fetch.ts +29 -1
  122. package/src/stories/AnnouncementBar.stories.tsx +188 -152
  123. package/src/types/.announcement.md +2 -2
  124. package/src/types/announcement.ts +37 -7
  125. package/src/utils/.announcement-storage.md +19 -24
  126. package/src/utils/announcement-storage.ts +74 -28
  127. package/src/utils/app-config.ts +10 -1
  128. package/src/utils/color-analysis.ts +16 -1
  129. package/src/utils/index.ts +3 -0
  130. package/dist/chunk-DH6HTYOV.js.map +0 -1
  131. package/dist/chunk-G3QYCV63.cjs.map +0 -1
  132. package/dist/chunk-GA5AN24T.cjs.map +0 -1
  133. package/dist/chunk-HGKWTKW7.js.map +0 -1
  134. package/dist/chunk-J4XR6YYZ.cjs.map +0 -1
  135. package/dist/chunk-MTBFE3JF.js.map +0 -1
  136. package/dist/chunk-Q3AO2QWK.cjs.map +0 -1
  137. package/dist/chunk-TTUQSOBL.js.map +0 -1
  138. /package/dist/{chunk-HBO2DMX4.js.map → chunk-3KZXOLFK.js.map} +0 -0
  139. /package/dist/{chunk-RNKXG55J.js.map → chunk-6WMVBCNA.js.map} +0 -0
  140. /package/dist/{chunk-A636Y7GU.js.map → chunk-7RVSGGO6.js.map} +0 -0
  141. /package/dist/{chunk-YXOWUHGQ.js.map → chunk-AYFWYOL6.js.map} +0 -0
  142. /package/dist/{chunk-GYFUGMNM.js.map → chunk-C3NPMZBI.js.map} +0 -0
  143. /package/dist/{chunk-YORONSXG.js.map → chunk-LSPBPUQM.js.map} +0 -0
  144. /package/dist/{chunk-AMPQKNAX.js.map → chunk-OATWTTCI.js.map} +0 -0
  145. /package/dist/{chunk-R6SMQ2CO.js.map → chunk-PQN5R5II.js.map} +0 -0
  146. /package/dist/{chunk-5Z5GXXRU.js.map → chunk-TFDNJTBX.js.map} +0 -0
  147. /package/dist/{chunk-NOWXUQWF.js.map → chunk-XXG2Z2JT.js.map} +0 -0
  148. /package/dist/{chunk-3I4IZYHM.js.map → chunk-ZVUR3A33.js.map} +0 -0
@@ -1,36 +1,82 @@
1
- // Stub for announcement storage
2
- export interface AnnouncementStorageOptions {
3
- key: string;
4
- defaultValue?: any;
1
+ /**
2
+ * Announcement dismissal store.
3
+ *
4
+ * The dismissal COOKIE is the single source of truth: the hub's root layout
5
+ * reads it server-side to decide whether to SSR-seed the bar (no flash for
6
+ * dismissed users), and the client reads it via `isAnnouncementDismissed`.
7
+ * One cookie per platform holding the LAST dismissed announcement id —
8
+ * dismissal is an id-match, never mere cookie presence, so a new announcement
9
+ * always shows after an old one was dismissed, and re-activating an old
10
+ * announcement intentionally re-shows it.
11
+ *
12
+ * The legacy per-id localStorage key (`<platform>-announcement-<id>-dismissed`)
13
+ * is READ-ONLY legacy: consulted only when no cookie exists for the platform,
14
+ * purely as the migration trigger (the bar's mount effect backfills the
15
+ * cookie). New dismissals write the cookie only, so the second store dies out.
16
+ *
17
+ * No `"use client"` directive on purpose — `announcementDismissCookieName` and
18
+ * `isDismissedCookieValue` are pure/isomorphic and imported by the hub's
19
+ * server layout; the DOM-touching helpers guard on `typeof document`.
20
+ */
21
+
22
+ /** Cookie name for a platform's dismissed-announcement id — the ONE home for
23
+ * the encoding, shared by the client writer and the hub's SSR reader. */
24
+ export function announcementDismissCookieName(platform: string): string {
25
+ return `${platform}-announcement-dismissed`
5
26
  }
6
27
 
7
- export function getStoredAnnouncement(key: string): any {
8
- if (typeof window !== 'undefined') {
9
- try {
10
- return JSON.parse(localStorage.getItem(key) || 'null');
11
- } catch {
12
- return null;
13
- }
14
- }
15
- return null;
28
+ /** THE dismissal match rule (id-match, not presence), shared across the
29
+ * server/client boundary. `undefined` id (no active announcement) → false. */
30
+ export function isDismissedCookieValue(
31
+ cookieValue: string | undefined,
32
+ id: string | undefined,
33
+ ): boolean {
34
+ return !!id && cookieValue === id
35
+ }
36
+
37
+ function readCookie(name: string): string | undefined {
38
+ if (typeof document === 'undefined') return undefined
39
+ const match = document.cookie
40
+ .split('; ')
41
+ .find((row) => row.startsWith(`${name}=`))
42
+ return match ? decodeURIComponent(match.slice(name.length + 1)) : undefined
16
43
  }
17
44
 
18
- export function setStoredAnnouncement(key: string, value: any): void {
19
- if (typeof window !== 'undefined') {
20
- try {
21
- localStorage.setItem(key, JSON.stringify(value));
22
- } catch {
23
- // Ignore storage errors
24
- }
45
+ const legacyDismissKey = (platform: string, id: string) =>
46
+ `${platform}-announcement-${id}-dismissed`
47
+
48
+ /** Persist a dismissal: cookie only (1 year). The SSR layout sees it on the
49
+ * next request; localStorage is intentionally NOT written (read-only legacy). */
50
+ export function dismissAnnouncement(platform: string, id: string): void {
51
+ if (typeof document === 'undefined') return
52
+ const name = announcementDismissCookieName(platform)
53
+ document.cookie = `${name}=${encodeURIComponent(id)}; path=/; max-age=31536000; SameSite=Lax`
54
+ }
55
+
56
+ /**
57
+ * Client-side dismissal check — cookie-first: the legacy localStorage key is
58
+ * consulted ONLY when no cookie exists for the platform. Reads browser
59
+ * storage, so callers must invoke it from effects, never during render
60
+ * (a render-time read would desync hydration from the SSR HTML).
61
+ */
62
+ export function isAnnouncementDismissed(platform: string, id: string): boolean {
63
+ if (typeof document === 'undefined') return false
64
+ const cookieValue = readCookie(announcementDismissCookieName(platform))
65
+ if (cookieValue !== undefined) return isDismissedCookieValue(cookieValue, id)
66
+ try {
67
+ return localStorage.getItem(legacyDismissKey(platform, id)) !== null
68
+ } catch {
69
+ return false
25
70
  }
26
71
  }
27
72
 
28
- export function clearStoredAnnouncement(key: string = 'announcement'): void {
29
- if (typeof window !== 'undefined') {
30
- try {
31
- localStorage.removeItem(key);
32
- } catch {
33
- // Ignore storage errors
34
- }
73
+ /** One-time cleanup of pre-refactor storage: the orphaned announcement cache
74
+ * (the old "instant paint" blob) — called from the bar's mount effect. */
75
+ export function clearLegacyAnnouncementCache(platform: string): void {
76
+ if (typeof window === 'undefined') return
77
+ try {
78
+ localStorage.removeItem(`${platform}-announcement-cache`)
79
+ } catch {
80
+ // ignore storage errors
35
81
  }
36
- }
82
+ }
@@ -16,5 +16,14 @@ export function getAppConfig() {
16
16
  }
17
17
 
18
18
  export function getAppType() {
19
- return process.env.NEXT_PUBLIC_APP_TYPE || 'openmsp';
19
+ // The exact `process.env.NEXT_PUBLIC_APP_TYPE` member expression is kept so
20
+ // Next/webpack can statically inline it. The try/catch makes the call safe
21
+ // in non-Next React hosts (Vite/CRA embeds) where `process` does not exist
22
+ // at runtime — those hosts fall back to 'openmsp' or pass an explicit
23
+ // platform where it matters (e.g. AnnouncementBar's `platform` prop).
24
+ try {
25
+ return process.env.NEXT_PUBLIC_APP_TYPE || 'openmsp';
26
+ } catch {
27
+ return 'openmsp';
28
+ }
20
29
  }
@@ -26,7 +26,7 @@ export function hexToRgb(hex: string): [number, number, number] {
26
26
  /**
27
27
  * Calculate relative luminance for contrast calculations
28
28
  */
29
- function getLuminance(rgb: [number, number, number]): number {
29
+ export function getLuminance(rgb: [number, number, number]): number {
30
30
  const [r, g, b] = rgb.map(c => {
31
31
  c = c / 255;
32
32
  return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
@@ -45,6 +45,21 @@ export function getContrastRatio(color1: [number, number, number], color2: [numb
45
45
  return (brightest + 0.05) / (darkest + 0.05);
46
46
  }
47
47
 
48
+ /**
49
+ * Pick the readable foreground shade for an arbitrary background hex — 'dark'
50
+ * when dark text has the better WCAG contrast on it, 'light' otherwise.
51
+ * Callers map the result to an ODS THEME, not to color literals (e.g. the
52
+ * announcement bar scopes its content with .theme-light when the background
53
+ * needs dark-on-light, .theme-dark otherwise — every color then resolves
54
+ * from the active theme's own tokens).
55
+ */
56
+ export function pickReadableTextColor(bgHex: string): 'dark' | 'light' {
57
+ const bg = hexToRgb(bgHex);
58
+ const darkContrast = getContrastRatio(bg, [26, 26, 26]);
59
+ const lightContrast = getContrastRatio(bg, [250, 250, 250]);
60
+ return darkContrast >= lightContrast ? 'dark' : 'light';
61
+ }
62
+
48
63
  /**
49
64
  * Extract dominant color from image canvas
50
65
  */
@@ -85,6 +85,9 @@ export * from './generic-domain-utils'
85
85
  // Color analysis (canvas-based image color extraction)
86
86
  export * from './color-analysis'
87
87
 
88
+ // Announcement dismissal store (cookie SSOT; server-safe name/match helpers)
89
+ export * from './announcement-storage'
90
+
88
91
  // Image-proxy URL builder (pure, runtime-configurable)
89
92
  export {
90
93
  type GetProxiedImageUrlOptions,