hypnagaga/src/docs/contributing/component-guidelines.stories.mdx
2023-07-20 18:15:05 +01:00

172 lines
4.1 KiB
Text

import { Meta } from '@storybook/addon-docs';
import { parameters } from '$docs/utils/docsPage.js';
<Meta
title="Contributing/Component guidelines"
parameters={{ ...parameters }}
/>
![](https://graphics.thomsonreuters.com/style-assets/images/logos/reuters-graphics-logo/svg/graphics-logo-color-dark.svg)
# Component guidelines
## Dependencies
Components should be written for any Svelte context. If your component needs, for example, values from SvelteKit stores, these should be passed in as props.
## Typescript
By default, component's are written in TypeScript, which adds robust type-checking and helpful hints for people using your component in editors like Visual Studio Code.
> If you've never used TypeScript, you can check out the [5-minute intro](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html). If you're still uneasy writing TypeScript, don't sweat it! Just write your component in plain JavaScript/Svelte. We'll convert at least your component's props to TypeScript as part of the PR review.
### Typing and documenting component props
Document props using [JSDoc comments](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html) (be sure to mark required props) and type props with TypeScript.
Here are a few examples:
#### Typing simple props
```svelte
<script lang="ts">
/** Height of the component */
export let height: number = 250;
/** Text colour */
export let colour: string = 'blue';
</script>
```
#### Documenting required props
```svelte
<script lang="ts">
/**
* Image source
* @required
*/
export let src: string;
/**
* AltText for the image
* @required
*/
export let altText: string;
</script>
```
#### Custom types for props
```svelte
<script lang="ts">
type ContainerWidth = 'normal' | 'wide' | 'wider' | 'widest' | 'fluid';
/** Width of the component within the text well. */
export let width: ContainerWidth = 'normal';
interface Person {
name: string;
age: number;
}
/**
* Array of people
* @required
*/
export let people: Person[];
</script>
```
#### Future syntax
Using some future syntax like [optional chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining) in your components currently breaks the automatic discovery of JSDoc comments in your component, which are used to fill in the [ArgsTable](https://storybook.js.org/docs/react/writing-docs/doc-block-argstable).
So instead of...
```javascript
myObject?.myOptionalProp;
```
...unfortunately, use something old-fashioned like...
```javascript
myObject.myOptionalProp ? myObject.myOptionalProp : null;
```
If your component docs still aren't working, check if you're using other future-JS sytax, for now.
## Styles
### Theming
Always respect styles set by the [`Theme`](/?path=/docs/theming-theme--default) component by using [CSS variables](?path=/docs/scss-css-variables--page) where they apply to your component.
Always set [fallback values](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties#custom_property_fallback_values) for the default light theme.
### SCSS
Use SCSS with the `lang` attribute to write your styles.
```svelte
<button>My component</button>
<style lang="scss">
button {
color: blue;
}
</style>
```
### Scope
Styles should **always** be scoped to your components.
```svelte
<button>My component</button>
<style lang="scss">
button {
color: blue;
}
</style>
```
In rare cases, you can use the SCSS `:global` operator to style child elements in your component, but those rules should still be scoped below a parent element.
```svelte
<svg></svg>
<style lang="scss">
svg {
:global {
path {
stroke: black;
}
}
}
</style>
```
### CSS variables
Use [CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) and props to allow better theming of your components.
```svelte
<script>
export let textColour = '#333';
</script>
<div style="--textColour: {textColour};">
<h3>My title</h3>
<p>My text.</p>
<p></p>
</div>
<style lang="scss">
div {
h3,
p {
color: var(--textColour, #333);
}
}
</style>
```