diff --git a/.changeset/silent-cherries-behave.md b/.changeset/silent-cherries-behave.md new file mode 100644 index 00000000000..ee09a911a13 --- /dev/null +++ b/.changeset/silent-cherries-behave.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Migrate 'InlineMessage' component to use CSS modules diff --git a/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-colorblind-linux.png b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-colorblind-linux.png new file mode 100644 index 00000000000..0f89572e51a Binary files /dev/null and b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-dimmed-linux.png b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-dimmed-linux.png new file mode 100644 index 00000000000..f13182a7a16 Binary files /dev/null and b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-dimmed-linux.png differ diff --git a/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-high-contrast-linux.png b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-high-contrast-linux.png new file mode 100644 index 00000000000..47bdf2c53ca Binary files /dev/null and b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-linux.png b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-linux.png new file mode 100644 index 00000000000..0f89572e51a Binary files /dev/null and b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-linux.png differ diff --git a/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-tritanopia-linux.png b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-tritanopia-linux.png new file mode 100644 index 00000000000..0f89572e51a Binary files /dev/null and b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-dark-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-colorblind-linux.png b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-colorblind-linux.png new file mode 100644 index 00000000000..5b522169e8c Binary files /dev/null and b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-high-contrast-linux.png b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-high-contrast-linux.png new file mode 100644 index 00000000000..7215a9c96dc Binary files /dev/null and b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-linux.png b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-linux.png new file mode 100644 index 00000000000..5b522169e8c Binary files /dev/null and b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-linux.png differ diff --git a/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-tritanopia-linux.png b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-tritanopia-linux.png new file mode 100644 index 00000000000..5b522169e8c Binary files /dev/null and b/.playwright/snapshots/components/InlineMessage.test.ts-snapshots/InlineMessage-Dev-Default-light-tritanopia-linux.png differ diff --git a/e2e/components/InlineMessage.test.ts b/e2e/components/InlineMessage.test.ts index cb595a96201..81814c82a20 100644 --- a/e2e/components/InlineMessage.test.ts +++ b/e2e/components/InlineMessage.test.ts @@ -12,6 +12,10 @@ const stories = [ title: 'Multiline', id: 'experimental-components-inlinemessage-features--multiline', }, + { + title: 'Dev Default', + id: 'experimental-components-inlinemessage-dev--dev-default', + }, ] const scenarios = matrix({ diff --git a/packages/react/src/InlineMessage/InlineMessage.dev.stories.tsx b/packages/react/src/InlineMessage/InlineMessage.dev.stories.tsx new file mode 100644 index 00000000000..69f87029b3a --- /dev/null +++ b/packages/react/src/InlineMessage/InlineMessage.dev.stories.tsx @@ -0,0 +1,18 @@ +import type {Meta} from '@storybook/react' +import React from 'react' +import {InlineMessage} from '.' + +const meta = { + title: 'Experimental/Components/InlineMessage/Dev', + component: InlineMessage, +} satisfies Meta + +export default meta + +export const DevDefault = () => { + return ( + + An example inline message + + ) +} diff --git a/packages/react/src/InlineMessage/InlineMessage.module.css b/packages/react/src/InlineMessage/InlineMessage.module.css new file mode 100644 index 00000000000..0ddbea7498b --- /dev/null +++ b/packages/react/src/InlineMessage/InlineMessage.module.css @@ -0,0 +1,42 @@ +.InlineMessage { + display: grid; + /* stylelint-disable-next-line primer/typography */ + font-size: var(--inline-message-fontSize); + /* stylelint-disable-next-line primer/typography */ + line-height: var(--inline-message-lineHeight); + /* stylelint-disable-next-line primer/colors */ + color: var(--inline-message-fgColor); + column-gap: 0.5rem; + grid-template-columns: auto 1fr; + align-items: start; + + &[data-size='small'] { + --inline-message-fontSize: var(--text-body-size-small); + --inline-message-lineHeight: var(--text-body-lineHeight-small, 1.6666); + } + + &[data-size='medium'] { + --inline-message-fontSize: var(--text-body-size-medium); + --inline-message-lineHeight: var(--text-body-lineHeight-medium, 1.4285); + } + + &[data-variant='warning'] { + --inline-message-fgColor: var(--fgColor-attention); + } + + &[data-variant='critical'] { + --inline-message-fgColor: var(--fgColor-danger); + } + + &[data-variant='success'] { + --inline-message-fgColor: var(--fgColor-success); + } + + &[data-variant='unavailable'] { + --inline-message-fgColor: var(--fgColor-muted); + } +} + +.InlineMessageIcon { + min-height: calc(var(--inline-message-lineHeight) * var(--inline-message-fontSize)); +} diff --git a/packages/react/src/InlineMessage/InlineMessage.tsx b/packages/react/src/InlineMessage/InlineMessage.tsx index 55f2296a6fd..173c9502f1b 100644 --- a/packages/react/src/InlineMessage/InlineMessage.tsx +++ b/packages/react/src/InlineMessage/InlineMessage.tsx @@ -1,80 +1,105 @@ import {AlertFillIcon, AlertIcon, CheckCircleFillIcon, CheckCircleIcon} from '@primer/octicons-react' +import {clsx} from 'clsx' import React from 'react' import styled from 'styled-components' import {get} from '../constants' - +import {toggleStyledComponent} from '../internal/utils/toggleStyledComponent' +import {useFeatureFlag} from '../FeatureFlags' +import classes from './InlineMessage.module.css' +import type {SxProp} from '../sx' type MessageVariant = 'critical' | 'success' | 'unavailable' | 'warning' -export type InlineMessageProps = React.ComponentPropsWithoutRef<'div'> & { - /** - * Specify the size of the InlineMessage - */ - size?: 'small' | 'medium' +const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team' - /** - * Specify the type of the InlineMessage - */ - variant: MessageVariant -} +export type InlineMessageProps = React.ComponentPropsWithoutRef<'div'> & + SxProp & { + /** + * Specify the size of the InlineMessage + */ + size?: 'small' | 'medium' -const StyledMessage = styled.div` - display: grid; - column-gap: 0.5rem; - grid-template-columns: auto 1fr; - align-items: start; - color: var(--inline-message-fgColor, ${get('colors.fg.muted')}); - line-height: var(--inline-message-lineHeight); - font-size: var(--inline-message-fontSize, ${get('fontSizes.1')}); - - &[data-size='small'] { - --inline-message-fontSize: var(--text-body-size-small, ${get('fontSizes.0')}); - --inline-message-lineHeight: var(--text-body-lineHeight-small, 1.6666); + /** + * Specify the type of the InlineMessage + */ + variant: MessageVariant } - &[data-size='medium'] { - --inline-message-fontSize: var(--text-body-size-medium, ${get('fontSizes.1')}); - --inline-message-lineHeight: var(--text-body-lineHeight-medium, 1.4285); - } +const StyledMessage = toggleStyledComponent( + CSS_MODULES_FEATURE_FLAG, + 'div', + styled.div` + display: grid; + column-gap: 0.5rem; + grid-template-columns: auto 1fr; + align-items: start; + color: var(--inline-message-fgColor, ${get('colors.fg.muted')}); + line-height: var(--inline-message-lineHeight); + font-size: var(--inline-message-fontSize, ${get('fontSizes.1')}); - &[data-variant='warning'] { - --inline-message-fgColor: ${get('colors.attention.fg')}; - } + &[data-size='small'] { + --inline-message-fontSize: var(--text-body-size-small, ${get('fontSizes.0')}); + --inline-message-lineHeight: var(--text-body-lineHeight-small, 1.6666); + } - &[data-variant='critical'] { - --inline-message-fgColor: ${get('colors.danger.fg')}; - } + &[data-size='medium'] { + --inline-message-fontSize: var(--text-body-size-medium, ${get('fontSizes.1')}); + --inline-message-lineHeight: var(--text-body-lineHeight-medium, 1.4285); + } - &[data-variant='success'] { - --inline-message-fgColor: ${get('colors.success.fg')}; - } + &[data-variant='warning'] { + --inline-message-fgColor: ${get('colors.attention.fg')}; + } - &[data-variant='unavailable'] { - --inline-message-fgColor: ${get('colors.fg.muted')}; - } + &[data-variant='critical'] { + --inline-message-fgColor: ${get('colors.danger.fg')}; + } + + &[data-variant='success'] { + --inline-message-fgColor: ${get('colors.success.fg')}; + } + + &[data-variant='unavailable'] { + --inline-message-fgColor: ${get('colors.fg.muted')}; + } - & .InlineMessageIcon { - min-height: calc(var(--inline-message-lineHeight) * var(--inline-message-fontSize)); + & .InlineMessageIcon { + min-height: calc(var(--inline-message-lineHeight) * var(--inline-message-fontSize)); + } + `, +) + +const variantToIcon = (enabled: boolean, variant: MessageVariant): React.ReactNode => { + const icons = { + warning: , + critical: , + success: , + unavailable: , } -` -const variantToIcon: Record = { - warning: , - critical: , - success: , - unavailable: , + return icons[variant] } -const variantToSmallIcon: Record = { - warning: , - critical: , - success: , - unavailable: , +const variantToSmallIcon = (enabled: boolean, variant: MessageVariant): React.ReactNode => { + const icons = { + warning: , + critical: , + success: , + unavailable: , + } + return icons[variant] } -export function InlineMessage({children, size = 'medium', variant, ...rest}: InlineMessageProps) { - const icon = size === 'small' ? variantToSmallIcon[variant] : variantToIcon[variant] +export function InlineMessage({children, className, size = 'medium', variant, ...rest}: InlineMessageProps) { + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) + + const icon = size === 'small' ? variantToSmallIcon(enabled, variant) : variantToIcon(enabled, variant) return ( - + {icon} {children}