@flamingo-stack/openframe-frontend-core 0.0.472 → 0.0.473

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 (97) hide show
  1. package/dist/{chunk-7D5KOJMF.js → chunk-2SPAHQYE.js} +4 -4
  2. package/dist/{chunk-4BUX2F5P.cjs → chunk-4EU6WL5O.cjs} +37 -37
  3. package/dist/{chunk-4BUX2F5P.cjs.map → chunk-4EU6WL5O.cjs.map} +1 -1
  4. package/dist/{chunk-DWQ4L3IB.cjs → chunk-4WHDDAVP.cjs} +31 -31
  5. package/dist/{chunk-DWQ4L3IB.cjs.map → chunk-4WHDDAVP.cjs.map} +1 -1
  6. package/dist/{chunk-XNJ2LZH2.js → chunk-4Y6LX6XR.js} +2 -2
  7. package/dist/{chunk-ZPUT2BB4.js → chunk-4YH4WKLC.js} +2 -2
  8. package/dist/{chunk-VC4FOIY7.cjs → chunk-5LTLYPIP.cjs} +62 -62
  9. package/dist/{chunk-VC4FOIY7.cjs.map → chunk-5LTLYPIP.cjs.map} +1 -1
  10. package/dist/{chunk-CUBNUQPZ.cjs → chunk-6OGOPPTI.cjs} +9 -9
  11. package/dist/{chunk-CUBNUQPZ.cjs.map → chunk-6OGOPPTI.cjs.map} +1 -1
  12. package/dist/{chunk-JO7XJQ6G.cjs → chunk-6VEEQBVJ.cjs} +15 -15
  13. package/dist/{chunk-JO7XJQ6G.cjs.map → chunk-6VEEQBVJ.cjs.map} +1 -1
  14. package/dist/{chunk-OUHLWOPJ.js → chunk-6WPUUGW5.js} +4 -4
  15. package/dist/{chunk-ONK4D4LG.cjs → chunk-B472QGDO.cjs} +5 -5
  16. package/dist/{chunk-ONK4D4LG.cjs.map → chunk-B472QGDO.cjs.map} +1 -1
  17. package/dist/{chunk-BY6TZ6KA.js → chunk-B52SBOUY.js} +4 -4
  18. package/dist/{chunk-KZZCBQDU.cjs → chunk-CDBQQA7V.cjs} +26 -26
  19. package/dist/{chunk-KZZCBQDU.cjs.map → chunk-CDBQQA7V.cjs.map} +1 -1
  20. package/dist/{chunk-73CH4CZL.cjs → chunk-CH7MDKPI.cjs} +7 -7
  21. package/dist/{chunk-73CH4CZL.cjs.map → chunk-CH7MDKPI.cjs.map} +1 -1
  22. package/dist/{chunk-EK2VQXUN.js → chunk-DBYUQOLS.js} +2 -2
  23. package/dist/{chunk-74ZFCTRZ.js → chunk-H6FKYKEQ.js} +2 -2
  24. package/dist/{chunk-W6RDDT3S.js → chunk-I5L3KUTE.js} +4 -4
  25. package/dist/{chunk-YTLINJRR.cjs → chunk-J5S5U76A.cjs} +26 -26
  26. package/dist/{chunk-YTLINJRR.cjs.map → chunk-J5S5U76A.cjs.map} +1 -1
  27. package/dist/{chunk-WD7SE532.cjs → chunk-KP37QDNS.cjs} +59 -59
  28. package/dist/{chunk-WD7SE532.cjs.map → chunk-KP37QDNS.cjs.map} +1 -1
  29. package/dist/{chunk-U5FNZ2TL.cjs → chunk-KXBXPOYM.cjs} +11 -11
  30. package/dist/{chunk-U5FNZ2TL.cjs.map → chunk-KXBXPOYM.cjs.map} +1 -1
  31. package/dist/{chunk-XDBNMB5K.js → chunk-LWIVRGDN.js} +2 -2
  32. package/dist/{chunk-TVMARS74.js → chunk-QESV36I2.js} +19 -24
  33. package/dist/chunk-QESV36I2.js.map +1 -0
  34. package/dist/{chunk-PJYGEXWM.js → chunk-SWNZZVYG.js} +2 -2
  35. package/dist/{chunk-NY4WLKNU.js → chunk-UCY6VITT.js} +2 -2
  36. package/dist/{chunk-RIEAXUJX.cjs → chunk-ZQRGJHNH.cjs} +19 -24
  37. package/dist/chunk-ZQRGJHNH.cjs.map +1 -0
  38. package/dist/components/announcement-bar.d.ts +1 -1
  39. package/dist/components/announcement-bar.d.ts.map +1 -1
  40. package/dist/components/case-studies/index.cjs +8 -8
  41. package/dist/components/case-studies/index.js +2 -2
  42. package/dist/components/chat/index.cjs +2 -2
  43. package/dist/components/chat/index.js +1 -1
  44. package/dist/components/contact/index.cjs +3 -3
  45. package/dist/components/contact/index.js +2 -2
  46. package/dist/components/docs/index.cjs +5 -5
  47. package/dist/components/docs/index.js +4 -4
  48. package/dist/components/embeds/index.cjs +3 -3
  49. package/dist/components/embeds/index.js +2 -2
  50. package/dist/components/faq/index.cjs +3 -3
  51. package/dist/components/faq/index.js +2 -2
  52. package/dist/components/features/index.cjs +2 -2
  53. package/dist/components/features/index.js +1 -1
  54. package/dist/components/help-center-pages/index.cjs +20 -20
  55. package/dist/components/help-center-pages/index.js +11 -11
  56. package/dist/components/index.cjs +168 -156
  57. package/dist/components/index.cjs.map +1 -1
  58. package/dist/components/index.js +47 -35
  59. package/dist/components/index.js.map +1 -1
  60. package/dist/components/navigation/index.cjs +2 -2
  61. package/dist/components/navigation/index.js +1 -1
  62. package/dist/components/onboarding-guides/index.cjs +5 -5
  63. package/dist/components/onboarding-guides/index.js +4 -4
  64. package/dist/components/related-content/index.cjs +3 -3
  65. package/dist/components/related-content/index.js +2 -2
  66. package/dist/components/tickets/index.cjs +5 -5
  67. package/dist/components/tickets/index.js +4 -4
  68. package/dist/components/ui/announcement-bar-view.d.ts +26 -24
  69. package/dist/components/ui/announcement-bar-view.d.ts.map +1 -1
  70. package/dist/components/ui/index.cjs +2 -2
  71. package/dist/components/ui/index.js +1 -1
  72. package/dist/index.cjs +2 -2
  73. package/dist/index.js +1 -1
  74. package/dist/types/announcement.cjs.map +1 -1
  75. package/dist/types/announcement.d.ts +5 -0
  76. package/dist/types/announcement.d.ts.map +1 -1
  77. package/dist/types/announcement.js.map +1 -1
  78. package/dist/types/index.cjs.map +1 -1
  79. package/dist/types/index.js.map +1 -1
  80. package/package.json +1 -1
  81. package/src/components/announcement-bar.tsx +58 -42
  82. package/src/components/ui/announcement-bar-view.tsx +42 -66
  83. package/src/stories/AnnouncementBar.stories.tsx +20 -0
  84. package/src/types/announcement.ts +5 -0
  85. package/dist/chunk-RIEAXUJX.cjs.map +0 -1
  86. package/dist/chunk-TVMARS74.js.map +0 -1
  87. /package/dist/{chunk-7D5KOJMF.js.map → chunk-2SPAHQYE.js.map} +0 -0
  88. /package/dist/{chunk-XNJ2LZH2.js.map → chunk-4Y6LX6XR.js.map} +0 -0
  89. /package/dist/{chunk-ZPUT2BB4.js.map → chunk-4YH4WKLC.js.map} +0 -0
  90. /package/dist/{chunk-OUHLWOPJ.js.map → chunk-6WPUUGW5.js.map} +0 -0
  91. /package/dist/{chunk-BY6TZ6KA.js.map → chunk-B52SBOUY.js.map} +0 -0
  92. /package/dist/{chunk-EK2VQXUN.js.map → chunk-DBYUQOLS.js.map} +0 -0
  93. /package/dist/{chunk-74ZFCTRZ.js.map → chunk-H6FKYKEQ.js.map} +0 -0
  94. /package/dist/{chunk-W6RDDT3S.js.map → chunk-I5L3KUTE.js.map} +0 -0
  95. /package/dist/{chunk-XDBNMB5K.js.map → chunk-LWIVRGDN.js.map} +0 -0
  96. /package/dist/{chunk-PJYGEXWM.js.map → chunk-SWNZZVYG.js.map} +0 -0
  97. /package/dist/{chunk-NY4WLKNU.js.map → chunk-UCY6VITT.js.map} +0 -0
