Skip to content

Commit

Permalink
chore: add AI variant for the Alert component
Browse files Browse the repository at this point in the history
  • Loading branch information
Isaacmaamouche committed Feb 7, 2025
1 parent 6228cc0 commit 08ec1b3
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 39 deletions.
48 changes: 33 additions & 15 deletions lib/src/components/Alert/docs/examples/cta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,39 @@ import { Alert } from '@/Alert'

const Example = () => {
return (
<Alert
cta={
<>
<Alert.Button>Button</Alert.Button>
<Alert.SecondaryButton>Button</Alert.SecondaryButton>
</>
}
>
<Alert.Title>Welcome to the jungle</Alert.Title>
<span>
Nunc laoreet egestas nulla, et dapibus sem malesuada in. Suspendisse eleifend accumsan
ultrices. Phasellus iaculis nisi sed dui ornare commodo. Nullam dapibus varius nibh a
ornare.
</span>
</Alert>
<>
<Alert
cta={
<>
<Alert.Button>Button</Alert.Button>
<Alert.SecondaryButton>Button</Alert.SecondaryButton>
</>
}
>
<Alert.Title>Welcome to the jungle</Alert.Title>
<span>
Nunc laoreet egestas nulla, et dapibus sem malesuada in. Suspendisse eleifend accumsan
ultrices. Phasellus iaculis nisi sed dui ornare commodo. Nullam dapibus varius nibh a
ornare.
</span>
</Alert>
<Alert
cta={
<>
<Alert.Button> AI Button</Alert.Button>
<Alert.SecondaryButton> AI Button</Alert.SecondaryButton>
</>
}
variant="ai"
>
<Alert.Title>Welcome to the jungle</Alert.Title>
<span>
Nunc laoreet egestas nulla, et dapibus sem malesuada in. Suspendisse eleifend accumsan
ultrices. Phasellus iaculis nisi sed dui ornare commodo. Nullam dapibus varius nibh a
ornare.
</span>
</Alert>
</>
)
}

Expand Down
6 changes: 6 additions & 0 deletions lib/src/components/Alert/docs/examples/variants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ const Example = () => {
ultrices. Phasellus iaculis nisi sed dui ornare commodo. Nullam dapibus varius nibh a
ornare.
</Alert>
<Alert variant="ai">
<Alert.Title>AI variant</Alert.Title>
Nunc laoreet egestas nulla, et dapibus sem malesuada in. Suspendisse eleifend accumsan
ultrices. Phasellus iaculis nisi sed dui ornare commodo. Nullam dapibus varius nibh a
ornare.
</Alert>
</Stack>
)
}
Expand Down
2 changes: 1 addition & 1 deletion lib/src/components/Alert/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ By default the size is `sm`.

### Alert.Button

When the `cta` prop is used, by default it will be displayed in a column on the right.
When the `cta` prop is used, by default it will be displayed in a row bellow the content.

<div data-playground="cta.tsx" data-component="Alert"></div>

