diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 353381929..53c668ba7 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -246,6 +246,12 @@ "source": "./plugins/marketplace-ops", "description": "Maintenance commands for Claude Code plugin marketplaces", "version": "0.1.2" + }, + { + "name": "patternfly", + "source": "./plugins/patternfly", + "description": "PatternFly React component migration and development tools", + "version": "1.2.0" } ] } diff --git a/PLUGINS.md b/PLUGINS.md index 96c6d4067..fcb3d3ff3 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -27,6 +27,7 @@ This document lists all available Claude Code plugins and their commands in the - [Openshift Tls Profile](#openshift-tls-profile-plugin) - [Origin](#origin-plugin) - [Ote Migration](#ote-migration-plugin) +- [Patternfly](#patternfly-plugin) - [Rds Analyzer](#rds-analyzer-plugin) - [Session](#session-plugin) - [Snowflake](#snowflake-plugin) @@ -350,6 +351,15 @@ Automate OpenShift Tests Extension (OTE) migration for component repositories See [plugins/ote-migration/README.md](plugins/ote-migration/README.md) for detailed documentation. +### Patternfly Plugin + +PatternFly v5 to v6 migration and glass theme implementation + +**Commands:** +- **`/patternfly:migrate` `[file-path]`** - Migrate PatternFly v5 to v6 (React components, CSS classes, tokens) + +See [plugins/patternfly/README.md](plugins/patternfly/README.md) for detailed documentation. + ### Rds Analyzer Plugin Reference Design Specification (RDS) Analyzer workflow: cluster-compare JSON to deviation reports (text/HTML/reporting) and Jira follow-up diff --git a/docs/data.json b/docs/data.json index 9da6dddca..d24e35f71 100644 --- a/docs/data.json +++ b/docs/data.json @@ -1822,6 +1822,33 @@ "name": "marketplace-ops", "skills": [], "version": "0.1.2" + }, + { + "commands": [ + { + "argument_hint": "[file-path]", + "description": "Migrate PatternFly v5 to v6 (React components, CSS classes, tokens)", + "name": "migrate", + "synopsis": "/patternfly:migrate [file-path]" + } + ], + "description": "PatternFly React component migration and development tools", + "has_readme": true, + "hooks": [], + "name": "patternfly", + "skills": [ + { + "description": "Migrate PatternFly React components from v5 to v6. Scans for component renames, prop updates, and import changes.", + "id": "patternfly-migration", + "name": "pf-react-migration" + }, + { + "description": "Enable PatternFly 6 glass theme (glassmorphism with backdrop blur and transparency)", + "id": "pf-glass-theme", + "name": "pf-glass-theme" + } + ], + "version": "1.2.0" } ] } \ No newline at end of file diff --git a/plugins/patternfly/.claude-plugin/plugin.json b/plugins/patternfly/.claude-plugin/plugin.json new file mode 100644 index 000000000..60faa278b --- /dev/null +++ b/plugins/patternfly/.claude-plugin/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "patternfly", + "description": "PatternFly v5 to v6 migration and glass theme implementation", + "version": "1.2.0", + "author": { + "name": "github.com/openshift-eng" + } +} diff --git a/plugins/patternfly/OWNERS b/plugins/patternfly/OWNERS new file mode 100644 index 000000000..12662f5fd --- /dev/null +++ b/plugins/patternfly/OWNERS @@ -0,0 +1,4 @@ +approvers: +- anandkuma77 +reviewers: +- anandkuma77 diff --git a/plugins/patternfly/README.md b/plugins/patternfly/README.md new file mode 100644 index 000000000..dee854cf5 --- /dev/null +++ b/plugins/patternfly/README.md @@ -0,0 +1,98 @@ +# PatternFly Plugin + +A Claude Code plugin for migrating and working with PatternFly React components. + +## Overview + +PatternFly is Red Hat's open source design system for enterprise product experiences. This plugin helps developers migrate from PatternFly v5 to v6 and implement modern glass theme (glassmorphism) effects in React applications. + +## Commands + +### `/patternfly:migrate` + +Migrate React components from PatternFly 5 to PatternFly 6. + +**Usage:** +```bash +/patternfly:migrate [file-path] +``` + +**Examples:** +```bash +# Migrate a specific file +/patternfly:migrate src/components/Dashboard.tsx + +# Migrate current working directory +/patternfly:migrate +``` + +**What it does:** +- Analyzes code for PatternFly v5 patterns +- Applies automated migrations for component renames, prop updates, and import changes +- Identifies manual updates needed for structural changes +- Provides testing recommendations + +## Skills + +### `pf-react-migration` + +Migrate PatternFly React components, CSS classes, and tokens from v5 to v6. + +**Coverage includes:** +- React component and prop migrations (Text → Content, Chip → Label, prop renames) +- CSS class migrations (pf-v5-* → pf-v6-*, legacy classes) +- Token migrations (--pf-global-* → --pf-t--*) +- Import path updates and deprecated component guidance +- Automated codemod integration +- Actionable scan commands for finding migration issues + +### `pf-glass-theme` + +Enable PatternFly 6 glass theme (glassmorphism) for React applications. + +**Features:** +- Add `.pf-v6-theme-glass` class to enable glass effects +- Global or component-level glass theme support +- Optional runtime theme toggle component +- Dark mode compatibility (`.pf-v6-theme-glass.pf-v6-theme-dark`) +- Glass token usage examples (backdrop blur, transparency) +- Template components for glass UI patterns + +## Installation + +This plugin is part of the `ai-helpers` repository and is automatically available when the repository is loaded. + +## Related Tools + +The plugin complements these official PatternFly migration tools: + +- **[@patternfly/pf-codemods](https://github.com/patternfly/pf-codemods)** - Automated code transformations +- **@patternfly/class-name-updater** - CSS class name updates +- **@patternfly/css-vars-updater** - CSS variable migrations + +Use this plugin for: +- AI-assisted analysis of complex migration scenarios +- One-off component migrations +- Understanding breaking changes +- Migration planning and strategy + +Use official codemods for: +- Comprehensive codebase-wide migrations +- Batch processing of many files +- Standardized transformations + +## Resources + +- [PatternFly v6 Documentation](https://www.patternfly.org/) +- [Migration Guide](https://www.patternfly.org/get-started/upgrade/) +- [Token Reference](https://www.patternfly.org/tokens/all-patternfly-tokens) +- [Component Examples](https://www.patternfly.org/components/all-components) + +## Contributing + +See the main [CLAUDE.md](../../CLAUDE.md) for contribution guidelines. + +When adding new commands or skills: +1. Bump version in `.claude-plugin/plugin.json` +2. Run `make lint` to validate +3. Run `make update` to sync marketplace.json diff --git a/plugins/patternfly/commands/migrate.md b/plugins/patternfly/commands/migrate.md new file mode 100644 index 000000000..1ea8d0f7a --- /dev/null +++ b/plugins/patternfly/commands/migrate.md @@ -0,0 +1,94 @@ +--- +description: Migrate PatternFly v5 to v6 (React components, CSS classes, tokens) +argument-hint: "[file-path]" +skill: pf-react-migration +--- + +## Name +patternfly:migrate + +## Synopsis +``` +/patternfly:migrate [file-path] +``` + +## Description +The `patternfly:migrate` command migrates PatternFly v5 to v6 across React components, CSS classes, and design tokens. It scans for legacy patterns, applies fixes, and identifies items requiring manual updates. + +This command provides: +- Automated detection of v5 patterns (components, CSS classes, tokens) +- Actionable scan commands using ripgrep for remaining issues +- Integration guidance for official @patternfly codemods +- Clear output with file:line references and confidence levels + +## Implementation +The command uses the `pf-react-migration` skill to: + +1. **Scan** for PatternFly v5 patterns using ripgrep commands +2. **Categorize** findings: React code, CSS classes, tokens, deprecated components +3. **Guide** codemod usage: pf-codemods, class-name-updater, css-vars-updater +4. **Apply** manual fixes for non-automatable changes +5. **Report** with confidence levels and testing recommendations + +Follows the concise, actionable pattern of the pf-class-migration-scanner skill. + +## Migration Scope + +### React Components & Props +- Component replacements: Text/TextContent → Content, Chip → Label, KebabToggle → MenuToggle +- Prop updates: isActive → isClicked, labelIcon → labelHelp +- Import paths: Charts /victory, deprecated → /deprecated +- Toolbar chip → label prop renames + +### CSS Classes & Tokens +- Legacy classes: pf-v5-*, pf-v4-*, pf-c-*, pf-u-*, pf-l-* +- Legacy tokens: --pf-v6-*, --pf-global-* → --pf-t--* (semantic) +- Color tokens requiring manual updates + +### Manual Verification Required +- Markup changes (EmptyState, Masthead, Button icons) +- Deprecated components (ApplicationLauncher, old Dropdown/Select, PageHeader, Tile) +- UI testing and accessibility + +## Return Value +- **Scan results**: File paths, current patterns, PF6 replacements +- **Confidence levels**: high/medium/low for each finding +- **Code changes**: Applied fixes with explanations (Why + How to apply) +- **Manual updates**: Items requiring manual verification with testing guidance + +## Examples + +1. **Migrate a single component file**: + ``` + /patternfly:migrate src/components/Dashboard.tsx + ``` + Analyzes and migrates PatternFly components in Dashboard.tsx + +2. **Migrate current working directory**: + ``` + /patternfly:migrate + ``` + Scans and migrates PatternFly v5 patterns in all files from the current directory + +3. **Analyze before migrating**: + ``` + /patternfly:migrate src/components --dry-run + ``` + Shows migration plan without applying changes (if user wants to review first) + +## Arguments +- `$1`: (Optional) File path or directory to migrate. If not provided, analyzes the current context or prompts for clarification. + +## Related Commands +After running migrations, consider: +- Running the official codemods: `npx @patternfly/pf-codemods --v6 --fix ./src` +- Updating CSS class names: `npx @patternfly/class-name-updater --v6 --fix ./src` +- Updating CSS variables: `npx @patternfly/css-vars-updater --fix ./src` +- Running tests to verify functionality + +## Notes +- This command complements but does not replace the official `@patternfly/pf-codemods` tool +- Use AI analysis for complex cases and one-off migrations +- Use official codemods for comprehensive codebase-wide migrations +- Always test migrated components, especially for markup changes +- Review color token replacements (watch for `t_temp_dev_tbd` placeholders) diff --git a/plugins/patternfly/skills/patternfly-migration/SKILL.md b/plugins/patternfly/skills/patternfly-migration/SKILL.md new file mode 100644 index 000000000..dc1a8c3b8 --- /dev/null +++ b/plugins/patternfly/skills/patternfly-migration/SKILL.md @@ -0,0 +1,85 @@ +--- +name: pf-react-migration +description: Migrate PatternFly React components from v5 to v6. Scans for component renames, prop updates, and import changes. +--- + +# PatternFly React Migration + +Migrate PatternFly React components from version 5 to version 6. + +Query the PatternFly MCP server when migration recommendations are ambiguous to verify the latest supported component patterns and tokens. + +## Migration scope + +### React Components and Props +- Component renames: `Text`/`TextContent`/`TextList` → `Content`, `Chip` → `Label`, `KebabToggle` → `MenuToggle` +- Prop updates: `isActive` → `isClicked`, `labelIcon` → `labelHelp`, `isOverflowLabel` → `variant="overflow"` +- Import paths: Charts `/victory`, deprecated → `/deprecated`, promoted "next" components to base +- Toolbar: Chip props → Label props (`deleteChip` → `deleteLabel`) +- Color props: `cyan` → `teal`, `gold` → `yellow` + +### CSS Classes and Tokens +- Legacy versioned classes: `pf-v5-*`, `pf-v4-*` +- Unversioned legacy classes: `pf-c-*`, `pf-u-*`, `pf-l-*` +- Legacy token patterns: `--pf-v6-*`, `--pf-global-*` → `--pf-t--*` (semantic tokens) + +### Deprecated Components +- ApplicationLauncher, ContextSelector, old Dropdown/Select, OptionsMenu, PageHeader, Tile, DragDrop + +## Scan commands + +```bash +# Find v5 imports and component usage +rg "@patternfly/react-core(?!/deprecated)" --type tsx --type jsx + +# Find legacy CSS classes +rg "pf-v5-|pf-v4-|pf-c-|pf-u-|pf-l-" src + +# Find legacy CSS tokens +rg "--pf-v6-|--pf-global-" src + +# Find deprecated component imports +rg "from.*@patternfly/react-core/deprecated" --type tsx --type jsx + +# Find specific component patterns to migrate +rg "<(Text|TextContent|TextList|Chip|KebabToggle)\b" --type tsx --type jsx +``` + +## Migration workflow + +1. **Run automated codemods first**: + ```bash + npx @patternfly/pf-codemods --v6 --fix ./src + npx @patternfly/class-name-updater --v6 --fix ./src + npx @patternfly/css-vars-updater --fix ./src + ``` + +2. **Scan for remaining issues** using commands above + +3. **Apply manual fixes** for: + - Markup changes (EmptyState, Masthead, Button icons) + - Deprecated components requiring custom replacements + - Color tokens (`t_temp_dev_tbd` → semantic tokens) + +4. **Test** UI behavior, accessibility, and responsive design + +## Replacement guidance + +- **Prefer** PatternFly React component props over CSS classes +- **Use** semantic tokens (`--pf-t--*`) over legacy tokens +- **Consult** [v6 token docs](https://www.patternfly.org/tokens/all-patternfly-tokens) for color replacements +- **Run** official codemods for comprehensive coverage before manual updates + +## Output format + +For each finding include: + +- file path and line number +- current component/class/token +- recommended PF6 replacement +- confidence (`high`, `medium`, `low`) +- whether manual testing required + +**Why:** Explain breaking change or deprecation reason + +**How to apply:** Provide code example if replacement is non-obvious diff --git a/plugins/patternfly/skills/pf-glass-theme/README.md b/plugins/patternfly/skills/pf-glass-theme/README.md new file mode 100644 index 000000000..e45571751 --- /dev/null +++ b/plugins/patternfly/skills/pf-glass-theme/README.md @@ -0,0 +1,154 @@ +# PatternFly Glass Theme Skill + +Enable glassmorphism (glass theme) effects in PatternFly 6 React applications. + +## Overview + +This skill helps implement the PatternFly 6 glass theme, which provides modern glassmorphism UI effects using backdrop blur and transparency. Glass theme uses PatternFly's built-in glass design tokens and the `.pf-v6-theme-glass` theme class. + +## What It Does + +1. **Adds glass theme class** to your app (global or component-level) +2. **Provides theme toggle component** for runtime switching (optional) +3. **Supports dark mode** combination (`.pf-v6-theme-glass.pf-v6-theme-dark`) +4. **Includes example components** using glass tokens + +## Glass Theme Tokens + +When `.pf-v6-theme-glass` is applied, these tokens activate: + +- `--pf-t--global--background--color--glass--primary--default` +- `--pf-t--global--background--color--glass--floating--default` +- `--pf-t--global--background--filter--glass--blur--primary` (0px → 12.5px) +- `--pf-t--global--background--filter--glass--blur--floating` +- `--pf-t--global--background--opacity--glass--primary` (100% → 80%) + +## Template Files + +### `scripts/useGlassTheme.ts` ⭐ **Recommended** +Custom React hook for glass theme management with proper cleanup. Supports both default PatternFly glass and Red Hat branded glass variants. + +### `scripts/glass-theme-enhanced.css` +Enhanced CSS for making glass effects visible: +- Subtle background gradients (Red Hat brand colors) +- Visual indicator badge +- Card hover effects +- Supports both light and dark modes + +### `scripts/GlassThemeToggle.tsx` +React component with a PatternFly Switch to toggle glass theme on/off at runtime. + +### `scripts/glass-example.tsx` +Example components demonstrating glass token usage: +- `GlassCard` - Basic card with glass background +- `GlassFloatingCard` - Elevated card with glass effects for modals/popovers + +## Usage Examples + +### Global Glass Theme (Recommended: Use Hook) + +**Best Practice - Custom Hook:** +```tsx +import { useGlassTheme } from './hooks/useGlassTheme'; + +export const MyPage: React.FC = () => { + // Default PatternFly glass + useGlassTheme(); + + // OR Red Hat branded glass + useGlassTheme({ variant: 'redhat' }); + + return
...
; +}; +``` + +**Alternative - HTML:** +```html + + + + + +``` + +### Component-Level Glass Theme + +Wrap specific components: +```tsx +
+ {/* Glass-themed content */} +
+``` + +### Glass + Dark Mode + +Combine theme classes: +```html + +``` + +### Custom Glass Component + +Use glass tokens directly: +```tsx + + {/* Content */} + +``` + +## OpenShift Console Plugins + +For console plugins, use the hook pattern: +```tsx +import { useGlassTheme } from './hooks/useGlassTheme'; +import './styles/glass-theme-enhanced.css'; + +export const MyConsolePage: React.FC = () => { + // Use Red Hat variant for console plugins + useGlassTheme({ variant: 'redhat' }); + + return
...
; +}; +``` + +**IMPORTANT**: The console manages `.pf-v6-theme-dark` automatically. Your hook should ONLY manage glass classes, not dark/light theme. + +## Making Glass Effects Visible + +Glass effects require layered content. Import the enhanced CSS: +```tsx +import './styles/glass-theme-enhanced.css'; +``` + +This adds: +- ✅ Subtle background gradients +- ✅ Visual indicator badge +- ✅ Card hover effects + +## Common Pitfalls + +❌ **Don't** manage `.pf-v6-theme-dark` in your glass hook +❌ **Don't** use hardcoded backgrounds (blocks glass effect) +❌ **Don't** forget to cleanup classes on unmount +✅ **Do** use the `useGlassTheme` hook +✅ **Do** remove hardcoded backgrounds +✅ **Do** add background gradients for visibility + +## Requirements + +- PatternFly 6 CSS loaded +- `@patternfly/react-core` v6 for React components +- Modern browser with backdrop-filter support (Chrome 76+, Safari 9+, Firefox 103+) + +## Related Skills + +- `pf-token-auditor` - Validate glass token usage in Figma designs +- `pf-react-migration` - Migrate from PatternFly 5 to 6 + +## Resources + +- [PatternFly Tokens](https://www.patternfly.org/tokens/all-patternfly-tokens) +- [PatternFly Themes](https://www.patternfly.org/get-started/develop#themes) diff --git a/plugins/patternfly/skills/pf-glass-theme/SKILL.md b/plugins/patternfly/skills/pf-glass-theme/SKILL.md new file mode 100644 index 000000000..02a1193d2 --- /dev/null +++ b/plugins/patternfly/skills/pf-glass-theme/SKILL.md @@ -0,0 +1,229 @@ +--- +name: pf-glass-theme +description: Enable PatternFly 6 glass theme (glassmorphism with backdrop blur and transparency) +--- + +# PatternFly Glass Theme + +Enable the PatternFly 6 glass theme for React applications using `.pf-v6-theme-glass` class and glass tokens. + +## Step 1: Determine Theme Scope + +Ask the user: +- **Global glass theme**: Apply to entire app (add class to `` or root element) +- **Component-level glass**: Apply to specific components only +- **Toggle support**: Include runtime theme switcher +- **Theme variant**: Default PatternFly glass OR Red Hat branded glass (`.pf-v6-theme-redhat`) +- **Console plugin**: For OpenShift console plugins, the console already manages `.pf-v6-theme-dark` + +Default to global if not specified. + +## Step 2: Find and Update Root Element + +### For Global Glass Theme + +**RECOMMENDED APPROACH**: Use the custom hook pattern for proper cleanup. + +1. **Copy** the `useGlassTheme` hook from `scripts/useGlassTheme.ts` to `src/hooks/useGlassTheme.ts` + +2. **Integrate** in your root component or page components: + ```tsx + import { useGlassTheme } from './hooks/useGlassTheme'; + + export const MyPage: React.FC = () => { + // Default PatternFly glass + useGlassTheme(); + + // OR Red Hat branded glass + useGlassTheme({ variant: 'redhat' }); + + return
...
; + }; + ``` + +**ALTERNATIVE**: If HTML modification is preferred: +1. **Find** the HTML template or root render file: + - Try: `public/index.html`, `index.html`, `src/index.html` + +2. **Read** the file + +3. **Check** if `pf-v6-theme-glass` class already exists on `` or root element + +4. **Edit** to add the class: + ```html + + + + + + ``` + +### For Component-Level Glass + +Guide the user to add the class to specific component wrappers: +```tsx +
+ {/* Glass-themed components */} +
+``` + +## Step 3: Optional - Add Theme Switcher + +If user wants toggle support, create a theme switcher component. + +1. **Copy** template from `scripts/GlassThemeToggle.tsx` (if available) OR create inline: + +```tsx +import React from 'react'; +import { Switch } from '@patternfly/react-core'; + +export const GlassThemeToggle: React.FC = () => { + const [isGlassEnabled, setIsGlassEnabled] = React.useState(() => + document.documentElement.classList.contains('pf-v6-theme-glass') + ); + + const handleToggle = (_event: React.FormEvent, checked: boolean) => { + setIsGlassEnabled(checked); + if (checked) { + document.documentElement.classList.add('pf-v6-theme-glass'); + } else { + document.documentElement.classList.remove('pf-v6-theme-glass'); + } + }; + + return ( + + ); +}; +``` + +2. **Write** to `src/components/GlassThemeToggle.tsx` + +3. Guide user to add `` in their app layout/settings + +## Step 4: Dark Mode Support (IMPORTANT) + +**CRITICAL WARNING**: The glass theme hook should NEVER manage `.pf-v6-theme-dark` class. + +### For OpenShift Console Plugins: +- The console ALREADY manages `.pf-v6-theme-dark` based on user preferences +- Your glass theme hook should ONLY add `.pf-v6-theme-glass` (and optionally `.pf-v6-theme-redhat`) +- The combination happens automatically: + - Light: `.pf-v6-theme-glass` (or `.pf-v6-theme-redhat.pf-v6-theme-glass`) + - Dark: `.pf-v6-theme-glass.pf-v6-theme-dark` (console adds the dark class) + +### For Standalone Apps: +If your app manages its own dark mode: +```tsx +// Your existing dark mode logic +if (isDarkMode) { + document.documentElement.classList.add('pf-v6-theme-dark'); +} else { + document.documentElement.classList.remove('pf-v6-theme-dark'); +} + +// Glass theme hook runs separately +useGlassTheme(); +``` + +Glass theme combines with dark mode: `.pf-v6-theme-glass.pf-v6-theme-dark` + +## Step 5: Make Glass Effects Visible + +**IMPORTANT**: Glass effects are only visible when there's layered content behind them. + +### Option A: Add Enhanced CSS (Recommended) +1. **Copy** `scripts/glass-theme-enhanced.css` to `src/styles/` +2. **Import** in your page components: + ```tsx + import './styles/glass-theme-enhanced.css'; + ``` +3. This adds: + - Subtle background gradients (Red Hat brand colors) + - Optional visual indicator badge + - Card hover effects + +### Option B: Custom Background +Add your own background gradient/image to make glass visible. + +**Why this is needed**: Glass effect requires something behind it to blur. Without background content, glass appears identical to solid surfaces. + +## Step 6: Verify Glass Token Usage + +Remind user that glass theme uses these tokens: +- `--pf-t--global--background--color--glass--primary--default` +- `--pf-t--global--background--color--glass--floating--default` +- `--pf-t--global--background--filter--glass--blur--primary` (12.5px when active) +- `--pf-t--global--background--opacity--glass--primary` (80% when active) + +Components using these tokens will automatically get glassmorphism effects when the theme is enabled. + +## Glass Token Reference + +When `.pf-v6-theme-glass` is applied: +- Background opacity: 100% → 80% +- Backdrop blur: 0px → 12.5px +- Works with contexts: `primary`, `floating` + +## Output Format + +Confirm with the user: +- ✅ Glass theme class added to [location] +- ✅ Scope: [global/component-level/with-toggle] +- ✅ Dark mode: [enabled/disabled] +- ✅ Theme switcher: [added/not-added] + +Tell the user: +- Glass effects activate on components using `--pf-t--global--background--color--glass--*` tokens +- To use glass on custom components, apply the glass background tokens +- Glass theme can be combined with dark mode (`.pf-v6-theme-glass.pf-v6-theme-dark`) + +## Common Pitfalls + +### 1. **Managing Dark Mode Incorrectly** +❌ DON'T add/remove `.pf-v6-theme-dark` in your glass theme hook +✅ DO let the console or app's theme system manage dark mode + +### 2. **Hardcoded Backgrounds** +❌ DON'T use hardcoded backgrounds like `background: '#1e1e1e'` - they block glass effects +✅ DO remove hardcoded backgrounds and let PatternFly tokens work + +### 3. **Glass Effect Not Visible** +Problem: Glass looks like solid backgrounds +Solution: +- Add background gradients (use enhanced CSS template) +- Ensure layered content exists +- Try dark mode (effect often more visible) +- Check browser supports `backdrop-filter` + +### 4. **Inconsistent Glass Across Pages** +Problem: Some pages have glass, some don't +Solution: +- Use glass hook in ALL page components +- OR add glass class to `` globally +- Ensure enhanced CSS is imported consistently + +### 5. **No Cleanup on Unmount** +❌ DON'T forget cleanup when using inline `useEffect` +✅ DO use the `useGlassTheme` hook which handles cleanup + +### 6. **Browser Compatibility** +Glass theme requires `backdrop-filter` support: +- ✅ Chrome/Edge 76+ +- ✅ Safari 9+ +- ✅ Firefox 103+ +- ❌ Older browsers (graceful degradation to solid backgrounds) + +## Notes + +- Always use Read tool before Edit tool +- Use Edit tool (not Write) for modifying existing files +- Check for existing theme classes to avoid duplicates +- Glass theme requires PatternFly 6 CSS to be loaded +- Glass tokens are defined in `tokens-glass.scss` and `tokens-local.scss` +- **Prefer the custom hook pattern over inline useEffect** for better cleanup and reusability diff --git a/plugins/patternfly/skills/pf-glass-theme/scripts/GlassThemeToggle.tsx b/plugins/patternfly/skills/pf-glass-theme/scripts/GlassThemeToggle.tsx new file mode 100644 index 000000000..4da38dca3 --- /dev/null +++ b/plugins/patternfly/skills/pf-glass-theme/scripts/GlassThemeToggle.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Switch } from '@patternfly/react-core'; + +interface GlassThemeToggleProps { + /** Optional custom label */ + label?: string; + /** Optional callback when theme changes */ + onThemeChange?: (isGlassEnabled: boolean) => void; +} + +export const GlassThemeToggle: React.FC = ({ + label = 'Glass theme', + onThemeChange, +}) => { + const [isGlassEnabled, setIsGlassEnabled] = React.useState(() => + document.documentElement.classList.contains('pf-v6-theme-glass') + ); + + const handleToggle = (_event: React.FormEvent, checked: boolean) => { + setIsGlassEnabled(checked); + + if (checked) { + document.documentElement.classList.add('pf-v6-theme-glass'); + } else { + document.documentElement.classList.remove('pf-v6-theme-glass'); + } + + onThemeChange?.(checked); + }; + + return ( + + ); +}; diff --git a/plugins/patternfly/skills/pf-glass-theme/scripts/glass-example.tsx b/plugins/patternfly/skills/pf-glass-theme/scripts/glass-example.tsx new file mode 100644 index 000000000..2da47d7f7 --- /dev/null +++ b/plugins/patternfly/skills/pf-glass-theme/scripts/glass-example.tsx @@ -0,0 +1,44 @@ +/** + * Example of using PatternFly 6 glass theme tokens in a custom component + * + * Glass theme activates when the .pf-v6-theme-glass class is on + */ + +import React from 'react'; +import { Card, CardTitle, CardBody } from '@patternfly/react-core'; + +export const GlassCard: React.FC<{ children: React.ReactNode }> = ({ children }) => { + return ( + + {children} + + ); +}; + +export const GlassFloatingCard: React.FC<{ title: string; children: React.ReactNode }> = ({ + title, + children, +}) => { + return ( + + {title} + {children} + + ); +}; diff --git a/plugins/patternfly/skills/pf-glass-theme/scripts/glass-theme-enhanced.css b/plugins/patternfly/skills/pf-glass-theme/scripts/glass-theme-enhanced.css new file mode 100644 index 000000000..95e8528c4 --- /dev/null +++ b/plugins/patternfly/skills/pf-glass-theme/scripts/glass-theme-enhanced.css @@ -0,0 +1,112 @@ +/** + * PatternFly Glass Theme - Enhanced Visibility + * + * This stylesheet provides minimal enhancements to make glass effects visible: + * - Subtle background gradients (adjust opacity as needed) + * - Uses official PatternFly glass tokens + * - Official glass parameters: 12.5px blur, 80% opacity + * + * IMPORTANT: Glass effects are only visible when there's layered content. + * These gradients ensure there's always something behind glass surfaces. + */ + +/* ========================================================================== + Background Gradients (Light Theme) + ========================================================================== */ + +.pf-v6-theme-glass body::before { + content: ''; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: -1; + background: + radial-gradient(ellipse at 15% 25%, rgba(0, 102, 204, 0.03) 0%, transparent 50%), + radial-gradient(ellipse at 85% 75%, rgba(238, 0, 0, 0.025) 0%, transparent 50%), + radial-gradient(ellipse at 50% 50%, rgba(0, 0, 0, 0.01) 0%, transparent 70%); + pointer-events: none; +} + +/* Dark Theme Background Gradients */ +.pf-v6-theme-glass.pf-v6-theme-dark body::before { + background: + radial-gradient(ellipse at 15% 25%, rgba(0, 136, 206, 0.06) 0%, transparent 50%), + radial-gradient(ellipse at 85% 75%, rgba(238, 0, 0, 0.05) 0%, transparent 50%), + radial-gradient(ellipse at 50% 50%, rgba(255, 255, 255, 0.015) 0%, transparent 70%); +} + +/* ========================================================================== + Red Hat Branded Glass Theme (Optional) + ========================================================================== */ + +/* Red Hat Light Glass */ +.pf-v6-theme-redhat.pf-v6-theme-glass body::before { + background: + radial-gradient(ellipse at 15% 25%, rgba(238, 0, 0, 0.03) 0%, transparent 50%), + radial-gradient(ellipse at 85% 75%, rgba(0, 102, 204, 0.025) 0%, transparent 50%), + radial-gradient(ellipse at 50% 50%, rgba(0, 0, 0, 0.01) 0%, transparent 70%); +} + +/* Red Hat Dark Glass */ +.pf-v6-theme-redhat.pf-v6-theme-glass.pf-v6-theme-dark body::before { + background: + radial-gradient(ellipse at 15% 25%, rgba(238, 0, 0, 0.06) 0%, transparent 50%), + radial-gradient(ellipse at 85% 75%, rgba(0, 136, 206, 0.05) 0%, transparent 50%), + radial-gradient(ellipse at 50% 50%, rgba(255, 255, 255, 0.015) 0%, transparent 70%); +} + +/* ========================================================================== + Optional: Glass Theme Indicator Badge + ========================================================================== */ + +.pf-v6-theme-glass .pf-v6-c-page__main-section:first-child::before { + content: 'Glass Theme Active'; + position: fixed; + bottom: 16px; + right: 16px; + padding: 8px 16px; + background: rgba(255, 255, 255, 0.6); + backdrop-filter: blur(12.5px); + -webkit-backdrop-filter: blur(12.5px); + color: rgba(0, 0, 0, 0.85); + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 20px; + font-size: 11px; + font-weight: 600; + letter-spacing: 0.3px; + z-index: 9999; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + pointer-events: none; + user-select: none; + opacity: 0.5; +} + +.pf-v6-theme-glass.pf-v6-theme-dark .pf-v6-c-page__main-section:first-child::before { + background: rgba(36, 36, 48, 0.65); + color: rgba(255, 255, 255, 0.9); + border: 1px solid rgba(255, 255, 255, 0.15); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); +} + +/* ========================================================================== + Optional: Subtle Card Enhancements + ========================================================================== */ + +.pf-v6-theme-glass .pf-v6-c-card { + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.pf-v6-theme-glass .pf-v6-c-card:hover { + transform: translateY(-2px); + box-shadow: + 0 4px 12px rgba(0, 0, 0, 0.08), + 0 1px 3px rgba(0, 0, 0, 0.12); +} + +.pf-v6-theme-glass.pf-v6-theme-dark .pf-v6-c-card:hover { + box-shadow: + 0 4px 12px rgba(0, 0, 0, 0.3), + 0 1px 3px rgba(0, 0, 0, 0.4); +} diff --git a/plugins/patternfly/skills/pf-glass-theme/scripts/useGlassTheme.ts b/plugins/patternfly/skills/pf-glass-theme/scripts/useGlassTheme.ts new file mode 100644 index 000000000..7f0f8de12 --- /dev/null +++ b/plugins/patternfly/skills/pf-glass-theme/scripts/useGlassTheme.ts @@ -0,0 +1,56 @@ +import { useEffect } from 'react'; + +/** + * Custom hook to apply PatternFly glass theme + * + * Options: + * - variant: 'default' | 'redhat' - Use Red Hat branded glass theme + * + * IMPORTANT: This hook does NOT manage dark/light theme. + * If your app already manages .pf-v6-theme-dark (like OpenShift console), + * this hook will work alongside it automatically. + */ +export const useGlassTheme = (options?: { variant?: 'default' | 'redhat' }) => { + const variant = options?.variant ?? 'default'; + + useEffect(() => { + const htmlElement = document.documentElement; + + // Increment reference counts + const glassCount = parseInt(htmlElement.dataset.pfGlassCount || '0', 10) + 1; + htmlElement.dataset.pfGlassCount = glassCount.toString(); + + let redhatCount = 0; + if (variant === 'redhat') { + redhatCount = parseInt(htmlElement.dataset.pfGlassRedhatCount || '0', 10) + 1; + htmlElement.dataset.pfGlassRedhatCount = redhatCount.toString(); + } + + // Apply classes only if this is the first consumer + if (glassCount === 1) { + htmlElement.classList.add('pf-v6-theme-glass'); + } + if (variant === 'redhat' && redhatCount === 1) { + htmlElement.classList.add('pf-v6-theme-redhat'); + } + + // Cleanup: decrement counts and remove classes only when last consumer unmounts + return () => { + const newGlassCount = parseInt(htmlElement.dataset.pfGlassCount || '1', 10) - 1; + htmlElement.dataset.pfGlassCount = Math.max(0, newGlassCount).toString(); + + if (newGlassCount === 0) { + htmlElement.classList.remove('pf-v6-theme-glass'); + } + + if (variant === 'redhat') { + const newRedhatCount = parseInt(htmlElement.dataset.pfGlassRedhatCount || '1', 10) - 1; + htmlElement.dataset.pfGlassRedhatCount = Math.max(0, newRedhatCount).toString(); + + if (newRedhatCount === 0) { + htmlElement.classList.remove('pf-v6-theme-redhat'); + } + } + }; + }, [variant]); +};