Skip to content

Commit

Permalink
feat(SelectionChip): introduce 1.0 component
Browse files Browse the repository at this point in the history
  • Loading branch information
booc0mtaco committed Dec 2, 2024
1 parent f205e07 commit b48beca
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/components/SelectionChip/SelectionChip.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*------------------------------------*\
# SELECTION CHIP
\*------------------------------------*/

/**
* SelectionChip
*/
.selection-chip {
display: inline-flex;
align-items: center;
gap: calc(var(--eds-size-1) / 16 * 1rem);

padding: calc(var(--eds-size-1) / 16 * 1rem) calc(var(--eds-size-2) / 16 * 1rem);
border-radius: calc(var(--eds-border-radius-full) * 1px);

color: var(--eds-theme-color-text-utility-interactive-primary);
border: 1px solid var(--eds-theme-color-border-utility-default-low-emphasis);
}

/** TODO-AH: make sure spacing on right is 20px equivalent when icon present */

/**
* Color theme tokens
*/

.selection-chip:hover {
background-color: var(--eds-theme-color-background-utility-default-no-emphasis-hover)
}

.selection-chip:active {
background-color: var(--eds-theme-color-background-utility-default-no-emphasis-active)
}

/** TODO-AH: implement default, active, and hover background colors when selected */
/** TODO-AH: add in selected border color. Also confirm how focus ring spacing should work */
35 changes: 35 additions & 0 deletions src/components/SelectionChip/SelectionChip.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { BADGE } from '@geometricpanda/storybook-addon-badges';
import type { StoryObj, Meta } from '@storybook/react';
import type React from 'react';

import { SelectionChip } from './SelectionChip';

export default {
title: 'Components/SelectionChip',
component: SelectionChip,
parameters: {
badges: [BADGE.BETA],
},
} as Meta<Args>;

type Args = React.ComponentProps<typeof SelectionChip>;

export const Default: StoryObj<Args> = {
args: {
label: 'Label',
},
};

export const Disabled: StoryObj<Args> = {
args: {
label: 'Label',
isDisabled: true,
},
};

export const WithIcon: StoryObj<Args> = {
args: {
label: 'Label',
leadingIcon: 'alarm-add',
},
};
7 changes: 7 additions & 0 deletions src/components/SelectionChip/SelectionChip.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { generateSnapshots } from '@chanzuckerberg/story-utils';
import * as stories from './SelectionChip.stories';
import type { StoryFile } from '../../util/utility-types';

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

import Icon, { type IconName } from '../Icon';
import Text from '../Text';

import styles from './SelectionChip.module.css';

export type SelectionChipProps = {
// Component API
/**
* CSS class names that can be appended to the component.
*/
className?: string;
// Design API
/**
* Whether the chip is disabled or not
*/
isDisabled?: boolean;
/**
* Text used in the chip to give it a description
*/
label: string;
/**
* Leading icon for the chip
*/
leadingIcon: IconName;
};

/**
* BETA: This component is still a work in progress and is subject to change.
*
* `import {SelectionChip} from "@chanzuckerberg/eds";`
*
*/
export const SelectionChip = ({
className,
isDisabled,
label,
leadingIcon,
// Add other deferenced props to use
...other
}: SelectionChipProps) => {
const componentClassName = clsx(styles['selection-chip'], className);

// TODO-AH: add in a context aware control based on the selection type: radio or checkbox
// TODO-AH: use a label for the container, so that clicks naturally go to the hidden control
// TODO-AH: use focus ring class

return (
<span
className={componentClassName}
// Other de-referenced props go here
{...other}
>
{leadingIcon && <Icon name={leadingIcon} purpose="decorative" />}
<Text as="span" preset="button-md">
{label}
</Text>
</span>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<SelectionChip /> Default story renders snapshot 1`] = `
<span
class="selection-chip"
>
<span
class="text text--button-md"
>
Label
</span>
</span>
`;

exports[`<SelectionChip /> Disabled story renders snapshot 1`] = `
<span
class="selection-chip"
>
<span
class="text text--button-md"
>
Label
</span>
</span>
`;

exports[`<SelectionChip /> WithIcon story renders snapshot 1`] = `
<span
class="selection-chip"
>
<svg
aria-hidden="true"
class="icon"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15 12h-2v-2c0-.55-.45-1-1-1s-1 .45-1 1v2H9c-.55 0-1 .45-1 1s.45 1 1 1h2v2c0 .55.45 1 1 1s1-.45 1-1v-2h2c.55 0 1-.45 1-1s-.45-1-1-1zm6.18-6.99L18.1 2.45c-.42-.35-1.05-.3-1.41.13-.35.42-.29 1.05.13 1.41l3.07 2.56c.42.35 1.05.3 1.41-.13.36-.42.3-1.05-.12-1.41zM4.1 6.55l3.07-2.56c.43-.36.49-.99.13-1.41-.35-.43-.98-.48-1.4-.13L2.82 5.01c-.42.36-.48.99-.12 1.41.35.43.98.48 1.4.13zM12 4c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9-4.03-9-9-9zm0 16c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7z"
/>
</svg>
<span
class="text text--button-md"
>
Label
</span>
</span>
`;
1 change: 1 addition & 0 deletions src/components/SelectionChip/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SelectionChip as default } from './SelectionChip';
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,4 @@ export type { AppNotificationProps as AppNotificationV2Props } from './component
*/
// https://headlessui.com/v1/react/transition
export { Transition } from '@headlessui/react';
export { default as SelectionChip } from './components/SelectionChip';

0 comments on commit b48beca

Please sign in to comment.