webapp/channels/src/components/CLAUDE.OPTIONAL.md
components/Each component directory should contain:
my_component/
├── index.ts # Re-exports
├── my_component.tsx # Component implementation
├── my_component.scss # Co-located styles (imported in component)
└── my_component.test.tsx
useSelector, useDispatch, useCallback, useMemo). See webapp/STYLE_GUIDE.md → React Component Structure.useX.ts) or child components.React.memo for components with heavy render logic.makeAsyncComponent:const HeavyComponent = makeAsyncComponent(
() => import('./heavy_component'),
);
import './my_component.scss')..MyComponent)..MyComponent__title).var(--variable-name) for colors from sass/base/_css_variables.scss.rgba(var(--color-rgb), 0.5) for opacity.// my_component.scss
.MyComponent {
color: var(--center-channel-color);
&__title {
font-weight: 600;
}
&.compact {
padding: 4px;
}
}
<button>, <input>, etc. over <div> with roles.GenericModal, Menu, WithTooltip, A11yController helpers.a11y--focused class for keyboard focus indicators.alt="" for decorative.<FormattedMessage> over useIntl() hook when possible.values={{b: (chunks) => <b>{chunks}</b>}}) instead of splitting strings.// Preferred
<FormattedMessage id="component.title" defaultMessage="Title" />
// When string is needed for props
const intl = useIntl();
<input placeholder={intl.formatMessage({id: 'input.placeholder', defaultMessage: 'Search...'})} />
*.test.tsx). See ../tests/react_testing_utils.tsx for helpers.userEvent and accessible queries (getByRole) over implementation-specific selectors.@testing-library/react or react-dom/test-utils. All testing utilities (act, screen, fireEvent, waitFor, waitForElementToBeRemoved, userEvent, renderWithContext, etc.) must be imported from tests/react_testing_utils, which re-exports everything from @testing-library/react alongside project-specific helpers.@mattermost/compass-icons/components (e.g., <DockWindowIcon size={18}/>), not raw <i className="icon icon-..."/> elements.channel_view/channel_view.tsx – full-page component structure with co-located SCSS.post_view/post_list_virtualized/post_list_virtualized.tsx – virtualization + hooks pattern.widgets/menu components – accessible menu behaviors.