Skip to content

4. React and Vue guidelines

Use the component name in all lowercase, use underscore signs (_) to separate the words for the file name.

Recommended
src/components/foo_bar_component.tsx
Not recommended
src/components/FooBarComponent.tsx

Always use React functional components for all components.

Recommended
const Foo = () => {
return <div>Foo</div>;
};
Not recommended
const Foo = React.createClass({
render() {
return <div>Foo</div>;
}
});

Prefer to use props destructuring to access the props in the component.

Recommended
const Foo = ({ bar }: { bar: string; }) => {
return <div>{bar}</div>;
};
Not recommended
const Foo = (props: { bar: string; }) => {
return <div>{props.bar}</div>;
};

4.1.2.2. Component and Component Props Types

Section titled “4.1.2.2. Component and Component Props Types”

For typing components, prefer to use the Component type from the @fintech-sandpit/ui/react package.

For typing component props, prefer to use the Props type from the @fintech-sandpit/ui/react package.

import type {
Component,
Props,
} from '@fintech-sandpit/ui/react';
interface FooBaseProps {
bar: string;
baz: number;
}
type FooProps = Props<FooBaseProps, HTMLSpanElement>
const Foo: Component<FooProps> = ({
bar,
baz,
...props
}) => (
<span {...props}>
{`bar: ${bar}, baz: ${baz}`}
</span>
);

Use PropsWithChildren for components that must have children.

import type {
Component,
PropsWithChildren,
} from '@fintech-sandpit/ui/react';
type FooProps = PropsWithChildren<{ label: string; }, HTMLButtonElement>
const Foo: Component<FooProps> = ({
label,
children,
...props
}) => (
<button
aria-label={label}
{...props}
>
{children}
</button>
);

Use the following props order for all components:

  • Reference prop ref
  • Variable arguments (foo={variable})
  • Static props (bar="value")
  • Class name (className="class")
  • Boolean props (baz)
  • Data props (data-foo="foo" or data-foo={variable})
  • Multiline and object props (prop={{ foo: 'foo', bar: 'bar' }})
  • Event handlers (onChange={handleChange})
<Foo
ref={ref}
foo={variable}
bar="value"
baz
className="flex"
data-foo="foo"
prop2={{ foo: 'foo', bar: 'bar' }}
onChange={handleChange}
/>

Use single quotes for strings in TypeScript and JavaScript code. Use double quotes for strings and attributes in HTML code.

Recommended
const foo = 'bar';
const Bar = () => {
<div className="foo">
{foo}
</div>
};
Not recommended
const foo = "bar";
const Bar = () => {
<div className='foo'>
{foo}
</div>
};

Always include a single space in your self-closing tag.

Recommended
<Foo />
<Bar />
Not recommended
<Foo/>
<Bar />

Avoid using multiple empty lines.

At the same block level, add an empty line between components.

Recommended
<div>
<Foo />
</div>
<div>
<Foo />
<Bar />
</div>
Not recommended
<div>
<Foo />
</div>
<div>
<Foo />
<Bar />
</div>

Always wrap component props to the next line, unless the component have only one prop.

Recommended
<Foo
bar="bar"
baz="baz"
/>
<Foo bar="bar" />
Not recommended
<Foo bar="bar" baz="baz" />

Always include a newline at the end of the file.

Use the component name in all lowercase, use underscore signs (_) to separate the words for the file name.

Recommended
src/components/foo_bar_component.vue
Not recommended
src/components/FooBarComponent.vue

Use single file components for all components.

Always use the <script setup> syntax.

The following order of the SFCs is recommended:

  • <script setup>
  • <template>
  • <style>

Prefer not to separate the code (e.g., use <script src="..."> or <style src="...">) into multiple files.

<template>
<div>Foo</div>
</template>

Always use the TypeScript defineProps syntax for component props.

Prefer to externalise the props’ types into a separate file.

<script setup lang="ts">
import { computed } from 'vue';
interface FooProps {
bar: string;
baz: number;
}
const props = defineProps<FooProps>();
const text = computed(() => `bar: ${props.bar}, baz: ${props.baz}`);
</script>
<template>
<div>
{{ text }}
</div>
</template>

Use the following props order for all components:

  • Model prop v-model="model"
  • Variable arguments (:foo="variable")
  • Numerical static props (:bar="100")
  • String static props (bar="text")
  • Boolean props (baz)
  • Multiline and object props (prop={{ foo: 'foo', bar: 'bar' }})
  • Class name (class="class")
  • Data props (data-foo="foo" or :data-foo="variable")
  • Event handlers (@click="handleClick")
<template>
<Foo
v-model="model"
:foo="variable"
:bar="100"
bar="text"
baz
class="class"
data-foo="foo"
@click="handleClick"
/>
</template>

Prefer to use TailwindCSS classes for styling the components.

If absolutely necessary, use the <style scoped> syntax for component styles.

<style scoped lang="css">
.foo {
text-color: #fff;
}
</style>

Use single quotes for strings in TypeScript and JavaScript code. Use double quotes for strings and attributes in the template code.

Recommended
<script setup lang="ts">
const foo = 'bar';
</script>
<template>
<div class="foo">
{{ foo }}
</div>
</template>
Not recommended
<script setup lang="ts">
const foo = "bar";
</script>
<template>
<div class='foo'>
{{ foo }}
</div>
</template>

Always include a single space in your self-closing tag.

Recommended
<template>
<Foo />
<Bar />
</template>
Not recommended
<template>
<Foo/>
<Bar />
</template>

Avoid using multiple empty lines.

At the same block level, add an empty line between components.

Recommended
<template>
<div>
<Foo />
</div>
<div>
<Foo />
<Bar />
</div>
</template>
Not recommended
<template>
<div>
<Foo />
</div>
<div>
<Foo />
<Bar />
</div>
</template>

Always wrap component props to the next line, unless the component have only one prop.

Recommended
<template>
<Foo
bar="bar"
baz="baz"
/>
<Foo bar="bar" />
</template>
Not recommended
<template>
<Foo bar="bar" baz="baz" />
</template>

Always include a newline at the end of the file.