hypnagaga/src/components/Spinner/Spinner.svelte
MinamiFunakoshiTR b67a0057a6
updates spinner
2025-03-25 09:44:27 -07:00

92 lines
2 KiB
Svelte

<!-- @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>