Spinner

    A spinner is a rotating circle that indicates the status or state of completion for a process that’s part of a user flow, such as verifying personal information or sending a request. The circles can indicate that a process is underway.

    Figma LibraryLocal HTMLGlobal HTMLReact
    considering
    not-available
    beta
    beta
    <svg
        class="gi-w-6 gi-h-6"
        viewBox="0 0 24 24"
        xmlns="http://www.w3.org/2000/svg"
    >
        <g>
        <circle
            cx="12"
            cy="12"
            r="9.5"
            fill="none"
            stroke-width="3"
            stroke-linecap="round"
        >
            <animate
            attributeName="stroke-dasharray"
            dur="1.5s"
            calcMode="spline"
            values="0 150;42 150;42 150;42 150"
            keyTimes="0;0.475;0.95;1"
            keySplines="0.42,0,0.58,1;0.42,0,0.58,1;0.42,0,0.58,1"
            repeatCount="indefinite"
            />
            <animate
            attributeName="stroke-dashoffset"
            dur="1.5s"
            calcMode="spline"
            values="0;-16;-59;-59"
            keyTimes="0;0.475;0.95;1"
            keySplines="0.42,0,0.58,1;0.42,0,0.58,1;0.42,0,0.58,1"
            repeatCount="indefinite"
            />
        </circle>
        <animateTransform
            attributeName="transform"
            type="rotate"
            dur="2s"
            values="0 12 12;360 12 12"
            repeatCount="indefinite"
        />
        </g>
    </svg>
    
    {{ 
        govieSpinner({
            "size": "md"
        }) 
    }}
    
    <Spinner />
    

    Button with a spinner

    <button id="button" disabled="true" aria-disabled="true" class="gi-btn gi-btn-regular gi-btn-primary-disabled">
        Loading...
        <svg
            class="gi-w-6 gi-h-6"
            viewBox="0 0 24 24"
            xmlns="http://www.w3.org/2000/svg"
        >
            <g>
            <circle
                cx="12"
                cy="12"
                r="9.5"
                fill="none"
                stroke-width="3"
                stroke-linecap="round"
            >
                <animate
                attributeName="stroke-dasharray"
                dur="1.5s"
                calcMode="spline"
                values="0 150;42 150;42 150;42 150"
                keyTimes="0;0.475;0.95;1"
                keySplines="0.42,0,0.58,1;0.42,0,0.58,1;0.42,0,0.58,1"
                repeatCount="indefinite"
                />
                <animate
                attributeName="stroke-dashoffset"
                dur="1.5s"
                calcMode="spline"
                values="0;-16;-59;-59"
                keyTimes="0;0.475;0.95;1"
                keySplines="0.42,0,0.58,1;0.42,0,0.58,1;0.42,0,0.58,1"
                repeatCount="indefinite"
                />
            </circle>
            <animateTransform
                attributeName="transform"
                type="rotate"
                dur="2s"
                values="0 12 12;360 12 12"
                repeatCount="indefinite"
            />
            </g>
        </svg>
    </button>
    
    {{ 
        govieButton({
            "content": 'Loading... ' + govieSpinner(),
            "disabled": true
        }) 
    }}
    
    import { Button } from '@govie-ds/react';
    
    <Button disabled={true}>
        Loading...
        <Spinner inline={true} />
    </Button>
    

    Modal with a spinner

    Loading...
    <div>
        <button class="gi-btn gi-btn-primary gi-btn-regular">Open Modal</button>
    </div>
    <div class="gi-modal gi-modal-close">
        <div class="gi-modal-container">
            <div class="grid gap-4 px-4 justify-items-center">
                <svg
                    class="gi-w-10 gi-h-10"
                    viewBox="0 0 24 24"
                    xmlns="http://www.w3.org/2000/svg"
                >
                    <g>
                    <circle
                        cx="12"
                        cy="12"
                        r="9.5"
                        fill="none"
                        stroke-width="3"
                        stroke-linecap="round"
                    >
                        <animate
                        attributeName="stroke-dasharray"
                        dur="1.5s"
                        calcMode="spline"
                        values="0 150;42 150;42 150;42 150"
                        keyTimes="0;0.475;0.95;1"
                        keySplines="0.42,0,0.58,1;0.42,0,0.58,1;0.42,0,0.58,1"
                        repeatCount="indefinite"
                        />
                        <animate
                        attributeName="stroke-dashoffset"
                        dur="1.5s"
                        calcMode="spline"
                        values="0;-16;-59;-59"
                        keyTimes="0;0.475;0.95;1"
                        keySplines="0.42,0,0.58,1;0.42,0,0.58,1;0.42,0,0.58,1"
                        repeatCount="indefinite"
                        />
                    </circle>
                    <animateTransform
                        attributeName="transform"
                        type="rotate"
                        dur="2s"
                        values="0 12 12;360 12 12"
                        repeatCount="indefinite"
                    />
                    </g>
                </svg>
                <span>Loading...</span>
            </div>
        </div>
    </div>
    
    {{ 
    govieModal({
        "html": "<div class='grid gap-4 px-4 justify-items-center'>"+govieSpinner()+"<span>Loading...</span></div>",
        "triggerButton": "<button>Open Modal</button>"
    }) 
    }}
    
    import { Modal, Button, Spinner } from '@govie-ds/react';
    
    <Modal triggerButton={<Button>Open Modal</Button>}  >
        <div className="grid gap-4 px-4 justify-items-center">
            <Spinner size="xl" />
            <span>Loading...</span>
        </div>
    </Modal>
    

    Usage best practices

    Here are some best practices for the usage of a Spinner component:

    1. Use spinners for short wait times (under 10 seconds):
      • Spinners are best for quick tasks like submitting a form or loading a small amount of data.
      • For longer waits (over 10 seconds), consider using progress bars or skeleton screens instead.
    2. Provide context and estimates:
      • Add helpful text explaining what's happening, e.g. "Loading your profile...".
      • If possible, give a general time estimate, e.g. "This may take a few seconds".
    3. Placement and visibility:
      • Centre the spinner within the loading area.
      • Ensure proper contrast against the background.
      • Add a slight delay (e.g. 100 ms) before showing the spinner to avoid flickering for very fast loads.
    4. Accessibility:
      • Use ARIA attributes like role="status" and aria-label to describe the loading state for screen readers.
      • Consider adding visually hidden text like "Now loading..." for accessibility.
    5. Alternative approaches:
      • For very quick loads (under 1 second), don't show a spinner at all.
      • Consider skeleton screens to show layout placeholders while content loads.
    6. Error handling:
      • Implement timeouts and error messaging if loading takes too long.
      • Provide options to retry or cancel the operation if it fails.
    7. Avoid overuse:
      • Don't use multiple spinners on the same page - use a single global indicator instead.
      • For component-level loading (e.g. in cards/dropdowns), consider skeleton loaders instead of spinners.