diff --git a/.cursor/rules/figma-rules.mdc b/.cursor/rules/figma-rules.mdc new file mode 100644 index 00000000000..880a0203d9e --- /dev/null +++ b/.cursor/rules/figma-rules.mdc @@ -0,0 +1,165 @@ +--- +description: Figma Dev Mode MCP rules +alwaysApply: true +--- + +# Figma Dev Mode MCP Rules + +You are an expert developer working with the Codecademy Gamut design system and Figma Dev Mode MCP integration. + +When generating code from Figma designs, follow these rules: + +## MANDATORY Pre-Generation Steps + +**BEFORE generating ANY code from Figma, you MUST:** + +1. **Inspect the Figma layer hierarchy**: + + - Call `get_metadata` WITH the nodeId to get parent component info + - Call `get_metadata` WITHOUT nodeId (empty string) to attempt to get CHILD layers + - **IMPORTANT**: Current limitation - `get_metadata` may not return nested child layer names (icons, nested components, etc.) + - **If child layer names are not available from tooling:** + - Analyze the screenshot and make your best guess about which icons/nested components are used + - Look for visual clues (user icon, gear icon, etc.) and match them to likely Gamut icon names + - Search the codebase to verify the icon exists (e.g., check for `PersonIcon`, `GearIcon`, etc. in `/packages/gamut-icons/src`) + - Generate the code using your best guess + - **AFTER generating the code**, ask the user to confirm the icons are correct + - Example: "I've generated the code using PersonIcon and GearIcon based on what I see in the screenshot. Can you confirm these are the correct icons from the Figma layers?" + - Map icon layer names to components in the codebase (e.g., "Regular/Interface/PersonIcon" → `PersonIcon`, "Mini/MiniCheckCircleIcon" → `MiniCheckCircleIcon`) + +2. **Read token files** (use read_file tool on ALL of these): + + - `/packages/gamut-styles/src/variables/spacing.ts` + - `/packages/gamut-styles/src/variables/colors.ts` + - `/packages/gamut-styles/src/variables/typography.ts` + - `/packages/gamut-styles/src/variables/borderRadii.ts` + +3. **Search for existing components** (use codebase_search): + + - Check if similar component exists in `/packages/gamut/src` + - If exists, extend it instead of creating new one + +4. **Understand the design system patterns**: + - Read example components like Badge, Tag, or Button + - Follow variance, system props, and styledOptions patterns + +## Asset Management + +- The Figma Dev Mode MCP Server provides an assets endpoint which can serve image and SVG assets +- **IMPORTANT**: do NOT use or create placeholders if a localhost source is provided + +## Component Usage + +- **IMPORTANT**: Always use components from `/packages` whenever possible +- Check if the Figma component name matches a Gamut component name and use that component +- **IMPORTANT**: All patterns should come from `/packages/gamut-patterns` - use the design's metadata to match the Figma component name to the pattern component +- **IMPORTANT**: All illustrations should come from `/packages/gamut-illustrations` - use the design's metadata to match the Figma component name to the illustration component +- **IMPORTANT**: All icons should come from `/packages/gamut-icons`: + - Try to get icon layer names from Figma metadata + - If layer names are not available, make your best guess based on the screenshot and verify the icon exists in the codebase + - Generate the code with your best guess, then confirm with the user after + - Map icon layer names to Gamut components (e.g., "Regular/Interface/PersonIcon" → `PersonIcon` from `@codecademy/gamut-icons`) + +## Styling Guidelines - STRICT RULES + +### ❌ NEVER Do This: + +```tsx +// NEVER use hardcoded pixel values +height: 24, +width: '64px', +fontSize: 14, + +// NEVER use hardcoded hex colors +color: '#ffffff', +backgroundColor: '#000000', + +// NEVER use CSS properties not in system props +backdropFilter: 'blur(1px)', + +// NEVER use inline styles +style={{ fontSize: 14 }} +``` + +### ✅ ALWAYS Do This: + +```tsx +// ALWAYS use spacing tokens (4, 8, 12, 16, 24, 32, 40, 48, 64, 96) +height: 24, // from spacing.ts +width: 64, // from spacing.ts + +// ALWAYS use fontSize tokens (14, 16, 18, 20, 22, 26, 34, 44, 64) +fontSize: 14, // from typography.ts + +// ALWAYS use borderRadii tokens (none, sm, md, lg, xl, full) +borderRadius: 'full', // from borderRadii.ts + +// ALWAYS use semantic color tokens +bg: 'background', +color: 'text', +borderColor: 'border', + +// ALWAYS use system props via system.css or styled components +system.css({ + bg: 'black', + color: 'white', + borderRadius: 'full', +}) +``` + +### Token Mapping Rules: + +1. **Spacing/Sizing**: Map Figma values to closest token from `spacing.ts` + + - 4px, 8px, 12px, 16px, 24px, 32px, 40px, 48px, 64px, 96px + +2. **Colors**: Use semantic tokens OR core colors from `colors.ts` + + - Semantic: `background`, `text`, `border`, `text-secondary`, etc. + - Core: `navy`, `white`, `black`, `blue`, `green`, `red`, `yellow`, etc. + - For Background component only: use color names (navy, white, etc.) + +3. **Border Radius**: Use tokens from `borderRadii.ts` + + - none (0px), sm (2px), md (4px), lg (8px), xl (16px), full (999px) + +4. **Typography**: Use tokens from `typography.ts` + + - fontFamily: `accent`, `base`, `monospace`, `system` + - fontSize: 14, 16, 18, 20, 22, 26, 34, 44, 64 + - fontWeight: 400, 700 or `base`, `title` + - lineHeight: `base` (1.5), `title` (1.2), `spacedTitle` (1.3) + +5. **If no exact match**: Document in code comment why custom value needed + +### Emotion & CSS-in-JS Patterns: + +- **IMPORTANT**: Do not use inline styles +- Use `styled` from `@emotion/styled` +- Use `system.css()` for style objects +- Use `styledOptions` for styled component options +- Compose system props with `variance.compose()` + +## Accessibility & Best Practices + +- **IMPORTANT**: Follow WCAG requirements for accessibility +- Always follow best practices from `/packages/styleguide/src/lib/Meta/Best Practices.mdx` + +## Implementation + +- Use the CodeConnect implementation when available +- Generate clean, maintainable React code using TypeScript +- Follow the existing Gamut patterns and conventions + +## Post-Generation Validation + +After generating code, verify: + +- [ ] No hardcoded hex colors (`#` in color values) +- [ ] No hardcoded pixel strings (`'24px'` format) +- [ ] All spacing values match tokens from spacing.ts +- [ ] All colors use semantic tokens or theme colors +- [ ] All border radius uses borderRadii tokens +- [ ] Component follows Gamut patterns (variance, system props, styledOptions) +- [ ] No inline styles +- [ ] Uses emotion styled components diff --git a/.eslintignore b/.eslintignore index 9152f931279..2b0150ad6de 100644 --- a/.eslintignore +++ b/.eslintignore @@ -8,4 +8,6 @@ docs **/tmp packages/gamut-icons/src/icons packages/gamut-patterns/src/patterns +**/code-connect/** +packages/code-connect .nx diff --git a/.eslintrc.js b/.eslintrc.js index 326e2bdff4c..3ace90f7b93 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -8,6 +8,8 @@ module.exports = { plugins: ['eslint-plugin-gamut'], + ignorePatterns: ['packages/code-connect/**/*'], + rules: { 'gamut/prefer-themed': 'error', 'gamut/no-css-standalone': 'error', diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/.github/instructions/figma.instructions.md b/.github/instructions/figma.instructions.md new file mode 100644 index 00000000000..d316f6a15c7 --- /dev/null +++ b/.github/instructions/figma.instructions.md @@ -0,0 +1,189 @@ +--- +applyTo: '**' +priority: high +--- + +# Figma Dev Mode MCP Rules + +You are an expert developer working with the Codecademy Gamut design system and Figma Dev Mode MCP integration. + +When generating code from Figma designs, follow these rules: + +## WORKFLOW TRIGGER - CRITICAL + +**When you see ANY of these patterns:** + +- Figma URL mentioned (figma.com/design/...) +- nodeId provided +- "generate from figma" or similar requests +- MCP Figma server is being used + +## MANDATORY Pre-Generation Steps - MUST BE COMPLETED IN ORDER + +**Step 1: Figma Inspection (REQUIRED)** + +- [ ] Call `get_metadata` WITH nodeId +- [ ] Call `get_metadata` WITHOUT nodeId +- **IMPORTANT**: Current limitation - `get_metadata` may not return nested child layer names (icons, nested components, etc.) + - **If child layer names are not available from tooling:** + - Analyze the screenshot and make your best guess about which icons/nested components are used + - Look for visual clues (user icon, gear icon, etc.) and match them to likely Gamut icon names + - Search the codebase to verify the icon exists (e.g., check for `PersonIcon`, `GearIcon`, etc. in `/packages/gamut-icons/src`) + - Generate the code using your best guess + - **AFTER generating the code**, ask the user to confirm the icons are correct + - Example: "I've generated the code using PersonIcon and GearIcon based on what I see in the screenshot. Can you confirm these are the correct icons from the Figma layers?" + - Map icon layer names to components in the codebase (e.g., "Regular/Interface/PersonIcon" → `PersonIcon`, "Mini/MiniCheckCircleIcon" → `MiniCheckCircleIcon`) +- [ ] Call `get_image` to get screenshot FOR CONFIRMATION ONLY +- [ ] **Validate that screenshot matches metadata understanding** + +**Step 1.5: Metadata Analysis (NEW - REQUIRED)** + +- [ ] **PRIMARY SOURCE**: Use Figma metadata to determine: + - Component name and type + - Layer structure and nested components + - Any CodeConnect implementations mentioned +- [ ] **SECONDARY SOURCE**: Use screenshot only to: + - Confirm visual styling details + - Identify icons if not available in metadata + - Validate layout and spacing +- [ ] **If metadata says "Badge" but screenshot looks different, trust the metadata** + +**Step 2: Token Analysis (REQUIRED)** + +- [ ] Read `/packages/gamut-styles/src/variables/spacing.ts` +- [ ] Read `/packages/gamut-styles/src/variables/colors.ts` +- [ ] Read `/packages/gamut-styles/src/variables/typography.ts` +- [ ] Read `/packages/gamut-styles/src/variables/borderRadii.ts` + +**Step 3: Component Research (REQUIRED)** + +- [ ] Search for existing components in `/packages/gamut/src` +- [ ] Read existing component if found +- [ ] Determine if extending existing vs creating new + +**Step 4: Generate Code** + +- [ ] Use existing components when possible +- [ ] Follow token mapping rules strictly +- [ ] Validate against post-generation checklist + +## Asset Management + +- The Figma Dev Mode MCP Server provides an assets endpoint which can serve image and SVG assets +- **IMPORTANT**: do NOT use or create placeholders if a localhost source is provided + +## Component Usage + +- **IMPORTANT**: Always use components from `/packages` whenever possible +- Check if the Figma component name matches a Gamut component name and use that component +- **IMPORTANT**: All patterns should come from `/packages/gamut-patterns` - use the design's metadata to match the Figma component name to the pattern component +- **IMPORTANT**: All illustrations should come from `/packages/gamut-illustrations` - use the design's metadata to match the Figma component name to the illustration component +- **IMPORTANT**: All icons should come from `/packages/gamut-icons`: + - Try to get icon layer names from Figma metadata + - If layer names are not available, make your best guess based on the screenshot and verify the icon exists in the codebase + - Generate the code with your best guess, then confirm with the user after + - Map icon layer names to Gamut components (e.g., "Regular/Interface/PersonIcon" → `PersonIcon` from `@codecademy/gamut-icons`) + +## Styling Guidelines - STRICT RULES + +### ❌ NEVER Do This: + +```tsx +// NEVER use hardcoded pixel values +height: 24, +width: '64px', +fontSize: 14, + +// NEVER use hardcoded hex colors +color: '#ffffff', +backgroundColor: '#000000', + +// NEVER use CSS properties not in system props +backdropFilter: 'blur(1px)', + +// NEVER use inline styles +style={{ fontSize: 14 }} +``` + +### ✅ ALWAYS Do This: + +```tsx +// ALWAYS use spacing tokens (4, 8, 12, 16, 24, 32, 40, 48, 64, 96) +height: 24, // from spacing.ts +width: 64, // from spacing.ts + +// ALWAYS use fontSize tokens (14, 16, 18, 20, 22, 26, 34, 44, 64) +fontSize: 14, // from typography.ts + +// ALWAYS use borderRadii tokens (none, sm, md, lg, xl, full) +borderRadius: 'full', // from borderRadii.ts + +// ALWAYS use semantic color tokens +bg: 'background', +color: 'text', +borderColor: 'border', + +// ALWAYS use system props via system.css or styled components +system.css({ + bg: 'black', + color: 'white', + borderRadius: 'full', +}) +``` + +### Token Mapping Rules: + +1. **Spacing/Sizing**: Map Figma values to closest token from `spacing.ts` + + - 4px, 8px, 12px, 16px, 24px, 32px, 40px, 48px, 64px, 96px + +2. **Colors**: Use semantic tokens OR core colors from `colors.ts` + + - Semantic: `background`, `text`, `border`, `text-secondary`, etc. + - Core: `navy`, `white`, `black`, `blue`, `green`, `red`, `yellow`, etc. + - For Background component only: use color names (navy, white, etc.) + +3. **Border Radius**: Use tokens from `borderRadii.ts` + + - none (0px), sm (2px), md (4px), lg (8px), xl (16px), full (999px) + +4. **Typography**: Use tokens from `typography.ts` + + - fontFamily: `accent`, `base`, `monospace`, `system` + - fontSize: 14, 16, 18, 20, 22, 26, 34, 44, 64 + - fontWeight: 400, 700 or `base`, `title` + - lineHeight: `base` (1.5), `title` (1.2), `spacedTitle` (1.3) + +5. **If no exact match**: Document in code comment why custom value needed + +### Emotion & CSS-in-JS Patterns: + +- **IMPORTANT**: Do not use inline styles +- Use `styled` from `@emotion/styled` +- Use `system.css()` for style objects +- Use `styledOptions` for styled component options +- Compose system props with `variance.compose()` + +## Accessibility & Best Practices + +- **IMPORTANT**: Follow WCAG requirements for accessibility +- Always follow best practices from `/packages/styleguide/src/lib/Meta/Best Practices.mdx` + +## Implementation + +- Use the CodeConnect implementation when available +- Generate clean, maintainable React code using TypeScript +- Follow the existing Gamut patterns and conventions + +## Post-Generation Validation + +After generating code, verify: + +- [ ] No hardcoded hex colors (`#` in color values) +- [ ] No hardcoded pixel strings (`'24px'` format) +- [ ] All spacing values match tokens from spacing.ts +- [ ] All colors use semantic tokens or theme colors +- [ ] All border radius uses borderRadii tokens +- [ ] Component follows Gamut patterns (variance, system props, styledOptions) +- [ ] No inline styles +- [ ] Uses emotion styled components diff --git a/.prettierignore b/.prettierignore index 291938f37e6..af4f080d196 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,6 +5,7 @@ node_modules packages/gamut-icons/src/icons packages/gamut-styles/**/*.d.ts packages/styleguide/stories/Core/Atoms/Markdown/*.md +packages/code-connect/**/* /.nx/cache /.nx/workspace-data diff --git a/figma.config.json b/figma.config.json new file mode 100644 index 00000000000..aa3e3439256 --- /dev/null +++ b/figma.config.json @@ -0,0 +1,7 @@ +{ + "codeConnect": { + "include": ["packages/code-connect/**/*.figma.{tsx,jsx}"], + "label": "React", + "interactiveSetupFigmaFileUrl": "https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=23-5&p=f&m=dev" + } +} diff --git a/packages/code-connect/Atoms/Anchor.figma.tsx b/packages/code-connect/Atoms/Anchor.figma.tsx new file mode 100644 index 00000000000..9cff9bae583 --- /dev/null +++ b/packages/code-connect/Atoms/Anchor.figma.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { Anchor } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + Anchor, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=19220%3A21856', + { + props: { + children: figma.string('✏️ label'), + icon: figma.boolean('👁 leading icon', { + true: figma.instance('↳ leading icon'), + false: figma.boolean('👁 trailing icon', { + true: figma.instance('↳ trailing icon'), + false: undefined, + }), + }), + variant: figma.enum('variant', { + Inline: 'inline', + Interface: 'interface', + Standard: 'standard', + 'Standard-secondary': 'standard-secondary', + }), + }, + example: ({ children, ...props }) => {children}, + } +); diff --git a/packages/code-connect/Atoms/Badge.figma.tsx b/packages/code-connect/Atoms/Badge.figma.tsx new file mode 100644 index 00000000000..94800ac0f40 --- /dev/null +++ b/packages/code-connect/Atoms/Badge.figma.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { Badge } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + Badge, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=8200%3A8349', + { + props: { + children: figma.string('✏️ label'), + icon: figma.instance('↳ icon'), + variant: figma.enum('variant', { + primary: 'primary', + secondary: 'secondary', + tertiary: 'tertiary', + tertiaryFill: 'tertiaryFill', + accent: 'accent', + }), + size: figma.enum('size', { + base: 'base', + sm: 'sm', + }), + }, + example: ({ children, ...props }: any) => ( + {children} + ), + } +); diff --git a/packages/code-connect/Atoms/Buttons/CTAButton.figma.tsx b/packages/code-connect/Atoms/Buttons/CTAButton.figma.tsx new file mode 100644 index 00000000000..f1d1208d72c --- /dev/null +++ b/packages/code-connect/Atoms/Buttons/CTAButton.figma.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { CTAButton } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + CTAButton, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=1615%3A1914', + { + props: { + children: figma.string('✏️ label'), + icon: figma.boolean('👁 leading icon', { + true: figma.instance('↳ leading icon'), + false: figma.boolean('👁 trailing icon', { + true: figma.instance('↳ trailing icon'), + false: undefined, + }), + }), + }, + example: ({ children, ...props }) => ( + {children} + ), + } +); diff --git a/packages/code-connect/Atoms/Buttons/FillButton.figma.tsx b/packages/code-connect/Atoms/Buttons/FillButton.figma.tsx new file mode 100644 index 00000000000..84f22e13cfd --- /dev/null +++ b/packages/code-connect/Atoms/Buttons/FillButton.figma.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { FillButton } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + FillButton, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=1106%3A7', + { + props: { + icon: figma.boolean('👁 leading icon', { + true: figma.instance('↳ leading icon'), + false: figma.boolean('👁 trailing icon', { + true: figma.instance('↳ trailing icon'), + false: undefined, + }), + }), + children: figma.string('✏️ label'), + variant: figma.enum('variant', { + primary: 'primary', + secondary: 'secondary', + danger: 'danger', + }), + size: figma.enum('size', { + normal: 'normal', + small: 'small', + large: 'large', + }), + }, + example: ({ children, ...props }) => ( + {children} + ), + } +); diff --git a/packages/code-connect/Atoms/Buttons/IconButton.figma.tsx b/packages/code-connect/Atoms/Buttons/IconButton.figma.tsx new file mode 100644 index 00000000000..65898b34504 --- /dev/null +++ b/packages/code-connect/Atoms/Buttons/IconButton.figma.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { IconButton } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + IconButton, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=1106%3A90', + { + props: { + icon: figma.instance('icon'), + size: figma.enum('size', { + normal: 'normal', + small: 'small', + large: 'large', + }), + toolTipInfo: figma.nestedProps('tooltip', { + tip: figma.textContent('✏️ tooltip'), + }), + }, + example: (props) => , + } +); diff --git a/packages/code-connect/Atoms/Buttons/StrokeButton.figma.tsx b/packages/code-connect/Atoms/Buttons/StrokeButton.figma.tsx new file mode 100644 index 00000000000..0d637bc317b --- /dev/null +++ b/packages/code-connect/Atoms/Buttons/StrokeButton.figma.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { StrokeButton } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + StrokeButton, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=1106%3A48', + { + props: { + children: figma.string('✏️ label'), + icon: figma.boolean('👁 leading icon', { + true: figma.instance('↳ leading icon'), + false: figma.boolean('👁 trailing icon', { + true: figma.instance('↳ trailing icon'), + false: undefined, + }), + }), + variant: figma.enum('variant', { + primary: 'primary', + secondary: 'secondary', + danger: 'danger', + }), + size: figma.enum('size', { + normal: 'normal', + small: 'small', + large: 'large', + }), + }, + example: ({ children, ...props }) => ( + {children} + ), + } +); diff --git a/packages/code-connect/Atoms/Buttons/TextButton.figma.tsx b/packages/code-connect/Atoms/Buttons/TextButton.figma.tsx new file mode 100644 index 00000000000..9bdc3a7e077 --- /dev/null +++ b/packages/code-connect/Atoms/Buttons/TextButton.figma.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { TextButton } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + TextButton, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=1106%3A69', + { + props: { + children: figma.string('✏️ label'), + icon: figma.boolean('👁 leading icon', { + true: figma.instance('↳ leading icon'), + false: figma.boolean('👁 trailing icon', { + true: figma.instance('↳ trailing icon'), + false: undefined, + }), + }), + size: figma.enum('size', { + small: 'small', + normal: 'normal', + large: 'large', + }), + }, + example: ({ children, ...props }) => ( + {children} + ), + } +); diff --git a/packages/code-connect/Atoms/Card.figma.tsx b/packages/code-connect/Atoms/Card.figma.tsx new file mode 100644 index 00000000000..a574e45ff0f --- /dev/null +++ b/packages/code-connect/Atoms/Card.figma.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { Card } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + Card, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=20111%3A63391', + { + props: { + variant: figma.enum('variant', { + Default: 'default', + White: 'white', + Yellow: 'yellow', + Beige: 'beige', + Navy: 'navy', + Hyper: 'hyper', + }), + shadow: figma.enum('shadow', { + 'pattern-right': 'patternRight', + 'pattern-left': 'patternLeft', + outline: 'outline', + none: 'none', + }), + isInteractive: figma.boolean('isInteractive'), + children: figma.children('.Card Content'), + }, + example: ({ children, ...props }) => ( + {children} + ), + } +); diff --git a/packages/code-connect/Atoms/Drawer.figma.tsx b/packages/code-connect/Atoms/Drawer.figma.tsx new file mode 100644 index 00000000000..94f66523b75 --- /dev/null +++ b/packages/code-connect/Atoms/Drawer.figma.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { Drawer } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + Drawer, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=115820-91241', + { + props: { + alignContentContainer: figma.enum('alignContentContainer', { + left: 'left', + right: 'right', + }), + expanded: true, + children: figma.textContent('text'), + }, + example: ({ children, ...props }) => ( + {children} + ), + } +); diff --git a/packages/code-connect/Atoms/FeatureShimmer.figma.tsx b/packages/code-connect/Atoms/FeatureShimmer.figma.tsx new file mode 100644 index 00000000000..192c8768a1e --- /dev/null +++ b/packages/code-connect/Atoms/FeatureShimmer.figma.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { FeatureShimmer } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + FeatureShimmer, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=61568%3A44253', + { + props: { + children: '{children}', + }, + example: (props) => {props.children}, + } +); diff --git a/packages/code-connect/Atoms/FormGroup.figma.tsx b/packages/code-connect/Atoms/FormGroup.figma.tsx new file mode 100644 index 00000000000..0ea9584300f --- /dev/null +++ b/packages/code-connect/Atoms/FormGroup.figma.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { FormGroup } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + FormGroup, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=47031%3A18018', + { + props: { + label: figma.string('✏️ label'), + infoTip: figma.boolean('infoTip'), + required: figma.boolean('required'), + labelSize: figma.enum('size', { + small: 'small', + large: 'large', + }), + infoTipData: figma.nestedProps('infotip', { + emphasis: figma.enum('emphasis', { low: 'low', high: 'high' }), + disabled: figma.enum('state', { + default: false, + hover: false, + active: false, + focus: false, + disabled: true, + }), + }), + description: figma.boolean('description', { + true: figma.textContent('description'), + }), + toolTipInfo: figma.nestedProps('.infotip-alignment', { + alignment: figma.enum('alignment', { + 'top-left': 'top-left', + 'top-right': 'top-right', + 'bottom-left': 'bottom-left', + 'bottom-right': 'bottom-right', + }), + info: figma.textContent('✏️ tip'), + }), + }, + example: (props) => ( + + ), + } +); diff --git a/packages/code-connect/Atoms/FormInputs/Checkbox.figma.tsx b/packages/code-connect/Atoms/FormInputs/Checkbox.figma.tsx new file mode 100644 index 00000000000..1be7cb6c9f5 --- /dev/null +++ b/packages/code-connect/Atoms/FormInputs/Checkbox.figma.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { Checkbox } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + Checkbox, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=1199%3A270', + { + props: { + label: figma.string('✏️ label'), + checked: figma.enum('checked', { + true: 'true', + false: 'false', + Indeterminate: 'false', + }), + indeterminate: figma.enum('checked', { + true: 'false', + false: 'false', + Indeterminate: 'true', + }), + ariaLabel: figma.string('✏️ label'), + }, + example: ({ ariaLabel, ...props }) => ( + + ), + } +); diff --git a/packages/code-connect/Atoms/FormInputs/Input.figma.tsx b/packages/code-connect/Atoms/FormInputs/Input.figma.tsx new file mode 100644 index 00000000000..af178e9c102 --- /dev/null +++ b/packages/code-connect/Atoms/FormInputs/Input.figma.tsx @@ -0,0 +1,124 @@ +import React from 'react'; +import { Input } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + Input, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=1189%3A590', + { + props: { + type: figma.enum('type', { + text: 'text', + number: 'number', + file: 'file', + }), + size: figma.enum('size', { + base: 'base', + small: 'small', + }), + error: figma.enum('state', { + error: true, + 'error + hover': true, + 'error + focus': true, + 'filled + error': true, + 'filled + error + hover': true, + 'filled + error + focus': true, + }), + valid: figma.enum('state', { + valid: true, + 'valid + hover': true, + 'valid + focus': true, + 'filled + valid': true, + 'filled + valid + focus': true, + 'filled + valid + hover': true, + }), + disabled: figma.enum('state', { + disabled: true, + 'filled + disabled': true, + }), + placeholder: figma.boolean('placeholder', { + true: figma.enum('state', { + enabled: figma.enum('type', { + text: figma.textContent('placeholder'), + number: figma.textContent('placeholder'), + }), + hover: figma.enum('type', { + text: figma.textContent('placeholder'), + number: figma.textContent('placeholder'), + }), + focus: figma.enum('type', { + text: figma.textContent('placeholder'), + number: figma.textContent('placeholder'), + }), + error: figma.enum('type', { + text: figma.textContent('placeholder'), + number: figma.textContent('placeholder'), + }), + 'error + hover': figma.enum('type', { + text: figma.textContent('placeholder'), + number: figma.textContent('placeholder'), + }), + 'error + focus': figma.enum('type', { + text: figma.textContent('placeholder'), + number: figma.textContent('placeholder'), + }), + disabled: figma.enum('type', { + text: figma.textContent('placeholder'), + number: figma.textContent('placeholder'), + }), + }), + }), + defaultValue: figma.enum('state', { + filled: figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + 'filled + hover': figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + 'filled + focus': figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + 'filled + valid': figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + 'filled + valid + hover': figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + 'filled + valid + focus': figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + 'filled + error': figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + 'filled + error + hover': figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + 'filled + error + focus': figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + 'filled + disabled': figma.enum('type', { + text: figma.string('input'), + number: figma.string('number'), + }), + }), + }, + example: (props) => , + } +); diff --git a/packages/code-connect/Atoms/FormInputs/Radio.figma.tsx b/packages/code-connect/Atoms/FormInputs/Radio.figma.tsx new file mode 100644 index 00000000000..49e1609899d --- /dev/null +++ b/packages/code-connect/Atoms/FormInputs/Radio.figma.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { Radio } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + Radio, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=1191%3A1622', + { + props: { + label: figma.string('✏️ label'), + checked: figma.boolean('selected'), + disabled: figma.enum('state', { + enabled: false, + hover: false, + active: false, + focus: false, + error: false, + disabled: true, + }), + error: figma.enum('state', { + enabled: false, + hover: false, + active: false, + focus: false, + error: true, + disabled: false, + }), + hasInfotip: figma.boolean('infoTip', { + true: true, + false: false, + }), + hasEmphasis: figma.nestedProps('infotip', { + emphasis: figma.enum('emphasis', { low: 'low', high: 'high' }), + }), + toolTipInfo: figma.nestedProps('.infotip-alignment', { + alignment: figma.enum('alignment', { + 'top-left': 'top-left', + 'top-right': 'top-right', + 'bottom-left': 'bottom-left', + 'bottom-right': 'bottom-right', + }), + info: figma.string('✏️ info tip'), + }), + }, + example: (props) => ( + + ), + } +); diff --git a/packages/code-connect/Atoms/FormInputs/Select.figma.tsx b/packages/code-connect/Atoms/FormInputs/Select.figma.tsx new file mode 100644 index 00000000000..b0923781cec --- /dev/null +++ b/packages/code-connect/Atoms/FormInputs/Select.figma.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { Select } from '@codecademy/gamut'; +import figma from '@figma/code-connect'; + +/** + * -- This file was auto-generated by Code Connect -- + * `props` includes a mapping from Figma properties and variants to + * suggested values. You should update this to match the props of your + * code component, and update the `example` function to return the + * code example you'd like to see in Figma + */ + +figma.connect( + Select, + 'https://www.figma.com/design/ReGfRNillGABAj5SlITalN/%F0%9F%93%90-Gamut?node-id=70050%3A14802', + { + props: { + sizeVariant: figma.enum('sizeVariant', { + base: 'base', + small: 'small', + }), + disabled: figma.enum('state', { + Enabled: false, + Hover: false, + Focus: false, + Active: false, + Filled: false, + 'Filled + Hover': false, + 'Filled + Focus': false, + 'Filled + Active': false, + Error: false, + Disabled: true, + }), + error: figma.enum('state', { + Enabled: false, + Hover: false, + Focus: false, + Active: false, + Filled: false, + 'Filled + Hover': false, + 'Filled + Focus': false, + 'Filled + Active': false, + Error: true, + Disabled: false, + }), + options: figma.children('*'), + defaultValue: figma.string('selection'), + }, + example: (props) =>