Skip to content

Commit 31349c1

Browse files
authored
feat: alert styles improved (#4071)
1 parent 6b341eb commit 31349c1

File tree

12 files changed

+251
-77
lines changed

12 files changed

+251
-77
lines changed

.changeset/new-cougars-collect.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@nextui-org/alert": patch
3+
"@nextui-org/theme": patch
4+
---
5+
6+
Alert styles improved

apps/docs/content/components/alert/controlled.ts

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export default function App() {
1313
title={title}
1414
description={description}
1515
isVisible={isVisible}
16+
variant="faded"
17+
color="success"
1618
onClose={() => setIsVisible(false)}
1719
/>
1820
) : (

apps/docs/content/components/alert/custom-styles.ts

+43-16
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,54 @@
1-
const App = `import {Alert} from "@nextui-org/react";
1+
const App = `import {Alert, Button} from "@nextui-org/react";
22
33
export default function App() {
4-
const title = "Success";
5-
const description = "Thanks for subscribing to our newsletter!";
6-
4+
const [isVisible, setIsVisible] = React.useState(true);
5+
76
return (
87
<div className="flex items-center justify-center w-full">
8+
{!isVisible && (
9+
<Button
10+
className="bg-background text-default-700 font-medium border-1 shadow-small"
11+
size="sm"
12+
variant="bordered"
13+
onPress={() => setIsVisible(true)}
14+
>
15+
Show Alert
16+
</Button>
17+
)}
918
<Alert
10-
title={title}
11-
description={description}
1219
classNames={{
13-
base: [
14-
"bg-background",
15-
"border",
16-
"border-foreground-400",
17-
"shadow",
18-
"hover:bg-slate-200",
19-
"cursor-pointer",
20+
base: [
21+
"bg-default-50 dark:bg-background",
22+
"relative before:content-[''] before:absolute before:z-10",
23+
"before:left-0 before:top-[-1px] before:bottom-[-1px] before:w-1 before:bg-secondary",
24+
"rounded-l-none border-l-0",
2025
],
21-
title: ["text-base", "text-foreground", "font-semibold"],
22-
description: ["text-base", "text-foreground-600"],
26+
mainWrapper: "pt-1",
27+
iconWrapper: "border-1 border-secondary-200 dark:bg-transparent",
28+
alertIcon: "text-secondary",
2329
}}
24-
/>
30+
isVisible={isVisible}
31+
title="The documents you requested are ready to be viewed"
32+
variant="faded"
33+
onClose={() => setIsVisible(false)}
34+
>
35+
<div className="flex items-center gap-1 mt-3">
36+
<Button
37+
className="bg-background text-default-700 font-medium border-1 shadow-small"
38+
size="sm"
39+
variant="bordered"
40+
>
41+
View documents
42+
</Button>
43+
<Button
44+
className="text-default-500 font-medium underline underline-offset-4"
45+
size="sm"
46+
variant="light"
47+
>
48+
Maybe later
49+
</Button>
50+
</div>
51+
</Alert>
2552
</div>
2653
);
2754
}`;

apps/docs/content/components/alert/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import customImpl from "./custom-impl";
55
import customStyles from "./custom-styles";
66
import variants from "./variants";
77
import withIcon from "./with-icon";
8+
import withAction from "./with-action";
89
import controlled from "./controlled";
910

1011
export const alertContent = {
@@ -15,5 +16,6 @@ export const alertContent = {
1516
customStyles,
1617
variants,
1718
withIcon,
19+
withAction,
1820
controlled,
1921
};

apps/docs/content/components/alert/variants.ts

+3-9
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,9 @@ const App = `import {Alert} from "@nextui-org/react";
33
export default function App() {
44
return (
55
<div className="flex flex-col gap-4 w-full">
6-
<Alert variant="solid">
7-
A solid variant alert
8-
</Alert>
9-
<Alert variant="bordered">
10-
A bordered variant alert
11-
</Alert>
12-
<Alert variant="flat">
13-
A flat variant alert
14-
</Alert>
6+
{["solid", "bordered", "flat", "faded"].map((variant) => (
7+
<Alert key={variant} variant={variant} color="danger" title={\`This is a \${variant} variant alert\`}/>
8+
))}
159
</div>
1610
);
1711
}`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const App = `import {Alert, Button} from "@nextui-org/react";
2+
3+
export default function App() {
4+
const [isVisible, setIsVisible] = React.useState(true);
5+
6+
return (
7+
<div className="flex items-center justify-center w-full">
8+
<Alert
9+
color="warning"
10+
description="Upgrade to a paid plan to continue"
11+
endContent={
12+
<Button color="warning" size="sm" variant="flat">
13+
Upgrade
14+
</Button>
15+
}
16+
title="You have no credits left"
17+
variant="faded"
18+
/>
19+
</div>
20+
);
21+
}`;
22+
23+
const react = {
24+
"/App.jsx": App,
25+
};
26+
27+
export default {
28+
...react,
29+
};

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

+19-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ Alert comes with 6 color variants to convey different meanings.
5959

6060
By default, Alert displays an appropriate icon based on the `color` prop. You can override this by providing a custom icon using the `icon` prop.
6161

62-
<CodeDemo title="With Icon" files={alertContent.withIcon} />
62+
### With Action
63+
64+
Alert supports an `endContent` prop for additional actions.
65+
66+
<CodeDemo title="With Action" files={alertContent.withAction} />
6367

6468
### Controlled Visibility
6569

@@ -92,6 +96,18 @@ Alert has the following attributes on the `base` element:
9296

9397
<Spacer y={4} />
9498

99+
### Slots
100+
101+
Alert has the following slots:
102+
103+
- `base`: The main alert container element
104+
- `title`: The title element
105+
- `description`: The description element
106+
- `mainWrapper`: The wrapper for the title and description content
107+
- `closeButton`: The close button element
108+
- `iconWrapper`: The wrapper for the alert icon
109+
- `alertIcon`: The alert icon element
110+
95111
## Accessibility
96112

97113
- Alert has role of `alert`
@@ -112,6 +128,8 @@ Alert has the following attributes on the `base` element:
112128
| color | `default` \| `primary` \| `secondary` \| `success` \| `warning` \| `danger` | The alert color theme | `default` |
113129
| variant | `solid` \| `bordered` \| `flat` \| `faded` | The alert variant | `flat` |
114130
| radius | `none` \| `sm` \| `md` \| `lg` \| `full` | The alert border radius | `md` |
131+
| startContent | `ReactNode` | The alert start content | - |
132+
| endContent | `ReactNode` | The alert end content | - |
115133
| isVisible | `boolean` | Whether the alert is visible | - |
116134
| isClosable | `boolean` | Whether the alert can be closed | `false` |
117135
| hideIcon | `boolean` | Whether the icon is hidden | `false` |

packages/components/alert/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@
4747
"@nextui-org/react-utils": "workspace:*",
4848
"@nextui-org/shared-icons": "workspace:*",
4949
"@nextui-org/shared-utils": "workspace:*",
50+
"@nextui-org/button": "workspace:*",
5051
"@react-stately/utils": "3.10.1",
51-
"@react-aria/utils": "3.24.1",
52-
"@nextui-org/button": "workspace:*"
52+
"@react-aria/utils": "3.24.1"
5353
},
5454
"devDependencies": {
5555
"@nextui-org/system": "workspace:*",

packages/components/alert/src/alert.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ const Alert = forwardRef<"div", AlertProps>((props, ref) => {
3232
const {
3333
title,
3434
icon,
35+
children,
3536
description,
37+
endContent,
38+
startContent,
3639
isClosable,
3740
domRef,
3841
handleClose,
@@ -56,14 +59,16 @@ const Alert = forwardRef<"div", AlertProps>((props, ref) => {
5659

5760
return (
5861
<div ref={domRef} role="alert" {...getBaseProps()}>
62+
{startContent}
5963
<div {...getIconWrapperProps()}>
6064
{customIcon || <IconComponent {...getAlertIconProps()} />}
6165
</div>
6266
<div {...getMainWrapperProps()}>
6367
{title && <div {...getTitleProps()}>{title}</div>}
6468
{!isEmpty(description) && <div {...getDescriptionProps()}>{description}</div>}
69+
{children}
6570
</div>
66-
71+
{endContent}
6772
{(isClosable || onClose) && (
6873
<Button
6974
isIconOnly

packages/components/alert/src/use-alert.ts

+17-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ interface Props extends HTMLNextUIProps<"div"> {
2727
* Icon to be displayed in the alert - overrides the default icon
2828
*/
2929
icon?: ReactNode;
30+
/**
31+
* Content to be displayed in the end side of the alert
32+
*/
33+
endContent?: ReactNode;
34+
/**
35+
* Content to be displayed in the start side of the alert
36+
*/
37+
startContent?: ReactNode;
3038
/**
3139
* Whether the alert is visible.
3240
* @default false
@@ -81,17 +89,21 @@ export function useAlert(originalProps: UseAlertProps) {
8189

8290
const {
8391
as,
84-
title: titleProp,
92+
title,
8593
children,
8694
description,
8795
onClose,
8896
isClosable,
8997
ref,
9098
icon,
99+
startContent,
100+
endContent,
91101
isVisible: isVisibleProp,
92102
isDefaultVisible,
93103
onVisibleChange,
94-
closeButtonProps = {},
104+
closeButtonProps = {
105+
size: "sm",
106+
},
95107
classNames,
96108
...otherProps
97109
} = props;
@@ -102,8 +114,6 @@ export function useAlert(originalProps: UseAlertProps) {
102114
onVisibleChange,
103115
);
104116

105-
const title = titleProp || children;
106-
107117
const Component = as || "div";
108118
const shouldFilterDOMProps = typeof Component === "string";
109119

@@ -178,9 +188,12 @@ export function useAlert(originalProps: UseAlertProps) {
178188
return {
179189
title,
180190
icon,
191+
children,
181192
description,
182193
isClosable,
183194
domRef,
195+
endContent,
196+
startContent,
184197
getBaseProps,
185198
getMainWrapperProps,
186199
getDescriptionProps,

0 commit comments

Comments
 (0)