AI-native Design-as-Code layout components inspired by Figma Auto Layout
npm install figma-react-layoutAI-native Design-as-Code layout components inspired by Figma Auto Layout
一套受 Figma Auto Layout 启发的 React 布局组件库,让"设计稿"这个中间产物消失,让设计语言与前端代码语言直接对齐。
- 🎨 Figma 对齐: 复刻 Figma Auto Layout 的使用体验
- 🔧 零配置: 开箱即用,合理的默认值和智能回退机制
- 📱 TypeScript: 完整的类型提示和检查
- 🎯 语义化: 直观的属性名,一个属性表达完整意图
- 🎨 Token 驱动: 统一的设计token确保视觉一致性
- ⚡ 高性能: 最小化重复计算,优化重渲染
``bash`
npm install figma-react-layout或
yarn add figma-react-layout或
pnpm add figma-react-layout
- React 16.8+ (需要 hooks 支持)
- Styled Components
`jsx
import { Box, Column, Row, ZStack } from 'figma-react-layout';
function App() {
const handleLogin = () => console.log('Login clicked');
const handleCancel = () => console.log('Cancel clicked');
return (
);
}
`
所有 figma-react-layout 组件都支持标准的 React onClick 事件处理器,就像普通 HTML 元素一样。
`jsx
import { Box, Column, Row, ZStack } from 'figma-react-layout';
function ClickableExample() {
const handleBoxClick = (event) => {
console.log('Box clicked!', event.target);
};
const handleColumnClick = () => {
alert('Column container clicked!');
};
const handleRowClick = (event) => {
event.stopPropagation(); // 阻止事件冒泡
console.log('Row coordinates:', event.clientX, event.clientY);
};
return (
{/ Box 点击 /}
height="80px"
fill="blue"
onClick={handleBoxClick}
style={{ cursor: 'pointer' }}
>
Click this Box
{/ Column 点击 /}
height="120px"
fill="green"
onClick={handleColumnClick}
alignment="center-center"
gap="10px"
>
{/ Row 点击 /}
height="80px"
fill="orange"
onClick={handleRowClick}
alignment="center-center"
gap="20px"
>
{/ ZStack 点击 /}
height="120px"
onClick={() => console.log('ZStack clicked')}
>
top="50%"
left="50%"
transform="translate(-50%, -50%)"
width="100px"
height="60px"
fill="purple"
alignment="center-center"
>
Stacked
);
}
`
#### 使用 useCallback 优化性能
`jsx
import React, { useCallback } from 'react';
function OptimizedExample({ data }) {
const handleClick = useCallback((event) => {
console.log('Clicked with data:', data);
}, [data]);
return (
height="80px"
fill="blue"
onClick={handleClick}
>
Optimized Click
);
}
`
#### 嵌套组件事件处理
`jsx
function NestedExample() {
const handleParentClick = () => console.log('Parent clicked');
const handleChildClick = (event) => {
event.stopPropagation(); // 阻止触发父级点击
console.log('Child clicked only');
};
return (
height="150px"
fill="lightblue"
onClick={handleParentClick}
>
fill="red"
onClick={handleChildClick}
>
Child (only fires this)
fill="green"
>
Child (bubbles to parent)
);
}
`
#### 可访问性支持
`jsx
function AccessibleExample() {
const handleClick = () => console.log('Accessible click');
return (
height="60px"
fill="blue"
onClick={handleClick}
tabIndex={0}
role="button"
onKeyDown={(event) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
handleClick();
}
}}
style={{ cursor: 'pointer' }}
>
Accessible Button
);
}
`
`jsx
import { render, screen, fireEvent } from '@testing-library/react';
import { Box } from 'figma-react-layout';
test('onClick handler works', () => {
const handleClick = jest.fn();
render(
onClick={handleClick}
>
Click me
);
const box = screen.getByTestId('clickable-box');
fireEvent.click(box);
expect(handleClick).toHaveBeenCalledTimes(1);
});
`
详细文档: 参见 onClick 事件处理指南
在线示例:
- onClick 示例页面
- onClick 调试面板
最通用的视觉容器,用于包裹内容或定义卡片、面板、背景块。
`jsx`
height="100px"
minWidth="150px"
maxWidth="300px"
alignment="center-center"
distribution="space-between"
gap="$md"
padding="x:$lg y:$sm"
fill="$surface"
strokeColor="$border"
strokeWeight="$sm"
strokeStyle="dashed"
radius="$md"
overflow="hidden"
>
内容
将多个子元素垂直堆叠,自动管理间距与对齐。
`jsx`
让元素在水平方向排列,支持自动换行。
`jsx`
将多个子元素按层叠方式排列,先定义的元素在上层。
`jsx`
`css
:root {
/ 间距 /
--xs: 4px;
--sm: 8px;
--md: 16px;
--lg: 24px;
--xl: 32px;
/ 颜色 /
--primary: #0066ff;
--secondary: #6c757d;
--surface: #ffffff;
--border: #e9ecef;
--error: #dc3545;
--muted: #6c757d;
/ 圆角 /
--none: 0;
--sm: 4px;
--md: 8px;
--lg: 16px;
--full: 50%;
}
`
`jsx`
{/ 自动转换为 CSS 变量 /}
`jsx`
`jsx`
strokeWeight="top:2px right:1px"
strokeStyle="top:solid right:dashed"
>
{/ 上边框:2px solid primary /}
{/ 右边框:1px dashed secondary /}
`jsx`
{/ 右上角:md /}
{/ 左下角:lg /}
{/ 其他角:0 /}
Stroke 属性智能默认值:当任何 stroke 属性被设置时,其他缺失属性自动补充默认值:
`jsx
// 只设置颜色,自动补充:weight="1px", style="solid"
// 只设置粗细,自动补充:color="$border", style="solid"
// 只设置样式,自动补充:color="$border", weight="1px"
`
根据容器类型,overflow 属性智能映射到不同 CSS 实现:
`jsx
// Box: 直接映射
// Column: 垂直方向控制
// Row: 水平方向控制
`
`jsx`
`jsx`
minWidth="200px"
maxWidth="400px"
height="hug"
minHeight="100px"
maxHeight="300px"
>
响应式尺寸约束
`jsx
import { ThemeProvider } from 'styled-components';
const customTheme = {
spacing: {
xs: '2px',
sm: '4px',
md: '8px',
lg: '16px',
xl: '24px',
},
colors: {
primary: '#your-brand-color',
surface: '#your-surface-color',
},
};
function App() {
return (
{/ 你的组件 /}
);
}
`
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| width/height | 'fill' \| 'hug' \| string | 'hug' | 尺寸控制 |minWidth/maxWidth
| | string \| null | null | 宽度约束 |minHeight/maxHeight
| | string \| null | null | 高度约束 |alignment
| | Alignment | 'top-left' | 9点对齐 |gap
| | string | '0' | 子元素间距 |padding
| | string | '0' | 内边距(支持方向控制) |fill
| | string \| null | null | 背景色 |strokeColor
| | string \| null | null | 边框颜色(支持方向控制) |strokeWeight
| | string \| null | null | 边框粗细(支持方向控制) |strokeStyle
| | StrokeStyle \| null | null | 边框样式 |radius
| | string \| null | null | 圆角(支持方向控制) |opacity
| | string \| null | null | 透明度 |overflow
| | Overflow | 'hidden' | 溢出处理 |
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| wrap | 'true' \| 'false' | 'false' | 是否自动换行 |
`jsx`
`jsx`
欢迎回来
优势对比:
- 代码量: 我们的方案节省 60% 代码量
- 可读性: alignment="center-center" vs items-center justify-center$lg
- 一致性: 统一的 token vs 混合的 p-8 gap-6 gap-4
- 维护性: 修改间距只需改一个 token
`bash`
npm install figma-react-layout styled-components
`css
/ 在你的全局CSS中 /
:root {
--xs: 4px;
--sm: 8px;
--md: 16px;
--lg: 24px;
--xl: 32px;
--primary: #0066ff;
--surface: #ffffff;
--border: #e9ecef;
--error: #dc3545;
--muted: #6c757d;
--none: 0;
--sm: 4px;
--md: 8px;
--lg: 16px;
--full: 50%;
}
`
`jsx
import { Box, Column, Row } from 'figma-react-layout';
// 直接替换原有的 div 和样式
function MyComponent() {
return (
内容
);
}
``
MIT License
欢迎提交 Issues 和 Pull Requests!