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/packages/react/src/InlineMessage/InlineMessage.dev.stories.tsx b/packages/react/src/InlineMessage/InlineMessage.dev.stories.tsx
index 31428524b11..95c6d281cac 100644
--- a/packages/react/src/InlineMessage/InlineMessage.dev.stories.tsx
+++ b/packages/react/src/InlineMessage/InlineMessage.dev.stories.tsx
@@ -9,6 +9,7 @@ const meta = {
export default meta
+// Previous Styled version of the component didn't accept an sx prop so no need to test if that works.
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}