storybook
Provides Storybook guidelines for stories, component vs page stories, and testing with play. Use when creating or modifying .stories.tsx files.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Provides Storybook guidelines for stories, component vs page stories, and testing with play. Use when creating or modifying .stories.tsx files.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Buttons (Button, IconButton, ExternalLinkButton, InternalLinkButton) and pressable surfaces (PressableBox, PressableListItem). variant is contained|outlined|ghost, size is sm|md, accent defaults to brand. Button label is the required text prop (not children); IconButton requires aria-label. Interactive hover/focus/active/disabled states are built in. For async onPress use ActionButton (runs the promise, shows spinner + inline error); Button state ('loading'|'success'|'failed') is the manual escape hatch that overlays a spinner/terminal icon and disables the button. Load when adding buttons or custom pressable elements.
Animate alouette UI two ways: NativeWind transitions (transition-*, duration-*, ease-* on state changes like active:/hover:/focus:) and CSS keyframe presence animations via PresenceOne / PresenceList (animate-slide-in/out, animate-collapse-in/out). exitDurationMs must come from animationDurationsMs so the unmount timer matches the keyframe. Both run on native via react-native-reanimated. Load when adding transitions or enter/exit animations.
Overlays: Modal (controlled by visible/onClose, with title or required aria-label, optional icon/footer, size sm/md/lg, dismiss via backdrop/close/ Escape/Android-back) and AlertDialog for confirmations. AlertDialog variant is confirm (cancel+confirm) | alert (single acknowledge) | required (single action, non-dismissible); accent defaults to danger. Prefer the icon-fixed presets QuestionAlertDialog / WarningAlertDialog / InfoAlertDialog / SuccessAlertDialog. Load when adding a modal, confirmation, or alert dialog.
Open external URLs with ExternalLink (wraps expo-web-browser / Linking) or ExternalLinkButton, configuring openLinkBehavior per platform (native: linking|webBrowser; web: targetBlank|targetSelf). Load when linking out to external URLs from alouette UI.
Semantic message banners: Message (requires accent + icon) and the presets InfoMessage, ConfirmationMessage, WarningMessage, ErrorMessage. Optional dismiss requires onDismiss and dismissIconAriaLabel together; size is sm/md/lg. Also ConnectionState, a top-pinned network-status banner driven by a state prop, and LinearProgress / CircularProgress determinate progress indicators (progress 0-100, accent, size xs/sm/md/lg). Load when showing inline status, alerts, dismissible notices, connection status, or progress.
Forms end to end. Inputs: InputText (mode: password/email/number/tel/url/search), TextArea, Switch (checked + onValueChange; use disabled not editable). Single-select: RadioGroup + Radio (circle-dot list) and RadioButtonGroup + RadioButton (segmented pill bar); controlled/uncontrolled via value/defaultValue/onValueChange + accent/disabled. Validation on react-hook-form: Form owns the instance and exposes submit() via render prop (no control passing); FormField wires Controller to FormItem label/error/required; FormFieldArray wraps useFieldArray with add/remove; FormSubmitButton drives loading/success/failed; SimpleVForm is the vertical-stack shortcut. errorToMessage required (i18n); FormValidationError distinguishes invalid fields from onSubmit failures. Load when building text fields, toggles, radio groups, or a validated form.
| name | storybook |
| description | Provides Storybook guidelines for stories, component vs page stories, and testing with play. Use when creating or modifying .stories.tsx files. |
Every component must have a .stories.tsx file. Key rules:
componentSubtitle in the meta"<ComponentName> Preview" using args, never wrapped in <Story>, showcasing the component in its most basic formminSize prop needs unset, 1, and 2; empty and non-empty). One Story.Section per variant. Do this from the start, not after being asked.play/test-only story never substitutes for a variant. Every distinct shape or state you exercise in a test (e.g. an object vs. raw-string data shape) must also appear as its own Story.Section in the Variants story so it renders and snapshots. Adding a test does not license skipping the visible variant.Story suffix (e.g. PreviewStory, VariantsStory). Use the Story and Story.Section components wrapper for consistent layoutthemes.stories.tsx covers thatA component stories file is typically composed with a " Preview" and " Variants" story (unlike what is commonly done in storybook), named after the component.
The preview story should be a simple story showcasing the component in its most basic form, while the variants story should showcase the different variants of the component using Story and Story.Section components to organize the story in a harmonized way.
fn instead of fake callbacksimport { fn } from "storybook";
export const ActionButtonStory: StoryObj = {
name: "ActionButton",
render: () => (
<Story>
<Story.Section title="Pressable">
<ActionButton onPress={fn()}>Click Me</ActionButton>
</Story.Section>
</Story>
),
};