@workday/canvas-kit-react
Version:
The parent module that contains all Workday Canvas Kit React components
145 lines (144 loc) • 10.9 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { buttonStencil } from '@workday/canvas-kit-react/button';
import { createContainer, focusRing } from '@workday/canvas-kit-react/common';
import { systemIconStencil } from '@workday/canvas-kit-react/icon';
import { Box, mergeStyles } from '@workday/canvas-kit-react/layout';
import { colorSpace, createStencil, px2rem } from '@workday/canvas-kit-styling';
import { base, system } from '@workday/canvas-tokens-web';
import { PillAvatar } from './PillAvatar';
import { PillCount, pillCountStencil } from './PillCount';
import { PillIcon } from './PillIcon';
import { PillIconButton } from './PillIconButton';
import { PillLabel } from './PillLabel';
import { usePillModel } from './usePillModel';
export const pillStencil = createStencil({
extends: buttonStencil,
vars: {
maxWidth: '',
},
base: { name: "2sncys", styles: "box-sizing:border-box;display:initial;flex-direction:row;align-items:center;border-radius:var(--cnvs-sys-shape-sm, var(--cnvs-sys-shape-x1, 0.25rem));font-family:var(--cnvs-sys-font-family-default, \"Roboto\");font-weight:var(--cnvs-sys-font-weight-normal, 400);line-height:var(--cnvs-sys-line-height-subtext-md, 1rem);font-size:var(--cnvs-sys-font-size-subtext-md, 0.75rem);letter-spacing:var(--cnvs-sys-letter-spacing-subtext-md, 0.02rem);box-shadow:none;outline:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:fit-content;padding:0.125rem var(--cnvs-sys-padding-xs, var(--cnvs-sys-space-x2, 0.5rem));height:var(--cnvs-sys-size-xs, var(--cnvs-sys-space-x6, 1.5rem));position:relative;gap:var(--cnvs-sys-gap-xs, var(--cnvs-sys-space-x1, 0.25rem));max-width:var(--maxWidth-pill-089441);white-space:nowrap;text-overflow:ellipsis;overflow:hidden;--background-button-a19f67:var(--cnvs-sys-color-surface-alt-default, var(--cnvs-sys-color-bg-alt-soft, oklch(0.3343 0.0951 253.3 / 0.05)));--border-button-a19f67:var(--cnvs-sys-color-border-transparent);--label-button-a19f67:var(--cnvs-sys-color-fg-strong);--color-system-icon-c9acc3:currentColor;--borderColor-pill-count-d41635:transparent;&:has(span){display:flex;line-height:var(--cnvs-sys-line-height-subtext-md, var(--cnvs-sys-line-height-subtext-medium, 1rem));}&:hover, &.hover{--background-button-a19f67:color-mix(in srgb, var(--cnvs-sys-color-surface-alt-default, var(--cnvs-sys-color-bg-alt-soft, oklch(0.3343 0.0951 253.3 / 0.05))) , var(--cnvs-base-palette-neutral-1000, oklch(0 0 0 / 1)) calc(0.0392 * 100%));--border-button-a19f67:var(--cnvs-sys-color-border-transparent);--label-button-a19f67:var(--cnvs-sys-color-fg-stronger);--color-system-icon-c9acc3:currentColor;--borderColor-pill-count-d41635:transparent;}&:active, &.active{--background-button-a19f67:color-mix(in srgb, var(--cnvs-sys-color-surface-alt-default, var(--cnvs-sys-color-bg-alt-soft, oklch(0.3343 0.0951 253.3 / 0.05))) , var(--cnvs-base-palette-neutral-1000, oklch(0 0 0 / 1)) calc(0.0745 * 100%));--label-button-a19f67:var(--cnvs-sys-color-fg-stronger);--color-system-icon-c9acc3:currentColor;--borderColor-pill-count-d41635:transparent;}&:focus-visible, &.focus{--border-button-a19f67:var(--cnvs-sys-color-brand-border-primary, oklch(0.6023 0.2032 255.68 / 1));--label-button-a19f67:var(--cnvs-sys-color-fg-strong);border-color:var(--cnvs-sys-color-brand-border-primary, oklch(0.6023 0.2032 255.68 / 1));--color-system-icon-c9acc3:currentColor;box-shadow:0 0 0 1px var(--cnvs-sys-color-brand-border-primary, oklch(0.6023 0.2032 255.68 / 1)), 0 0 0 1px var(--cnvs-sys-color-brand-border-primary, oklch(0.6023 0.2032 255.68 / 1));}&:disabled, &.disabled{--opacity-button-a19f67:var(--cnvs-sys-opacity-disabled);--background-button-a19f67:var(--cnvs-sys-color-surface-alt-default, var(--cnvs-sys-color-bg-alt-soft, oklch(0.3343 0.0951 253.3 / 0.05)));--label-button-a19f67:var(--cnvs-sys-color-fg-strong);--color-system-icon-c9acc3:currentColor;--backgroundColor-pill-count-d41635:var(--cnvs-sys-color-surface-alt-default, var(--cnvs-sys-color-bg-alt-soft, oklch(0.3343 0.0951 253.3 / 0.05)));--borderColor-pill-count-d41635:transparent;}" },
modifiers: {
variant: {
readOnly: { name: "2adjlp", styles: "border:0.0625rem solid var(--cnvs-sys-color-border-default, var(--cnvs-sys-color-border-divider, oklch(0.3057 0.079 256.22 / 0.13)));cursor:default;--background-button-a19f67:var(--cnvs-sys-color-bg-default);--label-button-a19f67:var(--cnvs-sys-color-fg-default);&:hover, &.hover{border-color:var(--cnvs-sys-color-border-default, var(--cnvs-sys-color-border-divider, oklch(0.3057 0.079 256.22 / 0.13)));--background-button-a19f67:var(--cnvs-sys-color-bg-default);}&:focus-visible, &.focus{--background-button-a19f67:var(--cnvs-sys-color-bg-default);}&:active, &.active{--background-button-a19f67:var(--cnvs-sys-color-bg-default);}&:disabled, &.disabled{--background-button-a19f67:var(--cnvs-sys-color-bg-default);}" },
removable: { name: "3zo4yr", styles: "&:focus-visible, &.focus{--background-button-a19f67:var(--cnvs-sys-color-bg-alt-default);--border-button-a19f67:var(--cnvs-sys-color-border-input-default);--label-button-a19f67:var(--cnvs-sys-color-fg-strong);box-shadow:none;}&:hover, &.hover{--background-button-a19f67:color-mix(in srgb, var(--cnvs-sys-color-surface-alt-default, var(--cnvs-sys-color-bg-alt-soft, oklch(0.3343 0.0951 253.3 / 0.05))) , var(--cnvs-base-palette-neutral-1000, oklch(0 0 0 / 1)) calc(0.0392 * 100%));--backgroundColor-pill-count-d41635:var(--cnvs-sys-color-surface-transparent, var(--cnvs-sys-color-bg-transparent-default, oklch(0 0 0 / 0)));}&:active, &.active{--background-button-a19f67:color-mix(in srgb, var(--cnvs-sys-color-surface-alt-default, var(--cnvs-sys-color-bg-alt-soft, oklch(0.3343 0.0951 253.3 / 0.05))) , var(--cnvs-base-palette-neutral-1000, oklch(0 0 0 / 1)) calc(0.0745 * 100%));--backgroundColor-pill-count-d41635:var(--cnvs-sys-color-surface-transparent, var(--cnvs-sys-color-bg-transparent-default, oklch(0 0 0 / 0)));}&:disabled, &.disabled{--background-button-a19f67:var(--cnvs-sys-color-bg-alt-default);--color-system-icon-c9acc3:currentColor;}cursor:default;overflow:revert;position:relative;" }
}
}
}, "pill-089441");
/**
* By default, a `Pill` renders an interactive element that accepts subcomponents. By "interactive"
* we mean that the Pill container is a focusable element (a `<button>`). All leading elements
* (icons or avatars) are intended to be descriptive, helping support the label. They should not
* receive focus.
*
* `Pill` is the container component. It also provides a React context model for its subcomponents.
* Based on the `variant` prop this component will render different styled `Pill`s.
*
* Example of read only:
*
* ```tsx
* <Pill variant="readOnly">This is a read only</Pill>
* ```
*
* Example of interactive:
*
* ```tsx
* <Pill onClick={() => console.log('clicked')}>
* <Pill.Avatar /> Regina Skeltor
* </Pill>
* ```
*
* Example of removable:
*
* ```tsx
* <Pill variant="removable">
* <Pill.Avatar /> Regina Skeltor
* <Pill.IconButton aria-label='Remove user' onClick={() => console.log('clicked')} />
* </Pill>
* ```
*
* If you set the `Pill` `variant` to `removable`, it will render a `<span>` element. You can then
* provide a `Pill.IconButton` that acts as the focus target. This creates a smaller, more
* intentional click target that prevents users from accidentally deleting an item.
*
* ```tsx
* <Pill variant="removable">
* Shoes
* <Pill.IconButton aria-label='Remove user' onClick={() => console.log('handle remove')} />
* </Pill>
* ```
*/
export const Pill = createContainer('button')({
displayName: 'Pill',
modelHook: usePillModel,
subComponents: {
/**
* This component renders an avatar. It supports all props of the `Avatar` component.
*
* ```tsx
* <Pill variant="removable">
* <Pill.Avatar url={avatarUrl} />
* <Pill.Label>Regina Skeltor</Pill.Label>
* <Pill.IconButton aria-label='Remove user' onClick={() => console.log('handle remove')} />
* </Pill>
* ```
*/
Avatar: PillAvatar,
/**
* This component renders its `children` as the count.
*
* ```tsx
* <Pill onClick={() => console.warn('clicked')}>
* <Pill.Label>Shoes</Pill.Label>
* <Pill.Count>30</Pill.Count>
* </Pill>
* ```
*/
Count: PillCount,
/**
* This component renders an `icon`. By default it renders a `plusIcon` but it can be overridden by
* providing an icon to the `icon` prop. You must provide an `aria-label` for the icon.
*
* ```tsx
* <Pill onClick={() => console.warn('clicked')}>
* <Pill.Icon aria-label='Add user' />
* <Pill.Label>Regina Skeltor</Pill.Label>
* </Pill>
* ```
*/
Icon: PillIcon,
/**
* This component renders a custom icon button. It is only intended to be used with the
* `removable` variant. By default, it renders a `xSmallIcon` but can be overridden by providing
* an icon to the `icon` prop.
*
* ```tsx
* <Pill variant="removable">
* <Pill.Label>Pink Shirts</Pill.Label>
* <Pill.IconButton aria-label='Remove item' onClick={() => console.warn('clicked')} />
* </Pill>
* ```
*/
IconButton: PillIconButton,
/**
* This component renders a `<span>` that automatically handles overflow by rendering a tooltip.
* There's no need to use this component directly since the overflow is handled for you automatically unless you have an icon or other element.
*
* ```tsx
* <Pill variant="readOnly">
* <Pill.Label>Read-only</Pill.Label>
* </Pill>
* ```
*/
Label: PillLabel,
},
})(({ variant, maxWidth = 200, children, ...elemProps }, Element, model) => {
const maxWidthCSSValue = typeof maxWidth === 'number' ? px2rem(maxWidth) : maxWidth;
const isReadOnly = variant === 'readOnly';
return (variant === null || variant === void 0 ? void 0 : variant.match(/^(readOnly|removable)$/)) ? (_jsx(Box, { as: Element !== 'button' ? Element : 'span', id: isReadOnly ? model.state.id : undefined, ...mergeStyles(elemProps, [
model.state.disabled ? 'disabled' : undefined,
pillStencil({ maxWidth: maxWidthCSSValue, variant }),
]), children: isReadOnly ? _jsx(PillLabel, { children: children }) : children })) : (_jsx(Element, { disabled: model.state.disabled, ...mergeStyles(elemProps, [
model.state.disabled ? 'disabled' : undefined,
pillStencil({ maxWidth: maxWidthCSSValue }),
]), children: children }));
});