Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions figma.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-react-components/Drawer 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Drawer.overlay drawer full.chromium.png 1142 Changed
vr-tests-react-components/Positioning 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Positioning.Positioning end.chromium.png 954 Changed
vr-tests-react-components/Positioning.Positioning end.updated 2 times.chromium.png 710 Changed
vr-tests-react-components/Skeleton converged 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/Skeleton converged.Opaque Skeleton with circle - Dark Mode.default.chromium.png 2 Changed
vr-tests-react-components/TagPicker 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-react-components/TagPicker.disabled - High Contrast.chromium.png 1321 Changed
vr-tests-react-components/TagPicker.disabled - RTL.disabled input hover.chromium.png 635 Changed
vr-tests-web-components/Avatar 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/Avatar. - Dark Mode.normal.chromium.png 10381 Changed
vr-tests-web-components/Badge 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/Badge. - Dark Mode.normal.chromium.png 444 Changed
vr-tests-web-components/MenuList 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/MenuList. - RTL.2nd selected.chromium.png 17 Changed
vr-tests/Callout 11 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/Callout.Bottom center.default.chromium.png 2116 Changed
vr-tests/Callout.Bottom left edge - RTL.default.chromium.png 2186 Changed
vr-tests/Callout.Left bottom edge.default.chromium.png 3123 Changed
vr-tests/Callout.Bottom right edge - RTL.default.chromium.png 1114 Changed
vr-tests/Callout.Bottom right edge.default.chromium.png 1120 Changed
vr-tests/Callout.Left center.default.chromium.png 2544 Changed
vr-tests/Callout.Right bottom edge.default.chromium.png 3037 Changed
vr-tests/Callout.Left top edge.default.chromium.png 2168 Changed
vr-tests/Callout.No callout width specified.default.chromium.png 2126 Changed
vr-tests/Callout.Right center.default.chromium.png 2080 Changed
vr-tests/Callout.Root.default.chromium.png 2181 Changed
vr-tests/Coachmark 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/Coachmark.Collapsed.default.chromium.png 159 Changed
vr-tests/Keytip 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/Keytip.Disabled.default.chromium.png 26 Changed
vr-tests/react-charting-LineChart 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-LineChart.Events - Dark Mode.default.chromium.png 16 Changed
vr-tests/react-charting-LineChart.Events - RTL.default.chromium.png 15 Changed
vr-tests/react-charting-MultiStackBarChart 4 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-MultiStackBarChart.Basic_Absolute - Dark Mode.default.chromium.png 363 Changed
vr-tests/react-charting-MultiStackBarChart.Basic_PartToWhole - RTL.default.chromium.png 343 Changed
vr-tests/react-charting-MultiStackBarChart.Basic_Absolute - RTL.default.chromium.png 343 Changed
vr-tests/react-charting-MultiStackBarChart.Basic_PartToWhole - Dark Mode.default.chromium.png 363 Changed
vr-tests/react-charting-VerticalBarChart 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests/react-charting-VerticalBarChart.Basic - Secondary Y Axis.default.chromium.png 3 Changed

There were 4 duplicate changes discarded. Check the build logs for more information.

