Skip to content

Commit

Permalink
feat(design system): new spinner component
Browse files Browse the repository at this point in the history
  • Loading branch information
g-saracca committed Sep 6, 2024
1 parent a477ae6 commit 67334b6
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 36 deletions.
1 change: 1 addition & 0 deletions packages/design-system/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
- **Stack:** NEW Stack element to manage layouts.
- **TransferList:** NEW TransferList component to transfer items between two list, also sortable.
- **Table:** extend Props Interface to accept `bordered` prop to add or remove borders on all sides of the table and cells. Defaults to true.
- **Spinner:** New Spinner component.

# [1.1.0](https://github.com/IQSS/dataverse-frontend/compare/@iqss/[email protected]...@iqss/[email protected]) (2024-03-12)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import "design-tokens/typography.module";
@import "design-tokens/colors.module";
@import 'design-tokens/typography.module';
@import 'design-tokens/colors.module';

// Theme

Expand All @@ -10,9 +10,9 @@ $info: $dv-info-color;
$warning: $dv-warning-color;
$danger: $dv-danger-color;

@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/mixins";
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins';

// Body
$body-color: $dv-text-color;
Expand All @@ -36,73 +36,74 @@ $link-color: $dv-link-color;
$link-hover-color: $dv-link-hover-color;

// Base
@import "bootstrap/scss/maps";
@import "bootstrap/scss/root";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
@import 'bootstrap/scss/maps';
@import 'bootstrap/scss/root';
@import 'bootstrap/scss/reboot';
@import 'bootstrap/scss/type';

// Buttons and Dropdowns
@import "bootstrap/scss/buttons";
@import 'bootstrap/scss/buttons';
@import 'bootstrap/scss/button-group';
@import "bootstrap/scss/dropdown";
@import 'bootstrap/scss/dropdown';

// Grid
@import "bootstrap/scss/utilities";
@import "bootstrap/scss/utilities/api";
@import "bootstrap/scss/containers";
@import "bootstrap/scss/grid";
@import 'bootstrap/scss/utilities';
@import 'bootstrap/scss/utilities/api';
@import 'bootstrap/scss/containers';
@import 'bootstrap/scss/grid';

// Badge
@import "bootstrap/scss/badge";
@import 'bootstrap/scss/badge';

// Forms
$form-label-font-weight: $dv-font-weight-bold;

@import "bootstrap/scss/forms";

@import 'bootstrap/scss/forms';

// Table
@import "bootstrap/scss/tables";

@import 'bootstrap/scss/tables';

// Accordion
@import "bootstrap/scss/accordion";
@import 'bootstrap/scss/accordion';

// Modal
@import "bootstrap/scss/modal";
@import "bootstrap/scss/close";
@import 'bootstrap/scss/modal';
@import 'bootstrap/scss/close';

// Breadcrumb
$breadcrumb-divider: ">";
$breadcrumb-divider: '>';

@import "bootstrap/scss/breadcrumb";
@import 'bootstrap/scss/breadcrumb';

// QuestionMarkTooltip
$tooltip-max-width: 500px;

@import "bootstrap/scss/tooltip";
@import 'bootstrap/scss/tooltip';

// Alert
@import "bootstrap/scss/alert";
@import 'bootstrap/scss/alert';

// Pagination
@import "bootstrap/scss/pagination";
@import 'bootstrap/scss/pagination';

// Card
@import "bootstrap/scss/card";
@import 'bootstrap/scss/card';

// Progress
@import "bootstrap/scss/progress";
@import 'bootstrap/scss/progress';

// Spinner
@import 'bootstrap/scss/spinners';

// Navbar

$navbar-light-brand-color: $dv-brand-color;
$navbar-brand-font-size: $dv-brand-font-size;

@import "bootstrap/scss/nav";
@import "bootstrap/scss/navbar";
@import "bootstrap/scss/transitions";
@import "bootstrap/scss/helpers";
@import 'bootstrap/scss/nav';
@import 'bootstrap/scss/navbar';
@import 'bootstrap/scss/transitions';
@import 'bootstrap/scss/helpers';

