diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 64c321b6..d6b3c6e7 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -33,7 +33,7 @@ module.exports = {
'rules': {
'react/display-name': 'off',
'no-unused-vars': [0],
- 'indent': ['error', 2],
+ 'indent': ['error', 2, {'SwitchCase': 1}],
'react/prop-types': [0],
'linebreak-style': ['error', 'unix'],
'quotes': ['error', 'single'],
diff --git a/src/layers/Callout/Callout.story.tsx b/src/layers/Callout/Callout.story.tsx
new file mode 100644
index 00000000..31b7daa1
--- /dev/null
+++ b/src/layers/Callout/Callout.story.tsx
@@ -0,0 +1,60 @@
+import React from 'react';
+import { Stack } from '@/layout';
+import { Text } from '@/typography';
+
+import {
+ Callout,
+ SuccessCallout,
+ WarningCallout,
+ ErrorCallout,
+ InfoCallout
+} from '@/layers';
+
+import CalendarIcon from '@/assets/icons/calendar.svg?react';
+
+export default {
+ title: 'Components/Layers/Callout',
+ component: Callout
+};
+
+export const Simple = () => (
+
+
+
+);
+
+export const Variants = () => (
+
+
+
+
+
+
+
+);
+
+export const CustomIcon = () => (
+
+ }
+ text="You will need admin privileges to install and access this application."
+ />
+
+);
+
+export const CustomText = () => (
+
+
+ You will need{' '}
+
+ admin
+ {' '}
+ privileges to install and access this application.
+
+ }
+ />
+
+);
diff --git a/src/layers/Callout/Callout.tsx b/src/layers/Callout/Callout.tsx
new file mode 100644
index 00000000..1bbad5f9
--- /dev/null
+++ b/src/layers/Callout/Callout.tsx
@@ -0,0 +1,46 @@
+import React, { FC, ReactNode } from 'react';
+import { Stack } from '@/layout';
+import { cn, useComponentTheme } from '@/utils';
+import { CalloutTheme } from './CalloutTheme';
+
+export interface CalloutProps {
+ /**
+ * The text of the callout.
+ */
+ text: string | ReactNode;
+
+ /**
+ * The icon of the callout.
+ */
+ icon?: ReactNode;
+
+ /**
+ * The variant of the callout.
+ */
+ variant?: 'default' | 'success' | 'error' | 'warning' | 'info';
+
+ /**
+ * The theme of the callout.
+ */
+ theme?: CalloutTheme;
+}
+
+export const Callout: FC = ({
+ text,
+ icon,
+ variant = 'default',
+ theme: customTheme
+}) => {
+ const theme = useComponentTheme('callout', customTheme);
+
+ return (
+
+ {icon && (
+
+ {icon}
+
+ )}
+ {text}
+
+ );
+};
diff --git a/src/layers/Callout/CalloutTheme.ts b/src/layers/Callout/CalloutTheme.ts
new file mode 100644
index 00000000..787b88cd
--- /dev/null
+++ b/src/layers/Callout/CalloutTheme.ts
@@ -0,0 +1,51 @@
+export interface CalloutTheme {
+ base: {
+ common: string;
+ variant: {
+ default: string;
+ success: string;
+ error: string;
+ warning: string;
+ info: string;
+ [key: string]: string;
+ };
+ };
+ icon: {
+ common: string;
+ variant: {
+ default: string;
+ success: string;
+ error: string;
+ warning: string;
+ info: string;
+ [key: string]: string;
+ };
+ };
+ text: string;
+}
+
+export const calloutTheme: CalloutTheme = {
+ base: {
+ common: 'px-4 py-3 border-b',
+ variant: {
+ default: 'bg-panel-background border-panel-accent',
+ success: 'bg-success-background border-success',
+ error: 'bg-error-background border-error',
+ warning: 'bg-warning-background border-warning',
+ info: 'bg-info-background border-info'
+ }
+ },
+ icon: {
+ common: '',
+ variant: {
+ default: '',
+ success: 'text-success',
+ error: 'text-error',
+ warning: 'text-warning',
+ info: 'text-info'
+ }
+ },
+ text: 'text-base'
+};
+
+export const legacyCalloutTheme: CalloutTheme = calloutTheme;
diff --git a/src/layers/Callout/ErrorCallout.tsx b/src/layers/Callout/ErrorCallout.tsx
new file mode 100644
index 00000000..9494a140
--- /dev/null
+++ b/src/layers/Callout/ErrorCallout.tsx
@@ -0,0 +1,8 @@
+import React, { FC } from 'react';
+import { Callout, CalloutProps } from './Callout';
+
+import ErrorCircleIcon from '@/assets/icons/error_circle.svg?react';
+
+export const ErrorCallout: FC = ({ icon, ...rest }) => (
+ } variant="error" {...rest} />
+);
diff --git a/src/layers/Callout/InfoCallout.tsx b/src/layers/Callout/InfoCallout.tsx
new file mode 100644
index 00000000..05fa2c44
--- /dev/null
+++ b/src/layers/Callout/InfoCallout.tsx
@@ -0,0 +1,8 @@
+import React, { FC } from 'react';
+import { Callout, CalloutProps } from './Callout';
+
+import InfoIcon from '@/assets/icons/info.svg?react';
+
+export const InfoCallout: FC = ({ icon, ...rest }) => (
+ } variant="info" {...rest} />
+);
diff --git a/src/layers/Callout/SuccessCallout.tsx b/src/layers/Callout/SuccessCallout.tsx
new file mode 100644
index 00000000..3b764ea9
--- /dev/null
+++ b/src/layers/Callout/SuccessCallout.tsx
@@ -0,0 +1,8 @@
+import React, { FC } from 'react';
+import { Callout, CalloutProps } from './Callout';
+
+import CheckCircleIcon from '@/assets/icons/check_circle.svg?react';
+
+export const SuccessCallout: FC = ({ icon, ...rest }) => (
+ } variant="success" {...rest} />
+);
diff --git a/src/layers/Callout/WarningCallout.tsx b/src/layers/Callout/WarningCallout.tsx
new file mode 100644
index 00000000..75ad394b
--- /dev/null
+++ b/src/layers/Callout/WarningCallout.tsx
@@ -0,0 +1,8 @@
+import React, { FC } from 'react';
+import { Callout, CalloutProps } from './Callout';
+
+import WarningIcon from '@/assets/icons/warning.svg?react';
+
+export const WarningCallout: FC = ({ icon, ...rest }) => (
+ } variant="warning" {...rest} />
+);
diff --git a/src/layers/Callout/index.ts b/src/layers/Callout/index.ts
new file mode 100644
index 00000000..1532a634
--- /dev/null
+++ b/src/layers/Callout/index.ts
@@ -0,0 +1,6 @@
+export * from './Callout';
+export * from './CalloutTheme';
+export * from './SuccessCallout';
+export * from './ErrorCallout';
+export * from './WarningCallout';
+export * from './InfoCallout';
diff --git a/src/layers/index.ts b/src/layers/index.ts
index 9dd3030e..e6d29481 100644
--- a/src/layers/index.ts
+++ b/src/layers/index.ts
@@ -6,3 +6,4 @@ export * from './Menu';
export * from './ContextMenu';
export * from './Notification';
export * from './Backdrop';
+export * from './Callout';
diff --git a/src/utils/Theme/themes/theme.ts b/src/utils/Theme/themes/theme.ts
index f840e331..edb774d4 100644
--- a/src/utils/Theme/themes/theme.ts
+++ b/src/utils/Theme/themes/theme.ts
@@ -79,7 +79,10 @@ import {
MenuTheme,
NotificationTheme,
PopoverTheme,
- TooltipTheme
+ TooltipTheme,
+ CalloutTheme,
+ calloutTheme,
+ legacyCalloutTheme
} from '@/layers';
import {
@@ -190,6 +193,7 @@ export interface ReablocksTheme {
tabs: TabsTheme;
breadcrumbs: BreadcrumbsTheme;
stepper: StepperTheme;
+ callout: CalloutTheme;
};
}
@@ -237,7 +241,8 @@ export const theme: ReablocksTheme = {
tabs: tabsTheme,
jsonTree: jsonTreeTheme,
breadcrumbs: breadcrumbsTheme,
- stepper: stepperTheme
+ stepper: stepperTheme,
+ callout: calloutTheme
}
};
@@ -285,6 +290,7 @@ export const legacyThemeVars: ReablocksTheme = {
tabs: legacyTabsTheme,
jsonTree: legacyJsonTreeTheme,
breadcrumbs: legacyBreadcrumbTheme,
- stepper: legacyStepperTheme
+ stepper: legacyStepperTheme,
+ callout: legacyCalloutTheme
}
};