CtrlK
BlogDocsLog inGet started
Tessl Logo

tessleng/ui

Implement frontend designs from figma using Chakra UI v3 and Storybook

92

1.64x
Quality

92%

Does it follow best practices?

Impact

92%

1.64x

Average score across 6 eval scenarios

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

STORY_TEMPLATES.mdskills/building-low-level-components/

Story Templates

UI Component Story Template

import { Box } from '@chakra-ui/react';
import type { Meta, StoryObj } from '@storybook/react-vite';

import { MyComponent } from './MyComponent';

const meta = {
  title: 'Components/UI/MyComponent',
  component: MyComponent,
  parameters: {
    layout: 'centered',
    backgrounds: { default: 'dark' },
  },
  decorators: [
    (Story) => (
      <Box padding="40px">
        <Story />
      </Box>
    ),
  ],
} satisfies Meta<typeof MyComponent>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
  args: {},
};

Use the Components/UI/ title prefix to group low-level components together in Storybook's sidebar.

Form Field Story Template

Form field stories need a form context. Wrap the component in a minimal form:

import { Box } from '@chakra-ui/react';
import type { Meta, StoryObj } from '@storybook/react-vite';

import { Form } from '~/lib/form/components/form';
import { useTesslForm } from '~/lib/form/use-tessl-form';

import { MyField } from './MyField';

function MyFieldStory(props: React.ComponentProps<typeof MyField>) {
  const form = useTesslForm({
    defaultValues: { example: '' },
    onSubmit: async () => {},
  });

  return (
    <Form form={form}>
      <form.AppField name="example">
        {(field) => <field.MyField {...props} />}
      </form.AppField>
    </Form>
  );
}

const meta = {
  title: 'Components/Form/MyField',
  component: MyFieldStory,
  parameters: {
    layout: 'centered',
    backgrounds: { default: 'dark' },
  },
  decorators: [
    (Story) => (
      <Box padding="40px" width="400px">
        <Story />
      </Box>
    ),
  ],
} satisfies Meta<typeof MyFieldStory>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
  args: { label: 'My Field' },
};

export const Required: Story = {
  args: { label: 'My Field', required: true },
};

export const WithHelper: Story = {
  args: { label: 'My Field', helper: 'Some helpful text' },
};

export const Disabled: Story = {
  args: { label: 'My Field', disabled: true },
};

Use the Components/Form/ title prefix for form field stories.

Required Stories

For every low-level component, include at minimum:

  • Default — the component with default/minimal props.
  • All variants — one story per variant value.
  • All sizes — one story per size value, if applicable.
  • Interactive statesDisabled, Hover (via parameters.pseudo), Active, Focused where applicable.
  • Edge cases — long text/overflow, empty content, min/max values.
  • Composition — if the component is used inside other components, show it in that context.

Use args for prop variations. Use render only when custom JSX wrapping is needed. Use Chakra Box in decorators — do NOT use raw HTML elements.

skills

building-low-level-components

README.md

tile.json