Code styleguide
In this section you will find common rules and best practices to follow when writing code for Shoreline.
Components
File structure
Component
// ✅ Good
// packages/shoreline/src/components/{component} folder
component
|__ stories
| |_ [examples].stories.tsx
| |_ play.stories.tsx
| |_ show.stories.tsx
| |__ tests
| | |_ tests.stories.tsx
|
|_ index.ts
|_ component.tsx
|_ component-composite.tsx
Theming
// ✅ Good
// packages/shoreline/src/themes/{theme}/{component} folder
component
|_ index.scss
|_ component.scss
|_ component-composite.scss
Prevent the use of React.FC
The use of React.FunctionComponent (or the React.FC shorthand) is discouraged to type the component props. If you need to type children explicitly, use React.ReactNode. Here you can see some good reasons why.
Do not use param destructuring
Prefer destructuring on the component’s body.
interface Props {
title: string
// ...
}
// ✅ Good
function Component(props: Props) {
const { title, ...restProps } = props
// ...
}
// 🚨 Bad
function Component({ title }: Props) {
// ...
}
Do not use inline typing
Always prefer creating an interface or type for the component props.
// ✅ Good
interface Props {
title: string
}
function Component(props: Props) {
// ...
}
// 🚨 Bad
function Component({ title }: { title: string }) {
// ...
}
Do not use inline extension
Avoid extending other types within the function param directly. Prefer extending or compose a new type for a cleaner code.
// ✅ Good
interface Props extends SomeTypeA {
title: string
}
function Component(props: Props) {
// ...
}
// ✅ Good
type Props = SomeTypeA & SomeTypeB
function Component(props: Props) {
// ...
}
// 🚨 Bad
function Component(props: Props & SomeTypeA) {
// ...
}
Prefer named exports
Named exports are preferred over default exports.
// ✅ Good
export function Component() {
// ...
}
// 🚨 Bad
export default function Component() {
// ...
}
Styling
Prefer tokens
Always prefer to use tokens instead of hardcoded values.
// ✅ Good
.component {
padding: var(--sl-space-4);
}
// 🚨 Bad
.component {
padding: 16px;
}
Use semantic data-attributes prefix
Always use the data-sl-
prefix for attributes that refer to the component.
// ✅ Good
[data-sl-component] {
// ...
}
// 🚨 Bad
[data-component] {
// ...
}
Avoid parent styles
While coding an app it doesn’t matter, but if you are within a library this is a bad practice! The user will not be able to customize the child’s style without the !important flag. So, you must avoid it.
// ✅ Good
[data-sl-component-heading] {
// ...
}
// 🚨 Bad
[data-sl-component] {
& > h1 {
// ...
}
}
Documentation
Always use JSDoc to document your component
We use the JSDoc to document our components and they are used to generate the component documentation in the site.
// ✅ Good
/**
* Component description
*
* @example
* <Component title="Hello" />
*/
function Component(props: Props) {
// ...
}
interface Props {
/**
* The title of the component
*/
title: string
}
// 🚨 Bad
function Component(props: Props) {
// ...
}
interface Props {
title: string
}