Webflow Apps 用户端
内部 Finsweet 库
Finsweet的Webflow应用程序的共享UI组件和公用设施.
🔗 现场故事书文档
安装
pnpm add @finsweet/webflow-apps-utils
使用量
import '@finsweet/webflow-apps-utils/index.css';
import { Button, Modal, Input, siteInfo } from '@finsweet/webflow-apps-utils';
项目结构
src/
├── lib/
│ ├── router/ # Client-side routing utilities
│ ├── stores/ # Stores for state management
│ ├── types/ # TypeScript type definitions
│ ├── ui/ # UI components and styling
│ │ ├── components/ # Reusable UI components
│ │ └── icons/ # SVG icon components
│ └── utils/ # Helper functions and utilities
编码标准
命名公约
文件与文件夹名称
-
文件夹: 使用
kebab-case所有目录名称✅ custom-code/ ✅ webflow-canvas/ ✅ browser-storage/ ❌ customCode/ ❌ WebflowCanvas/ -
文件: 使用
camelCase财务报告和审定财务报表PascalCase所有文件名✅ localStorage.ts ✅ handlePaste.ts ✅ getAllAssets.ts ✅ Button.svelte ✅ Form.svelte ❌ local-storage.ts ❌ handle_paste.ts ❌ form.svelte
代码命名
- 构成部分: 使用
PascalCase用于组件名称 - 职能: 使用
camelCase函数名称 - 变量: 使用
camelCase变量名称 - 常数: 使用
UPPERCASE常数 - 类型/界面: 使用
PascalCase类型定义
文件标准
- 保持函数文档简洁
测试 UI 组件
测试战略
所有UI组件应包括涵盖下列内容的全面测试:
- 基本渲染: 默认道具、自定义道具和各种配置
- 构成部分备选案文:所有可用的变体(初级、二级、危险等)
- 互动国家: 已禁用、装入、无效和其他状态组合
- 用户交互: 单击事件、键盘导航和格式提交
- 无障碍: ARIA属性,焦点管理和屏幕阅读器支持
- 视觉特征: 图标、工具提示、自定义样式和布局变化
测试结构
使用 Vitest 和测试库进行组件测试 :
import { fireEvent, render, screen, waitFor } from '@testing-library/svelte';
import { describe, expect, it, vi } from 'vitest';
import Component from './Component.svelte';
describe('Component Name', () => {
describe('Basic Rendering', () => {
it('renders with default props', () => {
render(Component);
const element = screen.getByRole('...');
expect(element).toBeInTheDocument();
});
});
describe('Variants', () => {
// Test all component variants
});
describe('States', () => {
// Test disabled, loading, invalid states
});
describe('Events', () => {
// Test user interactions
});
describe('Accessibility', () => {
// Test ARIA attributes and keyboard navigation
});
});
测试最佳做法
- 全面覆盖:测试所有道具、变体和状态
- 用户-儿童测试: 注重用户互动而非实施细节
- 无障碍测试: 验证 ARIA 属性、键盘导航和屏幕读取器支持
- 主动行为: 使用
waitFor用于测试工具提示、模式和动态内容 - 事件模拟: 正确锁定外部依赖和事件处理器
- 国家核查: 检查视觉状态和内在属性
示例:按钮组件测试
// Testing component variants
const variants: ButtonVariant[] = ['primary', 'secondary', 'danger', 'cms'];
variants.forEach((variant) => {
it(`renders ${variant} variant correctly`, () => {
render(Button, { variant });
const button = screen.getByRole('button');
expect(button).toHaveClass(`button--${variant}`);
});
});
// Testing interactive states
it('renders loading state', () => {
render(Button, { loading: true });
const button = screen.getByRole('button');
expect(button).toBeDisabled();
expect(button).toHaveAttribute('aria-busy', 'true');
expect(button).toHaveClass('button--loading');
});
// Testing accessibility
it('has proper ARIA attributes', () => {
render(Button, { ariaLabel: 'Custom label', loading: true });
const button = screen.getByRole('button');
expect(button).toHaveAttribute('aria-label', 'Custom label');
expect(button).toHaveAttribute('aria-busy', 'true');
});
// Testing async interactions (tooltips)
it('shows tooltip on hover', async () => {
render(Button, {
tooltip: { message: 'Help text', listener: 'hover', listenerout: 'hover' }
});
const button = screen.getByRole('button');
const tooltipTarget = button.closest('.target');
await fireEvent.mouseEnter(tooltipTarget || button);
expect(screen.getByText('Help text')).toBeInTheDocument();
});
发展
# Setup
pnpm install
# Development
pnpm dev # Start dev server
pnpm storybook # Component development
# Building & Testing
pnpm build # Build library
pnpm test # Run tests
pnpm lint # Check code quality
pnpm check # Check code quality
出版
自动发布时使用变换器。 创建更改列表 :
pnpm changeset
通过 GitHub Actions 将更改启动自动发布到 npm .