@mirohq/design-system-banner 0.1.0

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.
package/dist/main.js ADDED
@@ -0,0 +1,279 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var React = require('react');
5
+ var designSystemPrimitive = require('@mirohq/design-system-primitive');
6
+ var designSystemStitches = require('@mirohq/design-system-stitches');
7
+ var designSystemIcons = require('@mirohq/design-system-icons');
8
+ var designSystemUtils = require('@mirohq/design-system-utils');
9
+ var designSystemLink = require('@mirohq/design-system-link');
10
+ var designSystemIconButton = require('@mirohq/design-system-icon-button');
11
+ var designSystemTooltip = require('@mirohq/design-system-tooltip');
12
+
13
+ const StyledBanner = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
14
+ position: "relative",
15
+ boxSizing: "border-box",
16
+ width: "100%",
17
+ minHeight: "$11",
18
+ display: "flex",
19
+ alignItems: "center",
20
+ justifyContent: "space-between",
21
+ fontSize: "$175",
22
+ variants: {
23
+ variant: {
24
+ information: {
25
+ backgroundColor: "$notification-background-info",
26
+ color: "$notification-text-on-info"
27
+ },
28
+ warning: {
29
+ backgroundColor: "$notification-background-warning",
30
+ color: "$notification-text-on-warning"
31
+ },
32
+ danger: {
33
+ backgroundColor: "$notification-background-danger",
34
+ color: "$notification-text-on-danger"
35
+ },
36
+ announcement: {
37
+ backgroundColor: "$notification-background-announcement",
38
+ color: "$notification-text-on-announcement"
39
+ }
40
+ },
41
+ rounded: {
42
+ true: {
43
+ borderRadius: "$notification-banner"
44
+ },
45
+ false: {
46
+ borderRadius: 0
47
+ }
48
+ }
49
+ },
50
+ defaultVariants: {
51
+ variant: "information",
52
+ rounded: true
53
+ }
54
+ });
55
+ const StyledBannerContent = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
56
+ display: "flex",
57
+ padding: "$100 $200",
58
+ minWidth: 0,
59
+ flexDirection: "row",
60
+ alignItems: "center",
61
+ gap: "$200",
62
+ variants: {
63
+ align: {
64
+ start: {},
65
+ center: {
66
+ flex: 1,
67
+ justifyContent: "center",
68
+ textAlign: "center"
69
+ }
70
+ }
71
+ },
72
+ defaultVariants: {
73
+ align: "start"
74
+ }
75
+ });
76
+ const StyledBannerMessage = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
77
+ minWidth: 0,
78
+ // Inline links inherit the banner's text colour.
79
+ "& a": {
80
+ color: "inherit",
81
+ "&:hover, &:active, &:visited, &[data-hovered], &[data-pressed]": {
82
+ color: "inherit"
83
+ }
84
+ }
85
+ });
86
+
87
+ const BannerContext = React.createContext({});
88
+ const BannerProvider = ({
89
+ children,
90
+ ...restProps
91
+ }) => /* @__PURE__ */ jsxRuntime.jsx(BannerContext.Provider, { value: { ...restProps }, children });
92
+ const useBannerContext = () => React.useContext(BannerContext);
93
+
94
+ const FOREGROUND_COLOR = {
95
+ information: "$notification-icon-on-info",
96
+ warning: "$notification-icon-on-warning",
97
+ danger: "$notification-icon-on-danger",
98
+ announcement: "$notification-icon-on-announcement"
99
+ };
100
+ const colorVariants = designSystemUtils.mapKeysToVariants(FOREGROUND_COLOR, (key) => ({
101
+ color: FOREGROUND_COLOR[key]
102
+ }));
103
+ const interactiveColorVariants = designSystemUtils.mapKeysToVariants(
104
+ FOREGROUND_COLOR,
105
+ (key) => ({
106
+ color: FOREGROUND_COLOR[key],
107
+ backgroundColor: "transparent",
108
+ "&:hover, &[data-hovered], &:active, &[data-pressed]": {
109
+ color: FOREGROUND_COLOR[key],
110
+ backgroundColor: "transparent"
111
+ }
112
+ })
113
+ );
114
+
115
+ const StyledIconSlot = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
116
+ display: "flex",
117
+ alignItems: "center",
118
+ flexShrink: 0,
119
+ variants: {
120
+ variant: colorVariants
121
+ }
122
+ });
123
+
124
+ const defaultIcon = {
125
+ information: /* @__PURE__ */ jsxRuntime.jsx(designSystemIcons.IconInformationMarkCircle, {}),
126
+ warning: /* @__PURE__ */ jsxRuntime.jsx(designSystemIcons.IconWarning, {}),
127
+ danger: /* @__PURE__ */ jsxRuntime.jsx(designSystemIcons.IconExclamationPointCircle, {})
128
+ };
129
+ const IconSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
130
+ const { variant } = useBannerContext();
131
+ const content = React.Children.count(children) > 0 ? children : variant != null ? defaultIcon[variant] : void 0;
132
+ if (content == null) {
133
+ return null;
134
+ }
135
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledIconSlot, { ...restProps, ref: forwardRef, variant, children: content });
136
+ });
137
+ IconSlot.displayName = "Banner.IconSlot";
138
+
139
+ const StyledImageSlot = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
140
+ display: "flex",
141
+ alignItems: "center",
142
+ flexShrink: 0,
143
+ "& img": {
144
+ display: "block",
145
+ width: "$6",
146
+ height: "$6",
147
+ objectFit: "cover",
148
+ borderRadius: "$50"
149
+ }
150
+ });
151
+
152
+ const ImageSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
153
+ if (React.Children.count(children) === 0) {
154
+ return null;
155
+ }
156
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledImageSlot, { ...restProps, ref: forwardRef, children });
157
+ });
158
+ ImageSlot.displayName = "Banner.ImageSlot";
159
+
160
+ const StyledAction = designSystemStitches.styled(designSystemLink.Link, {
161
+ whiteSpace: "nowrap",
162
+ variants: {
163
+ color: interactiveColorVariants
164
+ }
165
+ });
166
+ const Action = React.forwardRef(
167
+ (props, forwardRef) => {
168
+ const { variant: bannerVariant } = useBannerContext();
169
+ return /* @__PURE__ */ jsxRuntime.jsx(
170
+ StyledAction,
171
+ {
172
+ ...props,
173
+ ref: forwardRef,
174
+ variant: "primary",
175
+ color: bannerVariant
176
+ }
177
+ );
178
+ }
179
+ );
180
+ Action.displayName = "Banner.Action";
181
+
182
+ const StyledDismissButton = designSystemStitches.styled(designSystemIconButton.IconButton, {
183
+ flexShrink: 0,
184
+ alignSelf: "center",
185
+ marginInlineEnd: "$100",
186
+ backgroundColor: "transparent",
187
+ "&:hover, &[data-hovered], &:active, &[data-pressed]": {
188
+ backgroundColor: "transparent"
189
+ },
190
+ variants: {
191
+ color: interactiveColorVariants
192
+ }
193
+ });
194
+ const DismissButton = React.forwardRef((props, forwardRef) => {
195
+ const { variant: bannerVariant } = useBannerContext();
196
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystemTooltip.Tooltip, { children: [
197
+ /* @__PURE__ */ jsxRuntime.jsx(designSystemTooltip.Tooltip.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
198
+ StyledDismissButton,
199
+ {
200
+ ...props,
201
+ ref: forwardRef,
202
+ variant: "ghost",
203
+ size: "medium",
204
+ color: bannerVariant,
205
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystemIcons.IconCross, {})
206
+ }
207
+ ) }),
208
+ /* @__PURE__ */ jsxRuntime.jsx(designSystemTooltip.Tooltip.Content, { children: props["aria-label"] })
209
+ ] });
210
+ });
211
+ DismissButton.displayName = "Banner.DismissButton";
212
+
213
+ const VARIANT_ROLE = {
214
+ information: "status",
215
+ warning: "alert",
216
+ danger: "alert",
217
+ announcement: "status"
218
+ };
219
+ const Banner = React.forwardRef(
220
+ ({
221
+ variant = "information",
222
+ rounded = true,
223
+ align = "start",
224
+ dismissible = true,
225
+ dismissed,
226
+ dismissLabel,
227
+ onDismiss,
228
+ children,
229
+ role,
230
+ ...props
231
+ }, forwardRef) => {
232
+ const [internalDismissed, setInternalDismissed] = React.useState(false);
233
+ if (dismissed != null ? dismissed : internalDismissed) {
234
+ return null;
235
+ }
236
+ const dismissButtonLabel = dismissible && dismissLabel != null && dismissLabel.length > 0 ? dismissLabel : null;
237
+ const handleDismiss = () => {
238
+ setInternalDismissed(true);
239
+ onDismiss == null ? void 0 : onDismiss();
240
+ };
241
+ const items = React.Children.toArray(children);
242
+ const isType = (child, type) => React.isValidElement(child) && child.type === type;
243
+ const leading = items.find(
244
+ (child) => isType(child, IconSlot) || isType(child, ImageSlot)
245
+ );
246
+ const action = items.find((child) => isType(child, Action));
247
+ const message = items.filter((child) => child !== leading && child !== action);
248
+ return /* @__PURE__ */ jsxRuntime.jsx(BannerProvider, { variant, children: /* @__PURE__ */ jsxRuntime.jsxs(
249
+ StyledBanner,
250
+ {
251
+ ...props,
252
+ ref: forwardRef,
253
+ variant,
254
+ rounded,
255
+ role: role != null ? role : VARIANT_ROLE[variant],
256
+ children: [
257
+ /* @__PURE__ */ jsxRuntime.jsxs(StyledBannerContent, { align, children: [
258
+ leading,
259
+ /* @__PURE__ */ jsxRuntime.jsx(StyledBannerMessage, { children: message }),
260
+ action
261
+ ] }),
262
+ dismissButtonLabel != null && /* @__PURE__ */ jsxRuntime.jsx(
263
+ DismissButton,
264
+ {
265
+ "aria-label": dismissButtonLabel,
266
+ onPress: handleDismiss
267
+ }
268
+ )
269
+ ]
270
+ }
271
+ ) });
272
+ }
273
+ );
274
+ Banner.IconSlot = IconSlot;
275
+ Banner.ImageSlot = ImageSlot;
276
+ Banner.Action = Action;
277
+
278
+ exports.Banner = Banner;
279
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sources":["../src/banner.styled.tsx","../src/hooks/use-banner-context.tsx","../src/banner.colors.ts","../src/partials/icon-slot.styled.ts","../src/partials/icon-slot.tsx","../src/partials/image-slot.styled.ts","../src/partials/image-slot.tsx","../src/partials/action.tsx","../src/partials/dismiss-button.tsx","../src/banner.tsx"],"sourcesContent":["import type { ComponentPropsWithRef } from 'react'\nimport { Primitive } from '@mirohq/design-system-primitive'\nimport { styled } from '@mirohq/design-system-stitches'\n\nexport const StyledBanner = styled(Primitive.div, {\n position: 'relative',\n boxSizing: 'border-box',\n width: '100%',\n minHeight: '$11',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: '$175',\n variants: {\n variant: {\n information: {\n backgroundColor: '$notification-background-info',\n color: '$notification-text-on-info',\n },\n warning: {\n backgroundColor: '$notification-background-warning',\n color: '$notification-text-on-warning',\n },\n danger: {\n backgroundColor: '$notification-background-danger',\n color: '$notification-text-on-danger',\n },\n announcement: {\n backgroundColor: '$notification-background-announcement',\n color: '$notification-text-on-announcement',\n },\n },\n rounded: {\n true: {\n borderRadius: '$notification-banner',\n },\n false: {\n borderRadius: 0,\n },\n },\n },\n defaultVariants: {\n variant: 'information',\n rounded: true,\n },\n})\n\nexport const StyledBannerContent = styled(Primitive.div, {\n display: 'flex',\n padding: '$100 $200',\n minWidth: 0,\n flexDirection: 'row',\n alignItems: 'center',\n gap: '$200',\n\n variants: {\n align: {\n start: {},\n center: {\n flex: 1,\n justifyContent: 'center',\n textAlign: 'center',\n },\n },\n },\n defaultVariants: {\n align: 'start',\n },\n})\n\nexport const StyledBannerMessage = styled(Primitive.div, {\n minWidth: 0,\n // Inline links inherit the banner's text colour.\n '& a': {\n color: 'inherit',\n '&:hover, &:active, &:visited, &[data-hovered], &[data-pressed]': {\n color: 'inherit',\n },\n },\n})\n\nexport type StyledBannerProps = ComponentPropsWithRef<typeof StyledBanner>\n\n// Derived from the styled `variant` variants — the single source of truth.\n// `Extract<…, string>` drops the stitches responsive-object form so the union\n// stays a plain, indexable string union (e.g. for VARIANT_ROLE / default-icon).\nexport type BannerVariant = Extract<StyledBannerProps['variant'], string>\n","import { createContext, useContext } from 'react'\n\nimport type { BannerVariant } from '../banner.styled'\n\ninterface BannerContextProps {\n variant?: BannerVariant\n}\n\nexport interface BannerProviderProps extends BannerContextProps {\n children: React.ReactNode\n}\n\nconst BannerContext = createContext<BannerContextProps>({})\n\nexport const BannerProvider = ({\n children,\n ...restProps\n}: BannerProviderProps): JSX.Element => (\n <BannerContext.Provider value={{ ...restProps }}>\n {children}\n </BannerContext.Provider>\n)\n\nexport const useBannerContext = (): BannerContextProps =>\n useContext(BannerContext)\n","import { mapKeysToVariants } from '@mirohq/design-system-utils'\n\nimport type { BannerVariant } from './banner.styled'\n\nexport const FOREGROUND_COLOR: Record<BannerVariant, string> = {\n information: '$notification-icon-on-info',\n warning: '$notification-icon-on-warning',\n danger: '$notification-icon-on-danger',\n announcement: '$notification-icon-on-announcement',\n}\n\nexport const colorVariants = mapKeysToVariants(FOREGROUND_COLOR, key => ({\n color: FOREGROUND_COLOR[key],\n}))\n\nexport const interactiveColorVariants = mapKeysToVariants(\n FOREGROUND_COLOR,\n key => ({\n color: FOREGROUND_COLOR[key],\n backgroundColor: 'transparent',\n '&:hover, &[data-hovered], &:active, &[data-pressed]': {\n color: FOREGROUND_COLOR[key],\n backgroundColor: 'transparent',\n },\n })\n)\n","import { Primitive } from '@mirohq/design-system-primitive'\nimport { styled } from '@mirohq/design-system-stitches'\n\nimport { colorVariants } from '../banner.colors'\n\nexport const StyledIconSlot = styled(Primitive.div, {\n display: 'flex',\n alignItems: 'center',\n flexShrink: 0,\n variants: {\n variant: colorVariants,\n },\n})\n","import React from 'react'\nimport type { ElementRef, ComponentPropsWithRef, ReactNode } from 'react'\nimport {\n IconExclamationPointCircle,\n IconInformationMarkCircle,\n IconWarning,\n} from '@mirohq/design-system-icons'\n\nimport { useBannerContext } from '../hooks/use-banner-context'\nimport type { BannerVariant } from '../banner.styled'\nimport { StyledIconSlot } from './icon-slot.styled'\n\nexport type StyledIconSlotProps = ComponentPropsWithRef<typeof StyledIconSlot>\n\nexport interface IconSlotProps extends Omit<StyledIconSlotProps, 'variant'> {\n /**\n * The DS icon. When omitted, the variant's default icon is shown for\n * information / warning / danger; announcement has no default (consumers\n * supply their own). For image avatars use `Banner.ImageSlot` instead.\n */\n children?: ReactNode\n}\n\nconst defaultIcon: Partial<Record<BannerVariant, ReactNode>> = {\n information: <IconInformationMarkCircle />,\n warning: <IconWarning />,\n danger: <IconExclamationPointCircle />,\n}\n\nexport const IconSlot = React.forwardRef<\n ElementRef<typeof StyledIconSlot>,\n IconSlotProps\n>(({ children, ...restProps }, forwardRef) => {\n const { variant } = useBannerContext()\n\n const content =\n React.Children.count(children) > 0\n ? children\n : variant != null\n ? defaultIcon[variant]\n : undefined\n\n if (content == null) {\n return null\n }\n\n return (\n <StyledIconSlot {...restProps} ref={forwardRef} variant={variant}>\n {content}\n </StyledIconSlot>\n )\n})\n\nIconSlot.displayName = 'Banner.IconSlot'\n","import { Primitive } from '@mirohq/design-system-primitive'\nimport { styled } from '@mirohq/design-system-stitches'\n\nexport const StyledImageSlot = styled(Primitive.div, {\n display: 'flex',\n alignItems: 'center',\n flexShrink: 0,\n '& img': {\n display: 'block',\n width: '$6',\n height: '$6',\n objectFit: 'cover',\n borderRadius: '$50',\n },\n})\n","import React from 'react'\nimport type { ElementRef, ComponentPropsWithRef, ReactNode } from 'react'\n\nimport { StyledImageSlot } from './image-slot.styled'\n\nexport type StyledImageSlotProps = ComponentPropsWithRef<typeof StyledImageSlot>\n\nexport interface ImageSlotProps extends StyledImageSlotProps {\n /**\n * The image icon. Pass an `<img>` (any source) — it is rendered as a square,\n * rounded avatar. For DS icons use `Banner.IconSlot` instead.\n */\n children?: ReactNode\n}\n\nexport const ImageSlot = React.forwardRef<\n ElementRef<typeof StyledImageSlot>,\n ImageSlotProps\n>(({ children, ...restProps }, forwardRef) => {\n if (React.Children.count(children) === 0) {\n return null\n }\n\n return (\n <StyledImageSlot {...restProps} ref={forwardRef}>\n {children}\n </StyledImageSlot>\n )\n})\n\nImageSlot.displayName = 'Banner.ImageSlot'\n","import React from 'react'\nimport type { ElementRef } from 'react'\nimport { Link } from '@mirohq/design-system-link'\nimport type { LinkProps } from '@mirohq/design-system-link'\nimport { styled } from '@mirohq/design-system-stitches'\n\nimport { useBannerContext } from '../hooks/use-banner-context'\nimport { interactiveColorVariants } from '../banner.colors'\n\nconst StyledAction = styled(Link, {\n whiteSpace: 'nowrap',\n variants: {\n color: interactiveColorVariants,\n },\n})\n\nexport type ActionProps = Omit<LinkProps, 'variant'>\n\nexport const Action = React.forwardRef<ElementRef<typeof Link>, ActionProps>(\n (props, forwardRef) => {\n const { variant: bannerVariant } = useBannerContext()\n return (\n <StyledAction\n {...props}\n ref={forwardRef}\n variant='primary'\n color={bannerVariant}\n />\n )\n }\n)\n\nAction.displayName = 'Banner.Action'\n","import React from 'react'\nimport type { ElementRef } from 'react'\nimport { styled } from '@mirohq/design-system-stitches'\nimport { IconButton } from '@mirohq/design-system-icon-button'\nimport type { IconButtonProps } from '@mirohq/design-system-icon-button'\nimport { IconCross } from '@mirohq/design-system-icons'\nimport { Tooltip } from '@mirohq/design-system-tooltip'\n\nimport { useBannerContext } from '../hooks/use-banner-context'\nimport { interactiveColorVariants } from '../banner.colors'\n\nconst StyledDismissButton = styled(IconButton, {\n flexShrink: 0,\n alignSelf: 'center',\n marginInlineEnd: '$100',\n backgroundColor: 'transparent',\n '&:hover, &[data-hovered], &:active, &[data-pressed]': {\n backgroundColor: 'transparent',\n },\n variants: {\n color: interactiveColorVariants,\n },\n})\n\n// The icon, ghost variant and size are owned by the banner\nexport type DismissButtonProps = Omit<\n IconButtonProps,\n 'variant' | 'size' | 'children'\n>\n\nexport const DismissButton = React.forwardRef<\n ElementRef<typeof IconButton>,\n DismissButtonProps\n>((props, forwardRef) => {\n const { variant: bannerVariant } = useBannerContext()\n\n return (\n <Tooltip>\n <Tooltip.Trigger asChild>\n <StyledDismissButton\n {...props}\n ref={forwardRef}\n variant='ghost'\n size='medium'\n color={bannerVariant}\n >\n <IconCross />\n </StyledDismissButton>\n </Tooltip.Trigger>\n <Tooltip.Content>{props['aria-label']}</Tooltip.Content>\n </Tooltip>\n )\n})\n\nDismissButton.displayName = 'Banner.DismissButton'\n","import React, { useState, isValidElement } from 'react'\nimport type { ElementRef, ForwardRefExoticComponent, ReactNode } from 'react'\n\nimport {\n StyledBanner,\n StyledBannerContent,\n StyledBannerMessage,\n} from './banner.styled'\nimport type { StyledBannerProps, BannerVariant } from './banner.styled'\nimport { BannerProvider } from './hooks/use-banner-context'\nimport { IconSlot } from './partials/icon-slot'\nimport { ImageSlot } from './partials/image-slot'\nimport { Action } from './partials/action'\nimport { DismissButton } from './partials/dismiss-button'\n\nexport interface BannerProps extends StyledBannerProps {\n /**\n * Visual style — drives background, default icon and tone.\n * @default 'information'\n */\n variant?: Extract<StyledBannerProps['variant'], string>\n\n /**\n * Rounded floating banner (`true`) or full-page, edge-to-edge banner (`false`).\n * @default true\n */\n rounded?: boolean\n\n /**\n * Content alignment. `center` fills the row and centres the content.\n * @default 'start'\n */\n align?: 'start' | 'center'\n\n /**\n * Whether to show the dismiss button.\n * @default true\n */\n dismissible?: boolean\n\n /**\n * Controlled dismissed state. When set, the consumer owns visibility and the\n * banner does not self-hide on dismiss. Omit for uncontrolled self-hide.\n */\n dismissed?: boolean\n\n /**\n * aria-label for the dismiss button. Required for the dismiss button to render.\n */\n dismissLabel?: string\n\n /**\n * Callback invoked once the dismiss button is clicked.\n */\n onDismiss?: () => void\n\n /**\n * The banner message. Rich text (bold, inline links) is composed by the\n * consumer and passed as children — there is no markdown parsing here.\n */\n children?: ReactNode\n}\n\n// danger/warning announce assertively (alert); the rest politely (status).\nconst VARIANT_ROLE: Record<BannerVariant, 'alert' | 'status'> = {\n information: 'status',\n warning: 'alert',\n danger: 'alert',\n announcement: 'status',\n}\n\n/**\n * Banner displays a prominent, full-width message at the top of a surface.\n *\n * @experimental Beta — the API may still change while teams adopt it.\n */\nexport const Banner = React.forwardRef<\n ElementRef<typeof StyledBanner>,\n BannerProps\n>(\n (\n {\n variant = 'information',\n rounded = true,\n align = 'start',\n dismissible = true,\n dismissed,\n dismissLabel,\n onDismiss,\n children,\n role,\n ...props\n },\n forwardRef\n ) => {\n const [internalDismissed, setInternalDismissed] = useState<boolean>(false)\n\n // Controlled when `dismissed` is provided; otherwise self-managed.\n if (dismissed ?? internalDismissed) {\n return null\n }\n\n // The dismiss button renders only when a label is provided.\n const dismissButtonLabel =\n dismissible && dismissLabel != null && dismissLabel.length > 0\n ? dismissLabel\n : null\n\n const handleDismiss = (): void => {\n setInternalDismissed(true)\n onDismiss?.()\n }\n\n // Pull out the leading visual (IconSlot/ImageSlot) and the action; the rest\n // is the message, wrapped so its rich-text children flow inline as one block.\n const items = React.Children.toArray(children)\n const isType = (child: ReactNode, type: unknown): boolean =>\n isValidElement(child) && child.type === type\n const leading = items.find(\n child => isType(child, IconSlot) || isType(child, ImageSlot)\n )\n const action = items.find(child => isType(child, Action))\n const message = items.filter(child => child !== leading && child !== action)\n\n return (\n <BannerProvider variant={variant}>\n <StyledBanner\n {...props}\n ref={forwardRef}\n variant={variant}\n rounded={rounded}\n role={role ?? VARIANT_ROLE[variant]}\n >\n <StyledBannerContent align={align}>\n {leading}\n <StyledBannerMessage>{message}</StyledBannerMessage>\n {action}\n </StyledBannerContent>\n {dismissButtonLabel != null && (\n <DismissButton\n aria-label={dismissButtonLabel}\n onPress={handleDismiss}\n />\n )}\n </StyledBanner>\n </BannerProvider>\n )\n }\n) as ForwardRefExoticComponent<BannerProps> & Partials\n\nexport interface Partials {\n IconSlot: typeof IconSlot\n ImageSlot: typeof ImageSlot\n Action: typeof Action\n}\n\nBanner.IconSlot = IconSlot\nBanner.ImageSlot = ImageSlot\nBanner.Action = Action\n"],"names":["styled","Primitive","createContext","jsx","useContext","mapKeysToVariants","IconInformationMarkCircle","IconWarning","IconExclamationPointCircle","Link","IconButton","Tooltip","IconCross","useState","isValidElement","jsxs"],"mappings":";;;;;;;;;;;;AAIO,MAAM,YAAA,GAAeA,2BAAA,CAAOC,+BAAA,CAAU,GAAA,EAAK;AAAA,EAChD,QAAA,EAAU,UAAA;AAAA,EACV,SAAA,EAAW,YAAA;AAAA,EACX,KAAA,EAAO,MAAA;AAAA,EACP,SAAA,EAAW,KAAA;AAAA,EACX,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,cAAA,EAAgB,eAAA;AAAA,EAChB,QAAA,EAAU,MAAA;AAAA,EACV,QAAA,EAAU;AAAA,IACR,OAAA,EAAS;AAAA,MACP,WAAA,EAAa;AAAA,QACX,eAAA,EAAiB,+BAAA;AAAA,QACjB,KAAA,EAAO;AAAA,OACT;AAAA,MACA,OAAA,EAAS;AAAA,QACP,eAAA,EAAiB,kCAAA;AAAA,QACjB,KAAA,EAAO;AAAA,OACT;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,eAAA,EAAiB,iCAAA;AAAA,QACjB,KAAA,EAAO;AAAA,OACT;AAAA,MACA,YAAA,EAAc;AAAA,QACZ,eAAA,EAAiB,uCAAA;AAAA,QACjB,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,OAAA,EAAS;AAAA,MACP,IAAA,EAAM;AAAA,QACJ,YAAA,EAAc;AAAA,OAChB;AAAA,MACA,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA;AAChB;AACF,GACF;AAAA,EACA,eAAA,EAAiB;AAAA,IACf,OAAA,EAAS,aAAA;AAAA,IACT,OAAA,EAAS;AAAA;AAEb,CAAC,CAAA;AAEM,MAAM,mBAAA,GAAsBD,2BAAA,CAAOC,+BAAA,CAAU,GAAA,EAAK;AAAA,EACvD,OAAA,EAAS,MAAA;AAAA,EACT,OAAA,EAAS,WAAA;AAAA,EACT,QAAA,EAAU,CAAA;AAAA,EACV,aAAA,EAAe,KAAA;AAAA,EACf,UAAA,EAAY,QAAA;AAAA,EACZ,GAAA,EAAK,MAAA;AAAA,EAEL,QAAA,EAAU;AAAA,IACR,KAAA,EAAO;AAAA,MACL,OAAO,EAAC;AAAA,MACR,MAAA,EAAQ;AAAA,QACN,IAAA,EAAM,CAAA;AAAA,QACN,cAAA,EAAgB,QAAA;AAAA,QAChB,SAAA,EAAW;AAAA;AACb;AACF,GACF;AAAA,EACA,eAAA,EAAiB;AAAA,IACf,KAAA,EAAO;AAAA;AAEX,CAAC,CAAA;AAEM,MAAM,mBAAA,GAAsBD,2BAAA,CAAOC,+BAAA,CAAU,GAAA,EAAK;AAAA,EACvD,QAAA,EAAU,CAAA;AAAA;AAAA,EAEV,KAAA,EAAO;AAAA,IACL,KAAA,EAAO,SAAA;AAAA,IACP,gEAAA,EAAkE;AAAA,MAChE,KAAA,EAAO;AAAA;AACT;AAEJ,CAAC,CAAA;;ACnED,MAAM,aAAA,GAAgBC,mBAAA,CAAkC,EAAE,CAAA;AAEnD,MAAM,iBAAiB,CAAC;AAAA,EAC7B,QAAA;AAAA,EACA,GAAG;AACL,CAAA,qBACEC,cAAA,CAAC,cAAc,QAAA,EAAd,EAAuB,OAAO,EAAE,GAAG,SAAA,EAAU,EAC3C,QAAA,EACH,CAAA;AAGK,MAAM,gBAAA,GAAmB,MAC9BC,gBAAA,CAAW,aAAa,CAAA;;ACpBnB,MAAM,gBAAA,GAAkD;AAAA,EAC7D,WAAA,EAAa,4BAAA;AAAA,EACb,OAAA,EAAS,+BAAA;AAAA,EACT,MAAA,EAAQ,8BAAA;AAAA,EACR,YAAA,EAAc;AAChB,CAAA;AAEO,MAAM,aAAA,GAAgBC,mCAAA,CAAkB,gBAAA,EAAkB,CAAA,GAAA,MAAQ;AAAA,EACvE,KAAA,EAAO,iBAAiB,GAAG;AAC7B,CAAA,CAAE,CAAA;AAEK,MAAM,wBAAA,GAA2BA,mCAAA;AAAA,EACtC,gBAAA;AAAA,EACA,CAAA,GAAA,MAAQ;AAAA,IACN,KAAA,EAAO,iBAAiB,GAAG,CAAA;AAAA,IAC3B,eAAA,EAAiB,aAAA;AAAA,IACjB,qDAAA,EAAuD;AAAA,MACrD,KAAA,EAAO,iBAAiB,GAAG,CAAA;AAAA,MAC3B,eAAA,EAAiB;AAAA;AACnB,GACF;AACF,CAAA;;ACpBO,MAAM,cAAA,GAAiBL,2BAAA,CAAOC,+BAAA,CAAU,GAAA,EAAK;AAAA,EAClD,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,UAAA,EAAY,CAAA;AAAA,EACZ,QAAA,EAAU;AAAA,IACR,OAAA,EAAS;AAAA;AAEb,CAAC,CAAA;;ACWD,MAAM,WAAA,GAAyD;AAAA,EAC7D,WAAA,iCAAcK,2CAAA,EAAA,EAA0B,CAAA;AAAA,EACxC,OAAA,iCAAUC,6BAAA,EAAA,EAAY,CAAA;AAAA,EACtB,MAAA,iCAASC,4CAAA,EAAA,EAA2B;AACtC,CAAA;AAEO,MAAM,QAAA,GAAW,MAAM,UAAA,CAG5B,CAAC,EAAE,QAAA,EAAU,GAAG,SAAA,EAAU,EAAG,UAAA,KAAe;AAC5C,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,gBAAA,EAAiB;AAErC,EAAA,MAAM,OAAA,GACJ,KAAA,CAAM,QAAA,CAAS,KAAA,CAAM,QAAQ,CAAA,GAAI,CAAA,GAC7B,QAAA,GACA,OAAA,IAAW,IAAA,GACX,WAAA,CAAY,OAAO,CAAA,GACnB,MAAA;AAEN,EAAA,IAAI,WAAW,IAAA,EAAM;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,sCACG,cAAA,EAAA,EAAgB,GAAG,WAAW,GAAA,EAAK,UAAA,EAAY,SAC7C,QAAA,EAAA,OAAA,EACH,CAAA;AAEJ,CAAC,CAAA;AAED,QAAA,CAAS,WAAA,GAAc,iBAAA;;AClDhB,MAAM,eAAA,GAAkBR,2BAAA,CAAOC,+BAAA,CAAU,GAAA,EAAK;AAAA,EACnD,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,UAAA,EAAY,CAAA;AAAA,EACZ,OAAA,EAAS;AAAA,IACP,OAAA,EAAS,OAAA;AAAA,IACT,KAAA,EAAO,IAAA;AAAA,IACP,MAAA,EAAQ,IAAA;AAAA,IACR,SAAA,EAAW,OAAA;AAAA,IACX,YAAA,EAAc;AAAA;AAElB,CAAC,CAAA;;ACCM,MAAM,SAAA,GAAY,MAAM,UAAA,CAG7B,CAAC,EAAE,QAAA,EAAU,GAAG,SAAA,EAAU,EAAG,UAAA,KAAe;AAC5C,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,KAAA,CAAM,QAAQ,MAAM,CAAA,EAAG;AACxC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,sCACG,eAAA,EAAA,EAAiB,GAAG,SAAA,EAAW,GAAA,EAAK,YAClC,QAAA,EACH,CAAA;AAEJ,CAAC,CAAA;AAED,SAAA,CAAU,WAAA,GAAc,kBAAA;;ACrBxB,MAAM,YAAA,GAAeD,4BAAOS,qBAAA,EAAM;AAAA,EAChC,UAAA,EAAY,QAAA;AAAA,EACZ,QAAA,EAAU;AAAA,IACR,KAAA,EAAO;AAAA;AAEX,CAAC,CAAA;AAIM,MAAM,SAAS,KAAA,CAAM,UAAA;AAAA,EAC1B,CAAC,OAAO,UAAA,KAAe;AACrB,IAAA,MAAM,EAAE,OAAA,EAAS,aAAA,EAAc,GAAI,gBAAA,EAAiB;AACpD,IAAA,uBACEN,cAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACE,GAAG,KAAA;AAAA,QACJ,GAAA,EAAK,UAAA;AAAA,QACL,OAAA,EAAQ,SAAA;AAAA,QACR,KAAA,EAAO;AAAA;AAAA,KACT;AAAA,EAEJ;AACF,CAAA;AAEA,MAAA,CAAO,WAAA,GAAc,eAAA;;ACrBrB,MAAM,mBAAA,GAAsBH,4BAAOU,iCAAA,EAAY;AAAA,EAC7C,UAAA,EAAY,CAAA;AAAA,EACZ,SAAA,EAAW,QAAA;AAAA,EACX,eAAA,EAAiB,MAAA;AAAA,EACjB,eAAA,EAAiB,aAAA;AAAA,EACjB,qDAAA,EAAuD;AAAA,IACrD,eAAA,EAAiB;AAAA,GACnB;AAAA,EACA,QAAA,EAAU;AAAA,IACR,KAAA,EAAO;AAAA;AAEX,CAAC,CAAA;AAQM,MAAM,aAAA,GAAgB,KAAA,CAAM,UAAA,CAGjC,CAAC,OAAO,UAAA,KAAe;AACvB,EAAA,MAAM,EAAE,OAAA,EAAS,aAAA,EAAc,GAAI,gBAAA,EAAiB;AAEpD,EAAA,uCACGC,2BAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAAR,cAAA,CAACQ,2BAAA,CAAQ,OAAA,EAAR,EAAgB,OAAA,EAAO,IAAA,EACtB,QAAA,kBAAAR,cAAA;AAAA,MAAC,mBAAA;AAAA,MAAA;AAAA,QACE,GAAG,KAAA;AAAA,QACJ,GAAA,EAAK,UAAA;AAAA,QACL,OAAA,EAAQ,OAAA;AAAA,QACR,IAAA,EAAK,QAAA;AAAA,QACL,KAAA,EAAO,aAAA;AAAA,QAEP,yCAACS,2BAAA,EAAA,EAAU;AAAA;AAAA,KACb,EACF,CAAA;AAAA,mCACCD,2BAAA,CAAQ,OAAA,EAAR,EAAiB,QAAA,EAAA,KAAA,CAAM,YAAY,CAAA,EAAE;AAAA,GAAA,EACxC,CAAA;AAEJ,CAAC,CAAA;AAED,aAAA,CAAc,WAAA,GAAc,sBAAA;;ACU5B,MAAM,YAAA,GAA0D;AAAA,EAC9D,WAAA,EAAa,QAAA;AAAA,EACb,OAAA,EAAS,OAAA;AAAA,EACT,MAAA,EAAQ,OAAA;AAAA,EACR,YAAA,EAAc;AAChB,CAAA;AAOO,MAAM,SAAS,KAAA,CAAM,UAAA;AAAA,EAI1B,CACE;AAAA,IACE,OAAA,GAAU,aAAA;AAAA,IACV,OAAA,GAAU,IAAA;AAAA,IACV,KAAA,GAAQ,OAAA;AAAA,IACR,WAAA,GAAc,IAAA;AAAA,IACd,SAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,IAAA;AAAA,IACA,GAAG;AAAA,KAEL,UAAA,KACG;AACH,IAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAIE,eAAkB,KAAK,CAAA;AAGzE,IAAA,IAAI,gCAAa,iBAAA,EAAmB;AAClC,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,qBACJ,WAAA,IAAe,YAAA,IAAgB,QAAQ,YAAA,CAAa,MAAA,GAAS,IACzD,YAAA,GACA,IAAA;AAEN,IAAA,MAAM,gBAAgB,MAAY;AAChC,MAAA,oBAAA,CAAqB,IAAI,CAAA;AACzB,MAAA,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,EAAA;AAAA,IACF,CAAA;AAIA,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,QAAQ,CAAA;AAC7C,IAAA,MAAM,MAAA,GAAS,CAAC,KAAA,EAAkB,IAAA,KAChCC,qBAAe,KAAK,CAAA,IAAK,MAAM,IAAA,KAAS,IAAA;AAC1C,IAAA,MAAM,UAAU,KAAA,CAAM,IAAA;AAAA,MACpB,WAAS,MAAA,CAAO,KAAA,EAAO,QAAQ,CAAA,IAAK,MAAA,CAAO,OAAO,SAAS;AAAA,KAC7D;AACA,IAAA,MAAM,SAAS,KAAA,CAAM,IAAA,CAAK,WAAS,MAAA,CAAO,KAAA,EAAO,MAAM,CAAC,CAAA;AACxD,IAAA,MAAM,UAAU,KAAA,CAAM,MAAA,CAAO,WAAS,KAAA,KAAU,OAAA,IAAW,UAAU,MAAM,CAAA;AAE3E,IAAA,uBACEX,cAAA,CAAC,kBAAe,OAAA,EACd,QAAA,kBAAAY,eAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACE,GAAG,KAAA;AAAA,QACJ,GAAA,EAAK,UAAA;AAAA,QACL,OAAA;AAAA,QACA,OAAA;AAAA,QACA,IAAA,EAAM,IAAA,IAAA,IAAA,GAAA,IAAA,GAAQ,YAAA,CAAa,OAAO,CAAA;AAAA,QAElC,QAAA,EAAA;AAAA,0BAAAA,eAAA,CAAC,uBAAoB,KAAA,EAClB,QAAA,EAAA;AAAA,YAAA,OAAA;AAAA,4BACDZ,cAAA,CAAC,uBAAqB,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,YAC7B;AAAA,WAAA,EACH,CAAA;AAAA,UACC,sBAAsB,IAAA,oBACrBA,cAAA;AAAA,YAAC,aAAA;AAAA,YAAA;AAAA,cACC,YAAA,EAAY,kBAAA;AAAA,cACZ,OAAA,EAAS;AAAA;AAAA;AACX;AAAA;AAAA,KAEJ,EACF,CAAA;AAAA,EAEJ;AACF;AAQA,MAAA,CAAO,QAAA,GAAW,QAAA;AAClB,MAAA,CAAO,SAAA,GAAY,SAAA;AACnB,MAAA,CAAO,MAAA,GAAS,MAAA;;;;"}
package/dist/module.js ADDED
@@ -0,0 +1,277 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import React, { createContext, useContext, useState, isValidElement } from 'react';
3
+ import { Primitive } from '@mirohq/design-system-primitive';
4
+ import { styled } from '@mirohq/design-system-stitches';
5
+ import { IconExclamationPointCircle, IconWarning, IconInformationMarkCircle, IconCross } from '@mirohq/design-system-icons';
6
+ import { mapKeysToVariants } from '@mirohq/design-system-utils';
7
+ import { Link } from '@mirohq/design-system-link';
8
+ import { IconButton } from '@mirohq/design-system-icon-button';
9
+ import { Tooltip } from '@mirohq/design-system-tooltip';
10
+
11
+ const StyledBanner = styled(Primitive.div, {
12
+ position: "relative",
13
+ boxSizing: "border-box",
14
+ width: "100%",
15
+ minHeight: "$11",
16
+ display: "flex",
17
+ alignItems: "center",
18
+ justifyContent: "space-between",
19
+ fontSize: "$175",
20
+ variants: {
21
+ variant: {
22
+ information: {
23
+ backgroundColor: "$notification-background-info",
24
+ color: "$notification-text-on-info"
25
+ },
26
+ warning: {
27
+ backgroundColor: "$notification-background-warning",
28
+ color: "$notification-text-on-warning"
29
+ },
30
+ danger: {
31
+ backgroundColor: "$notification-background-danger",
32
+ color: "$notification-text-on-danger"
33
+ },
34
+ announcement: {
35
+ backgroundColor: "$notification-background-announcement",
36
+ color: "$notification-text-on-announcement"
37
+ }
38
+ },
39
+ rounded: {
40
+ true: {
41
+ borderRadius: "$notification-banner"
42
+ },
43
+ false: {
44
+ borderRadius: 0
45
+ }
46
+ }
47
+ },
48
+ defaultVariants: {
49
+ variant: "information",
50
+ rounded: true
51
+ }
52
+ });
53
+ const StyledBannerContent = styled(Primitive.div, {
54
+ display: "flex",
55
+ padding: "$100 $200",
56
+ minWidth: 0,
57
+ flexDirection: "row",
58
+ alignItems: "center",
59
+ gap: "$200",
60
+ variants: {
61
+ align: {
62
+ start: {},
63
+ center: {
64
+ flex: 1,
65
+ justifyContent: "center",
66
+ textAlign: "center"
67
+ }
68
+ }
69
+ },
70
+ defaultVariants: {
71
+ align: "start"
72
+ }
73
+ });
74
+ const StyledBannerMessage = styled(Primitive.div, {
75
+ minWidth: 0,
76
+ // Inline links inherit the banner's text colour.
77
+ "& a": {
78
+ color: "inherit",
79
+ "&:hover, &:active, &:visited, &[data-hovered], &[data-pressed]": {
80
+ color: "inherit"
81
+ }
82
+ }
83
+ });
84
+
85
+ const BannerContext = createContext({});
86
+ const BannerProvider = ({
87
+ children,
88
+ ...restProps
89
+ }) => /* @__PURE__ */ jsx(BannerContext.Provider, { value: { ...restProps }, children });
90
+ const useBannerContext = () => useContext(BannerContext);
91
+
92
+ const FOREGROUND_COLOR = {
93
+ information: "$notification-icon-on-info",
94
+ warning: "$notification-icon-on-warning",
95
+ danger: "$notification-icon-on-danger",
96
+ announcement: "$notification-icon-on-announcement"
97
+ };
98
+ const colorVariants = mapKeysToVariants(FOREGROUND_COLOR, (key) => ({
99
+ color: FOREGROUND_COLOR[key]
100
+ }));
101
+ const interactiveColorVariants = mapKeysToVariants(
102
+ FOREGROUND_COLOR,
103
+ (key) => ({
104
+ color: FOREGROUND_COLOR[key],
105
+ backgroundColor: "transparent",
106
+ "&:hover, &[data-hovered], &:active, &[data-pressed]": {
107
+ color: FOREGROUND_COLOR[key],
108
+ backgroundColor: "transparent"
109
+ }
110
+ })
111
+ );
112
+
113
+ const StyledIconSlot = styled(Primitive.div, {
114
+ display: "flex",
115
+ alignItems: "center",
116
+ flexShrink: 0,
117
+ variants: {
118
+ variant: colorVariants
119
+ }
120
+ });
121
+
122
+ const defaultIcon = {
123
+ information: /* @__PURE__ */ jsx(IconInformationMarkCircle, {}),
124
+ warning: /* @__PURE__ */ jsx(IconWarning, {}),
125
+ danger: /* @__PURE__ */ jsx(IconExclamationPointCircle, {})
126
+ };
127
+ const IconSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
128
+ const { variant } = useBannerContext();
129
+ const content = React.Children.count(children) > 0 ? children : variant != null ? defaultIcon[variant] : void 0;
130
+ if (content == null) {
131
+ return null;
132
+ }
133
+ return /* @__PURE__ */ jsx(StyledIconSlot, { ...restProps, ref: forwardRef, variant, children: content });
134
+ });
135
+ IconSlot.displayName = "Banner.IconSlot";
136
+
137
+ const StyledImageSlot = styled(Primitive.div, {
138
+ display: "flex",
139
+ alignItems: "center",
140
+ flexShrink: 0,
141
+ "& img": {
142
+ display: "block",
143
+ width: "$6",
144
+ height: "$6",
145
+ objectFit: "cover",
146
+ borderRadius: "$50"
147
+ }
148
+ });
149
+
150
+ const ImageSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
151
+ if (React.Children.count(children) === 0) {
152
+ return null;
153
+ }
154
+ return /* @__PURE__ */ jsx(StyledImageSlot, { ...restProps, ref: forwardRef, children });
155
+ });
156
+ ImageSlot.displayName = "Banner.ImageSlot";
157
+
158
+ const StyledAction = styled(Link, {
159
+ whiteSpace: "nowrap",
160
+ variants: {
161
+ color: interactiveColorVariants
162
+ }
163
+ });
164
+ const Action = React.forwardRef(
165
+ (props, forwardRef) => {
166
+ const { variant: bannerVariant } = useBannerContext();
167
+ return /* @__PURE__ */ jsx(
168
+ StyledAction,
169
+ {
170
+ ...props,
171
+ ref: forwardRef,
172
+ variant: "primary",
173
+ color: bannerVariant
174
+ }
175
+ );
176
+ }
177
+ );
178
+ Action.displayName = "Banner.Action";
179
+
180
+ const StyledDismissButton = styled(IconButton, {
181
+ flexShrink: 0,
182
+ alignSelf: "center",
183
+ marginInlineEnd: "$100",
184
+ backgroundColor: "transparent",
185
+ "&:hover, &[data-hovered], &:active, &[data-pressed]": {
186
+ backgroundColor: "transparent"
187
+ },
188
+ variants: {
189
+ color: interactiveColorVariants
190
+ }
191
+ });
192
+ const DismissButton = React.forwardRef((props, forwardRef) => {
193
+ const { variant: bannerVariant } = useBannerContext();
194
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
195
+ /* @__PURE__ */ jsx(Tooltip.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
196
+ StyledDismissButton,
197
+ {
198
+ ...props,
199
+ ref: forwardRef,
200
+ variant: "ghost",
201
+ size: "medium",
202
+ color: bannerVariant,
203
+ children: /* @__PURE__ */ jsx(IconCross, {})
204
+ }
205
+ ) }),
206
+ /* @__PURE__ */ jsx(Tooltip.Content, { children: props["aria-label"] })
207
+ ] });
208
+ });
209
+ DismissButton.displayName = "Banner.DismissButton";
210
+
211
+ const VARIANT_ROLE = {
212
+ information: "status",
213
+ warning: "alert",
214
+ danger: "alert",
215
+ announcement: "status"
216
+ };
217
+ const Banner = React.forwardRef(
218
+ ({
219
+ variant = "information",
220
+ rounded = true,
221
+ align = "start",
222
+ dismissible = true,
223
+ dismissed,
224
+ dismissLabel,
225
+ onDismiss,
226
+ children,
227
+ role,
228
+ ...props
229
+ }, forwardRef) => {
230
+ const [internalDismissed, setInternalDismissed] = useState(false);
231
+ if (dismissed != null ? dismissed : internalDismissed) {
232
+ return null;
233
+ }
234
+ const dismissButtonLabel = dismissible && dismissLabel != null && dismissLabel.length > 0 ? dismissLabel : null;
235
+ const handleDismiss = () => {
236
+ setInternalDismissed(true);
237
+ onDismiss == null ? void 0 : onDismiss();
238
+ };
239
+ const items = React.Children.toArray(children);
240
+ const isType = (child, type) => isValidElement(child) && child.type === type;
241
+ const leading = items.find(
242
+ (child) => isType(child, IconSlot) || isType(child, ImageSlot)
243
+ );
244
+ const action = items.find((child) => isType(child, Action));
245
+ const message = items.filter((child) => child !== leading && child !== action);
246
+ return /* @__PURE__ */ jsx(BannerProvider, { variant, children: /* @__PURE__ */ jsxs(
247
+ StyledBanner,
248
+ {
249
+ ...props,
250
+ ref: forwardRef,
251
+ variant,
252
+ rounded,
253
+ role: role != null ? role : VARIANT_ROLE[variant],
254
+ children: [
255
+ /* @__PURE__ */ jsxs(StyledBannerContent, { align, children: [
256
+ leading,
257
+ /* @__PURE__ */ jsx(StyledBannerMessage, { children: message }),
258
+ action
259
+ ] }),
260
+ dismissButtonLabel != null && /* @__PURE__ */ jsx(
261
+ DismissButton,
262
+ {
263
+ "aria-label": dismissButtonLabel,
264
+ onPress: handleDismiss
265
+ }
266
+ )
267
+ ]
268
+ }
269
+ ) });
270
+ }
271
+ );
272
+ Banner.IconSlot = IconSlot;
273
+ Banner.ImageSlot = ImageSlot;
274
+ Banner.Action = Action;
275
+
276
+ export { Banner };
277
+ //# sourceMappingURL=module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.js","sources":["../src/banner.styled.tsx","../src/hooks/use-banner-context.tsx","../src/banner.colors.ts","../src/partials/icon-slot.styled.ts","../src/partials/icon-slot.tsx","../src/partials/image-slot.styled.ts","../src/partials/image-slot.tsx","../src/partials/action.tsx","../src/partials/dismiss-button.tsx","../src/banner.tsx"],"sourcesContent":["import type { ComponentPropsWithRef } from 'react'\nimport { Primitive } from '@mirohq/design-system-primitive'\nimport { styled } from '@mirohq/design-system-stitches'\n\nexport const StyledBanner = styled(Primitive.div, {\n position: 'relative',\n boxSizing: 'border-box',\n width: '100%',\n minHeight: '$11',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n fontSize: '$175',\n variants: {\n variant: {\n information: {\n backgroundColor: '$notification-background-info',\n color: '$notification-text-on-info',\n },\n warning: {\n backgroundColor: '$notification-background-warning',\n color: '$notification-text-on-warning',\n },\n danger: {\n backgroundColor: '$notification-background-danger',\n color: '$notification-text-on-danger',\n },\n announcement: {\n backgroundColor: '$notification-background-announcement',\n color: '$notification-text-on-announcement',\n },\n },\n rounded: {\n true: {\n borderRadius: '$notification-banner',\n },\n false: {\n borderRadius: 0,\n },\n },\n },\n defaultVariants: {\n variant: 'information',\n rounded: true,\n },\n})\n\nexport const StyledBannerContent = styled(Primitive.div, {\n display: 'flex',\n padding: '$100 $200',\n minWidth: 0,\n flexDirection: 'row',\n alignItems: 'center',\n gap: '$200',\n\n variants: {\n align: {\n start: {},\n center: {\n flex: 1,\n justifyContent: 'center',\n textAlign: 'center',\n },\n },\n },\n defaultVariants: {\n align: 'start',\n },\n})\n\nexport const StyledBannerMessage = styled(Primitive.div, {\n minWidth: 0,\n // Inline links inherit the banner's text colour.\n '& a': {\n color: 'inherit',\n '&:hover, &:active, &:visited, &[data-hovered], &[data-pressed]': {\n color: 'inherit',\n },\n },\n})\n\nexport type StyledBannerProps = ComponentPropsWithRef<typeof StyledBanner>\n\n// Derived from the styled `variant` variants — the single source of truth.\n// `Extract<…, string>` drops the stitches responsive-object form so the union\n// stays a plain, indexable string union (e.g. for VARIANT_ROLE / default-icon).\nexport type BannerVariant = Extract<StyledBannerProps['variant'], string>\n","import { createContext, useContext } from 'react'\n\nimport type { BannerVariant } from '../banner.styled'\n\ninterface BannerContextProps {\n variant?: BannerVariant\n}\n\nexport interface BannerProviderProps extends BannerContextProps {\n children: React.ReactNode\n}\n\nconst BannerContext = createContext<BannerContextProps>({})\n\nexport const BannerProvider = ({\n children,\n ...restProps\n}: BannerProviderProps): JSX.Element => (\n <BannerContext.Provider value={{ ...restProps }}>\n {children}\n </BannerContext.Provider>\n)\n\nexport const useBannerContext = (): BannerContextProps =>\n useContext(BannerContext)\n","import { mapKeysToVariants } from '@mirohq/design-system-utils'\n\nimport type { BannerVariant } from './banner.styled'\n\nexport const FOREGROUND_COLOR: Record<BannerVariant, string> = {\n information: '$notification-icon-on-info',\n warning: '$notification-icon-on-warning',\n danger: '$notification-icon-on-danger',\n announcement: '$notification-icon-on-announcement',\n}\n\nexport const colorVariants = mapKeysToVariants(FOREGROUND_COLOR, key => ({\n color: FOREGROUND_COLOR[key],\n}))\n\nexport const interactiveColorVariants = mapKeysToVariants(\n FOREGROUND_COLOR,\n key => ({\n color: FOREGROUND_COLOR[key],\n backgroundColor: 'transparent',\n '&:hover, &[data-hovered], &:active, &[data-pressed]': {\n color: FOREGROUND_COLOR[key],\n backgroundColor: 'transparent',\n },\n })\n)\n","import { Primitive } from '@mirohq/design-system-primitive'\nimport { styled } from '@mirohq/design-system-stitches'\n\nimport { colorVariants } from '../banner.colors'\n\nexport const StyledIconSlot = styled(Primitive.div, {\n display: 'flex',\n alignItems: 'center',\n flexShrink: 0,\n variants: {\n variant: colorVariants,\n },\n})\n","import React from 'react'\nimport type { ElementRef, ComponentPropsWithRef, ReactNode } from 'react'\nimport {\n IconExclamationPointCircle,\n IconInformationMarkCircle,\n IconWarning,\n} from '@mirohq/design-system-icons'\n\nimport { useBannerContext } from '../hooks/use-banner-context'\nimport type { BannerVariant } from '../banner.styled'\nimport { StyledIconSlot } from './icon-slot.styled'\n\nexport type StyledIconSlotProps = ComponentPropsWithRef<typeof StyledIconSlot>\n\nexport interface IconSlotProps extends Omit<StyledIconSlotProps, 'variant'> {\n /**\n * The DS icon. When omitted, the variant's default icon is shown for\n * information / warning / danger; announcement has no default (consumers\n * supply their own). For image avatars use `Banner.ImageSlot` instead.\n */\n children?: ReactNode\n}\n\nconst defaultIcon: Partial<Record<BannerVariant, ReactNode>> = {\n information: <IconInformationMarkCircle />,\n warning: <IconWarning />,\n danger: <IconExclamationPointCircle />,\n}\n\nexport const IconSlot = React.forwardRef<\n ElementRef<typeof StyledIconSlot>,\n IconSlotProps\n>(({ children, ...restProps }, forwardRef) => {\n const { variant } = useBannerContext()\n\n const content =\n React.Children.count(children) > 0\n ? children\n : variant != null\n ? defaultIcon[variant]\n : undefined\n\n if (content == null) {\n return null\n }\n\n return (\n <StyledIconSlot {...restProps} ref={forwardRef} variant={variant}>\n {content}\n </StyledIconSlot>\n )\n})\n\nIconSlot.displayName = 'Banner.IconSlot'\n","import { Primitive } from '@mirohq/design-system-primitive'\nimport { styled } from '@mirohq/design-system-stitches'\n\nexport const StyledImageSlot = styled(Primitive.div, {\n display: 'flex',\n alignItems: 'center',\n flexShrink: 0,\n '& img': {\n display: 'block',\n width: '$6',\n height: '$6',\n objectFit: 'cover',\n borderRadius: '$50',\n },\n})\n","import React from 'react'\nimport type { ElementRef, ComponentPropsWithRef, ReactNode } from 'react'\n\nimport { StyledImageSlot } from './image-slot.styled'\n\nexport type StyledImageSlotProps = ComponentPropsWithRef<typeof StyledImageSlot>\n\nexport interface ImageSlotProps extends StyledImageSlotProps {\n /**\n * The image icon. Pass an `<img>` (any source) — it is rendered as a square,\n * rounded avatar. For DS icons use `Banner.IconSlot` instead.\n */\n children?: ReactNode\n}\n\nexport const ImageSlot = React.forwardRef<\n ElementRef<typeof StyledImageSlot>,\n ImageSlotProps\n>(({ children, ...restProps }, forwardRef) => {\n if (React.Children.count(children) === 0) {\n return null\n }\n\n return (\n <StyledImageSlot {...restProps} ref={forwardRef}>\n {children}\n </StyledImageSlot>\n )\n})\n\nImageSlot.displayName = 'Banner.ImageSlot'\n","import React from 'react'\nimport type { ElementRef } from 'react'\nimport { Link } from '@mirohq/design-system-link'\nimport type { LinkProps } from '@mirohq/design-system-link'\nimport { styled } from '@mirohq/design-system-stitches'\n\nimport { useBannerContext } from '../hooks/use-banner-context'\nimport { interactiveColorVariants } from '../banner.colors'\n\nconst StyledAction = styled(Link, {\n whiteSpace: 'nowrap',\n variants: {\n color: interactiveColorVariants,\n },\n})\n\nexport type ActionProps = Omit<LinkProps, 'variant'>\n\nexport const Action = React.forwardRef<ElementRef<typeof Link>, ActionProps>(\n (props, forwardRef) => {\n const { variant: bannerVariant } = useBannerContext()\n return (\n <StyledAction\n {...props}\n ref={forwardRef}\n variant='primary'\n color={bannerVariant}\n />\n )\n }\n)\n\nAction.displayName = 'Banner.Action'\n","import React from 'react'\nimport type { ElementRef } from 'react'\nimport { styled } from '@mirohq/design-system-stitches'\nimport { IconButton } from '@mirohq/design-system-icon-button'\nimport type { IconButtonProps } from '@mirohq/design-system-icon-button'\nimport { IconCross } from '@mirohq/design-system-icons'\nimport { Tooltip } from '@mirohq/design-system-tooltip'\n\nimport { useBannerContext } from '../hooks/use-banner-context'\nimport { interactiveColorVariants } from '../banner.colors'\n\nconst StyledDismissButton = styled(IconButton, {\n flexShrink: 0,\n alignSelf: 'center',\n marginInlineEnd: '$100',\n backgroundColor: 'transparent',\n '&:hover, &[data-hovered], &:active, &[data-pressed]': {\n backgroundColor: 'transparent',\n },\n variants: {\n color: interactiveColorVariants,\n },\n})\n\n// The icon, ghost variant and size are owned by the banner\nexport type DismissButtonProps = Omit<\n IconButtonProps,\n 'variant' | 'size' | 'children'\n>\n\nexport const DismissButton = React.forwardRef<\n ElementRef<typeof IconButton>,\n DismissButtonProps\n>((props, forwardRef) => {\n const { variant: bannerVariant } = useBannerContext()\n\n return (\n <Tooltip>\n <Tooltip.Trigger asChild>\n <StyledDismissButton\n {...props}\n ref={forwardRef}\n variant='ghost'\n size='medium'\n color={bannerVariant}\n >\n <IconCross />\n </StyledDismissButton>\n </Tooltip.Trigger>\n <Tooltip.Content>{props['aria-label']}</Tooltip.Content>\n </Tooltip>\n )\n})\n\nDismissButton.displayName = 'Banner.DismissButton'\n","import React, { useState, isValidElement } from 'react'\nimport type { ElementRef, ForwardRefExoticComponent, ReactNode } from 'react'\n\nimport {\n StyledBanner,\n StyledBannerContent,\n StyledBannerMessage,\n} from './banner.styled'\nimport type { StyledBannerProps, BannerVariant } from './banner.styled'\nimport { BannerProvider } from './hooks/use-banner-context'\nimport { IconSlot } from './partials/icon-slot'\nimport { ImageSlot } from './partials/image-slot'\nimport { Action } from './partials/action'\nimport { DismissButton } from './partials/dismiss-button'\n\nexport interface BannerProps extends StyledBannerProps {\n /**\n * Visual style — drives background, default icon and tone.\n * @default 'information'\n */\n variant?: Extract<StyledBannerProps['variant'], string>\n\n /**\n * Rounded floating banner (`true`) or full-page, edge-to-edge banner (`false`).\n * @default true\n */\n rounded?: boolean\n\n /**\n * Content alignment. `center` fills the row and centres the content.\n * @default 'start'\n */\n align?: 'start' | 'center'\n\n /**\n * Whether to show the dismiss button.\n * @default true\n */\n dismissible?: boolean\n\n /**\n * Controlled dismissed state. When set, the consumer owns visibility and the\n * banner does not self-hide on dismiss. Omit for uncontrolled self-hide.\n */\n dismissed?: boolean\n\n /**\n * aria-label for the dismiss button. Required for the dismiss button to render.\n */\n dismissLabel?: string\n\n /**\n * Callback invoked once the dismiss button is clicked.\n */\n onDismiss?: () => void\n\n /**\n * The banner message. Rich text (bold, inline links) is composed by the\n * consumer and passed as children — there is no markdown parsing here.\n */\n children?: ReactNode\n}\n\n// danger/warning announce assertively (alert); the rest politely (status).\nconst VARIANT_ROLE: Record<BannerVariant, 'alert' | 'status'> = {\n information: 'status',\n warning: 'alert',\n danger: 'alert',\n announcement: 'status',\n}\n\n/**\n * Banner displays a prominent, full-width message at the top of a surface.\n *\n * @experimental Beta — the API may still change while teams adopt it.\n */\nexport const Banner = React.forwardRef<\n ElementRef<typeof StyledBanner>,\n BannerProps\n>(\n (\n {\n variant = 'information',\n rounded = true,\n align = 'start',\n dismissible = true,\n dismissed,\n dismissLabel,\n onDismiss,\n children,\n role,\n ...props\n },\n forwardRef\n ) => {\n const [internalDismissed, setInternalDismissed] = useState<boolean>(false)\n\n // Controlled when `dismissed` is provided; otherwise self-managed.\n if (dismissed ?? internalDismissed) {\n return null\n }\n\n // The dismiss button renders only when a label is provided.\n const dismissButtonLabel =\n dismissible && dismissLabel != null && dismissLabel.length > 0\n ? dismissLabel\n : null\n\n const handleDismiss = (): void => {\n setInternalDismissed(true)\n onDismiss?.()\n }\n\n // Pull out the leading visual (IconSlot/ImageSlot) and the action; the rest\n // is the message, wrapped so its rich-text children flow inline as one block.\n const items = React.Children.toArray(children)\n const isType = (child: ReactNode, type: unknown): boolean =>\n isValidElement(child) && child.type === type\n const leading = items.find(\n child => isType(child, IconSlot) || isType(child, ImageSlot)\n )\n const action = items.find(child => isType(child, Action))\n const message = items.filter(child => child !== leading && child !== action)\n\n return (\n <BannerProvider variant={variant}>\n <StyledBanner\n {...props}\n ref={forwardRef}\n variant={variant}\n rounded={rounded}\n role={role ?? VARIANT_ROLE[variant]}\n >\n <StyledBannerContent align={align}>\n {leading}\n <StyledBannerMessage>{message}</StyledBannerMessage>\n {action}\n </StyledBannerContent>\n {dismissButtonLabel != null && (\n <DismissButton\n aria-label={dismissButtonLabel}\n onPress={handleDismiss}\n />\n )}\n </StyledBanner>\n </BannerProvider>\n )\n }\n) as ForwardRefExoticComponent<BannerProps> & Partials\n\nexport interface Partials {\n IconSlot: typeof IconSlot\n ImageSlot: typeof ImageSlot\n Action: typeof Action\n}\n\nBanner.IconSlot = IconSlot\nBanner.ImageSlot = ImageSlot\nBanner.Action = Action\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ import * as react from 'react';
2
+ import react__default, { ComponentPropsWithRef, ReactNode, ForwardRefExoticComponent } from 'react';
3
+ import * as _mirohq_design_system_stitches from '@mirohq/design-system-stitches';
4
+ import * as _mirohq_design_system_primitive from '@mirohq/design-system-primitive';
5
+ import { LinkProps } from '@mirohq/design-system-link';
6
+
7
+ /* Utilities */
8
+ /* ========================================================================== */
9
+
10
+ /** Returns a string with the given prefix followed by the given values. */
11
+ type Prefixed<K extends string, T> = `${K}${Extract<T, boolean | number | string>}`
12
+
13
+ type TransformProps<Props, Media> = {
14
+ [K in keyof Props]: (
15
+ | Props[K]
16
+ | (
17
+ & {
18
+ [KMedia in Prefixed<'@', 'initial' | keyof Media>]?: Props[K]
19
+ }
20
+ & {
21
+ [KMedia in string]: Props[K]
22
+ }
23
+ )
24
+ )
25
+ }
26
+
27
+ declare const StyledBanner: react.ForwardRefExoticComponent<Omit<Omit<_mirohq_design_system_stitches.StyledComponentProps<react.ForwardRefExoticComponent<_mirohq_design_system_primitive.PrimitiveProps<"div">>>, "variant" | "rounded"> & TransformProps<{
28
+ variant?: "information" | "warning" | "danger" | "announcement" | undefined;
29
+ rounded?: boolean | "true" | "false" | undefined;
30
+ }, {}> & _mirohq_design_system_stitches.CustomStylesProps, "ref"> & react.RefAttributes<HTMLDivElement>> & _mirohq_design_system_stitches.StitchesInternals<react.ForwardRefExoticComponent<_mirohq_design_system_primitive.PrimitiveProps<"div">>, {
31
+ variant?: "information" | "warning" | "danger" | "announcement" | undefined;
32
+ rounded?: boolean | "true" | "false" | undefined;
33
+ }, {}>;
34
+ type StyledBannerProps = ComponentPropsWithRef<typeof StyledBanner>;
35
+ type BannerVariant = Extract<StyledBannerProps['variant'], string>;
36
+
37
+ declare const StyledIconSlot: react.ForwardRefExoticComponent<Omit<Omit<_mirohq_design_system_stitches.StyledComponentProps<react.ForwardRefExoticComponent<_mirohq_design_system_primitive.PrimitiveProps<"div">>>, "variant"> & TransformProps<{
38
+ variant?: BannerVariant | undefined;
39
+ }, {}> & _mirohq_design_system_stitches.CustomStylesProps, "ref"> & react.RefAttributes<HTMLDivElement>> & _mirohq_design_system_stitches.StitchesInternals<react.ForwardRefExoticComponent<_mirohq_design_system_primitive.PrimitiveProps<"div">>, {
40
+ variant?: BannerVariant | undefined;
41
+ }, {}>;
42
+
43
+ type StyledIconSlotProps = ComponentPropsWithRef<typeof StyledIconSlot>;
44
+ interface IconSlotProps extends Omit<StyledIconSlotProps, 'variant'> {
45
+ /**
46
+ * The DS icon. When omitted, the variant's default icon is shown for
47
+ * information / warning / danger; announcement has no default (consumers
48
+ * supply their own). For image avatars use `Banner.ImageSlot` instead.
49
+ */
50
+ children?: ReactNode;
51
+ }
52
+ declare const IconSlot: react__default.ForwardRefExoticComponent<Omit<IconSlotProps, "ref"> & react__default.RefAttributes<HTMLDivElement>>;
53
+
54
+ declare const StyledImageSlot: react.ForwardRefExoticComponent<Omit<Omit<_mirohq_design_system_stitches.StyledComponentProps<react.ForwardRefExoticComponent<_mirohq_design_system_primitive.PrimitiveProps<"div">>>, never> & TransformProps<{}, {}> & _mirohq_design_system_stitches.CustomStylesProps, "ref"> & react.RefAttributes<HTMLDivElement>> & _mirohq_design_system_stitches.StitchesInternals<react.ForwardRefExoticComponent<_mirohq_design_system_primitive.PrimitiveProps<"div">>, {}, {}>;
55
+
56
+ type StyledImageSlotProps = ComponentPropsWithRef<typeof StyledImageSlot>;
57
+ interface ImageSlotProps extends StyledImageSlotProps {
58
+ /**
59
+ * The image icon. Pass an `<img>` (any source) — it is rendered as a square,
60
+ * rounded avatar. For DS icons use `Banner.IconSlot` instead.
61
+ */
62
+ children?: ReactNode;
63
+ }
64
+ declare const ImageSlot: react__default.ForwardRefExoticComponent<Omit<ImageSlotProps, "ref"> & react__default.RefAttributes<HTMLDivElement>>;
65
+
66
+ type ActionProps = Omit<LinkProps, 'variant'>;
67
+ declare const Action: react__default.ForwardRefExoticComponent<Omit<ActionProps, "ref"> & react__default.RefAttributes<HTMLAnchorElement | HTMLButtonElement>>;
68
+
69
+ interface BannerProps extends StyledBannerProps {
70
+ /**
71
+ * Visual style — drives background, default icon and tone.
72
+ * @default 'information'
73
+ */
74
+ variant?: Extract<StyledBannerProps['variant'], string>;
75
+ /**
76
+ * Rounded floating banner (`true`) or full-page, edge-to-edge banner (`false`).
77
+ * @default true
78
+ */
79
+ rounded?: boolean;
80
+ /**
81
+ * Content alignment. `center` fills the row and centres the content.
82
+ * @default 'start'
83
+ */
84
+ align?: 'start' | 'center';
85
+ /**
86
+ * Whether to show the dismiss button.
87
+ * @default true
88
+ */
89
+ dismissible?: boolean;
90
+ /**
91
+ * Controlled dismissed state. When set, the consumer owns visibility and the
92
+ * banner does not self-hide on dismiss. Omit for uncontrolled self-hide.
93
+ */
94
+ dismissed?: boolean;
95
+ /**
96
+ * aria-label for the dismiss button. Required for the dismiss button to render.
97
+ */
98
+ dismissLabel?: string;
99
+ /**
100
+ * Callback invoked once the dismiss button is clicked.
101
+ */
102
+ onDismiss?: () => void;
103
+ /**
104
+ * The banner message. Rich text (bold, inline links) is composed by the
105
+ * consumer and passed as children — there is no markdown parsing here.
106
+ */
107
+ children?: ReactNode;
108
+ }
109
+ /**
110
+ * Banner displays a prominent, full-width message at the top of a surface.
111
+ *
112
+ * @experimental Beta — the API may still change while teams adopt it.
113
+ */
114
+ declare const Banner: ForwardRefExoticComponent<BannerProps> & Partials;
115
+ interface Partials {
116
+ IconSlot: typeof IconSlot;
117
+ ImageSlot: typeof ImageSlot;
118
+ Action: typeof Action;
119
+ }
120
+
121
+ export { Banner };
122
+ export type { BannerProps };
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@mirohq/design-system-banner",
3
+ "version": "0.1.0",
4
+ "description": "",
5
+ "author": "Miro",
6
+ "source": "src/index.ts",
7
+ "main": "dist/main.js",
8
+ "module": "dist/module.js",
9
+ "types": "dist/types.d.ts",
10
+ "sideEffects": false,
11
+ "exports": {
12
+ ".": {
13
+ "require": "./dist/main.js",
14
+ "import": "./dist/module.js",
15
+ "types": "./dist/types.d.ts"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "peerDependencies": {
25
+ "@stitches/react": "^1.2.8",
26
+ "react": "^16.14 || ^17 || ^18 || ^19"
27
+ },
28
+ "dependencies": {
29
+ "@mirohq/design-system-icon-button": "^4.2.37",
30
+ "@mirohq/design-system-icons": "^1.40.2",
31
+ "@mirohq/design-system-link": "^2.5.22",
32
+ "@mirohq/design-system-stitches": "^3.3.30",
33
+ "@mirohq/design-system-primitive": "^2.2.1",
34
+ "@mirohq/design-system-tooltip": "^4.4.32",
35
+ "@mirohq/design-system-utils": "^1.3.0"
36
+ },
37
+ "scripts": {
38
+ "build": "rollup -c ../../../rollup.config.js",
39
+ "clean": "rm -rf dist",
40
+ "prebuild": "pnpm clean"
41
+ }
42
+ }