diff --git a/.changeset/chilled-masks-lay.md b/.changeset/chilled-masks-lay.md
new file mode 100644
index 0000000..32f591c
--- /dev/null
+++ b/.changeset/chilled-masks-lay.md
@@ -0,0 +1,5 @@
+---
+"eslint-plugin-primer-react": patch
+---
+
+Add no-deprecated-flash ESLint rule to warn against Flash component usage
diff --git a/docs/rules/no-deprecated-flash.md b/docs/rules/no-deprecated-flash.md
new file mode 100644
index 0000000..1bee09e
--- /dev/null
+++ b/docs/rules/no-deprecated-flash.md
@@ -0,0 +1,61 @@
+# No Deprecated Flash
+
+## Rule Details
+
+This rule discourages the use of Flash component and suggests using Banner component from `@primer/react/experimental` instead.
+
+Flash component is deprecated and will be removed from @primer/react. The Banner component provides the same functionality and should be used instead.
+
+👎 Examples of **incorrect** code for this rule
+
+```jsx
+import {Flash} from '@primer/react'
+
+function ExampleComponent() {
+ return Warning message
+}
+```
+
+```jsx
+import {Flash} from '@primer/react'
+
+function ExampleComponent() {
+ return (
+
+ Banner content
+
+ )
+}
+```
+
+👍 Examples of **correct** code for this rule:
+
+```jsx
+import {Banner} from '@primer/react/experimental'
+
+function ExampleComponent() {
+ return Warning message
+}
+```
+
+```jsx
+import {Banner} from '@primer/react/experimental'
+
+function ExampleComponent() {
+ return (
+
+ Banner content
+
+ )
+}
+```
+
+## Auto-fix
+
+This rule provides automatic fixes that:
+
+- Replace `Flash` component usage with `Banner`
+- Update import statements from `@primer/react` to `@primer/react/experimental`
+- Preserve all props, attributes, and children content
+- Handle mixed imports appropriately
+- Avoid duplicate Banner imports when they already exist
diff --git a/src/index.js b/src/index.js
index 1dc3315..13da72d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -19,6 +19,7 @@ module.exports = {
'prefer-action-list-item-onselect': require('./rules/prefer-action-list-item-onselect'),
'enforce-css-module-identifier-casing': require('./rules/enforce-css-module-identifier-casing'),
'enforce-css-module-default-import': require('./rules/enforce-css-module-default-import'),
+ 'no-deprecated-flash': require('./rules/no-deprecated-flash'),
'use-styled-react-import': require('./rules/use-styled-react-import'),
},
configs: {
diff --git a/src/rules/__tests__/no-deprecated-flash.test.js b/src/rules/__tests__/no-deprecated-flash.test.js
new file mode 100644
index 0000000..2a41b2b
--- /dev/null
+++ b/src/rules/__tests__/no-deprecated-flash.test.js
@@ -0,0 +1,156 @@
+'use strict'
+
+const {RuleTester} = require('eslint')
+const rule = require('../no-deprecated-flash')
+
+const ruleTester = new RuleTester({
+ languageOptions: {
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+})
+
+ruleTester.run('no-deprecated-flash', rule, {
+ valid: [
+ // Banner import and usage is valid
+ {
+ code: `import {Banner} from '@primer/react/experimental'
+
+function Component() {
+ return Content
+}`,
+ },
+ // Flash imported from other packages is valid
+ {
+ code: `import {Flash} from 'some-other-package'
+
+function Component() {
+ return Content
+}`,
+ },
+ // No import of Flash
+ {
+ code: `import {Button} from '@primer/react'
+
+function Component() {
+ return
+}`,
+ },
+ ],
+ invalid: [
+ // Basic Flash import and usage
+ {
+ code: `import {Flash} from '@primer/react'
+
+function Component() {
+ return Banner content
+}`,
+ errors: [{messageId: 'flashDeprecated'}, {messageId: 'flashDeprecated'}],
+ },
+
+ // Flash with complex props
+ {
+ code: `import {Flash} from '@primer/react'
+
+function Component() {
+ return (
+
+ Banner content
+
+ )
+}`,
+ errors: [{messageId: 'flashDeprecated'}, {messageId: 'flashDeprecated'}],
+ },
+
+ // Mixed imports - Flash with other components
+ {
+ code: `import {Button, Flash, Text} from '@primer/react'
+
+function Component() {
+ return (
+
+
+ Error message
+ Some text
+
+ )
+}`,
+ errors: [{messageId: 'flashDeprecated'}, {messageId: 'flashDeprecated'}],
+ },
+
+ // Flash only import
+ {
+ code: `import {Flash} from '@primer/react'
+
+function Component() {
+ return Just Flash
+}`,
+ errors: [{messageId: 'flashDeprecated'}, {messageId: 'flashDeprecated'}],
+ },
+
+ // Self-closing Flash
+ {
+ code: `import {Flash} from '@primer/react'
+
+function Component() {
+ return
+}`,
+ errors: [{messageId: 'flashDeprecated'}, {messageId: 'flashDeprecated'}],
+ },
+
+ // Multiple Flash components
+ {
+ code: `import {Flash} from '@primer/react'
+
+function Component() {
+ return (
+
+ Warning
+ Error
+
+ )
+}`,
+ errors: [{messageId: 'flashDeprecated'}, {messageId: 'flashDeprecated'}, {messageId: 'flashDeprecated'}],
+ },
+
+ // Flash with existing Banner import (should not duplicate)
+ {
+ code: `import {Flash} from '@primer/react'
+import {Banner} from '@primer/react/experimental'
+
+function Component() {
+ return (
+
+ Flash message
+ Banner message
+
+ )
+}`,
+ errors: [{messageId: 'flashDeprecated'}, {messageId: 'flashDeprecated'}],
+ },
+
+ // Flash with existing experimental imports like TooltipV2
+ {
+ code: `import {Flash} from '@primer/react'
+import {TooltipV2} from '@primer/react/experimental'
+
+function Component() {
+ return (
+
+ Flash message
+ Tooltip content
+
+ )
+}`,
+ errors: [{messageId: 'flashDeprecated'}, {messageId: 'flashDeprecated'}],
+ },
+ ],
+})
diff --git a/src/rules/no-deprecated-flash.js b/src/rules/no-deprecated-flash.js
new file mode 100644
index 0000000..61d3b2f
--- /dev/null
+++ b/src/rules/no-deprecated-flash.js
@@ -0,0 +1,67 @@
+'use strict'
+
+const {getJSXOpeningElementName} = require('../utils/get-jsx-opening-element-name')
+const {isPrimerComponent} = require('../utils/is-primer-component')
+const url = require('../url')
+
+/**
+ * @type {import('eslint').Rule.RuleModule}
+ */
+module.exports = {
+ meta: {
+ type: 'problem',
+ docs: {
+ description: 'Flash component is deprecated. Use Banner from @primer/react/experimental instead.',
+ recommended: true,
+ url: url(module),
+ },
+ schema: [],
+ messages: {
+ flashDeprecated: 'Flash component is deprecated. Use Banner from @primer/react/experimental instead.',
+ },
+ },
+ create(context) {
+ const sourceCode = context.sourceCode || context.getSourceCode()
+
+ return {
+ ImportDeclaration(node) {
+ // Check if importing Flash from @primer/react
+ if (node.source.value !== '@primer/react') {
+ return
+ }
+
+ const flashSpecifier = node.specifiers.find(
+ specifier => specifier.type === 'ImportSpecifier' && specifier.imported?.name === 'Flash',
+ )
+
+ if (!flashSpecifier) {
+ return
+ }
+
+ context.report({
+ node: flashSpecifier,
+ messageId: 'flashDeprecated',
+ })
+ },
+
+ JSXElement(node) {
+ const elementName = getJSXOpeningElementName(node.openingElement)
+
+ if (elementName !== 'Flash') {
+ return
+ }
+
+ // Check if Flash is imported from @primer/react using isPrimerComponent
+ const scope = sourceCode.getScope ? sourceCode.getScope(node.openingElement) : context.getScope()
+ if (!isPrimerComponent(node.openingElement.name, scope)) {
+ return
+ }
+
+ context.report({
+ node: node.openingElement.name,
+ messageId: 'flashDeprecated',
+ })
+ },
+ }
+ },
+}