Skip to content

Commit

Permalink
feat(VisualPageIndicator): introduce 1.0 component
Browse files Browse the repository at this point in the history
  • Loading branch information
booc0mtaco committed Dec 18, 2024
1 parent 032cb5d commit 3bb004b
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/components/VisualPageIndicator/VisualPageIndicator.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*------------------------------------*\
# VISUAL PAGE INDICATOR
\*------------------------------------*/

/**
* VisualPageIndicator
*/
.visual-page-indicator {
display: flex;
justify-content: center;
gap: calc(var(--eds-size-1-and-half) / 16 * 1rem);
}

.visual-page-indicator__item {
--visual-page-indicator-bg: var(--eds-theme-color-background-utility-disabled-medium-emphasis);

height: calc(var(--eds-size-1-and-half) / 16 * 1rem);
width: calc(var(--eds-size-1-and-half) / 16 * 1rem);
border-radius: calc(var(--eds-border-radius-full) * 1px);

background-color: var(--visual-page-indicator-bg);
}

.visual-page-indicator--active {
--visual-page-indicator-bg: var(--eds-theme-color-background-brand-pink);
}

/**
* TODO-AH:
* - Add color ease with eds-anim-move-medium / eds-anim-ease
* TODO-AH:
* - introduce new tokens for inactive and active? (or use the root tokens?)
*/
37 changes: 37 additions & 0 deletions src/components/VisualPageIndicator/VisualPageIndicator.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { StoryObj, Meta } from '@storybook/react';
import type React from 'react';

import { VisualPageIndicator } from './VisualPageIndicator';

export default {
title: 'Components/VisualPageIndicator',
component: VisualPageIndicator,
parameters: {
badges: ['api-1.0', 'theme-2.0'],
},
} as Meta<Args>;

type Args = React.ComponentProps<typeof VisualPageIndicator>;

export const Default: StoryObj<Args> = {
args: {
activePage: 0,
totalPageCount: 6,
},
};

export const MinimumPages: StoryObj<Args> = {
args: {
activePage: 1,
totalPageCount: 2,
},
};

export const FivePages: StoryObj<Args> = {
args: {
activePage: 2,
totalPageCount: 5,
},
};

// TODO-AH: add implementation example showing usage of state with a label for a11y handling
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { generateSnapshots } from '@chanzuckerberg/story-utils';
import * as stories from './VisualPageIndicator.stories';
import type { StoryFile } from '../../util/utility-types';

describe('<VisualPageIndicator />', () => {
generateSnapshots(stories as StoryFile);
});
59 changes: 59 additions & 0 deletions src/components/VisualPageIndicator/VisualPageIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import clsx from 'clsx';
import React from 'react';
import styles from './VisualPageIndicator.module.css';

export type VisualPageIndicatorProps = {
// Component API
/**
* CSS class names that can be appended to the component.
*/
className?: string;
// Design API
/**
* Index of the active page in the indicator (0-based).
*/
activePage: number;
/**
* Total number of pages available in this experience
*/
totalPageCount: number;
};

/**
* `import {VisualPageIndicator} from "@chanzuckerberg/eds";`
*
* Static visual cue to help users understand their current position within a series of content or pages.
*/
export const VisualPageIndicator = ({
className,
activePage = 0,
totalPageCount = 0,
...other
}: VisualPageIndicatorProps) => {
const componentClassName = clsx(styles['visual-page-indicator'], className);

// TODO-AH: add warning when totalPageCount < 2
// TODO-AH: add error for activePage under and overflow, with clamping
// TODO-AH: handle warning when not used in conjunction with an a descriptive label

return (
<ul className={componentClassName} {...other}>
{Array(totalPageCount)
.fill(0)
.map((_, index) => {
return `Page ${index}`;
})
.map((name, index) => {
return (
<li
className={clsx(
styles['visual-page-indicator__item'],
index === activePage && styles['visual-page-indicator--active'],
)}
key={name}
></li>
);
})}
</ul>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<VisualPageIndicator /> Default story renders snapshot 1`] = `
<ul
class="visual-page-indicator"
>
<li
class="visual-page-indicator__item visual-page-indicator--active"
/>
<li
class="visual-page-indicator__item"
/>
<li
class="visual-page-indicator__item"
/>
<li
class="visual-page-indicator__item"
/>
<li
class="visual-page-indicator__item"
/>
<li
class="visual-page-indicator__item"
/>
</ul>
`;

exports[`<VisualPageIndicator /> FivePages story renders snapshot 1`] = `
<ul
class="visual-page-indicator"
>
<li
class="visual-page-indicator__item"
/>
<li
class="visual-page-indicator__item"
/>
<li
class="visual-page-indicator__item visual-page-indicator--active"
/>
<li
class="visual-page-indicator__item"
/>
<li
class="visual-page-indicator__item"
/>
</ul>
`;

exports[`<VisualPageIndicator /> MinimumPages story renders snapshot 1`] = `
<ul
class="visual-page-indicator"
>
<li
class="visual-page-indicator__item"
/>
<li
class="visual-page-indicator__item visual-page-indicator--active"
/>
</ul>
`;
1 change: 1 addition & 0 deletions src/components/VisualPageIndicator/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { VisualPageIndicator as default } from './VisualPageIndicator';
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,4 @@ export type { AppNotificationProps as AppNotificationV2Props } from './component
*/
// https://headlessui.com/v1/react/transition
export { Transition } from '@headlessui/react';
export { default as VisualPageIndicator } from './components/VisualPageIndicator';

0 comments on commit 3bb004b

Please sign in to comment.