@@ -3,44 +3,29 @@
3
3
  import type { CSSProperties, ReactElement, ReactNode } from 'react';
4
4
  import { cn } from '../../utils/cn';
5
5
 
6
- /**
7
- * Mirrors `screens.md` in tailwind.config.ts (800px), which is also where the
8
- * ODS responsive tokens step up (ods-responsive-tokens.css). ONE breakpoint
9
- * for the whole bar: the `md:` variants below and the `onContentClick` guard
10
- * must never disagree (they did before — the guard read a stale 768px while
11
- * the CSS switched at 800px).
12
- */
13
- const MD_QUERY = '(min-width: 800px)';
14
-
15
6
  export interface AnnouncementBarViewProps {
16
7
  /**
17
8
  * Leading slot — typically an icon, at content width before the title. Size
18
- * it in the slot: the bar's icon runs 20px below `md` and 24px from `md` up,
19
- * and no ODS icon token carries that pair (`--icon-size-icon-size` is 16/24).
9
+ * it in the slot: the bar's icon is 16px below `md` (must not exceed the
10
+ * 20px title row, Figma 9418-52387) and 24px from `md` up.
20
11
  */
21
12
  startAdornment?: ReactNode;
22
13
  /**
23
- * Bar message, always ONE line. A plain string gets the strip's text
24
- * treatment (`text-h6`, truncating); pass a ReactElement to own the markup
25
- * (e.g. bold title + inline description truncating as one unit).
14
+ * Bar message. A plain string gets the mockup's text treatment (`text-h4` =
15
+ * DM Sans 500, 14/20 below `md` and 18/24 from `md` up), wrapping below `md`
16
+ * and truncating to one line from `md` up. Pass a ReactElement to own the
17
+ * markup (e.g. bold title + inline description) — mirror that responsive
18
+ * wrap/truncate pair in your element.
26
19
  */
27
20
  title?: string | ReactElement;
28
21
  /**
29
- * Primary CTA, at content width after the title. Hidden below `md`, where
30
- * the content row becomes the tap target instead (`onContentClick`) the
31
- * banner pattern's touch-first tradeoff.
22
+ * Primary CTA. From `md` up it sits inline at content width between the
23
+ * title and `endAdornment`; below `md` it moves to its own full-width row
24
+ * under the content (Figma 2862-8391) and the bar's height grows to fit.
32
25
  */
33
26
  actionBlock?: ReactElement;
34
- /** Trailing slot (e.g. a dismiss button). Outside the tap target, every breakpoint. */
27
+ /** Trailing slot (e.g. a dismiss button) stays in the top/content row on every breakpoint. */
35
28
  endAdornment?: ReactElement;
36
- /**
37
- * Below `md` only: fires when the content row is tapped, standing in for the
38
- * `actionBlock` that is CSS-hidden at that width. No-op from `md` up, where
39
- * the CTA is visible and owns the interaction.
40
- */
41
- onContentClick?: () => void;
42
- /** Extra classes for the padded content row (e.g. a cursor affordance). */
43
- contentClassName?: string;
44
29
  /** Surface styling (background, text color, theme scope) is the consumer's — pass it here. */
45
30
  className?: string;
46
31
  style?: CSSProperties;
@@ -50,62 +35,53 @@ export interface AnnouncementBarViewProps {
50
35
  * Pure presentational announcement/notification bar. No data fetching,
51
36
  * storage, or navigation — consumers own state and pass content through slots.
52
37
  *
53
- * Anatomy follows the announcement-bar industry standard: ONE line of text at
54
- * 13-14px inside a 44px-tall strip (guides converge on 40-60px with a single
55
- * sentence; two stacked 18px rows blow past that), ONE compact CTA on the
56
- * right, and a trailing dismiss slot. Spacing is the ODS responsive tokens,
57
- * which step at the same 800px as `md`: `l` = 16/24px edge padding, `s` =
58
- * 8/12px gap, `m` = CTA offset, `xs` = 4/8px.
38
+ * Layout (Figma 9418-52494 desktop/tablet, 2862-8391 mobile):
39
+ * - `md` (800px) and up: ONE row inside a strip with a RESERVED 56px minimum
40
+ * height (`md:min-h-14`, the mockup's strip height) held unconditionally,
41
+ * so toggling or removing the action never resizes the bar on
42
+ * desktop/tablet. Title truncates to one line.
43
+ * - Below `md`: the container stacks (`px` 16 / `py` 8 / gap 8). Top row =
44
+ * `startAdornment` + wrapping title + `endAdornment`; when an `actionBlock`
45
+ * is present it renders as a VISIBLE full-width button on its own second
46
+ * row and the bar's height adapts to content (76px with a single-line
47
+ * title and CTA per Figma 9418-52387: 8 + 20 + 8 + 32 + 8).
48
+ *
49
+ * The `actionBlock` element is mounted in both positions (inline `md`-up slot
50
+ * and the mobile full-width row); exactly one is `display:none` at any width,
51
+ * so keyboard/AT always reach exactly one control.
59
52
  */
60
53
  export function AnnouncementBarView({
61
54
  startAdornment,
62
55
  title,
63
56
  actionBlock,
64
57
  endAdornment,
65
- onContentClick,
66
- contentClassName,
67
58
  className,
68
59
  style,
69
60
  }: AnnouncementBarViewProps) {
70
- const handleContentClick = onContentClick
71
- ? () => {
72
- if (!window.matchMedia(MD_QUERY).matches) onContentClick();
73
- }
74
- : undefined;
75
-
76
61
  return (
77
- <div className={cn('flex w-full max-w-full min-h-11 items-center', className)} style={style}>
78
- {/* Content row — the tap target below `md`, where the CTA is hidden.
79
- Its vertical padding never drives the height; the 44px strip does. */}
80
- <div
81
- className={cn(
82
- 'flex min-w-0 flex-1 flex-row items-center gap-[var(--spacing-system-s)] py-[var(--spacing-system-xs)] pl-[var(--spacing-system-l)]',
83
- contentClassName,
84
- )}
85
- onClick={handleContentClick}
86
- >
62
+ <div
63
+ className={cn(
64
+ 'flex w-full max-w-full flex-col gap-[var(--spacing-system-s)] px-[var(--spacing-system-l)] py-[var(--spacing-system-s)] md:min-h-14 md:flex-row md:items-center md:py-0',
65
+ className,
66
+ )}
67
+ style={style}
68
+ >
69
+ {/* Content row: leading icon + title (+ inline CTA from `md`) + trailing
70
+ slot. `items-start` below `md` keeps the adornments pinned to the
71
+ first text line when the title wraps; `md:items-center` re-centers
72
+ everything in the fixed strip. */}
73
+ <div className="flex w-full min-w-0 flex-1 items-start gap-[var(--spacing-system-s)] md:w-auto md:items-center">
87
74
  {startAdornment && <div className="flex shrink-0 items-center">{startAdornment}</div>}
88
75
  {typeof title === 'string' ? (
89
- <p className="mb-0 min-w-0 max-w-full flex-1 truncate text-h6">{title}</p>
76
+ <p className="mb-0 min-w-0 max-w-full flex-1 break-words text-h4 md:truncate">{title}</p>
90
77
  ) : (
91
78
  title != null && <div className="min-w-0 max-w-full flex-1">{title}</div>
92
79
  )}
93
- {/* Below `md` the CTA is visually replaced by the row-wide tap target,
94
- but a `display:none` button is unreachable by keyboard and AT. So
95
- it is only visually hidden there (`sr-only`) and reveals itself on
96
- focus — the row stays the touch affordance while Tab still reaches
97
- a real, labelled control. `md:` restores the normal inline CTA. */}
98
- {actionBlock && (
99
- <div className="ml-[var(--spacing-system-m)] sr-only shrink-0 focus-within:not-sr-only md:not-sr-only md:flex">
100
- {actionBlock}
101
- </div>
102
- )}
80
+ {actionBlock && <div className="hidden shrink-0 md:flex">{actionBlock}</div>}
81
+ {endAdornment && <div className="flex shrink-0 items-center">{endAdornment}</div>}
103
82
  </div>
104
- {/* Trailing slot. Its own 32px hit box optically re-centers the glyph
105
- against the 16/24px left edge. */}
106
- {endAdornment && (
107
- <div className="ml-[var(--spacing-system-xs)] mr-[var(--spacing-system-m)] shrink-0">{endAdornment}</div>
108
- )}
83
+ {/* Mobile-only action row the CTA stretched to the bar's full width. */}
84
+ {actionBlock && <div className="flex w-full md:hidden [&>*]:w-full">{actionBlock}</div>}
109
85
  </div>
110
86
  );
111
87
  }
@@ -83,6 +83,26 @@ export const WithCTA: Story = {
83
83
  },
84
84
  }
85
85
 
86
+ /**
87
+ * Non-dismissible announcement — `dismissible={false}` drops the close (X)
88
+ * button, so the bar only disappears when the announcement is deactivated.
89
+ */
90
+ export const WithoutCloseButton: Story = {
91
+ args: {
92
+ dismissible: false,
93
+ initialAnnouncement: {
94
+ ...baseAnnouncement,
95
+ id: 'story-no-dismiss',
96
+ title: 'Mandatory Maintenance Notice',
97
+ description: 'This announcement cannot be dismissed by the user.',
98
+ cta_enabled: true,
99
+ cta_text: 'Learn More',
100
+ cta_url: 'https://example.com',
101
+ cta_target: '_blank',
102
+ },
103
+ },
104
+ }
105
+
86
106
  /**
87
107
  * Announcement with a CTA button that opens in the same tab.
88
108
  */
@@ -238,6 +238,11 @@ export interface AnnouncementBarProps {
238
238
  * cookies or touches localStorage).
239
239
  */
240
240
  previewMode?: boolean;
241
+ /**
242
+ * When false, the dismiss (X) button is not rendered — the bar can only
243
+ * disappear by deactivating the announcement. Default true.
244
+ */
245
+ dismissible?: boolean;
241
246
  className?: string;
242
247
  }
243
248