Skip to content

Commit 0ea47ed

Browse files
committed
fix: migration component Alert
1 parent d8f0947 commit 0ea47ed

File tree

35 files changed

+540
-137
lines changed

35 files changed

+540
-137
lines changed

apps/portal/src/content/docs/components/alert.mdx

Lines changed: 147 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,56 @@ description: Alert component
44
beta: true
55
---
66

7-
The `Alert` component provides a flexible UI element for displaying alert messages. It is composed of several subcomponents such as `AlertContainer`, `AlertTitle`, and `AlertDescription` to offer a structured and customizable interface.
7+
The `Alert` component provides a flexible UI element for displaying alert messages. It is composed of several subcomponents such as `AlertRoot`, `AlertTitle`, `AlertDescription`, and `AlertLink` to offer a structured and customizable interface.
88

99
import { DocsPage } from "@/components/docs-page";
1010

1111
<DocsPage.ComponentExample
1212
client:only
1313
code={`<div className="space-y-4">
14-
<Alert.Container className="bg-red-100 border-red-400 text-red-700 px-4 py-3">
15-
<Alert.Title className="font-bold">Error Alert</Alert.Title>
16-
<Alert.Description className="text-red-800">This is an error alert description.</Alert.Description>
17-
</Alert.Container>
18-
<Alert.Container className="bg-yellow-100 border-yellow-400 text-yellow-700 px-4 py-3">
19-
<Alert.Title className="font-bold">Warning Alert</Alert.Title>
20-
<Alert.Description className="text-yellow-800">This is a warning alert description.</Alert.Description>
21-
</Alert.Container>
14+
<Alert.Root theme="info">
15+
<Alert.Title>Alert Title</Alert.Title>
16+
<Alert.Description>This is an alert description.</Alert.Description>
17+
</Alert.Root>
18+
<Alert.Root theme="danger" dismissible>
19+
<Alert.Description >We couldn’t complete your request because it violates an Open Policy Agent (OPA) rule set by your organization. Please review the applicable policies or contact your administrator for clarification, then try creating the feature flag again.</Alert.Description>
20+
</Alert.Root>
21+
<Alert.Root theme="warning" dismissible>
22+
<Alert.Title>Warning Alert</Alert.Title>
23+
<Alert.Description>This is a warning alert description.</Alert.Description>
24+
</Alert.Root>
25+
<Alert.Root dismissible>
26+
<Alert.Title>Dismissible Alert</Alert.Title>
27+
</Alert.Root>
28+
<Alert.Root >
29+
<Alert.Title>Link Alert</Alert.Title>
30+
<Alert.Link to="/abc">Learn more</Alert.Link>
31+
</Alert.Root>
32+
<Alert.Root >
33+
<Alert.Title theme="warning">Link Alert as child</Alert.Title>
34+
<Alert.Link to="/abc" asChild><Button>Learn more</Button></Alert.Link>
35+
</Alert.Root>
36+
<Alert.Root theme="danger">
37+
<Alert.Title>Crowded Alert not expandable</Alert.Title>
38+
<Alert.Description >LoremLorem ipsum dolor sit amet consectetur adipisicing elit. Unde molestiae hic, iste nostrum, quia eaque amet autem optio rem earum nihil rerum illo! Possimus</Alert.Description>
39+
</Alert.Root>
40+
<Alert.Root expandable>
41+
<Alert.Title>Crowded Alert</Alert.Title>
42+
<Alert.Description >Lorem, ipsum dolor sit amet consectetur adipisicing elit. Placeat magnam suscipit fugit officiis dignissimos iusto similique deleniti. Quod odio amet quisquam, blanditiis necessitatibus aliquam cumque beatae debitis sunt nemo perspiciatis a saepe enim voluptas? Incidunt vel officiis quam, corrupti ea aliquid nobis! Soluta accusantium ex, alias quod velit explicabo modi exercitationem eaque incidunt fuga, nihil fugiat voluptatum doloribus repudiandae atque.</Alert.Description>
43+
<Alert.Link to="/abc">Learn more</Alert.Link>
44+
</Alert.Root>
45+
<Alert.Root theme="danger" expandable>
46+
<Alert.Title>Crowded Alert</Alert.Title>
47+
<Alert.Description >Lorem, ipsum dolor sit amet consectetur adipisicing elit. Placeat magnam suscipit fugit officiis dignissimos iusto similique deleniti. Quod odio amet quisquam, blanditiis necessitatibus aliquam cumque beatae debitis sunt nemo perspiciatis a saepe enim voluptas? Incidunt vel officiis quam, corrupti ea aliquid nobis! Soluta accusantium ex, alias quod velit explicabo modi exercitationem eaque incidunt fuga, nihil fugiat voluptatum doloribus repudiandae atque.</Alert.Description>
48+
</Alert.Root>
49+
<Alert.Root theme="warning" expandable>
50+
<Alert.Title>Crowded Alert</Alert.Title>
51+
<Alert.Description>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Placeat magnam suscipit fugit officiis dignissimos iusto similique deleniti. Quod odio amet quisquam, blanditiis necessitatibus aliquam cumque beatae debitis sunt nemo perspiciatis a saepe enim voluptas? Incidunt vel officiis quam, corrupti ea aliquid nobis! Soluta accusantium ex, alias quod velit explicabo modi exercitationem eaque incidunt fuga, nihil fugiat voluptatum doloribus repudiandae atque.</Alert.Description>
52+
</Alert.Root>
53+
<Alert.Root expandable>
54+
<Alert.Title>Expandable but not crowded</Alert.Title>
55+
<Alert.Description >LoremLorem ipsum dolor sit amet consectetur adipisicing elit. Unde molestiae hic</Alert.Description>
56+
</Alert.Root>
2257
</div>`}
2358
/>
2459

