refactored the Spinner component to match example from storybook

This commit is contained in:
deaxmachina 2025-01-16 11:30:50 +00:00
parent 18d5b01fea
commit bf10a61f9d
Failed to extract signature
9 changed files with 246 additions and 6 deletions

View file

@ -1,11 +1,7 @@
import type { StorybookConfig } from '@storybook/sveltekit';
const config: StorybookConfig = {
stories: [
'../src/**/*.mdx',
'../src/**/*.stories.@(js|ts|svelte)',
'../src/components/**/*.stories.@(js|jsx|ts|tsx|svelte)',
],
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|ts|svelte)'],
addons: [
'@storybook/addon-svelte-csf',
'@storybook/addon-essentials',

View file

@ -123,11 +123,13 @@
</script>
<Template >
{#snippet children({ args })}
{#snippet children({ ...args })}
<PhotoPack {...args} />
{/snippet}
</Template>
<Story
name="Default"
args="{{

View file

@ -0,0 +1,44 @@
<script module lang="ts">
import TestForSvelte5 from './TestForSvelte5.svelte';
// Don't lose the "?raw" in markdown imports!
// @ts-ignore raw
import componentDocs from './stories/docs/component.md?raw';
import { withComponentDocs } from '$docs/utils/withParams.js';
export const meta = {
title: 'Components/Graphics/TestForSvelte5',
component: TestForSvelte5,
...withComponentDocs(componentDocs),
// https://storybook.js.org/docs/svelte/essentials/controls
argTypes: {
width: {
control: 'select',
options: ['normal', 'wide', 'wider', 'widest', 'fluid'],
},
},
};
</script>
<script lang="ts">
import { Template, Story } from '@storybook/addon-svelte-csf';
// 🖼️ You can import images you need in stories directly in code!
// @ts-ignore img
import SharkImg from './stories/shark.jpg';
</script>
<Template >
{#snippet children({ ...args })}
<TestForSvelte5 {...args} />
{/snippet}
</Template>
<Story
name="Default"
args="{{
width: 'normal',
src: SharkImg,
altText: "Duh dum! It's a shark!!",
}}"
/>

View file

@ -0,0 +1,60 @@
<!-- @migration-task Error while migrating Svelte code: Cannot set properties of undefined (setting 'next') -->
<!-- @component `TestForSvelte5` [Read the docs.](https://reuters-graphics.github.io/graphics-components/?path=/docs/components-graphics-testforsvelte5--docs) -->
<script lang="ts">
/** ✏️ DOCUMENT your chart's props using TypeScript and JSDoc comments like below! */
/**
* A source for the image.
* @required
*/
export let src: string;
/**
* AltText for the image.
* @required
*/
export let altText: string;
/** Height of the image. */
export let height: number = 500;
// You can declare custom types to help users implement your component.
type ContainerWidth = 'normal' | 'wide' | 'wider' | 'widest' | 'fluid';
/** Width of the component within the text well. */
export let width: ContainerWidth = 'normal';
/** Add an ID to target with SCSS. */
export let id: string = '';
/** Add a class to target with SCSS. */
let cls: string = '';
export { cls as class };
import Block from '../Block/Block.svelte';
</script>
<Block {width} {id} class="photo {cls}">
<div
style:background-image="{`url(${src})`}"
style:height="{`${height}px`}"
></div>
<p class="visually-hidden">{altText}</p>
</Block>
<style lang="scss">
div {
width: 100%;
background-repeat: no-repeat;
background-size: cover;
}
.visually-hidden {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
</style>

View file

@ -0,0 +1,23 @@
> **Welcome to your new component!** Use this template to build your component and customise its storybook.
- Build your component in `TestForSvelte5/TestForSvelte5.svelte`.
- Write your component's storybook in `TestForSvelte5/TestForSvelte5.stories.svelte`.
- Don't forget to add your component to `src/index.js`:
```javascript
// ...
export { default as TestForSvelte5 } from './components/TestForSvelte5/TestForSvelte5.svelte';
```
- Commit your component to a new branch and push it to GitHub! 🏁
---
```html
<script>
import { TestForSvelte5 } from '@reuters-graphics/graphics-components';
</script>
<TestForSvelte5 />
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

View file

@ -49,3 +49,4 @@ export { default as Theme, themes } from './components/Theme/Theme.svelte';
export { default as ToolsHeader } from './components/ToolsHeader/ToolsHeader.svelte';
export { default as Video } from './components/Video/Video.svelte';
export { default as Visible } from './components/Visible/Visible.svelte';
export { default as TestForSvelte5 } from './components/TestForSvelte5/TestForSvelte5.svelte';

View file

@ -0,0 +1,22 @@
<script module lang="ts">
import { defineMeta } from '@storybook/addon-svelte-csf';
import Spinner from './Spinner.svelte';
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
const { Story } = defineMeta({
title: 'Components/Utilities/Spinner',
component: Spinner,
tags: ['autodocs'],
argTypes: {
colour: { control: 'color' },
ringWidth: { control: { type: 'range', min: 2, max: 20, step: 1 } },
width: { control: { type: 'range', min: 5, max: 100, step: 5 } },
speed: { control: { type: 'range', min: 0.2, max: 1.0, step: 0.1 } },
containerPadding: {
control: { type: 'range', min: 5, max: 100, step: 5 },
},
},
});
</script>
<Story name="Primary" />

View file

@ -0,0 +1,92 @@
<!-- @component `Spinner` [Read the docs.](https://reuters-graphics.github.io/graphics-components/?path=/docs/components-utilities-spinner--docs) -->
<script lang="ts">
interface Props {
/** Primary colour of the spinner. */
colour?: string;
/**
* Outer width of the spinner
*/
width?: number;
/**
* Width of the spinner ring
*/
ringWidth?: number;
/**
* How fast the spinner spins in seconds
*/
speed?: number;
/**
* Vertical padding for the spinner's container
*/
containerPadding?: number;
}
let {
colour = '#666',
width = 40,
ringWidth = 6,
speed = 0.8,
containerPadding = 10,
}: Props = $props();
</script>
<div
style:width="100%"
style:height="{`${width + containerPadding * 2}px`}"
class="component-container flex items-center justify-center"
>
<div
style="
--spinner-colour: {colour};
--spinner-ring-width: {ringWidth}px;
--spinner-ring-offset: -{ringWidth}px;
--spinner-speed: {speed}s;
width: {width}px;
height: {width}px;
margin: 0 auto;
"
>
<div class="spinner-container relative">
<div class="spinner absolute"></div>
</div>
</div>
</div>
<style lang="scss">
@keyframes spinner {
to {
transform: rotate(360deg);
}
}
.spinner-container {
height: 0;
padding-bottom: 100%;
color: var(--spinner-colour, #666);
}
.spinner {
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
border: var(--spinner-ring-width, 6px) solid transparent;
border-top-color: currentColor;
animation: spinner var(--spinner-speed, 0.8s) linear infinite;
&::before {
content: '';
position: absolute;
display: block;
left: var(--spinner-ring-offset, -6px);
top: var(--spinner-ring-offset, -6px);
width: 100%;
height: 100%;
border: var(--spinner-ring-width, 6px) solid currentColor;
box-sizing: content-box;
border-radius: 50%;
opacity: 0.25;
}
}
</style>