Expand Down
13 changes: 8 additions & 5 deletions lib/src/components/Alert/docs/properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
"required": false,
"type": {
"name": "enum",
"raw": "Size",
"raw": "Sizes",
"value": [
{
"value": "\"sm\""
Expand All @@ -137,7 +137,7 @@
},
"variant": {
"defaultValue": {
"value": "default"
"value": "tertiary"
},
"description": "",
"name": "variant",
Expand All @@ -157,10 +157,10 @@
"raw": "Variant",
"value": [
{
"value": "\"danger\""
"value": "\"default\""
},
{
"value": "\"success\""
"value": "\"danger\""
},
{
"value": "\"warning\""
Expand All @@ -169,10 +169,13 @@
"value": "\"info\""
},
{
"value": "\"default\""
"value": "\"success\""
},
{
"value": "\"beige\""
},
{
"value": "\"ai\""
}
]
}
Expand Down
40 changes: 27 additions & 13 deletions lib/src/components/Alert/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import React, { Children, cloneElement } from 'react'

import { Title } from './Title'
import * as S from './styles'
import { Sizes, Variant } from './theme'

import { CloseButton } from '@/CloseButton'
import { Button, ButtonProps } from '@/Button'
import { CreateWuiProps, forwardRef } from '@/System'
import { Box } from '@/Box'

type Size = 'sm' | 'md'
type Variant = 'danger' | 'success' | 'warning' | 'info' | 'default' | 'beige'
export interface AlertOptions {
closeButtonDataTestId?: string
cta?: JSX.Element
Expand All @@ -19,14 +18,14 @@ export interface AlertOptions {
handleClose?: () => void
icon?: JSX.Element | null
isFullWidth?: boolean
size?: Size
size?: Sizes
variant?: Variant
}

export type AlertProps = CreateWuiProps<'div', AlertOptions>

type CloneActionsReturns = React.ReactElement<
AlertProps,
unknown,
string | React.JSXElementConstructor<AlertProps>
>

Expand All @@ -47,6 +46,7 @@ const AlertComponent = forwardRef<'div', AlertProps>(
) => {
const closeButtonDataTestId = dataTestId ? `${dataTestId}-close-button` : undefined
const defaultVariantIcon = variant === 'beige' ? 'default' : variant
const withAiButton = variant === 'ai'

const content = Children.toArray(children).map((child: React.ReactElement) => {
if (child.type === Title) return cloneElement(child, { variant: size })
Expand All @@ -55,10 +55,21 @@ const AlertComponent = forwardRef<'div', AlertProps>(
})

// Handle clone actions recursively in case of multiple buttons
const cloneActions = (child: React.ReactElement<AlertProps>): CloneActionsReturns => {
const cloneActions = (child: React.ReactElement): CloneActionsReturns => {
if (child) {
if (child.type === AlertButton) return cloneElement(child, { size })
if (child.type === AlertSecondaryButton) return cloneElement(child, { size })
if (child.type === AlertButton) {
return cloneElement<ButtonProps>(child, {
size,
ai: withAiButton,
variant: withAiButton ? 'primary' : undefined,
})
}
if (child.type === AlertSecondaryButton) {
return cloneElement<ButtonProps>(child, {
size,
ai: withAiButton,
})
}

if (child.props?.children) {
return cloneElement(child, {
Expand Down Expand Up @@ -118,12 +129,15 @@ const AlertComponent = forwardRef<'div', AlertProps>(
)

// We need this component to check its existence in <Alert> and to allow users to add Button in <Alert> content
const AlertButton = forwardRef<'button', Omit<ButtonProps, 'size' | 'variant'>>((props, ref) => (
<Button flexShrink={0} ref={ref} w="fit-content" {...props} variant="secondary" />
))

const AlertSecondaryButton = forwardRef<'button', Omit<ButtonProps, 'size' | 'variant'>>(
(props, ref) => <Button flexShrink={0} ref={ref} w="fit-content" {...props} variant="tertiary" />
const AlertButton = forwardRef<'button', Omit<ButtonProps, 'size'>>(
({ variant = 'secondary', ...props }, ref) => (
<Button flexShrink={0} ref={ref} w="fit-content" {...props} variant={variant} />
)
)
const AlertSecondaryButton = forwardRef<'button', Omit<ButtonProps, 'size'>>(
({ variant = 'tertiary', ...props }, ref) => (
<Button flexShrink={0} ref={ref} w="fit-content" {...props} variant={variant} />
)
)

export const Alert = Object.assign(AlertComponent, {
Expand Down
10 changes: 7 additions & 3 deletions lib/src/components/Alert/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { CSSObject } from '@xstyled/styled-components'

import { ThemeValues } from '@/theme'

type State = 'default' | 'danger' | 'warning' | 'info' | 'success' | 'beige'
export type Variant = 'default' | 'danger' | 'warning' | 'info' | 'success' | 'beige' | 'ai'

type Sizes = 'sm' | 'md'
export type Sizes = 'sm' | 'md'

type AttributesState = CSSObject

Expand All @@ -15,7 +15,7 @@ export type ThemeAlerts = {
default: CSSObject
sizes: Record<Sizes, CSSObject>
}
} & Record<State, AttributesState>
} & Record<Variant, AttributesState>

export const getAlerts = (theme: ThemeValues): ThemeAlerts => {
const { borderWidths, colors, fontSizes, fontWeights, radii, space } = theme
Expand Down Expand Up @@ -59,6 +59,10 @@ export const getAlerts = (theme: ThemeValues): ThemeAlerts => {
borderColor: colors['beige-20'],
color: colors['beige-80'],
},
ai: {
backgroundColor: colors['violet-10'],
color: colors['violet-90'],
},
sizes: {
sm: {
padding: space.lg,
Expand Down
3 changes: 3 additions & 0 deletions lib/src/components/VariantIcon/docs/properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@
},
{
"value": "\"default\""
},
{
"value": "\"ai\""
}
]
}
Expand Down
12 changes: 10 additions & 2 deletions lib/src/components/VariantIcon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@ import React, { useMemo } from 'react'

import * as S from './styles'

import { AlertIcon, CheckIcon, InformationIcon, PromoteIcon, SquareAlertIcon } from '@/Icons'
import {
AlertIcon,
CheckIcon,
InformationIcon,
PromoteIcon,
SparklesIcon,
SquareAlertIcon,
} from '@/Icons'
import { CreateWuiProps, forwardRef } from '@/System'

type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'
type Variant = 'danger' | 'warning' | 'success' | 'info' | 'default'
type Variant = 'danger' | 'warning' | 'success' | 'info' | 'default' | 'ai'

export interface VariantIconOptions {
icon?: JSX.Element
Expand All @@ -27,6 +34,7 @@ export const VariantIcon = forwardRef<'div', VariantIconProps>(
if (variant === 'info') return <InformationIcon size={size} />
if (variant === 'warning') return <AlertIcon size={size} />
if (variant === 'danger') return <SquareAlertIcon size={size} />
if (variant === 'ai') return <SparklesIcon size={size} />
}, [size, icon, variant])

return Icon ? (
Expand Down

0 comments on commit 08ec1b3

Please sign in to comment.