@@ -28,10 +63,24 @@ import { DocsPage } from "@/components/docs-page";
2863
import { Alert } from '@harnessio/ui/components'
2964

3065
return (
31-
<Alert.Container>
32-
<Alert.Title>Alert Title</Alert.Title>
33-
<Alert.Description>This is the alert description.</Alert.Description>
34-
</Alert.Container>
66+
<Alert.Root
67+
theme="info"
68+
expandable
69+
dismissible
70+
onDismiss={handleDismiss}
71+
>
72+
<Alert.Title>My Alert</Alert.Title>
73+
74+
<Alert.Description>This is the description of the alert</Alert.Description>
75+
76+
<Alert.Link
77+
to="someplace"
78+
external
79+
asChild
80+
>
81+
Learn more
82+
</Alert.Link>
83+
</Alert.Root>
3584
)
3685
```
3786

@@ -40,17 +89,17 @@ return (
4089
All parts of the `Alert` component can be imported and composed as required.
4190

4291
```typescript jsx
43-
<Alert.Container>
92+
<Alert.Root>
4493
<Alert.Title />
4594
<Alert.Description />
46-
</Alert.Container>
95+
</Alert.Root>
4796
```
4897

4998
## API Reference
5099

51-
### Container
100+
### Root
52101

53-
The `Container` component serves as the main container for all alert elements.
102+
The `Root` component serves as the main container for all alert elements.
54103

55104
<DocsPage.PropsTable
56105
props={[
@@ -60,12 +109,46 @@ The `Container` component serves as the main container for all alert elements.
60109
"You can pass in your `Alert.Title` and `Alert.Description` as children",
61110
required: true,
62111
value: "ReactNode",
112+
defaultValue: "",
63113
},
64114
{
65115
name: "className",
66116
description: "Additional class names to apply to the alert container",
67117
required: false,
68118
value: "string",
119+
defaultValue: "",
120+
},
121+
{
122+
name: "theme",
123+
description:
124+
"Theme of the alert. Can be one of 'info', 'warning', or 'danger'.",
125+
required: false,
126+
value: "'info' | 'warning' | 'danger'",
127+
defaultValue: "'info'",
128+
},
129+
{
130+
name: "dismissible",
131+
description:
132+
"If true, the alert can be dismissed by the user. Default is false.",
133+
required: false,
134+
value: "boolean",
135+
defaultValue: "false",
136+
},
137+
{
138+
name: "expandable",
139+
description:
140+
"If true, the alert can be expanded to show more content. Default is false.",
141+
required: false,
142+
value: "boolean",
143+
defaultValue: "false",
144+
},
145+
{
146+
name: "onDismiss",
147+
description:
148+
"Callback function that is called when the alert is dismissed.",
149+
required: false,
150+
value: "() => void",
151+
defaultValue: "",
69152
},
70153
]}
71154
/>
@@ -119,3 +202,50 @@ The `Description` component displays the description of the alert.
119202
},
120203
]}
121204
/>
205+
206+
### Link
207+
208+
The `Link` component is used to create a link within the alert.
209+
210+
```typescript jsx
211+
<Alert.Link to="/path">Learn more</Alert.Link>
212+
```
213+
214+
<DocsPage.PropsTable
215+
props={[
216+
{
217+
name: "to",
218+
description: "The URL to link to.",
219+
required: true,
220+
value: "string",
221+
},
222+
{
223+
name: "children",
224+
description: "Link content",
225+
required: true,
226+
value: "ReactNode",
227+
},
228+
{
229+
name: "className",
230+
description: "Additional class names to apply to the alert link",
231+
required: false,
232+
value: "string",
233+
},
234+
{
235+
name: "external",
236+
description:
237+
"If true, the link will open in a new tab. Default is false.",
238+
required: false,
239+
value: "boolean",
240+
defaultValue: "false",
241+
},
242+
{
243+
name: "asChild",
244+
description:
245+
"If true, the link will be rendered as a child of the alert. Default is false.",
246+
required: false,
247+
value: "boolean",
248+
defaultValue: "false",
249+
},
250+
]}
251+
/>

packages/ui/src/components/alert/Alert.test.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,26 @@ import { render, screen } from '@testing-library/react'
22

33
import { Alert } from './'
44

5+
beforeAll(() => {
6+
global.ResizeObserver = class {
7+
observe() {}
8+
unobserve() {}
9+
disconnect() {}
10+
}
11+
})
12+
513
describe('Alert', () => {
614
test('it should display the alert title and description', async () => {
715
const title = 'TEST TITLE'
816
const description = 'TEST DESCRIPTION'
917

1018
render(
11-
<Alert.Container>
19+
<Alert.Root>
1220
<Alert.Title>{title}</Alert.Title>
1321
<Alert.Description>
1422
<p>{description}</p>
1523
</Alert.Description>
16-
</Alert.Container>
24+
</Alert.Root>
1725
)
1826

1927
expect(await screen.findByRole('heading', { name: title })).toBeInTheDocument()

packages/ui/src/components/alert/AlertContainer.tsx

Lines changed: 0 additions & 64 deletions
This file was deleted.

packages/ui/src/components/alert/AlertDescription.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export interface AlertDescriptionProps extends PropsWithChildren<React.HTMLAttri
77
}
88

99
export const AlertDescription = forwardRef<HTMLDivElement, AlertDescriptionProps>(({ className, children }, ref) => (
10-
<div ref={ref} className={cn('text-sm [&_p]:leading-relaxed', className)}>
10+
<div ref={ref} className={cn('cn-alert-description', className)}>
1111
{children}
1212
</div>
1313
))
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { forwardRef } from 'react'
2+
3+
import { Link, LinkProps } from '@components/link'
4+
import { Slot } from '@radix-ui/react-slot'
5+
import { cn } from '@utils/cn'
6+
7+
export interface AlertLinkProps extends LinkProps {
8+
external?: boolean
9+
asChild?: boolean
10+
}
11+
12+
export const AlertLink = forwardRef<HTMLAnchorElement, AlertLinkProps>(
13+
({ external = false, asChild = false, children, className, ...linkProps }, ref) => {
14+
if (asChild) {
15+
return (
16+
<div className="cn-alert-link-wrapper">
17+
<Slot ref={ref}>{children}</Slot>
18+
</div>
19+
)
20+
}
21+
22+
const externalProps = external ? { target: '_blank', rel: 'noopener noreferrer' } : {}
23+
24+
return (
25+
<div className="cn-alert-link-wrapper">
26+
<Link
27+
ref={ref}
28+
variant="secondary"
29+
suffixIcon
30+
className={cn('cn-alert-link', className)}
31+
{...externalProps}
32+
{...linkProps}
33+
>
34+
{children}
35+
</Link>
36+
</div>
37+
)
38+
}
39+
)
40+
41+
AlertLink.displayName = 'AlertLink'

0 commit comments

Comments
 (0)