.navbar-collapse {
justify-content: end;
Expand All @@ -124,12 +125,14 @@ th {
vertical-align: middle;
}

.btn-group > div:not(:last-child) > .btn-group > .btn, .btn-group-vertical >div:not(:last-child) > .btn-group > .btn {
.btn-group > div:not(:last-child) > .btn-group > .btn,
.btn-group-vertical > div:not(:last-child) > .btn-group > .btn {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}

.btn-group > div:not(:first-child) > .btn-group > .btn, .btn-group-vertical > div:not(:first-child) > .btn-group > .btn {
.btn-group > div:not(:first-child) > .btn-group > .btn,
.btn-group-vertical > div:not(:first-child) > .btn-group > .btn {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
35 changes: 35 additions & 0 deletions packages/design-system/src/lib/components/spinner/Spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ElementType } from 'react'
import { Spinner as SpinnerBS } from 'react-bootstrap'

type SpinnerVariant =
| 'primary'
| 'secondary'
| 'success'
| 'danger'
| 'warning'
| 'info'
| 'light'
| 'dark'
type SpinnerAnimations = 'border' | 'grow'

interface SpinnerProps {
variant?: SpinnerVariant
animation?: SpinnerAnimations
size?: 'sm'
role?: string
as?: ElementType
}

export const Spinner = ({
variant = 'primary',
animation,
size,
role = 'status',
as
}: SpinnerProps) => {
return (
<SpinnerBS variant={variant} animation={animation} size={size} role={role} as={as}>
<span className="visually-hidden">Loading...</span>
</SpinnerBS>
)
}
1 change: 1 addition & 0 deletions packages/design-system/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ export { Card } from './components/card/Card'
export { ProgressBar } from './components/progress-bar/ProgressBar'
export { Stack } from './components/stack/Stack'
export { TransferList } from './components/transfer-list/TransferList'
export { Spinner } from './components/spinner/Spinner'
64 changes: 64 additions & 0 deletions packages/design-system/src/lib/stories/spinner/Spinner.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { Meta, StoryObj } from '@storybook/react'

import { Spinner } from '../../components/spinner/Spinner'

/**
* ## Description
* The Spinner component is used to indicate a loading state.
*/
const meta: Meta<typeof Spinner> = {
title: 'Spinner',
component: Spinner,
tags: ['autodocs'],
parameters: {
layout: 'centered'
}
}

export default meta
type Story = StoryObj<typeof Spinner>

export const Default: Story = {
render: () => <Spinner variant="primary" />
}

export const AllBorderVariantsAtAGlance: Story = {
render: () => (
<div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
<Spinner animation="border" variant="primary" />
<Spinner animation="border" variant="secondary" />
<Spinner animation="border" variant="success" />
<Spinner animation="border" variant="danger" />
<Spinner animation="border" variant="warning" />
<Spinner animation="border" variant="info" />
<Spinner animation="border" variant="light" />
<Spinner animation="border" variant="dark" />
</div>
)
}

export const AllGrowVariantsAtAGlance: Story = {
render: () => (
<div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
<Spinner animation="grow" variant="primary" />
<Spinner animation="grow" variant="secondary" />
<Spinner animation="grow" variant="success" />
<Spinner animation="grow" variant="danger" />
<Spinner animation="grow" variant="warning" />
<Spinner animation="grow" variant="info" />
<Spinner animation="grow" variant="light" />
<Spinner animation="grow" variant="dark" />
</div>
)
}

export const AllSizesAtAGlance: Story = {
render: () => (
<div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
<Spinner animation="border" variant="primary" size="sm" />
<Spinner animation="border" variant="primary" />
<Spinner animation="grow" variant="primary" size="sm" />
<Spinner animation="grow" variant="primary" />
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Spinner } from '../../../src/lib/components/spinner/Spinner'

describe('Spinner', () => {
it('renders correctly', () => {
cy.mount(<Spinner />)

cy.findAllByRole('status').should('exist')
})
})

0 comments on commit 67334b6

Please sign in to comment.