UNPKG

@workday/canvas-kit-react

Version:

The parent module that contains all Workday Canvas Kit React components

145 lines (144 loc) • 10.9 kB
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 })); });