diff --git a/lib/src/components/Alert/docs/examples/cta.tsx b/lib/src/components/Alert/docs/examples/cta.tsx index 6d9b3bf8d..f60e61f0f 100644 --- a/lib/src/components/Alert/docs/examples/cta.tsx +++ b/lib/src/components/Alert/docs/examples/cta.tsx @@ -4,21 +4,39 @@ import { Alert } from '@/Alert' const Example = () => { return ( - - Button - Button - - } - > - Welcome to the jungle - - 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. - - + <> + + Button + Button + + } + > + Welcome to the jungle + + 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. + + + + Button + Button + + } + variant="ai" + > + Welcome to the jungle + + 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. + + + ) } diff --git a/lib/src/components/Alert/docs/examples/variants.tsx b/lib/src/components/Alert/docs/examples/variants.tsx index 0aec659b7..15fdfffc0 100644 --- a/lib/src/components/Alert/docs/examples/variants.tsx +++ b/lib/src/components/Alert/docs/examples/variants.tsx @@ -42,6 +42,12 @@ const Example = () => { ultrices. Phasellus iaculis nisi sed dui ornare commodo. Nullam dapibus varius nibh a ornare. + + AI variant + 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. + ) } diff --git a/lib/src/components/Alert/docs/index.mdx b/lib/src/components/Alert/docs/index.mdx index 23558ab6d..f783a5cc8 100644 --- a/lib/src/components/Alert/docs/index.mdx +++ b/lib/src/components/Alert/docs/index.mdx @@ -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.
diff --git a/lib/src/components/Alert/docs/properties.json b/lib/src/components/Alert/docs/properties.json index 514e53c5b..be48af90e 100644 --- a/lib/src/components/Alert/docs/properties.json +++ b/lib/src/components/Alert/docs/properties.json @@ -137,7 +137,7 @@ }, "variant": { "defaultValue": { - "value": "default" + "value": "tertiary" }, "description": "", "name": "variant", @@ -157,10 +157,10 @@ "raw": "Variant", "value": [ { - "value": "\"danger\"" + "value": "\"default\"" }, { - "value": "\"success\"" + "value": "\"danger\"" }, { "value": "\"warning\"" @@ -169,10 +169,13 @@ "value": "\"info\"" }, { - "value": "\"default\"" + "value": "\"success\"" }, { "value": "\"beige\"" + }, + { + "value": "\"ai\"" } ] } diff --git a/lib/src/components/Alert/index.tsx b/lib/src/components/Alert/index.tsx index 2e088e5c1..c7fd351c2 100644 --- a/lib/src/components/Alert/index.tsx +++ b/lib/src/components/Alert/index.tsx @@ -2,14 +2,13 @@ import React, { Children, cloneElement } from 'react' import { Title } from './Title' import * as S from './styles' +import { Size, 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 @@ -26,7 +25,7 @@ export interface AlertOptions { export type AlertProps = CreateWuiProps<'div', AlertOptions> type CloneActionsReturns = React.ReactElement< - AlertProps, + unknown, string | React.JSXElementConstructor > @@ -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 }) @@ -55,10 +55,22 @@ const AlertComponent = forwardRef<'div', AlertProps>( }) // Handle clone actions recursively in case of multiple buttons - const cloneActions = (child: React.ReactElement): 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) { + // If Alert variant is ai, we override the CTA Buttons to use the AI sub-variants + return cloneElement(child, { + size, + ai: withAiButton, + variant: withAiButton ? 'primary' : undefined, + }) + } + if (child.type === AlertSecondaryButton) { + return cloneElement(child, { + size, + ai: withAiButton, + }) + } if (child.props?.children) { return cloneElement(child, { @@ -97,20 +109,12 @@ const AlertComponent = forwardRef<'div', AlertProps>( )} {icon !== null && } - - {content} - {!!actions && ( - - {actions} - - )} - + {content} + {!!actions && ( + + {actions} + + )} ) @@ -118,12 +122,15 @@ const AlertComponent = forwardRef<'div', AlertProps>( ) // We need this component to check its existence in and to allow users to add Button in content -const AlertButton = forwardRef<'button', Omit>((props, ref) => ( - + + + + ) +} + +export default Example diff --git a/lib/src/components/Button/docs/index.mdx b/lib/src/components/Button/docs/index.mdx index e3cf8c437..d75a470c6 100644 --- a/lib/src/components/Button/docs/index.mdx +++ b/lib/src/components/Button/docs/index.mdx @@ -18,6 +18,12 @@ Add `danger` property to transform variant button with red color. Do not include
+#### AI + +Add `ai` property to transform variant button with purple color. Do not include secondary! + +
+ ### Sizes Use size property with `xs`, `sm`, `md` (default) or `lg`. diff --git a/lib/src/components/Button/docs/properties.json b/lib/src/components/Button/docs/properties.json index 2ea1204ee..8bf4e720e 100644 --- a/lib/src/components/Button/docs/properties.json +++ b/lib/src/components/Button/docs/properties.json @@ -2,9 +2,37 @@ "Button": { "tag": "button", "props": { + "ai": { + "defaultValue": null, + "description": "AI button with 3 variants: primary / tertiary / ghost", + "name": "ai", + "parent": { + "fileName": "welcome-ui/lib/src/components/Button/index.tsx", + "name": "ButtonOptions" + }, + "declarations": [ + { + "fileName": "welcome-ui/lib/src/components/Button/index.tsx", + "name": "ButtonOptions" + } + ], + "required": false, + "type": { + "name": "enum", + "raw": "boolean", + "value": [ + { + "value": "false" + }, + { + "value": "true" + } + ] + } + }, "danger": { "defaultValue": null, - "description": "Danger button with 3 variants: primary / tertiary / ghost", + "description": "Danger button with 3 variants: primary / tertiary / ghost\nTake precedence hover the AI prop", "name": "danger", "parent": { "fileName": "welcome-ui/lib/src/components/Button/index.tsx", @@ -103,7 +131,7 @@ "required": false, "type": { "name": "enum", - "raw": "Shape", + "raw": "\"circle\" | \"square\"", "value": [ { "value": "\"circle\"" @@ -171,9 +199,6 @@ "name": "enum", "raw": "Variant", "value": [ - { - "value": "\"disabled\"" - }, { "value": "\"primary\"" }, diff --git a/lib/src/components/Button/index.tsx b/lib/src/components/Button/index.tsx index ed0368a24..0c597bad5 100644 --- a/lib/src/components/Button/index.tsx +++ b/lib/src/components/Button/index.tsx @@ -1,21 +1,23 @@ import React from 'react' import * as S from './styles' +import { Size, Variant } from './theme' import { Loader } from '@/Loader' import { CreateWuiProps, forwardRef } from '@/System' import { Box } from '@/Box' -type Shape = 'circle' | 'square' -type Size = 'xs' | 'sm' | 'md' | 'lg' -type Variant = 'primary' | 'secondary' | 'tertiary' | 'ghost' | 'disabled' - export interface ButtonOptions { - /** Danger button with 3 variants: primary / tertiary / ghost */ + /** AI button with 3 variants: primary / tertiary / ghost */ + ai?: boolean + /** + * Danger button with 3 variants: primary / tertiary / ghost + * Take precedence hover the AI prop + */ danger?: boolean disabled?: boolean isLoading?: boolean - shape?: Shape + shape?: 'circle' | 'square' size?: Size variant?: Variant } @@ -28,6 +30,7 @@ export type ButtonProps = CreateWuiProps<'button', ButtonOptions> export const Button = forwardRef<'button', ButtonProps>( ( { + ai, children, danger, dataTestId, @@ -43,6 +46,7 @@ export const Button = forwardRef<'button', ButtonProps>( return ( ( - ({ danger, disabled, shape, size = 'md', variant = 'primary' }) => css` + ({ ai, danger, disabled, shape, size = 'md', variant = 'primary' }) => css` ${th(`buttons.${variant}`)}; + ${ai && + css` + ${th(`buttons.ai.${variant}`)}; + `} ${danger && css` ${th(`buttons.danger.${variant}`)}; @@ -69,6 +73,10 @@ export const Button = styled(AriakitButton).withConfig({ shouldForwardProp }) & - Record<'hover', Record> & - Record<'focus', Record> & - Record<'active', Record> & +export type ThemeButtons = Record & + Record<'hover', Record> & + Record<'focus', Record> & + Record<'active', Record> & Record<'disabled', CommonAttributesButton & { '&:focus': ReturnType }> & Record<'sizes', Record> & Record<'icon', Record>> @@ -72,6 +72,23 @@ export const getButtons = (theme: ThemeValues): ThemeButtons => { borderColor: 'transparent', }, }, + ai: { + primary: { + color: colors['neutral-10'], + backgroundColor: colors['violet-70'], + borderColor: 'transparent', + }, + tertiary: { + backgroundColor: 'neutral-10', + color: colors['violet-70'], + borderColor: colors['violet-70'], + }, + ghost: { + color: colors['violet-70'], + backgroundColor: colors['neutral-10'], + borderColor: 'transparent', + }, + }, hover: { primary: { backgroundColor: colors['primary-30'], @@ -99,6 +116,18 @@ export const getButtons = (theme: ThemeValues): ThemeButtons => { backgroundColor: colors['red-10'], }, }, + ai: { + primary: { + backgroundColor: colors['violet-60'], + borderColor: 'transparent', + }, + tertiary: { + backgroundColor: colors['violet-10'], + }, + ghost: { + backgroundColor: colors['violet-10'], + }, + }, }, focus: { primary: { ...focus(colors['primary-20']) }, @@ -110,6 +139,11 @@ export const getButtons = (theme: ThemeValues): ThemeButtons => { tertiary: { ...focus(colors['red-40']) }, ghost: { ...focus(colors['red-40']) }, }, + ai: { + primary: { ...focus(colors['violet-50']) }, + tertiary: { ...focus(colors['violet-50']) }, + ghost: { ...focus(colors['violet-50']) }, + }, }, active: { primary: { @@ -138,6 +172,18 @@ export const getButtons = (theme: ThemeValues): ThemeButtons => { backgroundColor: colors['red-20'], }, }, + ai: { + primary: { + backgroundColor: colors['violet-40'], + borderColor: colors['violet-40'], + }, + tertiary: { + backgroundColor: colors['violet-30'], + }, + ghost: { + backgroundColor: colors['violet-30'], + }, + }, }, disabled: { ...defaults, diff --git a/lib/src/components/Tag/docs/examples/variants.tsx b/lib/src/components/Tag/docs/examples/variants.tsx index c4522f5dd..72ae885f6 100644 --- a/lib/src/components/Tag/docs/examples/variants.tsx +++ b/lib/src/components/Tag/docs/examples/variants.tsx @@ -12,6 +12,7 @@ const Example = () => { Success Danger Warning + AI Blue Green Orange diff --git a/lib/src/components/Tag/docs/properties.json b/lib/src/components/Tag/docs/properties.json index ad7a3f773..9900ef5b3 100644 --- a/lib/src/components/Tag/docs/properties.json +++ b/lib/src/components/Tag/docs/properties.json @@ -153,19 +153,22 @@ "value": "\"default\"" }, { - "value": "\"info\"" + "value": "\"danger\"" }, { - "value": "\"success\"" + "value": "\"info\"" }, { - "value": "\"danger\"" + "value": "\"success\"" }, { "value": "\"warning\"" }, { "value": "\"primary\"" + }, + { + "value": "\"ai\"" } ] } diff --git a/lib/src/components/Tag/index.tsx b/lib/src/components/Tag/index.tsx index dde669bc3..79e6adfe6 100644 --- a/lib/src/components/Tag/index.tsx +++ b/lib/src/components/Tag/index.tsx @@ -1,23 +1,13 @@ import React from 'react' import { wrapChildren } from '../../utils/wrap-children' -import { ThemeSecondaryColors } from '../../theme/colors' import * as S from './styles' +import { Size, Variant } from './theme' import { CreateWuiProps, forwardRef } from '@/System' import { CrossIcon } from '@/Icons' -type Size = 'xs' | 'sm' | 'md' -type Variant = - | ThemeSecondaryColors - | 'default' - | 'info' - | 'success' - | 'danger' - | 'warning' - | 'primary' - export interface TagOptions { href?: string onClick?: () => void diff --git a/lib/src/components/Tag/theme.ts b/lib/src/components/Tag/theme.ts index e916f050d..f584876f1 100644 --- a/lib/src/components/Tag/theme.ts +++ b/lib/src/components/Tag/theme.ts @@ -13,6 +13,7 @@ export type Variant = | 'success' | 'warning' | 'primary' + | 'ai' export type ThemeTags = { default: CSSObject @@ -82,6 +83,10 @@ export const getTags = (theme: ThemeValues): ThemeTags => { pink: getSecondary('pink'), green: getSecondary('green'), violet: getSecondary('violet'), + ai: { + backgroundColor: colors['violet-20'], + color: colors['violet-90'], + }, }, hover: { default: { @@ -100,6 +105,9 @@ export const getTags = (theme: ThemeValues): ThemeTags => { pink: getSecondaryHover('pink'), green: getSecondaryHover('green'), violet: getSecondaryHover('violet'), + ai: { + backgroundColor: colors['violet-30'], + }, }, sizes: { xs: { diff --git a/lib/src/components/VariantIcon/docs/properties.json b/lib/src/components/VariantIcon/docs/properties.json index c690c3bbe..d61ddbd50 100644 --- a/lib/src/components/VariantIcon/docs/properties.json +++ b/lib/src/components/VariantIcon/docs/properties.json @@ -95,6 +95,9 @@ }, { "value": "\"default\"" + }, + { + "value": "\"ai\"" } ] } diff --git a/lib/src/components/VariantIcon/index.tsx b/lib/src/components/VariantIcon/index.tsx index 2714ffdc5..9da173901 100644 --- a/lib/src/components/VariantIcon/index.tsx +++ b/lib/src/components/VariantIcon/index.tsx @@ -1,13 +1,18 @@ import React, { useMemo } from 'react' import * as S from './styles' - -import { AlertIcon, CheckIcon, InformationIcon, PromoteIcon, SquareAlertIcon } from '@/Icons' +import { Size, Variant } from './theme' + +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' - export interface VariantIconOptions { icon?: JSX.Element size?: Size @@ -27,6 +32,7 @@ export const VariantIcon = forwardRef<'div', VariantIconProps>( if (variant === 'info') return if (variant === 'warning') return if (variant === 'danger') return + if (variant === 'ai') return }, [size, icon, variant]) return Icon ? ( diff --git a/lib/src/components/VariantIcon/theme.ts b/lib/src/components/VariantIcon/theme.ts index 8f5a202fb..20927604c 100644 --- a/lib/src/components/VariantIcon/theme.ts +++ b/lib/src/components/VariantIcon/theme.ts @@ -2,13 +2,9 @@ import { CSSObject } from '@xstyled/styled-components' import { ThemeValues } from '@/theme' -export type ThemeVariantIcon = { - danger: CSSObject - default: CSSObject - info: CSSObject - success: CSSObject - warning: CSSObject -} +export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' +export type Variant = 'danger' | 'warning' | 'success' | 'info' | 'default' | 'ai' +export type ThemeVariantIcon = Record export const getVariantIcon = (theme: ThemeValues): ThemeVariantIcon => { const { colors } = theme @@ -29,5 +25,8 @@ export const getVariantIcon = (theme: ThemeValues): ThemeVariantIcon => { info: { color: colors['blue-60'], }, + ai: { + color: colors['violet-70'], + }, } } diff --git a/website/build-app/examples.js b/website/build-app/examples.js index 3621a8020..804c28f3d 100644 --- a/website/build-app/examples.js +++ b/website/build-app/examples.js @@ -36,6 +36,7 @@ export default { "/Breadcrumb/docs/examples/last-child.tsx": dynamic(() => import("../../lib/src/components/Breadcrumb/docs/examples/last-child.tsx").then(mod => mod), { ssr: false }), "/Breadcrumb/docs/examples/overview.tsx": dynamic(() => import("../../lib/src/components/Breadcrumb/docs/examples/overview.tsx").then(mod => mod), { ssr: false }), "/Breadcrumb/docs/examples/separator.tsx": dynamic(() => import("../../lib/src/components/Breadcrumb/docs/examples/separator.tsx").then(mod => mod), { ssr: false }), + "/Button/docs/examples/ai.tsx": dynamic(() => import("../../lib/src/components/Button/docs/examples/ai.tsx").then(mod => mod), { ssr: false }), "/Button/docs/examples/danger.tsx": dynamic(() => import("../../lib/src/components/Button/docs/examples/danger.tsx").then(mod => mod), { ssr: false }), "/Button/docs/examples/disabled.tsx": dynamic(() => import("../../lib/src/components/Button/docs/examples/disabled.tsx").then(mod => mod), { ssr: false }), "/Button/docs/examples/icons.tsx": dynamic(() => import("../../lib/src/components/Button/docs/examples/icons.tsx").then(mod => mod), { ssr: false }),