"codeConnect": {
"include": [
"packages/react-components/*/stories/**/*.figma.{ts,tsx}",
"packages/react-components/*/stories/**/*.stories.{ts,tsx}"
],
"exclude": ["node_modules/**", "dist/**", "build/**"],
"parser": "react",
"docs": {
"storybookUrl": "http://localhost:3000"
}
}
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
"start": "node -r ./scripts/ts-node/src/register ./scripts/executors/src/start",
"generate": "node -r ./scripts/ts-node/src/register ./scripts/executors/src/generate-ui",
"clean": "nx run-many -t clean --verbose",
"reset-workspace": "node -r ./scripts/ts-node/src/register ./scripts/executors/src/reset-workspace.ts"
"reset-workspace": "node -r ./scripts/ts-node/src/register ./scripts/executors/src/reset-workspace.ts",
"figma:connect": "figma connect publish",
"figma:connect:dev": "figma connect dev"
},
"devDependencies": {
"@actions/core": "1.9.1",
Expand Down Expand Up @@ -57,6 +59,7 @@
"@dnd-kit/utilities": "^3.2.1",
"@eslint/compat": "1.3.0",
"@eslint/js": "9.26.0",
"@figma/code-connect": "1.3.6",
"@floating-ui/dom": "1.6.12",
"@fluentui/react-icons": "^2.0.306",
"@griffel/babel-preset": "1.5.8",
Expand Down
178 changes: 178 additions & 0 deletions packages/react-components/react-button/stories/FIGMA_CODE_CONNECT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Figma Code Connect Integration for Button Component

This document explains how to use the Figma Code Connect integration that has been added to the Button component in Fluent UI.

## Overview

Figma Code Connect allows developers and designers to link Figma components directly to their code implementation, providing a seamless design-to-development workflow. This integration shows the actual React code for components when inspecting them in Figma's Dev Mode.

## What's Been Added

### 1. Dependencies

- `@figma/code-connect` package has been added to the workspace

### 2. Configuration Files

- `Button.figma.tsx` - Maps Figma Button properties to React props
- `figma.config.json` - Project-wide Figma Code Connect configuration
- Updated `index.stories.tsx` - Added Figma metadata to Button stories

### 3. Scripts

- `yarn figma:connect` - Publish Code Connect mappings to Figma
- `yarn figma:connect:dev` - Run development server for Code Connect

## How It Works

### Property Mapping

The `Button.figma.tsx` file maps Figma design properties to React component props:

```typescript
figma.connect(Button, 'FIGMA_NODE_URL', {
props: {
children: figma.textContent('Button Text'),
appearance: figma.enum('Appearance', {
Primary: 'primary',
Secondary: 'secondary',
// ... other mappings
}),
size: figma.enum('Size', {
Small: 'small',
Medium: 'medium',
Large: 'large',
}),
// ... other props
},
example: ({ children, appearance, size, shape, disabled }) => (
<Button appearance={appearance} size={size} shape={shape} disabled={disabled}>
{children}
</Button>
),
});
```

### Storybook Integration

The Button stories now include Figma metadata in the `parameters` object:

```typescript
parameters: {
design: {
type: 'figma',
url: 'https://www.figma.com/design/yourfile/yournode',
},
figmaConnect: {
componentId: 'Button',
variantProps: ['appearance', 'size', 'shape', 'disabled'],
},
}
```

## Setup Instructions

### For Developers

1. **Get Figma Access Token**

- Visit [Figma Personal Access Tokens](https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens)
- Create a token with "File Content" and "Code Connect Write" scopes
- Set the token in your environment or provide it when prompted

2. **Update Figma URLs**

- Replace placeholder URLs in `Button.figma.tsx` with actual Figma component URLs
- Update the design URL in `index.stories.tsx`

3. **Run Code Connect Development Server**

```bash
yarn figma:connect:dev
```

4. **Publish to Figma** (when ready)
```bash
yarn figma:connect
```

### For Designers

1. **Open Figma Dev Mode**

- Select the Button component in your Figma file
- Switch to Dev Mode
- You should see the React code examples linked to your component

2. **View Component Code**
- The actual React implementation will be displayed
- Property mappings will show how design tokens translate to code props
- Live examples demonstrate component usage

## File Structure

```
packages/react-components/react-button/stories/src/Button/
├── Button.figma.tsx # Code Connect configuration
├── index.stories.tsx # Updated with Figma metadata
├── ButtonDefault.stories.tsx # Updated with Figma metadata
└── ...other story files

figma.config.json # Project-wide configuration
```

## Benefits

1. **Design-Code Consistency** - Ensures design components match code implementation
2. **Developer Handoff** - Developers can see exact code while inspecting designs
3. **Documentation** - Living documentation that stays up-to-date with code changes
4. **Efficiency** - Reduces back-and-forth between designers and developers

## Next Steps

1. **Connect Real Figma Components**

- Get the actual Figma file URLs for Button components
- Update the placeholder URLs in the configuration files

2. **Expand to Other Components**

- Follow the same pattern for other Fluent UI components
- Create `.figma.tsx` files for each component that needs Code Connect

3. **Set Up CI/CD Integration**
- Automate publishing of Code Connect mappings
- Integrate with your build process

## Troubleshooting

### Common Issues

1. **TypeScript Errors**

- Ensure React is imported as `import * as React from 'react'`
- Check that all prop mappings match actual component props

2. **Access Token Issues**

- Verify token has correct scopes
- Check token hasn't expired

3. **Missing Components in Figma**
- Ensure Figma URLs point to correct components
- Verify component is published in Figma

### Resources

- [Figma Code Connect Documentation](https://www.figma.com/developers/code-connect)
- [Code Connect GitHub Repository](https://github.com/figma/code-connect)
- [Fluent UI Button Documentation](https://react.fluentui.dev/?path=/docs/components-button-button--docs)

## Contributing

When adding new components or updating existing ones:

1. Create a corresponding `.figma.tsx` file
2. Update the component's stories with Figma metadata
3. Test the integration locally with `yarn figma:connect:dev`
4. Document any new property mappings
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as React from 'react';
import { Button } from '@fluentui/react-components';
import { figma } from '@figma/code-connect';

/**
* Figma Code Connect configuration for Button component
* This connects the Figma Button component to the React implementation
*/
figma.connect(
Button,
'https://www.figma.com/design/Z9KRuq4Dca3xEuC0BAt0YY/Design-Systems-Connect--Demo-?node-id=10-1271&m=dev', // Replace with actual Figma file URL
{
props: {
// Map Figma properties to React props
children: figma.textContent('Button Text'),
appearance: figma.enum('Appearance', {
Secondary: 'secondary', // Default
Primary: 'primary',
Outline: 'outline',
Subtle: 'subtle',
Transparent: 'transparent',
}),
size: figma.enum('Size', {
Small: 'small',
Medium: 'medium', // Default
Large: 'large',
}),
shape: figma.enum('Shape', {
Rounded: 'rounded', // Default
Circular: 'circular',
Square: 'square',
}),
disabled: figma.boolean('Disabled'),
disabledFocusable: figma.boolean('Disabled Focusable'),
// Icon mapping - assuming there's an icon variant
icon: figma.instance('Icon'),
iconPosition: figma.enum('Icon Position', {
Before: 'before', // Default
After: 'after',
}),
},
example: ({
children,
appearance,
size,
shape,
disabled,
disabledFocusable,
icon,
iconPosition,
}: {
children: any;
appearance: any;
size: any;
shape: any;
disabled: any;
disabledFocusable: any;
icon: any;
iconPosition: any;
}) => (
<Button
appearance={appearance}
size={size}
shape={shape}
disabled={disabled}
disabledFocusable={disabledFocusable}
icon={icon}
iconPosition={iconPosition}
>
{children}
</Button>
),
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,15 @@ import { Button } from '@fluentui/react-components';
import type { ButtonProps } from '@fluentui/react-components';

export const Default = (props: ButtonProps): JSXElement => <Button {...props}>Example</Button>;

// Add Figma Code Connect metadata to the default story
Default.parameters = {
design: {
type: 'figma',
url: 'https://www.figma.com/design/yourfile/yournode', // Replace with actual Figma file URL
},
figmaConnect: {
componentId: 'Button',
variantKey: 'Default',
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { Button } from '@fluentui/react-components';
import descriptionMd from './ButtonDescription.md';
import bestPracticesMd from './ButtonBestPractices.md';

// Import Figma Code Connect configuration
import './Button.figma';

export { Default } from './ButtonDefault.stories';
export { Shape } from './ButtonShape.stories';
export { Appearance } from './ButtonAppearance.stories';
Expand All @@ -12,7 +15,7 @@ export { Disabled } from './ButtonDisabled.stories';
export { Loading } from './ButtonLoading.stories';
export { WithLongText } from './ButtonWithLongText.stories';

export default {
const meta: Meta<typeof Button> = {
title: 'Components/Button/Button',
component: Button,
parameters: {
Expand All @@ -21,5 +24,46 @@ export default {
component: [descriptionMd, bestPracticesMd].join('\n'),
},
},
// Add Figma Code Connect metadata
design: {
type: 'figma',
url: 'https://www.figma.com/design/yourfile/yournode', // Replace with actual Figma file URL
},
figmaConnect: {
componentId: 'Button',
variantProps: ['appearance', 'size', 'shape', 'disabled', 'disabledFocusable', 'iconPosition'],
},
},
} as Meta;
argTypes: {
appearance: {
control: { type: 'select' },
options: ['secondary', 'primary', 'outline', 'subtle', 'transparent'],
defaultValue: 'secondary',
},
size: {
control: { type: 'select' },
options: ['small', 'medium', 'large'],
defaultValue: 'medium',
},
shape: {
control: { type: 'select' },
options: ['rounded', 'circular', 'square'],
defaultValue: 'rounded',
},
disabled: {
control: { type: 'boolean' },
defaultValue: false,
},
disabledFocusable: {
control: { type: 'boolean' },
defaultValue: false,
},
iconPosition: {
control: { type: 'select' },
options: ['before', 'after'],
defaultValue: 'before',
},
},
};

export default meta;
Loading
Loading