@stackone/malachite 2.69.0 → 2.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +11 -9
- package/dist/components/AccessPills.js +99 -0
- package/dist/components/AccessPills.js.map +1 -0
- package/dist/components/Alert.js +100 -75
- package/dist/components/Alert.js.map +1 -1
- package/dist/components/Button.js +75 -73
- package/dist/components/Button.js.map +1 -1
- package/dist/components/Modal.js +75 -74
- package/dist/components/Modal.js.map +1 -1
- package/dist/components/PopoverParts.js +35 -35
- package/dist/components/PopoverParts.js.map +1 -1
- package/dist/components/Search.js +30 -29
- package/dist/components/Search.js.map +1 -1
- package/dist/components/StatusPill.js +61 -0
- package/dist/components/StatusPill.js.map +1 -0
- package/dist/components/Surface.js +138 -133
- package/dist/components/Surface.js.map +1 -1
- package/dist/components/Toolbar.js +40 -33
- package/dist/components/Toolbar.js.map +1 -1
- package/dist/components/Typography/EllipsisText.js +27 -25
- package/dist/components/Typography/EllipsisText.js.map +1 -1
- package/dist/components/Typography/MarkdownBlock.js +36 -28
- package/dist/components/Typography/MarkdownBlock.js.map +1 -1
- package/dist/components/Typography/Text.js +24 -22
- package/dist/components/Typography/Text.js.map +1 -1
- package/dist/components/WizardLayout.js +81 -67
- package/dist/components/WizardLayout.js.map +1 -1
- package/dist/index.d.ts +74 -0
- package/dist/index.js +361 -357
- package/dist/index.js.map +1 -1
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Surface.js","sources":["../../src/components/Surface.tsx"],"sourcesContent":["import React from 'react';\nimport { paintOnChild } from './asChild';\nimport DisclosureArrow from './DisclosureArrow';\nimport { FOCUS_RING_INSET } from './focusRing';\nimport { resolveRel } from './linkRel';\nimport { safeHref } from './safeHref';\nimport { isRenderableNode } from './renderableNode';\nimport {\n FOREGROUND_RESET,\n SELECTED_ROW_ACCENT,\n SELECTED_ROW_BACKGROUND,\n SELECTED_ROW_FOREGROUND,\n SELECTED_TEXT_CONTEXT,\n} from './selectedRow';\n\nexport interface SurfaceProps {\n children?: React.ReactNode;\n padding?: boolean;\n /**\n * Content overflow. Defaults to `hidden` so children are clipped to the rounded\n * corners. Use `clip` to keep the rounded clipping WITHOUT creating a scroll\n * container — so a `position: sticky` descendant still pins (unlike `hidden`,\n * which traps it). `visible` disables clipping entirely.\n */\n overflow?: 'hidden' | 'visible' | 'clip';\n role?: React.AriaRole;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\ninterface SurfaceRowChromeProps {\n children?: React.ReactNode;\n /** Renders a bottom divider — omit on the last row in a Surface. */\n divider?: boolean;\n /** Removes the hover affordance / disables the control (e.g. while loading/busy). */\n disabled?: boolean;\n /** Announces the row as selected — `aria-checked` under a `radio`/`checkbox` role,\n * `aria-current` otherwise — and paints `Table`'s selected treatment unless `selection`\n * says not to. `'mixed'` is for a `checkbox` row that is partly selected: it announces\n * `aria-checked=\"mixed\"` there, never paints and never marks the row current, and counts\n * as not selected under any other role. */\n selected?: boolean | 'mixed';\n /** How a `selected` row shows it. `highlight` paints the treatment; `announce` leaves the\n * visual to a control inside the row and only sets the ARIA state. Defaults to `announce`\n * under `role=\"checkbox\"` and `highlight` otherwise. */\n selection?: 'highlight' | 'announce';\n /**\n * Tints the whole row by what it reports. `muted` is a row whose subject is inactive —\n * not disabled: it stays interactive. `success` and `error` are for a row that carries\n * an outcome, where the result belongs to the whole line rather than to one cell in it.\n */\n tone?: 'default' | 'muted' | 'success' | 'error';\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Stays an interface under its original name: a consumer may `extends` it. */\nexport interface SurfaceRowProps extends SurfaceRowChromeProps {\n asChild?: false;\n /**\n * When provided, the whole row becomes clickable: it renders as a `<button>`\n * (or `<a>` when `href` is set), so the entire row is the click target with\n * native focus + Enter/Space — no manual tabIndex/key handlers. For a\n * selectable row, put a presentational `<Radio>`/`<Checkbox>` inside as the\n * visual indicator; do NOT nest an interactive control (invalid + double tab stop).\n */\n onClick?: (event: React.MouseEvent) => void;\n /** Renders the clickable row as an anchor instead of a button. */\n href?: string;\n target?: React.HTMLAttributeAnchorTarget;\n rel?: string;\n /** Content pinned right, outside the row button, so it may hold its own control. */\n trailing?: React.ReactNode;\n /**\n * Shows `trailing` only while the row is hovered or holds focus, and while a menu\n * it opened is still open. Hidden by opacity, so it stays in the tab order; a touch screen,\n * which has no hover, always shows it.\n */\n revealTrailing?: boolean;\n /** ARIA role for a clickable row, e.g. `radio`/`checkbox` (wrap the list in a `radiogroup`). */\n role?: React.AriaRole;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n/**\n * The outcome tones reuse the tag tokens rather than minting row ones, so a row saying \"this\n * passed\" and a tag saying it are the same green wherever the two sit together.\n */\nconst TONE_CLASSES: Record<NonNullable<SurfaceRowProps['tone']>, string> = {\n default: '',\n muted: 'bg-[var(--malachite-card-dimmed-background)]',\n success: 'bg-[var(--malachite-tag-success-background)]',\n error: 'bg-[var(--malachite-tag-error-background)]',\n};\n\n/**\n * The text an outcome tone carries with it, through the same context channel a selected row\n * uses, so `Typography` inside the row follows the tint instead of staying near-black on it.\n * `color` as well, for row content that is not Typography.\n *\n * Only the outcome tones. `muted` dims its subject rather than recolouring it, and its\n * foreground is the ordinary one.\n */\nconst TONE_FOREGROUNDS: Partial<Record<NonNullable<SurfaceRowProps['tone']>, string>> = {\n success: 'var(--malachite-tag-success-foreground)',\n error: 'var(--malachite-tag-error-foreground)',\n};\n\nexport interface SurfaceRowAsChildProps extends SurfaceRowChromeProps {\n asChild: true;\n children: React.ReactElement;\n}\n\nexport type AnySurfaceRowProps = SurfaceRowProps | SurfaceRowAsChildProps;\n\n// Not `group-hover` or `group-has-[:focus-visible]`: WebKit never applies the first (its\n// `@media (hover: hover)` nested in the group selector) nor the second inside a shadow root,\n// so the control stayed hidden in Safari. An open menu takes focus out of the row into a\n// portal, and would otherwise lose its trigger.\nconst REVEALED_ON_INTERACTION =\n 'opacity-0 transition-opacity group-[:hover]/row:opacity-100 group-focus-within/row:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100';\n\nconst TRIPLE_SHADOW =\n '0px 0px 4px 0px rgba(0,0,0,0.08), 0px 4px 4px 0px rgba(0,0,0,0.08), 0px 4px 10px 0px rgba(0,0,0,0.05)';\n\n/**\n * A single full-bleed row inside a <Surface>. Owns the row chrome — hover\n * highlight, colour transition and an optional bottom divider — so consumers\n * compose their own content inside without re-implementing design-system styling.\n * Pass `onClick`/`href` to make the entire row clickable (rendered as a real\n * button/anchor, so keyboard navigation works natively).\n */\nconst SurfaceRow: React.FC<AnySurfaceRowProps> = (props) => {\n const {\n children,\n divider = false,\n disabled = false,\n selected,\n selection,\n tone = 'default',\n className = '',\n style,\n } = props;\n const asChild = props.asChild === true;\n const {\n onClick,\n href: rawHref,\n target,\n rel,\n trailing,\n revealTrailing,\n role,\n } = asChild ? ({} as SurfaceRowProps) : (props as SurfaceRowProps);\n // A rejected href (e.g. `javascript:`) leaves the row a button or a plain row, never an anchor.\n const href = safeHref(rawHref);\n const ariaLabel = asChild ? undefined : (props as SurfaceRowProps)['aria-label'];\n const ariaLabelledBy = asChild ? undefined : (props as SurfaceRowProps)['aria-labelledby'];\n const interactive = Boolean(onClick || href);\n // `asChild` is interactive for the hover affordance only, not the focus/reset classes.\n const hover =\n disabled && (interactive || asChild)\n ? ''\n : 'transition-colors hover:bg-[var(--malachite-buttonlist-hover-background)]';\n\n // A class, not an inline colour, which would outrank the hover utility. It replaces the\n // button reset's `bg-transparent` rather than joining it: same specificity, so the winner\n // would be whichever Tailwind emitted last.\n const tinted = tone !== 'default';\n const toneClass = TONE_CLASSES[tone];\n\n const chromeClasses = [\n 'w-full text-left border-0',\n toneClass,\n divider ? 'border-b border-solid border-[var(--malachite-card-border)]' : '',\n hover,\n ]\n .filter(Boolean)\n .join(' ');\n\n const controlClasses = [\n interactive\n ? `appearance-none ${tinted ? '' : 'bg-transparent'} p-0 ${FOCUS_RING_INSET}`\n : '',\n interactive && !disabled ? 'cursor-pointer' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const classes = [chromeClasses, controlClasses, className].filter(Boolean).join(' ');\n\n const paints = selection ? selection === 'highlight' : role !== 'checkbox';\n\n // A gradient layer so the tint composites over hover, and an inset shadow because\n // `ring-*` silently doesn't paint in a shadow root.\n const selectedStyle: React.CSSProperties =\n selected === true && paints\n ? {\n backgroundImage: `linear-gradient(${SELECTED_ROW_BACKGROUND}, ${SELECTED_ROW_BACKGROUND})`,\n color: SELECTED_ROW_FOREGROUND,\n boxShadow: `inset 2px 0 0 ${SELECTED_ROW_ACCENT}`,\n ...SELECTED_TEXT_CONTEXT,\n }\n : {};\n\n const toneForeground = TONE_FOREGROUNDS[tone];\n const toneStyle: React.CSSProperties = toneForeground\n ? ({\n color: toneForeground,\n '--malachite-ctx-text-primary': toneForeground,\n } as React.CSSProperties)\n : {};\n\n // `selected` last of the two: a row can be both, and selection is the state the reader is\n // acting on, so it wins the colour.\n const rowStyle = { ...toneStyle, ...selectedStyle, ...style };\n\n // Only a checkbox has a partly-checked state; a radio is chosen or not.\n const ariaChecked =\n role === 'checkbox' && selected === 'mixed'\n ? ('mixed' as const)\n : role === 'radio' || role === 'checkbox'\n ? selected === true\n : undefined;\n // `aria-current`, not `aria-pressed`: a selected row is one of many choices, not a toggle\n // (same call as `Dropdown`'s options). A role that carries its own state uses that instead.\n const ariaCurrent = ariaChecked === undefined && selected === true ? true : undefined;\n\n // Everything a control would have carried, for the branches that render none: the row\n // element is then the only thing assistive tech sees. `aria-disabled` because there is no\n // control to be natively disabled — and it is inert without a role, like the name.\n const rowFallbackAria = {\n role,\n 'aria-checked': ariaChecked,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-disabled': role && disabled ? true : undefined,\n };\n\n if (asChild) {\n return paintOnChild(children, classes, rowStyle);\n }\n\n if (isRenderableNode(trailing)) {\n const control =\n href && !disabled ? (\n <a\n href={href}\n target={target}\n rel={resolveRel(rel, target)}\n onClick={onClick}\n className={`${controlClasses} border-0 flex-1 min-w-0 text-left no-underline text-inherit`}\n role={role}\n aria-checked={ariaChecked}\n aria-current={ariaCurrent}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </a>\n ) : onClick ? (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className={`${controlClasses} border-0 flex-1 min-w-0 text-left`}\n role={role}\n aria-checked={ariaChecked}\n aria-current={ariaCurrent}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </button>\n ) : (\n // The set goes here, not on the wrapper: `radio` and `checkbox` make their\n // descendants presentational, which would bury a control in the trailing slot.\n <div className=\"flex-1 min-w-0\" {...rowFallbackAria}>\n {children}\n </div>\n );\n\n return (\n <div\n className={[\n chromeClasses,\n 'flex items-center',\n revealTrailing ? 'group/row' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={rowStyle}\n >\n {control}\n <div\n className={`shrink-0 flex items-center ${revealTrailing ? REVEALED_ON_INTERACTION : ''}`}\n >\n {trailing}\n </div>\n </div>\n );\n }\n\n if (href && !disabled) {\n return (\n <a\n href={href}\n target={target}\n rel={resolveRel(rel, target)}\n onClick={onClick}\n className={`${classes} no-underline text-inherit`}\n style={rowStyle}\n role={role}\n aria-checked={ariaChecked}\n aria-current={ariaCurrent}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </a>\n );\n }\n\n if (onClick) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className={classes}\n style={rowStyle}\n role={role}\n aria-checked={ariaChecked}\n aria-current={ariaCurrent}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </button>\n );\n }\n\n return (\n <div className={classes} style={rowStyle} {...rowFallbackAria}>\n {children}\n </div>\n );\n};\n\nexport interface SurfaceExpandableRowProps {\n /** The row itself, laid out across the line. May hold its own controls. */\n header: React.ReactNode;\n /** The body, rendered beneath the row while it is open. */\n children?: React.ReactNode;\n expanded: boolean;\n /** Omit for a row that cannot open. The arrow's space is still reserved, so a list of\n * rows stays in one column whether or not each one has a body. */\n onToggle?: (expanded: boolean) => void;\n /**\n * Pins the row while its body scrolls, so a long body never leaves the reader without\n * the line it belongs to. Offset by whatever is already pinned above it.\n */\n sticky?: boolean;\n stickyTopOffset?: number;\n divider?: boolean;\n tone?: SurfaceRowProps['tone'];\n /** Names the disclosure control, which is otherwise only an arrow. */\n 'aria-label'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Stops a click inside it from toggling the row, for the cells that hold controls.\n *\n * Explicit rather than sniffing the event's target for an interactive ancestor: a control\n * rendering into a shadow root retargets the event to its host, so the sniff would miss\n * exactly the components most likely to sit in a row.\n */\nconst ExpandableRowControls: React.FC<{\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}> = ({ children, className = '', style }) => (\n <div className={className} style={style} onClick={(event) => event.stopPropagation()}>\n {children}\n </div>\n);\n\n/**\n * A row that opens to reveal a body, for a line that carries its own controls.\n *\n * Not `Accordion`: that puts its header inside the toggle button, so a header holding a\n * dropdown or a second button is invalid. Here the row surface takes the click and a cell\n * opts out with `ExpandableRow.Controls`, while the arrow stays a real button so the\n * keyboard reaches it.\n */\n/**\n * The space before the header: the arrow's own inset, its glyph and the gap after it.\n * Exported so a consumer aligning a column header above these rows offsets by the same\n * amount instead of guessing at it.\n */\nexport const EXPANDABLE_ROW_LEAD_PX = 39;\n\nconst SurfaceExpandableRow: React.FC<SurfaceExpandableRowProps> & {\n Controls: typeof ExpandableRowControls;\n} = Object.assign(\n ({\n header,\n children,\n expanded,\n onToggle,\n sticky = false,\n stickyTopOffset = 0,\n divider = false,\n tone = 'default',\n 'aria-label': ariaLabel,\n className = '',\n style,\n }: SurfaceExpandableRowProps) => {\n const bodyId = React.useId();\n const toggle = onToggle ? () => onToggle(!expanded) : undefined;\n\n return (\n <SurfaceRow divider={divider} tone={tone} className={className} style={style}>\n {/* `group` so the arrow takes its hover state from the whole row. */}\n <div\n className={`group flex items-center w-full ${toggle ? 'cursor-pointer' : ''} ${\n sticky && expanded\n ? 'sticky z-[1] bg-[var(--malachite-card-background)]'\n : ''\n }`}\n style={sticky && expanded ? { top: stickyTopOffset } : undefined}\n // Presentational: the arrow below is the keyboard control, and this only\n // widens the pointer target.\n onClick={toggle}\n role=\"presentation\"\n >\n {/* Reserved whether or not this row opens, so a list stays in one column.\n The inset and gap match Accordion's header. */}\n <span className=\"shrink-0 flex items-center pl-[16px] pr-[12px]\">\n {toggle && (\n <button\n type=\"button\"\n className={`appearance-none bg-transparent border-0 p-0 flex items-center cursor-pointer ${FOCUS_RING_INSET}`}\n aria-expanded={expanded}\n aria-controls={bodyId}\n aria-label={ariaLabel}\n onClick={(event) => {\n event.stopPropagation();\n toggle();\n }}\n >\n <DisclosureArrow expanded={expanded} />\n </button>\n )}\n </span>\n {header}\n </div>\n {expanded && <div id={bodyId}>{children}</div>}\n </SurfaceRow>\n );\n },\n { Controls: ExpandableRowControls },\n);\n\ninterface SurfaceComponent extends React.FC<SurfaceProps> {\n Row: React.FC<AnySurfaceRowProps>;\n ExpandableRow: typeof SurfaceExpandableRow;\n}\n\nconst Surface = (({\n children,\n padding = false,\n overflow = 'hidden',\n role,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className = '',\n style,\n}: SurfaceProps) => {\n // Literal class names (not interpolated) so Tailwind's JIT emits them.\n const overflowClass =\n overflow === 'clip'\n ? 'overflow-clip'\n : overflow === 'visible'\n ? 'overflow-visible'\n : 'overflow-hidden';\n return (\n <div\n className={`w-full rounded-[var(--malachite-radius-xxl,14px)] ${overflowClass} bg-[var(--malachite-card-background)] border border-solid border-[var(--malachite-card-border)] ${padding ? 'py-3 px-4' : ''} ${className}`}\n style={{ boxShadow: TRIPLE_SHADOW, ...FOREGROUND_RESET, ...style }}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </div>\n );\n}) as SurfaceComponent;\n\nSurface.Row = SurfaceRow;\nSurface.ExpandableRow = SurfaceExpandableRow;\n\nexport default Surface;\nexport { Surface, SurfaceRow, SurfaceExpandableRow };\n"],"names":["TONE_CLASSES","TONE_FOREGROUNDS","REVEALED_ON_INTERACTION","TRIPLE_SHADOW","SurfaceRow","props","children","divider","disabled","selected","selection","tone","className","style","asChild","onClick","rawHref","target","rel","trailing","revealTrailing","role","href","safeHref","ariaLabel","ariaLabelledBy","interactive","hover","tinted","chromeClasses","controlClasses","FOCUS_RING_INSET","classes","selectedStyle","SELECTED_ROW_BACKGROUND","SELECTED_ROW_FOREGROUND","SELECTED_ROW_ACCENT","SELECTED_TEXT_CONTEXT","toneForeground","rowStyle","ariaChecked","ariaCurrent","rowFallbackAria","paintOnChild","isRenderableNode","control","jsx","resolveRel","jsxs","ExpandableRowControls","event","EXPANDABLE_ROW_LEAD_PX","SurfaceExpandableRow","header","expanded","onToggle","sticky","stickyTopOffset","bodyId","React","toggle","DisclosureArrow","Surface","padding","overflow","FOREGROUND_RESET"],"mappings":";;;;;;;;;AA2FA,MAAMA,IAAqE;AAAA,EACvE,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AACX,GAUMC,IAAkF;AAAA,EACpF,SAAS;AAAA,EACT,OAAO;AACX,GAaMC,IACF,0KAEEC,IACF,yGASEC,IAA2C,CAACC,MAAU;AACxD,QAAM;AAAA,IACF,UAAAC;AAAA,IACA,SAAAC,IAAU;AAAA,IACV,UAAAC,IAAW;AAAA,IACX,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,WAAAC,IAAY;AAAA,IACZ,OAAAC;AAAA,EAAA,IACAR,GACES,IAAUT,EAAM,YAAY,IAC5B;AAAA,IACF,SAAAU;AAAA,IACA,MAAMC;AAAA,IACN,QAAAC;AAAA,IACA,KAAAC;AAAA,IACA,UAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,MAAAC;AAAA,EAAA,IACAP,IAAW,CAAA,IAA0BT,GAEnCiB,IAAOC,EAASP,CAAO,GACvBQ,IAAYV,IAAU,SAAaT,EAA0B,YAAY,GACzEoB,IAAiBX,IAAU,SAAaT,EAA0B,iBAAiB,GACnFqB,IAAc,GAAQX,KAAWO,IAEjCK,IACFnB,MAAakB,KAAeZ,KACtB,KACA,6EAKJc,IAASjB,MAAS,WAGlBkB,IAAgB;AAAA,IAClB;AAAA,IAHc7B,EAAaW,CAAI;AAAA,IAK/BJ,IAAU,gEAAgE;AAAA,IAC1EoB;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG,GAEPG,IAAiB;AAAA,IACnBJ,IACM,mBAAmBE,IAAS,KAAK,gBAAgB,QAAQG,CAAgB,KACzE;AAAA,IACNL,KAAe,CAAClB,IAAW,mBAAmB;AAAA,EAAA,EAE7C,OAAO,OAAO,EACd,KAAK,GAAG,GAEPwB,IAAU,CAACH,GAAeC,GAAgBlB,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAM7EqB,IACFxB,MAAa,OALFC,IAAYA,MAAc,cAAcW,MAAS,cAMtD;AAAA,IACI,iBAAiB,mBAAmBa,CAAuB,KAAKA,CAAuB;AAAA,IACvF,OAAOC;AAAA,IACP,WAAW,iBAAiBC,CAAmB;AAAA,IAC/C,GAAGC;AAAA,EAAA,IAEP,CAAA,GAEJC,IAAiBrC,EAAiBU,CAAI,GAUtC4B,IAAW,EAAE,GAToBD,IAChC;AAAA,IACG,OAAOA;AAAA,IACP,gCAAgCA;AAAA,EAAA,IAEpC,CAAA,GAI2B,GAAGL,GAAe,GAAGpB,EAAA,GAGhD2B,IACFnB,MAAS,cAAcZ,MAAa,UAC7B,UACDY,MAAS,WAAWA,MAAS,aAC3BZ,MAAa,KACb,QAGNgC,IAAcD,MAAgB,UAAa/B,MAAa,KAAO,KAAO,QAKtEiC,IAAkB;AAAA,IACpB,MAAArB;AAAA,IACA,gBAAgBmB;AAAA,IAChB,gBAAgBC;AAAA,IAChB,cAAcjB;AAAA,IACd,mBAAmBC;AAAA,IACnB,iBAAiBJ,KAAQb,IAAW,KAAO;AAAA,EAAA;AAG/C,MAAIM;AACA,WAAO6B,EAAarC,GAAU0B,GAASO,CAAQ;AAGnD,MAAIK,EAAiBzB,CAAQ,GAAG;AAC5B,UAAM0B,IACFvB,KAAQ,CAACd,IACL,gBAAAsC;AAAA,MAAC;AAAA,MAAA;AAAA,QACG,MAAAxB;AAAA,QACA,QAAAL;AAAA,QACA,KAAK8B,EAAW7B,GAAKD,CAAM;AAAA,QAC3B,SAAAF;AAAA,QACA,WAAW,GAAGe,CAAc;AAAA,QAC5B,MAAAT;AAAA,QACA,gBAAcmB;AAAA,QACd,gBAAcC;AAAA,QACd,cAAYjB;AAAA,QACZ,mBAAiBC;AAAA,QAEhB,UAAAnB;AAAA,MAAA;AAAA,IAAA,IAELS,IACA,gBAAA+B;AAAA,MAAC;AAAA,MAAA;AAAA,QACG,MAAK;AAAA,QACL,SAAA/B;AAAA,QACA,UAAAP;AAAA,QACA,WAAW,GAAGsB,CAAc;AAAA,QAC5B,MAAAT;AAAA,QACA,gBAAcmB;AAAA,QACd,gBAAcC;AAAA,QACd,cAAYjB;AAAA,QACZ,mBAAiBC;AAAA,QAEhB,UAAAnB;AAAA,MAAA;AAAA,IAAA;AAAA;AAAA;AAAA,wBAKJ,OAAA,EAAI,WAAU,kBAAkB,GAAGoC,GAC/B,UAAApC,EAAA,CACL;AAAA;AAGR,WACI,gBAAA0C;AAAA,MAAC;AAAA,MAAA;AAAA,QACG,WAAW;AAAA,UACPnB;AAAA,UACA;AAAA,UACAT,IAAiB,cAAc;AAAA,UAC/BR;AAAA,QAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,QACb,OAAO2B;AAAA,QAEN,UAAA;AAAA,UAAAM;AAAA,UACD,gBAAAC;AAAA,YAAC;AAAA,YAAA;AAAA,cACG,WAAW,8BAA8B1B,IAAiBlB,IAA0B,EAAE;AAAA,cAErF,UAAAiB;AAAA,YAAA;AAAA,UAAA;AAAA,QACL;AAAA,MAAA;AAAA,IAAA;AAAA,EAGZ;AAEA,SAAIG,KAAQ,CAACd,IAEL,gBAAAsC;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,MAAAxB;AAAA,MACA,QAAAL;AAAA,MACA,KAAK8B,EAAW7B,GAAKD,CAAM;AAAA,MAC3B,SAAAF;AAAA,MACA,WAAW,GAAGiB,CAAO;AAAA,MACrB,OAAOO;AAAA,MACP,MAAAlB;AAAA,MACA,gBAAcmB;AAAA,MACd,gBAAcC;AAAA,MACd,cAAYjB;AAAA,MACZ,mBAAiBC;AAAA,MAEhB,UAAAnB;AAAA,IAAA;AAAA,EAAA,IAKTS,IAEI,gBAAA+B;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,MAAK;AAAA,MACL,SAAA/B;AAAA,MACA,UAAAP;AAAA,MACA,WAAWwB;AAAA,MACX,OAAOO;AAAA,MACP,MAAAlB;AAAA,MACA,gBAAcmB;AAAA,MACd,gBAAcC;AAAA,MACd,cAAYjB;AAAA,MACZ,mBAAiBC;AAAA,MAEhB,UAAAnB;AAAA,IAAA;AAAA,EAAA,IAMT,gBAAAwC,EAAC,SAAI,WAAWd,GAAS,OAAOO,GAAW,GAAGG,GACzC,UAAApC,GACL;AAER,GAgCM2C,IAID,CAAC,EAAE,UAAA3C,GAAU,WAAAM,IAAY,IAAI,OAAAC,QAC9B,gBAAAiC,EAAC,OAAA,EAAI,WAAAlC,GAAsB,OAAAC,GAAc,SAAS,CAACqC,MAAUA,EAAM,gBAAA,GAC9D,UAAA5C,GACL,GAgBS6C,KAAyB,IAEhCC,KAEF,OAAO;AAAA,EACP,CAAC;AAAA,IACG,QAAAC;AAAA,IACA,UAAA/C;AAAA,IACA,UAAAgD;AAAA,IACA,UAAAC;AAAA,IACA,QAAAC,IAAS;AAAA,IACT,iBAAAC,IAAkB;AAAA,IAClB,SAAAlD,IAAU;AAAA,IACV,MAAAI,IAAO;AAAA,IACP,cAAca;AAAA,IACd,WAAAZ,IAAY;AAAA,IACZ,OAAAC;AAAA,EAAA,MAC6B;AAC7B,UAAM6C,IAASC,EAAM,MAAA,GACfC,IAASL,IAAW,MAAMA,EAAS,CAACD,CAAQ,IAAI;AAEtD,WACI,gBAAAN,EAAC5C,GAAA,EAAW,SAAAG,GAAkB,MAAAI,GAAY,WAAAC,GAAsB,OAAAC,GAE5D,UAAA;AAAA,MAAA,gBAAAmC;AAAA,QAAC;AAAA,QAAA;AAAA,UACG,WAAW,kCAAkCY,IAAS,mBAAmB,EAAE,IACvEJ,KAAUF,IACJ,uDACA,EACV;AAAA,UACA,OAAOE,KAAUF,IAAW,EAAE,KAAKG,MAAoB;AAAA,UAGvD,SAASG;AAAA,UACT,MAAK;AAAA,UAIL,UAAA;AAAA,YAAA,gBAAAd,EAAC,QAAA,EAAK,WAAU,kDACX,UAAAc,KACG,gBAAAd;AAAA,cAAC;AAAA,cAAA;AAAA,gBACG,MAAK;AAAA,gBACL,WAAW,gFAAgFf,CAAgB;AAAA,gBAC3G,iBAAeuB;AAAA,gBACf,iBAAeI;AAAA,gBACf,cAAYlC;AAAA,gBACZ,SAAS,CAAC0B,MAAU;AAChB,kBAAAA,EAAM,gBAAA,GACNU,EAAA;AAAA,gBACJ;AAAA,gBAEA,UAAA,gBAAAd,EAACe,KAAgB,UAAAP,EAAA,CAAoB;AAAA,cAAA;AAAA,YAAA,GAGjD;AAAA,YACCD;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAEJC,KAAY,gBAAAR,EAAC,OAAA,EAAI,IAAIY,GAAS,UAAApD,EAAA,CAAS;AAAA,IAAA,GAC5C;AAAA,EAER;AAAA,EACA,EAAE,UAAU2C,EAAA;AAChB,GAOMa,IAAW,CAAC;AAAA,EACd,UAAAxD;AAAA,EACA,SAAAyD,IAAU;AAAA,EACV,UAAAC,IAAW;AAAA,EACX,MAAA3C;AAAA,EACA,cAAcG;AAAA,EACd,mBAAmBC;AAAA,EACnB,WAAAb,IAAY;AAAA,EACZ,OAAAC;AACJ,MASQ,gBAAAiC;AAAA,EAAC;AAAA,EAAA;AAAA,IACG,WAAW,qDAPfkB,MAAa,SACP,kBACAA,MAAa,YACX,qBACA,iBAGyE,oGAAoGD,IAAU,cAAc,EAAE,IAAInD,CAAS;AAAA,IACxN,OAAO,EAAE,WAAWT,GAAe,GAAG8D,GAAkB,GAAGpD,EAAA;AAAA,IAC3D,MAAAQ;AAAA,IACA,cAAYG;AAAA,IACZ,mBAAiBC;AAAA,IAEhB,UAAAnB;AAAA,EAAA;AAAA;AAKbwD,EAAQ,MAAM1D;AACd0D,EAAQ,gBAAgBV;"}
|
|
1
|
+
{"version":3,"file":"Surface.js","sources":["../../src/components/Surface.tsx"],"sourcesContent":["import React from 'react';\nimport { paintOnChild } from './asChild';\nimport DisclosureArrow from './DisclosureArrow';\nimport { FOCUS_RING_INSET } from './focusRing';\nimport { resolveRel } from './linkRel';\nimport { safeHref } from './safeHref';\nimport { isRenderableNode } from './renderableNode';\nimport {\n FOREGROUND_RESET,\n SELECTED_ROW_ACCENT,\n SELECTED_ROW_BACKGROUND,\n SELECTED_ROW_FOREGROUND,\n SELECTED_TEXT_CONTEXT,\n} from './selectedRow';\n\nexport interface SurfaceProps {\n children?: React.ReactNode;\n padding?: boolean;\n /**\n * Content overflow. Defaults to `hidden` so children are clipped to the rounded\n * corners. Use `clip` to keep the rounded clipping WITHOUT creating a scroll\n * container — so a `position: sticky` descendant still pins (unlike `hidden`,\n * which traps it). `visible` disables clipping entirely.\n */\n overflow?: 'hidden' | 'visible' | 'clip';\n role?: React.AriaRole;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\ninterface SurfaceRowChromeProps {\n children?: React.ReactNode;\n /** Renders a bottom divider — omit on the last row in a Surface. */\n divider?: boolean;\n /** Removes the hover affordance / disables the control (e.g. while loading/busy). */\n disabled?: boolean;\n /** Announces the row as selected — `aria-checked` under a `radio`/`checkbox` role,\n * `aria-current` otherwise — and paints `Table`'s selected treatment unless `selection`\n * says not to. `'mixed'` is for a `checkbox` row that is partly selected: it announces\n * `aria-checked=\"mixed\"` there, never paints and never marks the row current, and counts\n * as not selected under any other role. */\n selected?: boolean | 'mixed';\n /** How a `selected` row shows it. `highlight` paints the treatment; `announce` leaves the\n * visual to a control inside the row and only sets the ARIA state. Defaults to `announce`\n * under `role=\"checkbox\"` and `highlight` otherwise. */\n selection?: 'highlight' | 'announce';\n /**\n * Tints the whole row by what it reports. `muted` is a row whose subject is inactive —\n * not disabled: it stays interactive. `success` and `error` are for a row that carries\n * an outcome, where the result belongs to the whole line rather than to one cell in it.\n */\n tone?: 'default' | 'muted' | 'success' | 'error';\n /** `compact` is an 8px by 16px inset the row owns. */\n inset?: 'none' | 'compact';\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst INSET_CLASSES: Record<NonNullable<SurfaceRowChromeProps['inset']>, string> = {\n none: '',\n compact: 'px-[16px] py-[8px]',\n};\n\n/** Stays an interface under its original name: a consumer may `extends` it. */\nexport interface SurfaceRowProps extends SurfaceRowChromeProps {\n asChild?: false;\n /**\n * When provided, the whole row becomes clickable: it renders as a `<button>`\n * (or `<a>` when `href` is set), so the entire row is the click target with\n * native focus + Enter/Space — no manual tabIndex/key handlers. For a\n * selectable row, put a presentational `<Radio>`/`<Checkbox>` inside as the\n * visual indicator; do NOT nest an interactive control (invalid + double tab stop).\n */\n onClick?: (event: React.MouseEvent) => void;\n /** Renders the clickable row as an anchor instead of a button. */\n href?: string;\n target?: React.HTMLAttributeAnchorTarget;\n rel?: string;\n /** Content pinned right, outside the row button, so it may hold its own control. */\n trailing?: React.ReactNode;\n /**\n * Shows `trailing` only while the row is hovered or holds focus, and while a menu\n * it opened is still open. Hidden by opacity, so it stays in the tab order; a touch screen,\n * which has no hover, always shows it.\n */\n revealTrailing?: boolean;\n /** ARIA role for a clickable row, e.g. `radio`/`checkbox` (wrap the list in a `radiogroup`). */\n role?: React.AriaRole;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\n/**\n * The outcome tones reuse the tag tokens rather than minting row ones, so a row saying \"this\n * passed\" and a tag saying it are the same green wherever the two sit together.\n */\nconst TONE_CLASSES: Record<NonNullable<SurfaceRowProps['tone']>, string> = {\n default: '',\n muted: 'bg-[var(--malachite-card-dimmed-background)]',\n success: 'bg-[var(--malachite-tag-success-background)]',\n error: 'bg-[var(--malachite-tag-error-background)]',\n};\n\n/**\n * The text an outcome tone carries with it, through the same context channel a selected row\n * uses, so `Typography` inside the row follows the tint instead of staying near-black on it.\n * `color` as well, for row content that is not Typography.\n *\n * Only the outcome tones. `muted` dims its subject rather than recolouring it, and its\n * foreground is the ordinary one.\n */\nconst TONE_FOREGROUNDS: Partial<Record<NonNullable<SurfaceRowProps['tone']>, string>> = {\n success: 'var(--malachite-tag-success-foreground)',\n error: 'var(--malachite-tag-error-foreground)',\n};\n\nexport interface SurfaceRowAsChildProps extends SurfaceRowChromeProps {\n asChild: true;\n children: React.ReactElement;\n}\n\nexport type AnySurfaceRowProps = SurfaceRowProps | SurfaceRowAsChildProps;\n\n// Not `group-hover` or `group-has-[:focus-visible]`: WebKit never applies the first (its\n// `@media (hover: hover)` nested in the group selector) nor the second inside a shadow root,\n// so the control stayed hidden in Safari. An open menu takes focus out of the row into a\n// portal, and would otherwise lose its trigger.\nconst REVEALED_ON_INTERACTION =\n 'opacity-0 transition-opacity group-[:hover]/row:opacity-100 group-focus-within/row:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100';\n\nconst TRIPLE_SHADOW =\n '0px 0px 4px 0px rgba(0,0,0,0.08), 0px 4px 4px 0px rgba(0,0,0,0.08), 0px 4px 10px 0px rgba(0,0,0,0.05)';\n\n/**\n * A single full-bleed row inside a <Surface>. Owns the row chrome — hover\n * highlight, colour transition and an optional bottom divider — so consumers\n * compose their own content inside without re-implementing design-system styling.\n * Pass `onClick`/`href` to make the entire row clickable (rendered as a real\n * button/anchor, so keyboard navigation works natively).\n */\nconst SurfaceRow: React.FC<AnySurfaceRowProps> = (props) => {\n const {\n children,\n divider = false,\n disabled = false,\n selected,\n selection,\n tone = 'default',\n inset = 'none',\n className = '',\n style,\n } = props;\n const asChild = props.asChild === true;\n const {\n onClick,\n href: rawHref,\n target,\n rel,\n trailing,\n revealTrailing,\n role,\n } = asChild ? ({} as SurfaceRowProps) : (props as SurfaceRowProps);\n // A rejected href (e.g. `javascript:`) leaves the row a button or a plain row, never an anchor.\n const href = safeHref(rawHref);\n const ariaLabel = asChild ? undefined : (props as SurfaceRowProps)['aria-label'];\n const ariaLabelledBy = asChild ? undefined : (props as SurfaceRowProps)['aria-labelledby'];\n const interactive = Boolean(onClick || href);\n // `asChild` is interactive for the hover affordance only, not the focus/reset classes.\n const hover =\n disabled && (interactive || asChild)\n ? ''\n : 'transition-colors hover:bg-[var(--malachite-buttonlist-hover-background)]';\n\n // A class, not an inline colour, which would outrank the hover utility. It replaces the\n // button reset's `bg-transparent` rather than joining it: same specificity, so the winner\n // would be whichever Tailwind emitted last.\n const tinted = tone !== 'default';\n const toneClass = TONE_CLASSES[tone];\n\n const hasTrailing = !asChild && isRenderableNode(trailing);\n const insetClass = INSET_CLASSES[inset];\n const controlPadding = insetClass && !hasTrailing ? '' : 'p-0';\n\n const chromeClasses = [\n 'w-full text-left border-0',\n toneClass,\n divider ? 'border-b border-solid border-[var(--malachite-card-border)]' : '',\n hover,\n ]\n .filter(Boolean)\n .join(' ');\n\n const controlClasses = [\n interactive\n ? `appearance-none ${tinted ? '' : 'bg-transparent'} ${controlPadding} ${FOCUS_RING_INSET}`\n : '',\n interactive && !disabled ? 'cursor-pointer' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const classes = [chromeClasses, controlClasses, hasTrailing ? '' : insetClass, className]\n .filter(Boolean)\n .join(' ');\n\n const paints = selection ? selection === 'highlight' : role !== 'checkbox';\n\n // A gradient layer so the tint composites over hover, and an inset shadow because\n // `ring-*` silently doesn't paint in a shadow root.\n const selectedStyle: React.CSSProperties =\n selected === true && paints\n ? {\n backgroundImage: `linear-gradient(${SELECTED_ROW_BACKGROUND}, ${SELECTED_ROW_BACKGROUND})`,\n color: SELECTED_ROW_FOREGROUND,\n boxShadow: `inset 2px 0 0 ${SELECTED_ROW_ACCENT}`,\n ...SELECTED_TEXT_CONTEXT,\n }\n : {};\n\n const toneForeground = TONE_FOREGROUNDS[tone];\n const toneStyle: React.CSSProperties = toneForeground\n ? ({\n color: toneForeground,\n '--malachite-ctx-text-primary': toneForeground,\n } as React.CSSProperties)\n : {};\n\n // `selected` last of the two: a row can be both, and selection is the state the reader is\n // acting on, so it wins the colour.\n const rowStyle = { ...toneStyle, ...selectedStyle, ...style };\n\n // Only a checkbox has a partly-checked state; a radio is chosen or not.\n const ariaChecked =\n role === 'checkbox' && selected === 'mixed'\n ? ('mixed' as const)\n : role === 'radio' || role === 'checkbox'\n ? selected === true\n : undefined;\n // `aria-current`, not `aria-pressed`: a selected row is one of many choices, not a toggle\n // (same call as `Dropdown`'s options). A role that carries its own state uses that instead.\n const ariaCurrent = ariaChecked === undefined && selected === true ? true : undefined;\n\n // Everything a control would have carried, for the branches that render none: the row\n // element is then the only thing assistive tech sees. `aria-disabled` because there is no\n // control to be natively disabled — and it is inert without a role, like the name.\n const rowFallbackAria = {\n role,\n 'aria-checked': ariaChecked,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-disabled': role && disabled ? true : undefined,\n };\n\n if (asChild) {\n return paintOnChild(children, classes, rowStyle);\n }\n\n if (hasTrailing) {\n const control =\n href && !disabled ? (\n <a\n href={href}\n target={target}\n rel={resolveRel(rel, target)}\n onClick={onClick}\n className={`${controlClasses} border-0 flex-1 min-w-0 text-left no-underline text-inherit`}\n role={role}\n aria-checked={ariaChecked}\n aria-current={ariaCurrent}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </a>\n ) : onClick ? (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className={`${controlClasses} border-0 flex-1 min-w-0 text-left`}\n role={role}\n aria-checked={ariaChecked}\n aria-current={ariaCurrent}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </button>\n ) : (\n // The set goes here, not on the wrapper: `radio` and `checkbox` make their\n // descendants presentational, which would bury a control in the trailing slot.\n <div className=\"flex-1 min-w-0\" {...rowFallbackAria}>\n {children}\n </div>\n );\n\n return (\n <div\n className={[\n chromeClasses,\n 'flex items-center',\n insetClass,\n revealTrailing ? 'group/row' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={rowStyle}\n >\n {control}\n <div\n className={`shrink-0 flex items-center ${revealTrailing ? REVEALED_ON_INTERACTION : ''}`}\n >\n {trailing}\n </div>\n </div>\n );\n }\n\n if (href && !disabled) {\n return (\n <a\n href={href}\n target={target}\n rel={resolveRel(rel, target)}\n onClick={onClick}\n className={`${classes} no-underline text-inherit`}\n style={rowStyle}\n role={role}\n aria-checked={ariaChecked}\n aria-current={ariaCurrent}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </a>\n );\n }\n\n if (onClick) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n className={classes}\n style={rowStyle}\n role={role}\n aria-checked={ariaChecked}\n aria-current={ariaCurrent}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </button>\n );\n }\n\n return (\n <div className={classes} style={rowStyle} {...rowFallbackAria}>\n {children}\n </div>\n );\n};\n\nexport interface SurfaceExpandableRowProps {\n /** The row itself, laid out across the line. May hold its own controls. */\n header: React.ReactNode;\n /** The body, rendered beneath the row while it is open. */\n children?: React.ReactNode;\n expanded: boolean;\n /** Omit for a row that cannot open. The arrow's space is still reserved, so a list of\n * rows stays in one column whether or not each one has a body. */\n onToggle?: (expanded: boolean) => void;\n /**\n * Pins the row while its body scrolls, so a long body never leaves the reader without\n * the line it belongs to. Offset by whatever is already pinned above it.\n */\n sticky?: boolean;\n stickyTopOffset?: number;\n divider?: boolean;\n tone?: SurfaceRowProps['tone'];\n /** Names the disclosure control, which is otherwise only an arrow. */\n 'aria-label'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Stops a click inside it from toggling the row, for the cells that hold controls.\n *\n * Explicit rather than sniffing the event's target for an interactive ancestor: a control\n * rendering into a shadow root retargets the event to its host, so the sniff would miss\n * exactly the components most likely to sit in a row.\n */\nconst ExpandableRowControls: React.FC<{\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}> = ({ children, className = '', style }) => (\n <div className={className} style={style} onClick={(event) => event.stopPropagation()}>\n {children}\n </div>\n);\n\n/**\n * A row that opens to reveal a body, for a line that carries its own controls.\n *\n * Not `Accordion`: that puts its header inside the toggle button, so a header holding a\n * dropdown or a second button is invalid. Here the row surface takes the click and a cell\n * opts out with `ExpandableRow.Controls`, while the arrow stays a real button so the\n * keyboard reaches it.\n */\n/**\n * The space before the header: the arrow's own inset, its glyph and the gap after it.\n * Exported so a consumer aligning a column header above these rows offsets by the same\n * amount instead of guessing at it.\n */\nexport const EXPANDABLE_ROW_LEAD_PX = 39;\n\nconst SurfaceExpandableRow: React.FC<SurfaceExpandableRowProps> & {\n Controls: typeof ExpandableRowControls;\n} = Object.assign(\n ({\n header,\n children,\n expanded,\n onToggle,\n sticky = false,\n stickyTopOffset = 0,\n divider = false,\n tone = 'default',\n 'aria-label': ariaLabel,\n className = '',\n style,\n }: SurfaceExpandableRowProps) => {\n const bodyId = React.useId();\n const toggle = onToggle ? () => onToggle(!expanded) : undefined;\n\n return (\n <SurfaceRow divider={divider} tone={tone} className={className} style={style}>\n {/* `group` so the arrow takes its hover state from the whole row. */}\n <div\n className={`group flex items-center w-full ${toggle ? 'cursor-pointer' : ''} ${\n sticky && expanded\n ? 'sticky z-[1] bg-[var(--malachite-card-background)]'\n : ''\n }`}\n style={sticky && expanded ? { top: stickyTopOffset } : undefined}\n // Presentational: the arrow below is the keyboard control, and this only\n // widens the pointer target.\n onClick={toggle}\n role=\"presentation\"\n >\n {/* Reserved whether or not this row opens, so a list stays in one column.\n The inset and gap match Accordion's header. */}\n <span className=\"shrink-0 flex items-center pl-[16px] pr-[12px]\">\n {toggle && (\n <button\n type=\"button\"\n className={`appearance-none bg-transparent border-0 p-0 flex items-center cursor-pointer ${FOCUS_RING_INSET}`}\n aria-expanded={expanded}\n aria-controls={bodyId}\n aria-label={ariaLabel}\n onClick={(event) => {\n event.stopPropagation();\n toggle();\n }}\n >\n <DisclosureArrow expanded={expanded} />\n </button>\n )}\n </span>\n {header}\n </div>\n {expanded && <div id={bodyId}>{children}</div>}\n </SurfaceRow>\n );\n },\n { Controls: ExpandableRowControls },\n);\n\ninterface SurfaceComponent extends React.FC<SurfaceProps> {\n Row: React.FC<AnySurfaceRowProps>;\n ExpandableRow: typeof SurfaceExpandableRow;\n}\n\nconst Surface = (({\n children,\n padding = false,\n overflow = 'hidden',\n role,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className = '',\n style,\n}: SurfaceProps) => {\n // Literal class names (not interpolated) so Tailwind's JIT emits them.\n const overflowClass =\n overflow === 'clip'\n ? 'overflow-clip'\n : overflow === 'visible'\n ? 'overflow-visible'\n : 'overflow-hidden';\n return (\n <div\n className={`w-full rounded-[var(--malachite-radius-xxl,14px)] ${overflowClass} bg-[var(--malachite-card-background)] border border-solid border-[var(--malachite-card-border)] ${padding ? 'py-3 px-4' : ''} ${className}`}\n style={{ boxShadow: TRIPLE_SHADOW, ...FOREGROUND_RESET, ...style }}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n >\n {children}\n </div>\n );\n}) as SurfaceComponent;\n\nSurface.Row = SurfaceRow;\nSurface.ExpandableRow = SurfaceExpandableRow;\n\nexport default Surface;\nexport { Surface, SurfaceRow, SurfaceExpandableRow };\n"],"names":["INSET_CLASSES","TONE_CLASSES","TONE_FOREGROUNDS","REVEALED_ON_INTERACTION","TRIPLE_SHADOW","SurfaceRow","props","children","divider","disabled","selected","selection","tone","inset","className","style","asChild","onClick","rawHref","target","rel","trailing","revealTrailing","role","href","safeHref","ariaLabel","ariaLabelledBy","interactive","hover","tinted","toneClass","hasTrailing","isRenderableNode","insetClass","controlPadding","chromeClasses","controlClasses","FOCUS_RING_INSET","classes","selectedStyle","SELECTED_ROW_BACKGROUND","SELECTED_ROW_FOREGROUND","SELECTED_ROW_ACCENT","SELECTED_TEXT_CONTEXT","toneForeground","rowStyle","ariaChecked","ariaCurrent","rowFallbackAria","paintOnChild","control","jsx","resolveRel","jsxs","ExpandableRowControls","event","EXPANDABLE_ROW_LEAD_PX","SurfaceExpandableRow","header","expanded","onToggle","sticky","stickyTopOffset","bodyId","React","toggle","DisclosureArrow","Surface","padding","overflow","FOREGROUND_RESET"],"mappings":"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"}
|
|
@@ -1,58 +1,65 @@
|
|
|
1
1
|
import { jsx as s } from "react/jsx-runtime";
|
|
2
|
-
const
|
|
2
|
+
const _ = 200, i = 160, x = 200, I = 260, b = 8, f = {
|
|
3
3
|
none: "",
|
|
4
4
|
compact: "px-[12px] py-[8px]",
|
|
5
5
|
default: "px-[16px] py-[12px]"
|
|
6
|
+
}, L = {
|
|
7
|
+
card: "bg-[var(--malachite-card-background)]",
|
|
8
|
+
page: "bg-[var(--malachite-card-sunken-background)]"
|
|
6
9
|
}, T = ({
|
|
7
|
-
children:
|
|
8
|
-
minWidth: e =
|
|
9
|
-
className:
|
|
10
|
-
style:
|
|
10
|
+
children: a,
|
|
11
|
+
minWidth: e = x,
|
|
12
|
+
className: t = "",
|
|
13
|
+
style: l
|
|
11
14
|
}) => /* @__PURE__ */ s(
|
|
12
15
|
"div",
|
|
13
16
|
{
|
|
14
|
-
className:
|
|
15
|
-
style: { flex: `100 1 ${
|
|
16
|
-
children:
|
|
17
|
+
className: t,
|
|
18
|
+
style: { flex: `100 1 ${I}px`, minWidth: e, ...l },
|
|
19
|
+
children: a
|
|
17
20
|
}
|
|
18
|
-
),
|
|
19
|
-
children:
|
|
20
|
-
width: e =
|
|
21
|
-
minWidth:
|
|
22
|
-
grow:
|
|
23
|
-
className:
|
|
21
|
+
), u = ({
|
|
22
|
+
children: a,
|
|
23
|
+
width: e = _,
|
|
24
|
+
minWidth: t = i,
|
|
25
|
+
grow: l = !0,
|
|
26
|
+
className: o = "",
|
|
24
27
|
style: r
|
|
25
|
-
}) => /* @__PURE__ */ s("div", { className:
|
|
26
|
-
children:
|
|
28
|
+
}) => /* @__PURE__ */ s("div", { className: o, style: { flex: `${l ? 1 : 0} 1 ${e}px`, minWidth: t, ...r }, children: a }), c = ({
|
|
29
|
+
children: a,
|
|
27
30
|
divider: e = !1,
|
|
28
|
-
padding:
|
|
29
|
-
layout:
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
padding: t = "default",
|
|
32
|
+
layout: l = "plain",
|
|
33
|
+
surface: o = "card",
|
|
34
|
+
sticky: r = !1,
|
|
35
|
+
className: n = "",
|
|
36
|
+
style: d
|
|
32
37
|
}) => {
|
|
33
|
-
const
|
|
34
|
-
"w-full
|
|
35
|
-
|
|
38
|
+
const p = [
|
|
39
|
+
"w-full",
|
|
40
|
+
L[o],
|
|
41
|
+
r ? "sticky top-0 z-10" : "",
|
|
42
|
+
f[t],
|
|
36
43
|
e ? "border-0 border-b border-solid border-[var(--malachite-card-border)]" : "",
|
|
37
|
-
|
|
44
|
+
n
|
|
38
45
|
].filter(Boolean).join(" ");
|
|
39
|
-
return /* @__PURE__ */ s("div", { className:
|
|
46
|
+
return /* @__PURE__ */ s("div", { className: p, style: { ...l === "filters" ? {
|
|
40
47
|
display: "flex",
|
|
41
48
|
alignItems: "center",
|
|
42
49
|
flexWrap: "wrap",
|
|
43
|
-
gap:
|
|
44
|
-
} : {}, ...
|
|
50
|
+
gap: b
|
|
51
|
+
} : {}, ...d }, children: a });
|
|
45
52
|
};
|
|
46
53
|
c.Fill = T;
|
|
47
|
-
c.Item =
|
|
54
|
+
c.Item = u;
|
|
48
55
|
export {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
I as TOOLBAR_FILL_BASIS_PX,
|
|
57
|
+
x as TOOLBAR_FILL_MIN_WIDTH_PX,
|
|
58
|
+
i as TOOLBAR_FILTER_MIN_WIDTH_PX,
|
|
59
|
+
_ as TOOLBAR_FILTER_WIDTH_PX,
|
|
53
60
|
c as Toolbar,
|
|
54
61
|
T as ToolbarFill,
|
|
55
|
-
|
|
62
|
+
u as ToolbarItem,
|
|
56
63
|
c as default
|
|
57
64
|
};
|
|
58
65
|
//# sourceMappingURL=Toolbar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.js","sources":["../../src/components/Toolbar.tsx"],"sourcesContent":["import React from 'react';\n\nexport const TOOLBAR_FILTER_WIDTH_PX = 200;\n\nexport const TOOLBAR_FILTER_MIN_WIDTH_PX = 160;\n\nexport const TOOLBAR_FILL_MIN_WIDTH_PX = 200;\n\nexport const TOOLBAR_FILL_BASIS_PX = 260;\n\nconst TOOLBAR_GAP_PX = 8;\n\nexport interface ToolbarProps {\n children?: React.ReactNode;\n /** Draw a bottom divider — for a bar that sits above scrolling/list content. */\n divider?: boolean;\n /** Padding preset (applies to both axes). `none` for a bar that must sit flush with\n * the content it pins over — the consumer then owns the gutter. */\n padding?: 'none' | 'compact' | 'default';\n layout?: 'plain' | 'filters';\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport interface ToolbarFillProps {\n children?: React.ReactNode;\n minWidth?: number;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport interface ToolbarItemProps {\n children?: React.ReactNode;\n width?: number;\n minWidth?: number;\n grow?: boolean;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst PADDING_CLASSES: Record<NonNullable<ToolbarProps['padding']>, string> = {\n none: '',\n compact: 'px-[12px] py-[8px]',\n default: 'px-[16px] py-[12px]',\n};\n\nconst ToolbarFill: React.FC<ToolbarFillProps> = ({\n children,\n minWidth = TOOLBAR_FILL_MIN_WIDTH_PX,\n className = '',\n style,\n}) => (\n <div\n className={className}\n style={{ flex: `100 1 ${TOOLBAR_FILL_BASIS_PX}px`, minWidth, ...style }}\n >\n {children}\n </div>\n);\n\nconst ToolbarItem: React.FC<ToolbarItemProps> = ({\n children,\n width = TOOLBAR_FILTER_WIDTH_PX,\n minWidth = TOOLBAR_FILTER_MIN_WIDTH_PX,\n grow = true,\n className = '',\n style,\n}) => (\n <div className={className} style={{ flex: `${grow ? 1 : 0} 1 ${width}px`, minWidth, ...style }}>\n {children}\n </div>\n);\n\ninterface ToolbarComponent extends React.FC<ToolbarProps> {\n Fill: typeof ToolbarFill;\n Item: typeof ToolbarItem;\n}\n\nconst Toolbar = (({\n children,\n divider = false,\n padding = 'default',\n layout = 'plain',\n className = '',\n style,\n}) => {\n const classes = [\n 'w-full
|
|
1
|
+
{"version":3,"file":"Toolbar.js","sources":["../../src/components/Toolbar.tsx"],"sourcesContent":["import React from 'react';\n\nexport const TOOLBAR_FILTER_WIDTH_PX = 200;\n\nexport const TOOLBAR_FILTER_MIN_WIDTH_PX = 160;\n\nexport const TOOLBAR_FILL_MIN_WIDTH_PX = 200;\n\nexport const TOOLBAR_FILL_BASIS_PX = 260;\n\nconst TOOLBAR_GAP_PX = 8;\n\nexport interface ToolbarProps {\n children?: React.ReactNode;\n /** Draw a bottom divider — for a bar that sits above scrolling/list content. */\n divider?: boolean;\n /** Padding preset (applies to both axes). `none` for a bar that must sit flush with\n * the content it pins over — the consumer then owns the gutter. */\n padding?: 'none' | 'compact' | 'default';\n layout?: 'plain' | 'filters';\n /** `page` paints the sunken page ground, for a bar that sits above a card. */\n surface?: 'card' | 'page';\n sticky?: boolean;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport interface ToolbarFillProps {\n children?: React.ReactNode;\n minWidth?: number;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport interface ToolbarItemProps {\n children?: React.ReactNode;\n width?: number;\n minWidth?: number;\n grow?: boolean;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst PADDING_CLASSES: Record<NonNullable<ToolbarProps['padding']>, string> = {\n none: '',\n compact: 'px-[12px] py-[8px]',\n default: 'px-[16px] py-[12px]',\n};\n\nconst SURFACE_CLASSES: Record<NonNullable<ToolbarProps['surface']>, string> = {\n card: 'bg-[var(--malachite-card-background)]',\n page: 'bg-[var(--malachite-card-sunken-background)]',\n};\n\nconst ToolbarFill: React.FC<ToolbarFillProps> = ({\n children,\n minWidth = TOOLBAR_FILL_MIN_WIDTH_PX,\n className = '',\n style,\n}) => (\n <div\n className={className}\n style={{ flex: `100 1 ${TOOLBAR_FILL_BASIS_PX}px`, minWidth, ...style }}\n >\n {children}\n </div>\n);\n\nconst ToolbarItem: React.FC<ToolbarItemProps> = ({\n children,\n width = TOOLBAR_FILTER_WIDTH_PX,\n minWidth = TOOLBAR_FILTER_MIN_WIDTH_PX,\n grow = true,\n className = '',\n style,\n}) => (\n <div className={className} style={{ flex: `${grow ? 1 : 0} 1 ${width}px`, minWidth, ...style }}>\n {children}\n </div>\n);\n\ninterface ToolbarComponent extends React.FC<ToolbarProps> {\n Fill: typeof ToolbarFill;\n Item: typeof ToolbarItem;\n}\n\nconst Toolbar = (({\n children,\n divider = false,\n padding = 'default',\n layout = 'plain',\n surface = 'card',\n sticky = false,\n className = '',\n style,\n}) => {\n const classes = [\n 'w-full',\n SURFACE_CLASSES[surface],\n sticky ? 'sticky top-0 z-10' : '',\n PADDING_CLASSES[padding],\n divider ? 'border-0 border-b border-solid border-[var(--malachite-card-border)]' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const layoutStyle: React.CSSProperties =\n layout === 'filters'\n ? {\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap',\n gap: TOOLBAR_GAP_PX,\n }\n : {};\n\n return (\n <div className={classes} style={{ ...layoutStyle, ...style }}>\n {children}\n </div>\n );\n}) as ToolbarComponent;\n\nToolbar.Fill = ToolbarFill;\nToolbar.Item = ToolbarItem;\n\nexport default Toolbar;\nexport { Toolbar, ToolbarFill, ToolbarItem };\n"],"names":["TOOLBAR_FILTER_WIDTH_PX","TOOLBAR_FILTER_MIN_WIDTH_PX","TOOLBAR_FILL_MIN_WIDTH_PX","TOOLBAR_FILL_BASIS_PX","TOOLBAR_GAP_PX","PADDING_CLASSES","SURFACE_CLASSES","ToolbarFill","children","minWidth","className","style","jsx","ToolbarItem","width","grow","Toolbar","divider","padding","layout","surface","sticky","classes"],"mappings":";AAEO,MAAMA,IAA0B,KAE1BC,IAA8B,KAE9BC,IAA4B,KAE5BC,IAAwB,KAE/BC,IAAiB,GAiCjBC,IAAwE;AAAA,EAC1E,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AACb,GAEMC,IAAwE;AAAA,EAC1E,MAAM;AAAA,EACN,MAAM;AACV,GAEMC,IAA0C,CAAC;AAAA,EAC7C,UAAAC;AAAA,EACA,UAAAC,IAAWP;AAAA,EACX,WAAAQ,IAAY;AAAA,EACZ,OAAAC;AACJ,MACI,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACG,WAAAF;AAAA,IACA,OAAO,EAAE,MAAM,SAASP,CAAqB,MAAM,UAAAM,GAAU,GAAGE,EAAA;AAAA,IAE/D,UAAAH;AAAA,EAAA;AACL,GAGEK,IAA0C,CAAC;AAAA,EAC7C,UAAAL;AAAA,EACA,OAAAM,IAAQd;AAAA,EACR,UAAAS,IAAWR;AAAA,EACX,MAAAc,IAAO;AAAA,EACP,WAAAL,IAAY;AAAA,EACZ,OAAAC;AACJ,wBACK,OAAA,EAAI,WAAAD,GAAsB,OAAO,EAAE,MAAM,GAAGK,IAAO,IAAI,CAAC,MAAMD,CAAK,MAAM,UAAAL,GAAU,GAAGE,EAAA,GAClF,UAAAH,EAAA,CACL,GAQEQ,IAAW,CAAC;AAAA,EACd,UAAAR;AAAA,EACA,SAAAS,IAAU;AAAA,EACV,SAAAC,IAAU;AAAA,EACV,QAAAC,IAAS;AAAA,EACT,SAAAC,IAAU;AAAA,EACV,QAAAC,IAAS;AAAA,EACT,WAAAX,IAAY;AAAA,EACZ,OAAAC;AACJ,MAAM;AACF,QAAMW,IAAU;AAAA,IACZ;AAAA,IACAhB,EAAgBc,CAAO;AAAA,IACvBC,IAAS,sBAAsB;AAAA,IAC/BhB,EAAgBa,CAAO;AAAA,IACvBD,IAAU,yEAAyE;AAAA,IACnFP;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAYb,SACI,gBAAAE,EAAC,OAAA,EAAI,WAAWU,GAAS,OAAO,EAAE,GAVlCH,MAAW,YACL;AAAA,IACI,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,KAAKf;AAAA,EAAA,IAET,CAAA,GAG4C,GAAGO,EAAA,GAChD,UAAAH,EAAA,CACL;AAER;AAEAQ,EAAQ,OAAOT;AACfS,EAAQ,OAAOH;"}
|
|
@@ -1,44 +1,46 @@
|
|
|
1
|
-
import { jsx as
|
|
1
|
+
import { jsx as n } from "react/jsx-runtime";
|
|
2
2
|
import { useRef as u } from "react";
|
|
3
|
-
import
|
|
4
|
-
import { getFontSize as
|
|
5
|
-
const
|
|
6
|
-
children:
|
|
3
|
+
import x from "../Tooltip.js";
|
|
4
|
+
import { getFontWeight as S, getFontSize as g, getTextColor as w } from "./textStyles.js";
|
|
5
|
+
const b = ({
|
|
6
|
+
children: s,
|
|
7
7
|
tooltip: t,
|
|
8
|
-
maxWidth:
|
|
9
|
-
color:
|
|
8
|
+
maxWidth: p = "100%",
|
|
9
|
+
color: c = "primary",
|
|
10
10
|
size: o,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
fontWeight: r,
|
|
12
|
+
tooltipWhenTruncated: f = !1,
|
|
13
|
+
tooltipPlacement: a,
|
|
14
|
+
className: m = "",
|
|
15
|
+
style: d = {}
|
|
15
16
|
}) => {
|
|
16
|
-
const
|
|
17
|
-
color:
|
|
18
|
-
...o ? { fontSize:
|
|
19
|
-
|
|
17
|
+
const h = {
|
|
18
|
+
color: w(c),
|
|
19
|
+
...o ? { fontSize: g(o) } : {},
|
|
20
|
+
...r ? { fontWeight: S(r) } : {},
|
|
21
|
+
maxWidth: p,
|
|
20
22
|
overflow: "hidden",
|
|
21
23
|
whiteSpace: "nowrap",
|
|
22
24
|
textOverflow: "ellipsis",
|
|
23
25
|
display: "inline-block",
|
|
24
26
|
verticalAlign: "top",
|
|
25
|
-
...
|
|
26
|
-
},
|
|
27
|
-
return t ? /* @__PURE__ */
|
|
28
|
-
|
|
27
|
+
...d
|
|
28
|
+
}, l = u(null), i = /* @__PURE__ */ n("span", { ref: l, className: m, style: h, children: s });
|
|
29
|
+
return t ? /* @__PURE__ */ n(
|
|
30
|
+
x,
|
|
29
31
|
{
|
|
30
32
|
text: t,
|
|
31
|
-
placement:
|
|
33
|
+
placement: a,
|
|
32
34
|
isShrinkable: !0,
|
|
33
|
-
shouldShow:
|
|
34
|
-
const e =
|
|
35
|
+
shouldShow: f ? () => {
|
|
36
|
+
const e = l.current;
|
|
35
37
|
return !!e && e.scrollWidth > e.clientWidth;
|
|
36
38
|
} : void 0,
|
|
37
|
-
children:
|
|
39
|
+
children: i
|
|
38
40
|
}
|
|
39
|
-
) :
|
|
41
|
+
) : i;
|
|
40
42
|
};
|
|
41
43
|
export {
|
|
42
|
-
|
|
44
|
+
b as default
|
|
43
45
|
};
|
|
44
46
|
//# sourceMappingURL=EllipsisText.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EllipsisText.js","sources":["../../../src/components/Typography/EllipsisText.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport Tooltip from '../Tooltip';\nimport type { TextColor } from './Text';\nimport type { FontSize } from './textStyles';\nimport { getFontSize, getTextColor } from './textStyles';\n\nexport interface EllipsisTextProps {\n children: React.ReactNode;\n tooltip?: React.ReactNode | string;\n /**\n * Defaults to filling the container. Pass a fixed width only when the text should\n * truncate before its container runs out of room (e.g. a column with a hard cap).\n */\n maxWidth?: string;\n color?: TextColor;\n size?: FontSize;\n /**\n * Show `tooltip` only when the text is actually cut off. Opt-in, because `tooltip` is any\n * node: a caller repeating the label wants this, and one supplying something the label does\n * not say — a full path, a timestamp — would lose it.\n */\n tooltipWhenTruncated?: boolean;\n tooltipPlacement?: 'top' | 'bottom' | 'left' | 'right';\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst EllipsisText: React.FC<EllipsisTextProps> = ({\n children,\n tooltip,\n maxWidth = '100%',\n color = 'primary',\n size,\n tooltipWhenTruncated = false,\n tooltipPlacement,\n className = '',\n style = {},\n}) => {\n const ellipsisStyles: React.CSSProperties = {\n color: getTextColor(color),\n ...(size ? { fontSize: getFontSize(size) } : {}),\n maxWidth,\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n display: 'inline-block',\n verticalAlign: 'top',\n ...style,\n };\n\n const textRef = useRef<HTMLSpanElement>(null);\n\n const textElement = (\n <span ref={textRef} className={className} style={ellipsisStyles}>\n {children}\n </span>\n );\n\n if (tooltip) {\n // Measured on hover, not at mount: what fits depends on the container and on webfonts\n // that land after `DOMContentLoaded`, so a value read once is wrong for the rest of the\n // page's life.\n // Without `isShrinkable` the tooltip wrapper is floored at min-content and a percentage `maxWidth` never truncates.\n return (\n <Tooltip\n text={tooltip}\n placement={tooltipPlacement}\n isShrinkable\n shouldShow={\n tooltipWhenTruncated\n ? () => {\n const node = textRef.current;\n return !!node && node.scrollWidth > node.clientWidth;\n }\n : undefined\n }\n >\n {textElement}\n </Tooltip>\n );\n }\n\n return textElement;\n};\n\nexport default EllipsisText;\n"],"names":["EllipsisText","children","tooltip","maxWidth","color","size","tooltipWhenTruncated","tooltipPlacement","className","style","ellipsisStyles","getTextColor","getFontSize","textRef","useRef","textElement","jsx","Tooltip","node"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"EllipsisText.js","sources":["../../../src/components/Typography/EllipsisText.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport Tooltip from '../Tooltip';\nimport type { TextColor } from './Text';\nimport type { FontSize, FontWeight } from './textStyles';\nimport { getFontSize, getFontWeight, getTextColor } from './textStyles';\n\nexport interface EllipsisTextProps {\n children: React.ReactNode;\n tooltip?: React.ReactNode | string;\n /**\n * Defaults to filling the container. Pass a fixed width only when the text should\n * truncate before its container runs out of room (e.g. a column with a hard cap).\n */\n maxWidth?: string;\n color?: TextColor;\n size?: FontSize;\n fontWeight?: FontWeight;\n /**\n * Show `tooltip` only when the text is actually cut off. Opt-in, because `tooltip` is any\n * node: a caller repeating the label wants this, and one supplying something the label does\n * not say — a full path, a timestamp — would lose it.\n */\n tooltipWhenTruncated?: boolean;\n tooltipPlacement?: 'top' | 'bottom' | 'left' | 'right';\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst EllipsisText: React.FC<EllipsisTextProps> = ({\n children,\n tooltip,\n maxWidth = '100%',\n color = 'primary',\n size,\n fontWeight,\n tooltipWhenTruncated = false,\n tooltipPlacement,\n className = '',\n style = {},\n}) => {\n const ellipsisStyles: React.CSSProperties = {\n color: getTextColor(color),\n ...(size ? { fontSize: getFontSize(size) } : {}),\n ...(fontWeight ? { fontWeight: getFontWeight(fontWeight) } : {}),\n maxWidth,\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: 'ellipsis',\n display: 'inline-block',\n verticalAlign: 'top',\n ...style,\n };\n\n const textRef = useRef<HTMLSpanElement>(null);\n\n const textElement = (\n <span ref={textRef} className={className} style={ellipsisStyles}>\n {children}\n </span>\n );\n\n if (tooltip) {\n // Measured on hover, not at mount: what fits depends on the container and on webfonts\n // that land after `DOMContentLoaded`, so a value read once is wrong for the rest of the\n // page's life.\n // Without `isShrinkable` the tooltip wrapper is floored at min-content and a percentage `maxWidth` never truncates.\n return (\n <Tooltip\n text={tooltip}\n placement={tooltipPlacement}\n isShrinkable\n shouldShow={\n tooltipWhenTruncated\n ? () => {\n const node = textRef.current;\n return !!node && node.scrollWidth > node.clientWidth;\n }\n : undefined\n }\n >\n {textElement}\n </Tooltip>\n );\n }\n\n return textElement;\n};\n\nexport default EllipsisText;\n"],"names":["EllipsisText","children","tooltip","maxWidth","color","size","fontWeight","tooltipWhenTruncated","tooltipPlacement","className","style","ellipsisStyles","getTextColor","getFontSize","getFontWeight","textRef","useRef","textElement","jsx","Tooltip","node"],"mappings":";;;;AA4BA,MAAMA,IAA4C,CAAC;AAAA,EAC/C,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,OAAAC,IAAQ;AAAA,EACR,MAAAC;AAAA,EACA,YAAAC;AAAA,EACA,sBAAAC,IAAuB;AAAA,EACvB,kBAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,OAAAC,IAAQ,CAAA;AACZ,MAAM;AACF,QAAMC,IAAsC;AAAA,IACxC,OAAOC,EAAaR,CAAK;AAAA,IACzB,GAAIC,IAAO,EAAE,UAAUQ,EAAYR,CAAI,EAAA,IAAM,CAAA;AAAA,IAC7C,GAAIC,IAAa,EAAE,YAAYQ,EAAcR,CAAU,EAAA,IAAM,CAAA;AAAA,IAC7D,UAAAH;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,SAAS;AAAA,IACT,eAAe;AAAA,IACf,GAAGO;AAAA,EAAA,GAGDK,IAAUC,EAAwB,IAAI,GAEtCC,sBACD,QAAA,EAAK,KAAKF,GAAS,WAAAN,GAAsB,OAAOE,GAC5C,UAAAV,GACL;AAGJ,SAAIC,IAMI,gBAAAgB;AAAA,IAACC;AAAA,IAAA;AAAA,MACG,MAAMjB;AAAA,MACN,WAAWM;AAAA,MACX,cAAY;AAAA,MACZ,YACID,IACM,MAAM;AACF,cAAMa,IAAOL,EAAQ;AACrB,eAAO,CAAC,CAACK,KAAQA,EAAK,cAAcA,EAAK;AAAA,MAC7C,IACA;AAAA,MAGT,UAAAH;AAAA,IAAA;AAAA,EAAA,IAKNA;AACX;"}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { jsx as i, jsxs as
|
|
1
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
2
2
|
import b from "marked-react";
|
|
3
3
|
import d from "react";
|
|
4
4
|
import { FOCUS_RING as E } from "../focusRing.js";
|
|
5
|
-
import
|
|
5
|
+
import p from "./CodeText.js";
|
|
6
6
|
import x from "./PageTitle.js";
|
|
7
7
|
import k from "./SectionTitle.js";
|
|
8
8
|
import { getInlineMarked as y } from "./inlineMarkdown.js";
|
|
9
9
|
import { getFontSize as L, getTextColor as R } from "./textStyles.js";
|
|
10
|
-
const _ = "• ",
|
|
10
|
+
const _ = "• ", N = {
|
|
11
11
|
color: "inherit",
|
|
12
12
|
textDecoration: "underline",
|
|
13
13
|
fontWeight: 600
|
|
14
|
-
},
|
|
14
|
+
}, S = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]), u = (e) => {
|
|
15
15
|
if (typeof e != "string")
|
|
16
16
|
return !1;
|
|
17
17
|
const r = /^([a-z][a-z0-9+.-]*):/i.exec(e.replace(/[\u0000-\u0020]/g, ""));
|
|
18
|
-
return !r ||
|
|
19
|
-
},
|
|
18
|
+
return !r || S.has(`${r[1].toLowerCase()}:`);
|
|
19
|
+
}, T = (e) => /^\/(?![/\\])[^\t\n\r]*$/.test(e), f = `md-link rounded-xs ${E}`, w = ({
|
|
20
20
|
omitMargin: e,
|
|
21
21
|
links: r,
|
|
22
22
|
renderLink: s
|
|
@@ -38,14 +38,22 @@ const _ = "• ", S = {
|
|
|
38
38
|
);
|
|
39
39
|
},
|
|
40
40
|
paragraph(t) {
|
|
41
|
-
return /* @__PURE__ */ i(
|
|
41
|
+
return /* @__PURE__ */ i(
|
|
42
|
+
"div",
|
|
43
|
+
{
|
|
44
|
+
className: "md-paragraph",
|
|
45
|
+
style: { marginBottom: e ? "0px" : "16px" },
|
|
46
|
+
children: t
|
|
47
|
+
},
|
|
48
|
+
this.elementId
|
|
49
|
+
);
|
|
42
50
|
},
|
|
43
51
|
codespan(t) {
|
|
44
|
-
return /* @__PURE__ */ i(
|
|
52
|
+
return /* @__PURE__ */ i(p, { variant: "inline", children: t }, this.elementId);
|
|
45
53
|
},
|
|
46
54
|
code(t) {
|
|
47
55
|
return /* @__PURE__ */ i("pre", { style: { margin: e ? 0 : "16px 0" }, children: /* @__PURE__ */ i(
|
|
48
|
-
|
|
56
|
+
p,
|
|
49
57
|
{
|
|
50
58
|
style: {
|
|
51
59
|
display: "block",
|
|
@@ -66,7 +74,7 @@ const _ = "• ", S = {
|
|
|
66
74
|
// `text`/`strong` are deliberately NOT overridden: a wrapping Text emits a font-weight, and
|
|
67
75
|
// the nested 400 beat strong's 600 — which is why bold never rendered.
|
|
68
76
|
link(t, n) {
|
|
69
|
-
return
|
|
77
|
+
return u(t) ? r === "inert" ? /* @__PURE__ */ i("span", { style: N, children: n }, this.elementId) : s && T(t) ? /* @__PURE__ */ i(d.Fragment, { children: s({ href: t, children: n, className: f }) }, this.elementId) : (
|
|
70
78
|
// Hover is in tailwind.css: CLAUDE.md forbids JS for styling, and JS misses keyboard.
|
|
71
79
|
// FOCUS_RING because a colour change alone is not a focus indicator.
|
|
72
80
|
/* @__PURE__ */ i(
|
|
@@ -84,7 +92,7 @@ const _ = "• ", S = {
|
|
|
84
92
|
},
|
|
85
93
|
// Overridden only to vet `src`. Alt text stands in for a rejected image.
|
|
86
94
|
image(t, n, l) {
|
|
87
|
-
return
|
|
95
|
+
return u(t) ? /* @__PURE__ */ i(
|
|
88
96
|
"img",
|
|
89
97
|
{
|
|
90
98
|
src: t,
|
|
@@ -119,14 +127,14 @@ const _ = "• ", S = {
|
|
|
119
127
|
}
|
|
120
128
|
}), F = () => ({
|
|
121
129
|
paragraph(e) {
|
|
122
|
-
return /* @__PURE__ */
|
|
130
|
+
return /* @__PURE__ */ a("span", { children: [
|
|
123
131
|
e,
|
|
124
132
|
" "
|
|
125
133
|
] }, this.elementId);
|
|
126
134
|
},
|
|
127
135
|
// Roles are pinned: without the real <h*> the heading leaves the a11y tree entirely.
|
|
128
136
|
heading(e, r) {
|
|
129
|
-
return /* @__PURE__ */
|
|
137
|
+
return /* @__PURE__ */ a(
|
|
130
138
|
"span",
|
|
131
139
|
{
|
|
132
140
|
role: "heading",
|
|
@@ -145,10 +153,10 @@ const _ = "• ", S = {
|
|
|
145
153
|
// Items OPEN with it, so tailwind.css suppresses the leading one on a first-child list.
|
|
146
154
|
list(e, r, s) {
|
|
147
155
|
const t = d.Children.toArray(e);
|
|
148
|
-
return /* @__PURE__ */
|
|
156
|
+
return /* @__PURE__ */ a("span", { role: "list", style: { display: "inline" }, children: [
|
|
149
157
|
t.map((n, l) => (
|
|
150
158
|
// Index as key: one list node's rendered children never reorder.
|
|
151
|
-
/* @__PURE__ */
|
|
159
|
+
/* @__PURE__ */ a("span", { role: "listitem", style: { display: "inline" }, children: [
|
|
152
160
|
/* @__PURE__ */ i("br", {}),
|
|
153
161
|
/* @__PURE__ */ i("span", { "aria-hidden": "true", children: r ? `${(s ?? 1) + l}. ` : _ }),
|
|
154
162
|
n
|
|
@@ -161,7 +169,7 @@ const _ = "• ", S = {
|
|
|
161
169
|
return /* @__PURE__ */ i(d.Fragment, { children: e }, this.elementId);
|
|
162
170
|
},
|
|
163
171
|
blockquote(e) {
|
|
164
|
-
return /* @__PURE__ */
|
|
172
|
+
return /* @__PURE__ */ a("span", { children: [
|
|
165
173
|
e,
|
|
166
174
|
" "
|
|
167
175
|
] }, this.elementId);
|
|
@@ -172,8 +180,8 @@ const _ = "• ", S = {
|
|
|
172
180
|
},
|
|
173
181
|
// Whitespace collapses, so a multi-line snippet becomes one run instead of the whole budget.
|
|
174
182
|
code(e) {
|
|
175
|
-
return /* @__PURE__ */
|
|
176
|
-
/* @__PURE__ */ i(
|
|
183
|
+
return /* @__PURE__ */ a(d.Fragment, { children: [
|
|
184
|
+
/* @__PURE__ */ i(p, { variant: "inline", children: e }),
|
|
177
185
|
" "
|
|
178
186
|
] }, this.elementId);
|
|
179
187
|
},
|
|
@@ -182,7 +190,7 @@ const _ = "• ", S = {
|
|
|
182
190
|
},
|
|
183
191
|
// Flattened to cell text: rows would each cost a line while carrying little at preview width.
|
|
184
192
|
table(e) {
|
|
185
|
-
return /* @__PURE__ */
|
|
193
|
+
return /* @__PURE__ */ a("span", { children: [
|
|
186
194
|
e,
|
|
187
195
|
" "
|
|
188
196
|
] }, this.elementId);
|
|
@@ -197,7 +205,7 @@ const _ = "• ", S = {
|
|
|
197
205
|
return /* @__PURE__ */ i("span", { children: e }, this.elementId);
|
|
198
206
|
},
|
|
199
207
|
tableCell(e) {
|
|
200
|
-
return /* @__PURE__ */
|
|
208
|
+
return /* @__PURE__ */ a("span", { children: [
|
|
201
209
|
e,
|
|
202
210
|
" "
|
|
203
211
|
] }, this.elementId);
|
|
@@ -235,13 +243,13 @@ const _ = "• ", S = {
|
|
|
235
243
|
let n = !0;
|
|
236
244
|
for (; ; ) {
|
|
237
245
|
h.lastIndex = 0;
|
|
238
|
-
let o = null,
|
|
239
|
-
for (;
|
|
240
|
-
if (
|
|
241
|
-
o =
|
|
246
|
+
let o = null, c = h.exec(s);
|
|
247
|
+
for (; c; ) {
|
|
248
|
+
if (c.index > 0) {
|
|
249
|
+
o = c;
|
|
242
250
|
break;
|
|
243
251
|
}
|
|
244
|
-
|
|
252
|
+
c = h.exec(s);
|
|
245
253
|
}
|
|
246
254
|
if (!o)
|
|
247
255
|
break;
|
|
@@ -292,18 +300,18 @@ const _ = "• ", S = {
|
|
|
292
300
|
variant: n = "block",
|
|
293
301
|
normalizeSource: l = !1,
|
|
294
302
|
links: o = "interactive",
|
|
295
|
-
renderLink:
|
|
303
|
+
renderLink: c
|
|
296
304
|
}) => {
|
|
297
305
|
const m = d.useMemo(
|
|
298
306
|
() => l ? H(I(e ?? "")) : I(e ?? ""),
|
|
299
307
|
[e, l]
|
|
300
308
|
), g = d.useMemo(
|
|
301
309
|
() => ({
|
|
302
|
-
...
|
|
310
|
+
...w({ omitMargin: t, links: o, renderLink: c }),
|
|
303
311
|
...n === "flow" ? F() : {},
|
|
304
312
|
...n === "inline" ? C() : {}
|
|
305
313
|
}),
|
|
306
|
-
[t, n, o,
|
|
314
|
+
[t, n, o, c]
|
|
307
315
|
);
|
|
308
316
|
return e ? /* @__PURE__ */ i(
|
|
309
317
|
n === "block" ? "div" : "span",
|