@stackone/malachite 2.32.0 → 2.33.1
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/dist/components/FieldMessage.js.map +1 -1
- package/dist/components/Input/Input.js +65 -58
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/SelectionBar.js +1 -1
- package/dist/components/SelectionBar.js.map +1 -1
- package/dist/components/SidePanel.js +60 -36
- package/dist/components/SidePanel.js.map +1 -1
- package/dist/components/TextArea/TextArea.js +1 -1
- package/dist/components/TextArea/TextArea.js.map +1 -1
- package/dist/components/Tooltip.js +57 -56
- package/dist/components/Tooltip.js.map +1 -1
- package/dist/components/Typography/CodeText.js +45 -22
- package/dist/components/Typography/CodeText.js.map +1 -1
- package/dist/components/Typography/EllipsisText.js +14 -12
- package/dist/components/Typography/EllipsisText.js.map +1 -1
- package/dist/components/selectionBarChrome.js +13 -13
- package/dist/components/selectionBarChrome.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.js","sources":["../../src/components/Tooltip.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId, useInsertionEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ensureOverlayStyles, overlayIdentity } from './portalOverlay';\nimport { useTopLayer } from './topLayer';\n\n// Split after each delimiter so long values (URLs, dotted paths) wrap at \"/\" or \".\"\n// instead of mid-token. <wbr> is copy-safe (a zero-width space would corrupt a copied\n// URL); overflow-wrap still handles a single run too long to fit.\nconst WRAP_AFTER = /(?<=[/\\\\.\\-_?&#=:@])/;\nconst withBreakOpportunities = (value: string): React.ReactNode =>\n value.split(WRAP_AFTER).map((chunk, i) => (\n <React.Fragment key={i}>\n {chunk}\n <wbr />\n </React.Fragment>\n ));\n\ninterface TooltipProps {\n text: React.ReactNode | string;\n children: React.ReactNode;\n delay?: number;\n wrapChildren?: boolean;\n placement?: 'top' | 'bottom' | 'left' | 'right';\n isShrinkable?: boolean;\n fill?: boolean;\n /** Max width of tooltip. Default: 320px */\n maxWidth?: number | string;\n /** Called synchronously when the trigger is hovered/focused; return false to\n * suppress the tooltip for this interaction. Lets wrappers defer expensive\n * checks (e.g. truncation measurement) to interaction time instead of mount. */\n shouldShow?: () => boolean;\n triggerAs?: 'div' | 'span';\n /** Whether the tooltip acts as the trigger's accessible description. False where the\n * trigger already points at the same sentence on screen, so it is not announced twice. */\n describesTrigger?: boolean;\n}\n\nconst SHRINKABLE_STYLE: React.CSSProperties = {\n minWidth: 0,\n overflow: 'hidden',\n};\n\nconst FILL_STYLE: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n};\n\n/** Kept clear of the viewport edge so a clamped tooltip does not sit flush against it. */\nconst VIEWPORT_MARGIN = 8;\n\nconst Tooltip: React.FC<TooltipProps> = ({\n text,\n children,\n delay = 1,\n wrapChildren = false,\n triggerAs = 'div',\n placement = 'top',\n isShrinkable = false,\n maxWidth = '320px',\n fill = false,\n shouldShow,\n describesTrigger = true,\n}) => {\n const triggerStyle =\n isShrinkable || fill\n ? { ...(isShrinkable ? SHRINKABLE_STYLE : {}), ...(fill ? FILL_STYLE : {}) }\n : undefined;\n\n const [isVisible, setIsVisible] = useState(false);\n // Portal mounts on first show, not on mount: an at-rest tooltip otherwise\n // costs a hidden document.body node plus a getBoundingClientRect per render —\n // multiplied by every row in a large table.\n const [hasShown, setHasShown] = useState(false);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showFrameRef = useRef<number | null>(null);\n\n const cancelPendingShow = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n showFrameRef.current = null;\n }\n }, []);\n\n const scheduleVisible = () => {\n // Two steps so the portal mounts hidden first and the fade-in transition\n // still runs on the very first show. The frame is tracked so leave/blur/\n // unmount can cancel a show that is already past its delay.\n setHasShown(true);\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n }\n showFrameRef.current = requestAnimationFrame(() => {\n showFrameRef.current = null;\n setIsVisible(true);\n });\n };\n const tooltipRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n\n // Tied to visibility, not mount: the node is latched into the DOM after its first show, and\n // re-entering on each show keeps a tooltip above the panel it is annotating.\n useTopLayer(tooltipRef, isVisible);\n\n const tooltipId = useId();\n\n const hasText = text !== null && text !== undefined && text !== '' && text !== false;\n\n const handleMouseEnter = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n if (!hasText || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n\n timeoutRef.current = setTimeout(() => {\n scheduleVisible();\n }, delay * 1000);\n };\n\n const handleMouseLeave = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n cancelPendingShow();\n setIsVisible(false);\n };\n\n const handleFocus = () => {\n if (!hasText || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n scheduleVisible();\n };\n\n const handleBlur = () => {\n cancelPendingShow();\n setIsVisible(false);\n };\n\n const [, forceUpdate] = useState({});\n\n useEffect(() => {\n // Only a VISIBLE tooltip needs to track scroll/resize; keeping global\n // listeners per mounted instance made every scroll event fan out across\n // every tooltip on the page.\n if (!isVisible) {\n return () => {\n cancelPendingShow();\n };\n }\n const handleUpdate = () => {\n forceUpdate({});\n };\n\n window.addEventListener('scroll', handleUpdate, true);\n window.addEventListener('resize', handleUpdate);\n\n return () => {\n cancelPendingShow();\n window.removeEventListener('scroll', handleUpdate, true);\n window.removeEventListener('resize', handleUpdate);\n };\n }, [isVisible, cancelPendingShow]);\n\n // The first render that mounts the tooltip has no measured width yet, so the clamp below\n // cannot run on it. One extra pass once it is in the DOM gives the clamp its measurement\n // — before the opacity transition finishes, so nothing is seen sliding into place.\n useEffect(() => {\n if (isVisible) {\n forceUpdate({});\n }\n }, [isVisible]);\n\n const getTooltipStyles = (): React.CSSProperties => {\n if (!triggerRef.current) {\n return { display: 'none' };\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n\n const baseStyles: React.CSSProperties = {\n position: 'fixed',\n display: 'flex',\n width: 'max-content',\n maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,\n minWidth: '32px',\n minHeight: '32px',\n padding: '8px 12px',\n alignItems: 'center',\n gap: '8px',\n borderRadius: '12px',\n backgroundColor: 'var(--malachite-tooltip-background, rgb(59, 59, 59))',\n color: 'var(--malachite-tooltip-foreground, rgb(255, 255, 255))',\n boxShadow: 'var(--malachite-tooltip-shadow, 0px 0px 10px 0px rgba(0, 0, 0, 0.20))',\n fontSize: '14px',\n lineHeight: '1.4',\n whiteSpace: 'normal',\n textAlign: 'left',\n pointerEvents: 'none',\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? 'visible' : 'hidden',\n transition:\n 'opacity 150ms ease-in-out, transform 150ms ease-in-out, visibility 150ms ease-in-out',\n };\n\n // A trigger near the viewport edge would otherwise centre a wide tooltip half off\n // screen, where the panel or the window crops it. Clamping the CENTRE keeps the\n // `translateX(-50%)` placement honest: the box stays put, it just stops short.\n const centeredLeft = (): number => {\n const desired = rect.left + rect.width / 2;\n const width = tooltipRef.current?.getBoundingClientRect().width ?? 0;\n\n if (width === 0) {\n return desired;\n }\n\n const half = width / 2;\n const min = VIEWPORT_MARGIN + half;\n const max = window.innerWidth - VIEWPORT_MARGIN - half;\n\n // A tooltip wider than the viewport has no in-bounds centre; leave it centred\n // rather than pinning it to a nonsensical one.\n return min > max ? desired : Math.min(Math.max(desired, min), max);\n };\n\n switch (placement) {\n case 'top':\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'bottom':\n return {\n ...baseStyles,\n top: rect.bottom + 8,\n left: centeredLeft(),\n transform: `translateX(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'left':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.left - 8,\n transform: `translate(-100%, -50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'right':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.right + 8,\n transform: `translateY(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n default:\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n }\n };\n\n // Only reference the tooltip id once the portal can exist — a dangling\n // aria-describedby (text set, never shown) confuses assistive tech.\n const describedBy = hasText && hasShown && describesTrigger ? tooltipId : undefined;\n useInsertionEffect(() => {\n if (hasText && hasShown) {\n ensureOverlayStyles();\n }\n }, [hasText, hasShown]);\n const renderedChildren =\n wrapChildren || !React.isValidElement(children) ? (\n <span aria-describedby={describedBy} style={fill ? FILL_STYLE : undefined}>\n {children}\n </span>\n ) : (\n React.cloneElement(children as React.ReactElement, {\n 'aria-describedby':\n [(children as React.ReactElement).props['aria-describedby'], describedBy]\n .filter(Boolean)\n .join(' ') || undefined,\n })\n );\n\n const Trigger = triggerAs;\n\n // Create the tooltip content without its own shadow root\n return (\n <>\n <Trigger\n ref={triggerRef}\n className=\"relative flex items-center\"\n style={triggerStyle}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {renderedChildren}\n </Trigger>\n\n {hasText &&\n hasShown &&\n createPortal(\n <div\n ref={tooltipRef}\n id={tooltipId}\n role=\"tooltip\"\n // Nothing references it, and the sentence is already on screen and\n // described: left in the tree it is a second copy to read past.\n aria-hidden={describesTrigger ? undefined : true}\n {...overlayIdentity('tooltip')}\n style={getTooltipStyles()}\n >\n {/* min-w-0 + overflow-wrap let long values wrap within maxWidth. */}\n <span\n style={{\n minWidth: 0,\n overflowWrap: 'anywhere',\n }}\n >\n {typeof text === 'string' ? withBreakOpportunities(text) : text}\n </span>\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport default Tooltip;\n"],"names":["WRAP_AFTER","withBreakOpportunities","value","chunk","i","jsxs","React","SHRINKABLE_STYLE","FILL_STYLE","VIEWPORT_MARGIN","Tooltip","text","children","delay","wrapChildren","triggerAs","placement","isShrinkable","maxWidth","fill","shouldShow","describesTrigger","triggerStyle","isVisible","setIsVisible","useState","hasShown","setHasShown","timeoutRef","useRef","showFrameRef","cancelPendingShow","useCallback","scheduleVisible","tooltipRef","triggerRef","useTopLayer","tooltipId","useId","hasText","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","forceUpdate","useEffect","handleUpdate","getTooltipStyles","rect","baseStyles","centeredLeft","desired","width","_a","half","min","max","describedBy","useInsertionEffect","ensureOverlayStyles","renderedChildren","jsx","Fragment","createPortal","overlayIdentity"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tooltip.js","sources":["../../src/components/Tooltip.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId, useInsertionEffect, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ensureOverlayStyles, overlayIdentity } from './portalOverlay';\nimport { useTopLayer } from './topLayer';\n\n// Split after each delimiter so long values (URLs, dotted paths) wrap at \"/\" or \".\"\n// instead of mid-token. <wbr> is copy-safe (a zero-width space would corrupt a copied\n// URL); overflow-wrap still handles a single run too long to fit.\nconst WRAP_AFTER = /(?<=[/\\\\.\\-_?&#=:@])/;\nconst withBreakOpportunities = (value: string): React.ReactNode =>\n value.split(WRAP_AFTER).map((chunk, i) => (\n <React.Fragment key={i}>\n {chunk}\n <wbr />\n </React.Fragment>\n ));\n\ninterface TooltipProps {\n text: React.ReactNode | string;\n children: React.ReactNode;\n delay?: number;\n wrapChildren?: boolean;\n placement?: 'top' | 'bottom' | 'left' | 'right';\n isShrinkable?: boolean;\n fill?: boolean;\n /** Max width of tooltip. Default: 320px */\n maxWidth?: number | string;\n /** Called synchronously when the trigger is hovered/focused; return false to\n * suppress the tooltip for this interaction. Lets wrappers defer expensive\n * checks (e.g. truncation measurement) to interaction time instead of mount. */\n shouldShow?: () => boolean;\n triggerAs?: 'div' | 'span';\n inline?: boolean;\n /** Whether the tooltip acts as the trigger's accessible description. False where the\n * trigger already points at the same sentence on screen, so it is not announced twice. */\n describesTrigger?: boolean;\n}\n\nconst SHRINKABLE_STYLE: React.CSSProperties = {\n minWidth: 0,\n overflow: 'hidden',\n};\n\nconst FILL_STYLE: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n};\n\n/** Kept clear of the viewport edge so a clamped tooltip does not sit flush against it. */\nconst VIEWPORT_MARGIN = 8;\n\nconst Tooltip: React.FC<TooltipProps> = ({\n text,\n children,\n delay = 1,\n wrapChildren = false,\n triggerAs = 'div',\n inline = false,\n placement = 'top',\n isShrinkable = false,\n maxWidth = '320px',\n fill = false,\n shouldShow,\n describesTrigger = true,\n}) => {\n const triggerStyle =\n isShrinkable || fill\n ? { ...(isShrinkable ? SHRINKABLE_STYLE : {}), ...(fill ? FILL_STYLE : {}) }\n : undefined;\n\n const [isVisible, setIsVisible] = useState(false);\n // Portal mounts on first show, not on mount: an at-rest tooltip otherwise\n // costs a hidden document.body node plus a getBoundingClientRect per render —\n // multiplied by every row in a large table.\n const [hasShown, setHasShown] = useState(false);\n const timeoutRef = useRef<NodeJS.Timeout | null>(null);\n const showFrameRef = useRef<number | null>(null);\n\n const cancelPendingShow = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n showFrameRef.current = null;\n }\n }, []);\n\n const scheduleVisible = () => {\n // Two steps so the portal mounts hidden first and the fade-in transition\n // still runs on the very first show. The frame is tracked so leave/blur/\n // unmount can cancel a show that is already past its delay.\n setHasShown(true);\n if (showFrameRef.current !== null) {\n cancelAnimationFrame(showFrameRef.current);\n }\n showFrameRef.current = requestAnimationFrame(() => {\n showFrameRef.current = null;\n setIsVisible(true);\n });\n };\n const tooltipRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n\n // Tied to visibility, not mount: the node is latched into the DOM after its first show, and\n // re-entering on each show keeps a tooltip above the panel it is annotating.\n useTopLayer(tooltipRef, isVisible);\n\n const tooltipId = useId();\n\n const hasText = text !== null && text !== undefined && text !== '' && text !== false;\n\n const handleMouseEnter = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n if (!hasText || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n\n timeoutRef.current = setTimeout(() => {\n scheduleVisible();\n }, delay * 1000);\n };\n\n const handleMouseLeave = (e: React.MouseEvent) => {\n e.stopPropagation();\n\n cancelPendingShow();\n setIsVisible(false);\n };\n\n const handleFocus = () => {\n if (!hasText || (shouldShow && !shouldShow())) {\n return;\n }\n\n cancelPendingShow();\n scheduleVisible();\n };\n\n const handleBlur = () => {\n cancelPendingShow();\n setIsVisible(false);\n };\n\n const [, forceUpdate] = useState({});\n\n useEffect(() => {\n // Only a VISIBLE tooltip needs to track scroll/resize; keeping global\n // listeners per mounted instance made every scroll event fan out across\n // every tooltip on the page.\n if (!isVisible) {\n return () => {\n cancelPendingShow();\n };\n }\n const handleUpdate = () => {\n forceUpdate({});\n };\n\n window.addEventListener('scroll', handleUpdate, true);\n window.addEventListener('resize', handleUpdate);\n\n return () => {\n cancelPendingShow();\n window.removeEventListener('scroll', handleUpdate, true);\n window.removeEventListener('resize', handleUpdate);\n };\n }, [isVisible, cancelPendingShow]);\n\n // The first render that mounts the tooltip has no measured width yet, so the clamp below\n // cannot run on it. One extra pass once it is in the DOM gives the clamp its measurement\n // — before the opacity transition finishes, so nothing is seen sliding into place.\n useEffect(() => {\n if (isVisible) {\n forceUpdate({});\n }\n }, [isVisible]);\n\n const getTooltipStyles = (): React.CSSProperties => {\n if (!triggerRef.current) {\n return { display: 'none' };\n }\n\n const rect = triggerRef.current.getBoundingClientRect();\n\n const baseStyles: React.CSSProperties = {\n position: 'fixed',\n display: 'flex',\n width: 'max-content',\n maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,\n minWidth: '32px',\n minHeight: '32px',\n padding: '8px 12px',\n alignItems: 'center',\n gap: '8px',\n borderRadius: '12px',\n backgroundColor: 'var(--malachite-tooltip-background, rgb(59, 59, 59))',\n color: 'var(--malachite-tooltip-foreground, rgb(255, 255, 255))',\n boxShadow: 'var(--malachite-tooltip-shadow, 0px 0px 10px 0px rgba(0, 0, 0, 0.20))',\n fontSize: '14px',\n lineHeight: '1.4',\n whiteSpace: 'normal',\n textAlign: 'left',\n pointerEvents: 'none',\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? 'visible' : 'hidden',\n transition:\n 'opacity 150ms ease-in-out, transform 150ms ease-in-out, visibility 150ms ease-in-out',\n };\n\n // A trigger near the viewport edge would otherwise centre a wide tooltip half off\n // screen, where the panel or the window crops it. Clamping the CENTRE keeps the\n // `translateX(-50%)` placement honest: the box stays put, it just stops short.\n const centeredLeft = (): number => {\n const desired = rect.left + rect.width / 2;\n const width = tooltipRef.current?.getBoundingClientRect().width ?? 0;\n\n if (width === 0) {\n return desired;\n }\n\n const half = width / 2;\n const min = VIEWPORT_MARGIN + half;\n const max = window.innerWidth - VIEWPORT_MARGIN - half;\n\n // A tooltip wider than the viewport has no in-bounds centre; leave it centred\n // rather than pinning it to a nonsensical one.\n return min > max ? desired : Math.min(Math.max(desired, min), max);\n };\n\n switch (placement) {\n case 'top':\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'bottom':\n return {\n ...baseStyles,\n top: rect.bottom + 8,\n left: centeredLeft(),\n transform: `translateX(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'left':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.left - 8,\n transform: `translate(-100%, -50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n case 'right':\n return {\n ...baseStyles,\n top: rect.top + rect.height / 2,\n left: rect.right + 8,\n transform: `translateY(-50%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n default:\n return {\n ...baseStyles,\n top: rect.top - 8,\n left: centeredLeft(),\n transform: `translate(-50%, -100%) ${isVisible ? 'scale(1)' : 'scale(0.95)'}`,\n };\n }\n };\n\n // Only reference the tooltip id once the portal can exist — a dangling\n // aria-describedby (text set, never shown) confuses assistive tech.\n const describedBy = hasText && hasShown && describesTrigger ? tooltipId : undefined;\n useInsertionEffect(() => {\n if (hasText && hasShown) {\n ensureOverlayStyles();\n }\n }, [hasText, hasShown]);\n const renderedChildren =\n wrapChildren || !React.isValidElement(children) ? (\n <span aria-describedby={describedBy} style={fill ? FILL_STYLE : undefined}>\n {children}\n </span>\n ) : (\n React.cloneElement(children as React.ReactElement, {\n 'aria-describedby':\n [(children as React.ReactElement).props['aria-describedby'], describedBy]\n .filter(Boolean)\n .join(' ') || undefined,\n })\n );\n\n const Trigger = inline ? 'span' : triggerAs;\n\n // Create the tooltip content without its own shadow root\n return (\n <>\n <Trigger\n ref={triggerRef}\n className={`relative ${inline ? 'inline-flex max-w-full align-middle' : 'flex'} items-center`}\n style={triggerStyle}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {renderedChildren}\n </Trigger>\n\n {hasText &&\n hasShown &&\n createPortal(\n <div\n ref={tooltipRef}\n id={tooltipId}\n role=\"tooltip\"\n // Nothing references it, and the sentence is already on screen and\n // described: left in the tree it is a second copy to read past.\n aria-hidden={describesTrigger ? undefined : true}\n {...overlayIdentity('tooltip')}\n style={getTooltipStyles()}\n >\n {/* min-w-0 + overflow-wrap let long values wrap within maxWidth. */}\n <span\n style={{\n minWidth: 0,\n overflowWrap: 'anywhere',\n }}\n >\n {typeof text === 'string' ? withBreakOpportunities(text) : text}\n </span>\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport default Tooltip;\n"],"names":["WRAP_AFTER","withBreakOpportunities","value","chunk","i","jsxs","React","SHRINKABLE_STYLE","FILL_STYLE","VIEWPORT_MARGIN","Tooltip","text","children","delay","wrapChildren","triggerAs","inline","placement","isShrinkable","maxWidth","fill","shouldShow","describesTrigger","triggerStyle","isVisible","setIsVisible","useState","hasShown","setHasShown","timeoutRef","useRef","showFrameRef","cancelPendingShow","useCallback","scheduleVisible","tooltipRef","triggerRef","useTopLayer","tooltipId","useId","hasText","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","forceUpdate","useEffect","handleUpdate","getTooltipStyles","rect","baseStyles","centeredLeft","desired","width","_a","half","min","max","describedBy","useInsertionEffect","ensureOverlayStyles","renderedChildren","jsx","Fragment","createPortal","overlayIdentity"],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
|
|
1
|
+
import { jsx as s } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as h } from "react";
|
|
3
|
+
import g from "../Tooltip.js";
|
|
4
|
+
const b = (e) => {
|
|
3
5
|
switch (e) {
|
|
4
6
|
case "xsmall":
|
|
5
7
|
return "12px";
|
|
@@ -16,34 +18,55 @@ const d = (e) => {
|
|
|
16
18
|
default:
|
|
17
19
|
return "14px";
|
|
18
20
|
}
|
|
19
|
-
},
|
|
21
|
+
}, S = ({
|
|
20
22
|
bold: e = !1,
|
|
21
|
-
children:
|
|
22
|
-
size:
|
|
23
|
-
hasBorder:
|
|
24
|
-
variant:
|
|
23
|
+
children: o,
|
|
24
|
+
size: c = "small",
|
|
25
|
+
hasBorder: r = !1,
|
|
26
|
+
variant: d = "block",
|
|
25
27
|
// Deliberately NOT `inherit`: secondary prose would drop the chip to 3.65:1 in dark mode,
|
|
26
28
|
// under AA's 4.5:1. Pinning primary measures 18.5:1 light / 9.4:1 dark.
|
|
27
|
-
color:
|
|
28
|
-
backgroundColor:
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
color: p = "var(--malachite-text-primary)",
|
|
30
|
+
backgroundColor: x,
|
|
31
|
+
truncate: l = !1,
|
|
32
|
+
className: m = "",
|
|
33
|
+
style: f = {}
|
|
31
34
|
}) => {
|
|
32
|
-
const
|
|
35
|
+
const a = h(null), t = d === "inline", u = {
|
|
33
36
|
fontFamily: "var(--malachite-font-mono, monospace)",
|
|
34
|
-
fontSize:
|
|
37
|
+
fontSize: t ? "0.9em" : b(c),
|
|
35
38
|
fontWeight: e ? 600 : 400,
|
|
36
|
-
color:
|
|
37
|
-
backgroundColor:
|
|
38
|
-
borderRadius:
|
|
39
|
-
border:
|
|
40
|
-
padding:
|
|
39
|
+
color: p,
|
|
40
|
+
backgroundColor: r ? "transparent" : x || "var(--malachite-card-dimmed-background, #f5f5f5)",
|
|
41
|
+
borderRadius: t ? "4px" : "8px",
|
|
42
|
+
border: r ? "none" : "1px solid var(--malachite-card-border, #e8e8e8)",
|
|
43
|
+
padding: r ? "0px" : t ? "0 4px" : "4px 8px",
|
|
41
44
|
display: "inline",
|
|
42
|
-
...
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
...l ? {
|
|
46
|
+
display: "inline-block",
|
|
47
|
+
maxWidth: "100%",
|
|
48
|
+
overflow: "hidden",
|
|
49
|
+
textOverflow: "ellipsis",
|
|
50
|
+
whiteSpace: "nowrap",
|
|
51
|
+
lineHeight: 1.35
|
|
52
|
+
} : {},
|
|
53
|
+
...f
|
|
54
|
+
}, i = /* @__PURE__ */ s("code", { ref: a, className: m, style: u, children: o });
|
|
55
|
+
return l ? /* @__PURE__ */ s(
|
|
56
|
+
g,
|
|
57
|
+
{
|
|
58
|
+
text: o,
|
|
59
|
+
inline: !0,
|
|
60
|
+
isShrinkable: !0,
|
|
61
|
+
shouldShow: () => {
|
|
62
|
+
const n = a.current;
|
|
63
|
+
return !!n && n.scrollWidth > n.clientWidth;
|
|
64
|
+
},
|
|
65
|
+
children: i
|
|
66
|
+
}
|
|
67
|
+
) : i;
|
|
45
68
|
};
|
|
46
69
|
export {
|
|
47
|
-
|
|
70
|
+
S as default
|
|
48
71
|
};
|
|
49
72
|
//# sourceMappingURL=CodeText.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeText.js","sources":["../../../src/components/Typography/CodeText.tsx"],"sourcesContent":["import React from 'react';\nimport type { FontSize } from './Text';\n\nconst getFontSize = (size: FontSize): string => {\n switch (size) {\n case 'xsmall':\n return '12px';\n case 'small':\n return '14px';\n case 'medium':\n return '16px';\n case 'large':\n return '18px';\n case 'xlarge':\n return '20px';\n case 'xxlarge':\n return '24px';\n default:\n return '14px';\n }\n};\n\nexport type CodeTextVariant = 'block' | 'inline';\n\nexport interface CodeTextProps {\n bold?: boolean;\n size?: FontSize;\n hasBorder?: boolean;\n variant?: CodeTextVariant;\n color?: string;\n backgroundColor?: string;\n children: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst CodeText: React.FC<CodeTextProps> = ({\n bold = false,\n children,\n size = 'small',\n hasBorder = false,\n variant = 'block',\n // Deliberately NOT `inherit`: secondary prose would drop the chip to 3.65:1 in dark mode,\n // under AA's 4.5:1. Pinning primary measures 18.5:1 light / 9.4:1 dark.\n color = 'var(--malachite-text-primary)',\n backgroundColor,\n className = '',\n style = {},\n}) => {\n const isInline = variant === 'inline';\n const codeStyles: React.CSSProperties = {\n fontFamily: 'var(--malachite-font-mono, monospace)',\n fontSize: isInline ? '0.9em' : getFontSize(size),\n fontWeight: bold ? 600 : 400,\n color,\n backgroundColor: hasBorder\n ? 'transparent'\n : backgroundColor || 'var(--malachite-card-dimmed-background, #f5f5f5)',\n borderRadius: isInline ? '4px' : '8px',\n border: hasBorder ? 'none' : '1px solid var(--malachite-card-border, #e8e8e8)',\n padding: hasBorder ? '0px' : isInline ? '0 4px' : '4px 8px',\n display: 'inline',\n ...style,\n };\n\n
|
|
1
|
+
{"version":3,"file":"CodeText.js","sources":["../../../src/components/Typography/CodeText.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport Tooltip from '../Tooltip';\nimport type { FontSize } from './Text';\n\nconst getFontSize = (size: FontSize): string => {\n switch (size) {\n case 'xsmall':\n return '12px';\n case 'small':\n return '14px';\n case 'medium':\n return '16px';\n case 'large':\n return '18px';\n case 'xlarge':\n return '20px';\n case 'xxlarge':\n return '24px';\n default:\n return '14px';\n }\n};\n\nexport type CodeTextVariant = 'block' | 'inline';\n\nexport interface CodeTextProps {\n bold?: boolean;\n size?: FontSize;\n hasBorder?: boolean;\n variant?: CodeTextVariant;\n color?: string;\n backgroundColor?: string;\n children: React.ReactNode;\n truncate?: boolean;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst CodeText: React.FC<CodeTextProps> = ({\n bold = false,\n children,\n size = 'small',\n hasBorder = false,\n variant = 'block',\n // Deliberately NOT `inherit`: secondary prose would drop the chip to 3.65:1 in dark mode,\n // under AA's 4.5:1. Pinning primary measures 18.5:1 light / 9.4:1 dark.\n color = 'var(--malachite-text-primary)',\n backgroundColor,\n truncate = false,\n className = '',\n style = {},\n}) => {\n const codeRef = useRef<HTMLElement>(null);\n const isInline = variant === 'inline';\n const codeStyles: React.CSSProperties = {\n fontFamily: 'var(--malachite-font-mono, monospace)',\n fontSize: isInline ? '0.9em' : getFontSize(size),\n fontWeight: bold ? 600 : 400,\n color,\n backgroundColor: hasBorder\n ? 'transparent'\n : backgroundColor || 'var(--malachite-card-dimmed-background, #f5f5f5)',\n borderRadius: isInline ? '4px' : '8px',\n border: hasBorder ? 'none' : '1px solid var(--malachite-card-border, #e8e8e8)',\n padding: hasBorder ? '0px' : isInline ? '0 4px' : '4px 8px',\n display: 'inline',\n ...(truncate\n ? {\n display: 'inline-block',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n lineHeight: 1.35,\n }\n : {}),\n ...style,\n };\n\n const code = (\n <code ref={codeRef} className={className} style={codeStyles}>\n {children}\n </code>\n );\n\n if (!truncate) {\n return code;\n }\n\n return (\n <Tooltip\n text={children}\n inline\n isShrinkable\n shouldShow={() => {\n const node = codeRef.current;\n return !!node && node.scrollWidth > node.clientWidth;\n }}\n >\n {code}\n </Tooltip>\n );\n};\n\nexport default CodeText;\n"],"names":["getFontSize","size","CodeText","bold","children","hasBorder","variant","color","backgroundColor","truncate","className","style","codeRef","useRef","isInline","codeStyles","code","jsx","Tooltip","node"],"mappings":";;;AAIA,MAAMA,IAAc,CAACC,MAA2B;AAC5C,UAAQA,GAAA;AAAA,IACJ,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX;AACI,aAAO;AAAA,EAAA;AAEnB,GAiBMC,IAAoC,CAAC;AAAA,EACvC,MAAAC,IAAO;AAAA,EACP,UAAAC;AAAA,EACA,MAAAH,IAAO;AAAA,EACP,WAAAI,IAAY;AAAA,EACZ,SAAAC,IAAU;AAAA;AAAA;AAAA,EAGV,OAAAC,IAAQ;AAAA,EACR,iBAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,WAAAC,IAAY;AAAA,EACZ,OAAAC,IAAQ,CAAA;AACZ,MAAM;AACF,QAAMC,IAAUC,EAAoB,IAAI,GAClCC,IAAWR,MAAY,UACvBS,IAAkC;AAAA,IACpC,YAAY;AAAA,IACZ,UAAUD,IAAW,UAAUd,EAAYC,CAAI;AAAA,IAC/C,YAAYE,IAAO,MAAM;AAAA,IACzB,OAAAI;AAAA,IACA,iBAAiBF,IACX,gBACAG,KAAmB;AAAA,IACzB,cAAcM,IAAW,QAAQ;AAAA,IACjC,QAAQT,IAAY,SAAS;AAAA,IAC7B,SAASA,IAAY,QAAQS,IAAW,UAAU;AAAA,IAClD,SAAS;AAAA,IACT,GAAIL,IACE;AAAA,MACI,SAAS;AAAA,MACT,UAAU;AAAA,MACV,UAAU;AAAA,MACV,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA,IAEhB,CAAA;AAAA,IACN,GAAGE;AAAA,EAAA,GAGDK,sBACD,QAAA,EAAK,KAAKJ,GAAS,WAAAF,GAAsB,OAAOK,GAC5C,UAAAX,GACL;AAGJ,SAAKK,IAKD,gBAAAQ;AAAA,IAACC;AAAA,IAAA;AAAA,MACG,MAAMd;AAAA,MACN,QAAM;AAAA,MACN,cAAY;AAAA,MACZ,YAAY,MAAM;AACd,cAAMe,IAAOP,EAAQ;AACrB,eAAO,CAAC,CAACO,KAAQA,EAAK,cAAcA,EAAK;AAAA,MAC7C;AAAA,MAEC,UAAAH;AAAA,IAAA;AAAA,EAAA,IAbEA;AAgBf;"}
|
|
@@ -1,32 +1,34 @@
|
|
|
1
1
|
import { jsx as i } from "react/jsx-runtime";
|
|
2
|
-
import { useRef as
|
|
3
|
-
import
|
|
4
|
-
import { getFontSize as
|
|
5
|
-
const
|
|
2
|
+
import { useRef as u } from "react";
|
|
3
|
+
import h from "../Tooltip.js";
|
|
4
|
+
import { getFontSize as x, getTextColor as S } from "./textStyles.js";
|
|
5
|
+
const T = ({
|
|
6
6
|
children: n,
|
|
7
7
|
tooltip: t,
|
|
8
8
|
maxWidth: s = "100%",
|
|
9
9
|
color: p = "primary",
|
|
10
10
|
size: o,
|
|
11
11
|
tooltipWhenTruncated: c = !1,
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
tooltipPlacement: f,
|
|
13
|
+
className: a = "",
|
|
14
|
+
style: m = {}
|
|
14
15
|
}) => {
|
|
15
16
|
const d = {
|
|
16
|
-
color:
|
|
17
|
-
...o ? { fontSize:
|
|
17
|
+
color: S(p),
|
|
18
|
+
...o ? { fontSize: x(o) } : {},
|
|
18
19
|
maxWidth: s,
|
|
19
20
|
overflow: "hidden",
|
|
20
21
|
whiteSpace: "nowrap",
|
|
21
22
|
textOverflow: "ellipsis",
|
|
22
23
|
display: "inline-block",
|
|
23
24
|
verticalAlign: "top",
|
|
24
|
-
...
|
|
25
|
-
}, r =
|
|
25
|
+
...m
|
|
26
|
+
}, r = u(null), l = /* @__PURE__ */ i("span", { ref: r, className: a, style: d, children: n });
|
|
26
27
|
return t ? /* @__PURE__ */ i(
|
|
27
|
-
|
|
28
|
+
h,
|
|
28
29
|
{
|
|
29
30
|
text: t,
|
|
31
|
+
placement: f,
|
|
30
32
|
isShrinkable: !0,
|
|
31
33
|
shouldShow: c ? () => {
|
|
32
34
|
const e = r.current;
|
|
@@ -37,6 +39,6 @@ const g = ({
|
|
|
37
39
|
) : l;
|
|
38
40
|
};
|
|
39
41
|
export {
|
|
40
|
-
|
|
42
|
+
T as default
|
|
41
43
|
};
|
|
42
44
|
//# 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 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 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 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","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 } 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":";;;;AA2BA,MAAMA,IAA4C,CAAC;AAAA,EAC/C,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,OAAAC,IAAQ;AAAA,EACR,MAAAC;AAAA,EACA,sBAAAC,IAAuB;AAAA,EACvB,kBAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,OAAAC,IAAQ,CAAA;AACZ,MAAM;AACF,QAAMC,IAAsC;AAAA,IACxC,OAAOC,EAAaP,CAAK;AAAA,IACzB,GAAIC,IAAO,EAAE,UAAUO,EAAYP,CAAI,EAAA,IAAM,CAAA;AAAA,IAC7C,UAAAF;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,SAAS;AAAA,IACT,eAAe;AAAA,IACf,GAAGM;AAAA,EAAA,GAGDI,IAAUC,EAAwB,IAAI,GAEtCC,sBACD,QAAA,EAAK,KAAKF,GAAS,WAAAL,GAAsB,OAAOE,GAC5C,UAAAT,GACL;AAGJ,SAAIC,IAMI,gBAAAc;AAAA,IAACC;AAAA,IAAA;AAAA,MACG,MAAMf;AAAA,MACN,WAAWK;AAAA,MACX,cAAY;AAAA,MACZ,YACID,IACM,MAAM;AACF,cAAMY,IAAOL,EAAQ;AACrB,eAAO,CAAC,CAACK,KAAQA,EAAK,cAAcA,EAAK;AAAA,MAC7C,IACA;AAAA,MAGT,UAAAH;AAAA,IAAA;AAAA,EAAA,IAKNA;AACX;"}
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { FOCUS_RING_SELECTION_BAR as a } from "./focusRing.js";
|
|
2
|
-
const o = 180,
|
|
3
|
-
.${
|
|
2
|
+
const o = 180, r = "malachite-selection-bar-track", e = "malachite-selection-bar-btn", i = "malachite-selection-bar", n = `
|
|
3
|
+
.${r} {
|
|
4
4
|
transition: opacity ${o}ms ease-out;
|
|
5
5
|
}
|
|
6
6
|
@media (prefers-reduced-motion: reduce) {
|
|
7
|
-
.${
|
|
7
|
+
.${r} {
|
|
8
8
|
transition: none;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
.${
|
|
11
|
+
.${e}--primary {
|
|
12
12
|
background-color: var(--malachite-selection-bar-foreground);
|
|
13
13
|
color: var(--malachite-selection-bar-background);
|
|
14
14
|
border: 1px solid var(--malachite-selection-bar-primary-border);
|
|
15
15
|
box-shadow: var(--malachite-shadow-default, 0px 1px 0px 0px rgba(0, 0, 0, 0.15));
|
|
16
16
|
}
|
|
17
|
-
.${
|
|
17
|
+
.${e}--primary:hover:not(:disabled) {
|
|
18
18
|
background-image: linear-gradient(
|
|
19
19
|
color-mix(in srgb, var(--malachite-selection-bar-foreground) 88%, var(--malachite-selection-bar-background)),
|
|
20
20
|
color-mix(in srgb, var(--malachite-selection-bar-foreground) 88%, var(--malachite-selection-bar-background))
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
|
-
.${
|
|
23
|
+
.${e}--secondary {
|
|
24
24
|
background-color: var(--malachite-selection-bar-divider);
|
|
25
25
|
background-image: linear-gradient(
|
|
26
26
|
color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background)),
|
|
@@ -28,28 +28,28 @@ const o = 180, e = "malachite-selection-bar-track", r = "malachite-selection-bar
|
|
|
28
28
|
);
|
|
29
29
|
color: var(--malachite-selection-bar-foreground);
|
|
30
30
|
}
|
|
31
|
-
.${
|
|
31
|
+
.${e}--secondary:hover:not(:disabled) {
|
|
32
32
|
background-image: linear-gradient(
|
|
33
33
|
color-mix(in srgb, var(--malachite-selection-bar-foreground) 30%, var(--malachite-selection-bar-background)),
|
|
34
34
|
color-mix(in srgb, var(--malachite-selection-bar-foreground) 30%, var(--malachite-selection-bar-background))
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
|
-
.${
|
|
37
|
+
.${e}--quiet {
|
|
38
38
|
background-color: transparent;
|
|
39
39
|
color: var(--malachite-selection-bar-foreground);
|
|
40
40
|
}
|
|
41
|
-
.${
|
|
41
|
+
.${e}--quiet:hover:not(:disabled) {
|
|
42
42
|
background-image: linear-gradient(
|
|
43
43
|
color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background)),
|
|
44
44
|
color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background))
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
|
-
`, c = `${
|
|
47
|
+
`, c = `${e} inline-flex h-7 shrink-0 cursor-pointer items-center gap-1.5 whitespace-nowrap rounded-[10px] border border-solid border-transparent px-[10px] text-[13px] font-medium disabled:cursor-not-allowed disabled:opacity-50 ${a}`, l = "flex items-center justify-center gap-2 rounded-2xl border border-solid border-[var(--malachite-selection-bar-border)] py-[6px] pl-[12px] pr-[6px] bg-[var(--malachite-selection-bar-background)] text-[var(--malachite-selection-bar-foreground)]", s = "var(--malachite-selection-bar-shadow)", d = "flex flex-col items-stretch gap-[2px] rounded-2xl p-[2px] bg-[var(--malachite-selection-bar-notice-background)]", b = "var(--malachite-selection-bar-notice-shadow)", m = "m-0 px-[12px] py-[8px] text-center text-[13px] font-medium leading-normal text-[var(--malachite-selection-bar-notice-foreground)]", g = "shrink-0 select-none text-[13px]", u = "text-[var(--malachite-selection-bar-muted-foreground)]";
|
|
48
48
|
export {
|
|
49
49
|
c as PILL_BUTTON_BASE,
|
|
50
|
-
|
|
50
|
+
e as PILL_BUTTON_CLASS,
|
|
51
51
|
g as PILL_DIVIDER,
|
|
52
|
-
|
|
52
|
+
u as PILL_MUTED_TEXT,
|
|
53
53
|
b as PILL_NOTICE_SHADOW,
|
|
54
54
|
d as PILL_NOTICE_SLEEVE,
|
|
55
55
|
m as PILL_NOTICE_TEXT,
|
|
@@ -57,7 +57,7 @@ export {
|
|
|
57
57
|
n as PILL_SHEET_CSS,
|
|
58
58
|
i as PILL_SHEET_ID,
|
|
59
59
|
l as PILL_SURFACE,
|
|
60
|
-
|
|
60
|
+
r as PILL_TRACK_CLASS,
|
|
61
61
|
o as PILL_TRANSITION_MS
|
|
62
62
|
};
|
|
63
63
|
//# sourceMappingURL=selectionBarChrome.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectionBarChrome.js","sources":["../../src/components/selectionBarChrome.ts"],"sourcesContent":["import { FOCUS_RING_SELECTION_BAR } from './focusRing';\n\n/** A `value + label` pair, e.g. `{ value: 3, label: 'Added' }`. */\nexport interface SelectionBarCount {\n value: string | number;\n label: string;\n}\n\nexport type SelectionBarEmphasis = 'primary' | 'secondary' | 'quiet';\n\nexport const PILL_TRANSITION_MS = 180;\n\nexport const PILL_TRACK_CLASS = 'malachite-selection-bar-track';\nexport const PILL_BUTTON_CLASS = 'malachite-selection-bar-btn';\nexport const PILL_SHEET_ID = 'malachite-selection-bar';\n\nexport const PILL_SHEET_CSS = `\n.${PILL_TRACK_CLASS} {\n transition: opacity ${PILL_TRANSITION_MS}ms ease-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .${PILL_TRACK_CLASS} {\n transition: none;\n }\n}\n.${PILL_BUTTON_CLASS}--primary {\n background-color: var(--malachite-selection-bar-foreground);\n color: var(--malachite-selection-bar-background);\n border: 1px solid var(--malachite-selection-bar-primary-border);\n box-shadow: var(--malachite-shadow-default, 0px 1px 0px 0px rgba(0, 0, 0, 0.15));\n}\n.${PILL_BUTTON_CLASS}--primary:hover:not(:disabled) {\n background-image: linear-gradient(\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 88%, var(--malachite-selection-bar-background)),\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 88%, var(--malachite-selection-bar-background))\n );\n}\n.${PILL_BUTTON_CLASS}--secondary {\n background-color: var(--malachite-selection-bar-divider);\n background-image: linear-gradient(\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background)),\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background))\n );\n color: var(--malachite-selection-bar-foreground);\n}\n.${PILL_BUTTON_CLASS}--secondary:hover:not(:disabled) {\n background-image: linear-gradient(\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 30%, var(--malachite-selection-bar-background)),\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 30%, var(--malachite-selection-bar-background))\n );\n}\n.${PILL_BUTTON_CLASS}--quiet {\n background-color: transparent;\n color: var(--malachite-selection-bar-foreground);\n}\n.${PILL_BUTTON_CLASS}--quiet:hover:not(:disabled) {\n background-image: linear-gradient(\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background)),\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background))\n );\n}\n`;\n\nexport const PILL_BUTTON_BASE = `${PILL_BUTTON_CLASS} inline-flex h-7 shrink-0 cursor-pointer items-center gap-1.5 whitespace-nowrap rounded-[10px] border border-solid border-transparent px-[10px] text-[13px] font-medium disabled:cursor-not-allowed disabled:opacity-50 ${FOCUS_RING_SELECTION_BAR}`;\n\nexport const PILL_SURFACE =\n 'flex items-center gap-2 rounded-2xl border border-solid border-[var(--malachite-selection-bar-border)] py-[6px] pl-[12px] pr-[6px] bg-[var(--malachite-selection-bar-background)] text-[var(--malachite-selection-bar-foreground)]';\n\nexport const PILL_SHADOW = 'var(--malachite-selection-bar-shadow)';\n\n/** The sleeve a `notice` wraps the pill in: the pill keeps its own surface inside it. */\nexport const PILL_NOTICE_SLEEVE =\n 'flex flex-col items-stretch gap-[2px] rounded-2xl p-[2px] bg-[var(--malachite-selection-bar-notice-background)]';\n\nexport const PILL_NOTICE_SHADOW = 'var(--malachite-selection-bar-notice-shadow)';\n\nexport const PILL_NOTICE_TEXT =\n 'm-0 px-[12px] py-[8px] text-center text-[13px] font-medium leading-normal text-[var(--malachite-selection-bar-notice-foreground)]';\n\nexport const PILL_DIVIDER = 'shrink-0 select-none text-[13px]';\n\nexport const PILL_MUTED_TEXT = 'text-[var(--malachite-selection-bar-muted-foreground)]';\n"],"names":["PILL_TRANSITION_MS","PILL_TRACK_CLASS","PILL_BUTTON_CLASS","PILL_SHEET_ID","PILL_SHEET_CSS","PILL_BUTTON_BASE","FOCUS_RING_SELECTION_BAR","PILL_SURFACE","PILL_SHADOW","PILL_NOTICE_SLEEVE","PILL_NOTICE_SHADOW","PILL_NOTICE_TEXT","PILL_DIVIDER","PILL_MUTED_TEXT"],"mappings":";AAUO,MAAMA,IAAqB,KAErBC,IAAmB,iCACnBC,IAAoB,+BACpBC,IAAgB,2BAEhBC,IAAiB;AAAA,GAC3BH,CAAgB;AAAA,0BACOD,CAAkB;AAAA;AAAA;AAAA,OAGrCC,CAAgB;AAAA;AAAA;AAAA;AAAA,GAIpBC,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMjBA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMjBA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQjBA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMjBA,CAAiB;AAAA;AAAA;AAAA;AAAA,GAIjBA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQPG,IAAmB,GAAGH,CAAiB,2NAA2NI,CAAwB,IAE1RC,IACT,
|
|
1
|
+
{"version":3,"file":"selectionBarChrome.js","sources":["../../src/components/selectionBarChrome.ts"],"sourcesContent":["import { FOCUS_RING_SELECTION_BAR } from './focusRing';\n\n/** A `value + label` pair, e.g. `{ value: 3, label: 'Added' }`. */\nexport interface SelectionBarCount {\n value: string | number;\n label: string;\n}\n\nexport type SelectionBarEmphasis = 'primary' | 'secondary' | 'quiet';\n\nexport const PILL_TRANSITION_MS = 180;\n\nexport const PILL_TRACK_CLASS = 'malachite-selection-bar-track';\nexport const PILL_BUTTON_CLASS = 'malachite-selection-bar-btn';\nexport const PILL_SHEET_ID = 'malachite-selection-bar';\n\nexport const PILL_SHEET_CSS = `\n.${PILL_TRACK_CLASS} {\n transition: opacity ${PILL_TRANSITION_MS}ms ease-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .${PILL_TRACK_CLASS} {\n transition: none;\n }\n}\n.${PILL_BUTTON_CLASS}--primary {\n background-color: var(--malachite-selection-bar-foreground);\n color: var(--malachite-selection-bar-background);\n border: 1px solid var(--malachite-selection-bar-primary-border);\n box-shadow: var(--malachite-shadow-default, 0px 1px 0px 0px rgba(0, 0, 0, 0.15));\n}\n.${PILL_BUTTON_CLASS}--primary:hover:not(:disabled) {\n background-image: linear-gradient(\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 88%, var(--malachite-selection-bar-background)),\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 88%, var(--malachite-selection-bar-background))\n );\n}\n.${PILL_BUTTON_CLASS}--secondary {\n background-color: var(--malachite-selection-bar-divider);\n background-image: linear-gradient(\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background)),\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background))\n );\n color: var(--malachite-selection-bar-foreground);\n}\n.${PILL_BUTTON_CLASS}--secondary:hover:not(:disabled) {\n background-image: linear-gradient(\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 30%, var(--malachite-selection-bar-background)),\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 30%, var(--malachite-selection-bar-background))\n );\n}\n.${PILL_BUTTON_CLASS}--quiet {\n background-color: transparent;\n color: var(--malachite-selection-bar-foreground);\n}\n.${PILL_BUTTON_CLASS}--quiet:hover:not(:disabled) {\n background-image: linear-gradient(\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background)),\n color-mix(in srgb, var(--malachite-selection-bar-foreground) 16%, var(--malachite-selection-bar-background))\n );\n}\n`;\n\nexport const PILL_BUTTON_BASE = `${PILL_BUTTON_CLASS} inline-flex h-7 shrink-0 cursor-pointer items-center gap-1.5 whitespace-nowrap rounded-[10px] border border-solid border-transparent px-[10px] text-[13px] font-medium disabled:cursor-not-allowed disabled:opacity-50 ${FOCUS_RING_SELECTION_BAR}`;\n\nexport const PILL_SURFACE =\n 'flex items-center justify-center gap-2 rounded-2xl border border-solid border-[var(--malachite-selection-bar-border)] py-[6px] pl-[12px] pr-[6px] bg-[var(--malachite-selection-bar-background)] text-[var(--malachite-selection-bar-foreground)]';\n\nexport const PILL_SHADOW = 'var(--malachite-selection-bar-shadow)';\n\n/** The sleeve a `notice` wraps the pill in: the pill keeps its own surface inside it. */\nexport const PILL_NOTICE_SLEEVE =\n 'flex flex-col items-stretch gap-[2px] rounded-2xl p-[2px] bg-[var(--malachite-selection-bar-notice-background)]';\n\nexport const PILL_NOTICE_SHADOW = 'var(--malachite-selection-bar-notice-shadow)';\n\nexport const PILL_NOTICE_TEXT =\n 'm-0 px-[12px] py-[8px] text-center text-[13px] font-medium leading-normal text-[var(--malachite-selection-bar-notice-foreground)]';\n\nexport const PILL_DIVIDER = 'shrink-0 select-none text-[13px]';\n\nexport const PILL_MUTED_TEXT = 'text-[var(--malachite-selection-bar-muted-foreground)]';\n"],"names":["PILL_TRANSITION_MS","PILL_TRACK_CLASS","PILL_BUTTON_CLASS","PILL_SHEET_ID","PILL_SHEET_CSS","PILL_BUTTON_BASE","FOCUS_RING_SELECTION_BAR","PILL_SURFACE","PILL_SHADOW","PILL_NOTICE_SLEEVE","PILL_NOTICE_SHADOW","PILL_NOTICE_TEXT","PILL_DIVIDER","PILL_MUTED_TEXT"],"mappings":";AAUO,MAAMA,IAAqB,KAErBC,IAAmB,iCACnBC,IAAoB,+BACpBC,IAAgB,2BAEhBC,IAAiB;AAAA,GAC3BH,CAAgB;AAAA,0BACOD,CAAkB;AAAA;AAAA;AAAA,OAGrCC,CAAgB;AAAA;AAAA;AAAA;AAAA,GAIpBC,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMjBA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMjBA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQjBA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMjBA,CAAiB;AAAA;AAAA;AAAA;AAAA,GAIjBA,CAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQPG,IAAmB,GAAGH,CAAiB,2NAA2NI,CAAwB,IAE1RC,IACT,qPAESC,IAAc,yCAGdC,IACT,mHAESC,IAAqB,gDAErBC,IACT,qIAESC,IAAe,oCAEfC,IAAkB;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -939,6 +939,7 @@ export declare interface CodeTextProps {
|
|
|
939
939
|
color?: string;
|
|
940
940
|
backgroundColor?: string;
|
|
941
941
|
children: default_2.ReactNode;
|
|
942
|
+
truncate?: boolean;
|
|
942
943
|
className?: string;
|
|
943
944
|
style?: default_2.CSSProperties;
|
|
944
945
|
}
|
|
@@ -1415,6 +1416,7 @@ declare interface EllipsisTextProps {
|
|
|
1415
1416
|
* not say — a full path, a timestamp — would lose it.
|
|
1416
1417
|
*/
|
|
1417
1418
|
tooltipWhenTruncated?: boolean;
|
|
1419
|
+
tooltipPlacement?: 'top' | 'bottom' | 'left' | 'right';
|
|
1418
1420
|
className?: string;
|
|
1419
1421
|
style?: default_2.CSSProperties;
|
|
1420
1422
|
}
|
|
@@ -2474,7 +2476,7 @@ declare interface InputProps {
|
|
|
2474
2476
|
/** Controlled value, for a source of truth outside the form (URL, app state). */
|
|
2475
2477
|
value?: string;
|
|
2476
2478
|
onBlur?: () => void;
|
|
2477
|
-
helperText?:
|
|
2479
|
+
helperText?: default_2.ReactNode;
|
|
2478
2480
|
showPasswordToggle?: boolean;
|
|
2479
2481
|
id?: string;
|
|
2480
2482
|
'aria-label'?: string;
|
|
@@ -4462,7 +4464,7 @@ declare interface TextAreaProps {
|
|
|
4462
4464
|
inFieldAction?: default_2.ReactNode;
|
|
4463
4465
|
/** See `TextAreaTone`. Defaults to `'default'`, so no existing field changes. */
|
|
4464
4466
|
tone?: TextAreaTone;
|
|
4465
|
-
helperText?:
|
|
4467
|
+
helperText?: default_2.ReactNode;
|
|
4466
4468
|
rows?: number;
|
|
4467
4469
|
/**
|
|
4468
4470
|
* Grows the field from `rows` up to this many lines as content is typed, then scrolls
|
|
@@ -4640,6 +4642,7 @@ declare interface TooltipProps {
|
|
|
4640
4642
|
* checks (e.g. truncation measurement) to interaction time instead of mount. */
|
|
4641
4643
|
shouldShow?: () => boolean;
|
|
4642
4644
|
triggerAs?: 'div' | 'span';
|
|
4645
|
+
inline?: boolean;
|
|
4643
4646
|
/** Whether the tooltip acts as the trigger's accessible description. False where the
|
|
4644
4647
|
* trigger already points at the same sentence on screen, so it is not announced twice. */
|
|
4645
4648
|
describesTrigger?: boolean;
|