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 } };