@stackone/malachite 2.53.0 → 2.55.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 +4 -3
- package/dist/components/ActionMenu.js +141 -134
- package/dist/components/ActionMenu.js.map +1 -1
- package/dist/components/FilterSearch.js +572 -0
- package/dist/components/FilterSearch.js.map +1 -0
- package/dist/components/PageLayout/regularLayout.js +58 -61
- package/dist/components/PageLayout/regularLayout.js.map +1 -1
- package/dist/components/Tag.js +22 -21
- package/dist/components/Tag.js.map +1 -1
- package/dist/components/Tooltip.js +97 -93
- package/dist/components/Tooltip.js.map +1 -1
- package/dist/components/actionMenuStyles.js +28 -19
- package/dist/components/actionMenuStyles.js.map +1 -1
- package/dist/components/filterSearchModel.js +76 -0
- package/dist/components/filterSearchModel.js.map +1 -0
- package/dist/components/filterSearchStyles.js +28 -0
- package/dist/components/filterSearchStyles.js.map +1 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.js +407 -405
- package/dist/index.js.map +1 -1
- package/dist/tailwind.css.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterSearch.js","sources":["../../src/components/FilterSearch.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useId,\n useInsertionEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport CaretDownIcon from './CustomIcons/CaretDownIcon';\nimport CheckmarkIcon from './CustomIcons/CheckmarkIcon';\nimport DismissIcon from './CustomIcons/DismissIcon';\nimport SearchIcon from './CustomIcons/SearchIcon';\nimport Spinner from './Spinner';\nimport { CONTROL_TEXT_SIZE, CONTROL_TEXT_SIZE_CLASS, type ControlSize } from './controlTextSize';\nimport { type ControlWidth, controlWidthStyle } from './controlWidth';\nimport { DROPDOWN_TRIGGER_ATTR, getTriggerVisual } from './dropdownTriggerStyle';\nimport { pushEscapeLayer } from './escapeLayers';\nimport {\n type FilterSearchChange,\n type FilterSearchFilter,\n type FilterSearchItemRow,\n type FilterSearchSelection,\n type FilterSearchToggle,\n type FilterSearchUpdate,\n chipText,\n clearAll,\n deselectAll,\n filterRows,\n orderSelections,\n removeFilter,\n resolveMode,\n searchRows,\n selectAll,\n toggleValue,\n} from './filterSearchModel';\nimport { FILTER_SEARCH_CLASS, ensureFilterSearchStyles } from './filterSearchStyles';\nimport {\n MENU_MAX_HEIGHT_PX,\n MENU_SPECS,\n type MenuGeometry,\n measureMenuGeometry,\n} from './floatingMenuGeometry';\nimport { FOCUS_RING } from './focusRing';\nimport { usePopupLayer } from './overlayLayers';\nimport { useTopLayer } from './topLayer';\nimport { useLatestRef } from './useLatestRef';\n\nexport type FilterSearchSize = ControlSize;\n\nexport interface FilterSearchProps {\n filters: FilterSearchFilter[];\n /** Controlled: the bar always shows `value`, so a URL-backed selection needs no syncing. */\n value: FilterSearchSelection[];\n /** `changes` lists only the filters that moved; an empty `items` means that filter was removed. */\n onChange: (next: FilterSearchSelection[], changes: FilterSearchChange[]) => void;\n /** Called when the clear control empties the bar, after `onChange`. */\n onClear?: () => void;\n /** The filter whose values are open, or `null` on the filter list — for loading values lazily. */\n onActiveFilterChange?: (filter: string | null) => void;\n placeholder?: string;\n size?: FilterSearchSize;\n width?: ControlWidth;\n loading?: boolean;\n disabled?: boolean;\n clearable?: boolean;\n /** Chips past this count collapse into `+N`. */\n maxVisibleChips?: number;\n className?: string;\n style?: React.CSSProperties;\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\nconst FIELD_SIZE_CLASSES: Record<FilterSearchSize, string> = {\n small: `min-h-[var(--malachite-control-height-small,28px)] gap-1 px-2.5 py-[2px] ${CONTROL_TEXT_SIZE_CLASS.small} rounded-[var(--malachite-radius-10,10px)]`,\n medium: `min-h-[var(--malachite-control-height-medium,32px)] gap-1 px-3 py-[3px] ${CONTROL_TEXT_SIZE_CLASS.medium} rounded-xl`,\n large: `min-h-[var(--malachite-control-height-large,42px)] gap-1.5 px-4 py-[6px] ${CONTROL_TEXT_SIZE_CLASS.large} rounded-[var(--malachite-radius-xxl,14px)]`,\n};\n\nconst CHIP_GAP: Record<FilterSearchSize, string> = {\n small: 'gap-1',\n medium: 'gap-1',\n large: 'gap-1.5',\n};\n\nconst CHIP_CLASSES = {\n resting:\n 'bg-[var(--malachite-tag-default-background,rgba(123,123,123,0.1))] text-[var(--malachite-text-primary,rgb(10,10,10))]',\n active: 'bg-[var(--malachite-accent-background,rgb(0,175,102))] text-[var(--malachite-card-background,rgb(255,255,255))]',\n};\n\nconst LOADING_ROWS = 5;\n\ntype Row =\n | { kind: 'filter'; filter: FilterSearchFilter }\n | { kind: 'toggle'; toggle: FilterSearchToggle }\n | { kind: 'item'; row: FilterSearchItemRow };\n\ninterface Chip {\n filter: string;\n text: string;\n}\n\ntype LabelMap = Map<string, { label: string; items: Map<string, string> }>;\n\nconst isEnabled = (row: Row | undefined) =>\n !!row && !(row.kind === 'item' && row.row.item.disabled);\n\nconst firstEnabledFrom = (rows: Row[], start: number): number => {\n for (let index = Math.max(start, 0); index < rows.length; index++) {\n if (isEnabled(rows[index])) return index;\n }\n return -1;\n};\n\nconst rowStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n width: '100%',\n flexShrink: 0,\n border: 'none',\n textAlign: 'left',\n borderRadius: 8,\n padding: '6px 10px',\n font: 'inherit',\n cursor: 'pointer',\n minWidth: 0,\n};\n\nconst pillStyle: React.CSSProperties = {\n borderRadius: 6,\n padding: '2px 6px',\n flexShrink: 0,\n whiteSpace: 'nowrap',\n};\n\nconst ellipsis: React.CSSProperties = {\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n minWidth: 0,\n};\n\nconst trailing: React.CSSProperties = { ...ellipsis, marginLeft: 'auto', flexShrink: 1 };\n\nconst keepFocus = (event: React.MouseEvent) => event.preventDefault();\n\n// A chip's own buttons decide whether the menu opens; the field's mousedown must not.\nconst keepChipClick = (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n};\n\nconst RowContent: React.FC<{ row: Row; showFilter: boolean }> = ({ row, showFilter }) => {\n if (row.kind === 'filter') {\n return (\n <>\n <span className={FILTER_SEARCH_CLASS.pill} style={pillStyle}>\n {row.filter.label}\n </span>\n {row.filter.info && <span style={ellipsis}>{row.filter.info}</span>}\n {row.filter.example && (\n <span className={FILTER_SEARCH_CLASS.hint} style={trailing}>\n {row.filter.example}\n </span>\n )}\n </>\n );\n }\n\n if (row.kind === 'toggle') {\n return (\n <span style={{ color: 'var(--malachite-text-primary, rgb(10, 10, 10))' }}>\n {row.toggle === 'select' ? 'Select All' : 'Deselect All'}\n </span>\n );\n }\n\n const { item, filter, selected } = row.row;\n return (\n <>\n {showFilter && (\n <span className={FILTER_SEARCH_CLASS.pill} style={pillStyle}>\n {filter.label}\n </span>\n )}\n <span style={ellipsis}>{item.label}</span>\n {selected ? (\n <CheckmarkIcon\n size={16}\n style={{\n marginLeft: 'auto',\n flexShrink: 0,\n color: 'var(--malachite-accent-background, rgb(0, 175, 102))',\n }}\n />\n ) : (\n showFilter &&\n filter.info && (\n <span className={FILTER_SEARCH_CLASS.hint} style={trailing}>\n {filter.info}\n </span>\n )\n )}\n </>\n );\n};\n\nconst FilterSearch: React.FC<FilterSearchProps> = ({\n filters,\n value,\n onChange,\n onClear,\n onActiveFilterChange,\n placeholder = 'Search',\n size = 'medium',\n width,\n loading = false,\n disabled = false,\n clearable = false,\n maxVisibleChips = 4,\n className = '',\n style,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n}) => {\n const instanceId = useId();\n const listboxId = `${instanceId}-listbox`;\n const optionId = (index: number) => `${instanceId}-option-${index}`;\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [activeFilter, setActiveFilterState] = useState<string | null>(null);\n const [highlighted, setHighlighted] = useState(0);\n const [position, setPosition] = useState<MenuGeometry | null>(null);\n\n const fieldRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const popoverRef = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const optionRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\n useTopLayer(popoverRef, open);\n const popupIdentity = usePopupLayer('multiselect', open, popoverRef);\n\n // Labels outlive a reload of `filters`, so applied chips keep their names while it is in flight.\n const previousLabels = useRef<LabelMap>(new Map());\n const labels = useMemo(() => {\n const next: LabelMap = new Map(previousLabels.current);\n for (const filter of filters) {\n // Merged, not replaced: a filter can reload with its values still in flight.\n const known = next.get(filter.value)?.items ?? new Map<string, string>();\n next.set(filter.value, {\n label: filter.label,\n items: new Map([\n ...known,\n ...filter.items.map((item) => [item.value, item.label] as const),\n ]),\n });\n }\n return next;\n }, [filters]);\n useEffect(() => {\n previousLabels.current = labels;\n }, [labels]);\n\n const previousOrder = useRef<string[]>([]);\n const order = useMemo(\n () => orderSelections(value, previousOrder.current, activeFilter),\n [value, activeFilter],\n );\n useEffect(() => {\n previousOrder.current = order;\n }, [order]);\n\n const mode = resolveMode(activeFilter, query);\n const activeFilterDef = filters.find((filter) => filter.value === activeFilter);\n\n const activeFilterRef = useRef(activeFilter);\n // Through a ref so an inline callback does not re-bind the open menu's listeners every render.\n const onActiveFilterChangeRef = useLatestRef(onActiveFilterChange);\n const setActiveFilter = useCallback(\n (next: string | null) => {\n if (activeFilterRef.current === next) return;\n activeFilterRef.current = next;\n setActiveFilterState(next);\n onActiveFilterChangeRef.current?.(next);\n },\n [onActiveFilterChangeRef],\n );\n\n const rows = useMemo<Row[]>(() => {\n if (loading) return [];\n if (mode === 'filters') return filters.map((filter) => ({ kind: 'filter', filter }));\n const { toggle, items } =\n mode === 'items'\n ? filterRows(activeFilterDef, value, query)\n : searchRows(filters, value, query);\n return [\n ...(toggle ? [{ kind: 'toggle' as const, toggle }] : []),\n ...items.map((row) => ({ kind: 'item' as const, row })),\n ];\n }, [loading, mode, filters, activeFilterDef, value, query]);\n\n // In `order`, so a filter emptied while it is being edited keeps its place in the row.\n const chips = useMemo<Chip[]>(() => {\n const applied = new Map(value.map((selection) => [selection.filter, selection.items]));\n const chipFor = (filter: string): Chip[] => {\n const entry = labels.get(filter);\n const items = applied.get(filter);\n if (!items) {\n return filter === activeFilter ? [{ filter, text: entry?.label ?? filter }] : [];\n }\n if (!entry && loading) return [];\n const itemLabels = items.map((item) => entry?.items.get(item) ?? item);\n return [{ filter, text: chipText(entry?.label ?? filter, itemLabels) }];\n };\n const pendingIsNew = activeFilter !== null && !order.includes(activeFilter);\n return [...order, ...(pendingIsNew ? [activeFilter] : [])].flatMap(chipFor);\n }, [order, value, labels, loading, activeFilter]);\n\n const visibleChips = chips.slice(0, maxVisibleChips);\n const hiddenChipCount = chips.length - visibleChips.length;\n\n const emit = useCallback(\n ({ next, changes }: FilterSearchUpdate) => {\n if (changes.length > 0) onChange(next, changes);\n },\n [onChange],\n );\n\n const close = useCallback(() => {\n setOpen(false);\n setQuery('');\n setActiveFilter(null);\n setPosition(null);\n }, [setActiveFilter]);\n\n const openMenu = () => {\n if (disabled || open) return;\n setHighlighted(0);\n setOpen(true);\n };\n\n const updatePosition = useCallback(() => {\n const field = fieldRef.current;\n if (!field) return;\n setPosition(\n measureMenuGeometry(popoverRef.current, {\n triggerRect: field.getBoundingClientRect(),\n preset: 'standard',\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n }),\n );\n }, []);\n\n useEffect(() => {\n if (disabled && open) close();\n }, [disabled, open, close]);\n\n useEffect(() => {\n if (!open) return;\n const handleClickOutside = (event: MouseEvent) => {\n const path = event.composedPath();\n const field = fieldRef.current;\n const popover = popoverRef.current;\n if ((!field || !path.includes(field)) && (!popover || !path.includes(popover))) {\n close();\n }\n };\n let frame: number | null = null;\n const handleScrollOrResize = () => {\n if (frame !== null) return;\n frame = requestAnimationFrame(() => {\n frame = null;\n updatePosition();\n });\n };\n const popEscapeLayer = pushEscapeLayer(close);\n document.addEventListener('mousedown', handleClickOutside);\n window.addEventListener('scroll', handleScrollOrResize, true);\n window.addEventListener('resize', handleScrollOrResize);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n window.removeEventListener('scroll', handleScrollOrResize, true);\n window.removeEventListener('resize', handleScrollOrResize);\n if (frame !== null) cancelAnimationFrame(frame);\n popEscapeLayer();\n };\n }, [open, close, updatePosition]);\n\n // Chips wrap onto a second line as they are added, which moves the menu's anchor.\n useLayoutEffect(() => {\n if (!open) return;\n updatePosition();\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => updatePosition());\n if (popoverRef.current) observer.observe(popoverRef.current);\n if (fieldRef.current) observer.observe(fieldRef.current);\n return () => observer.disconnect();\n }, [open, updatePosition]);\n\n // Every mode reuses one list element, so a new list would otherwise open at the old offset.\n // biome-ignore lint/correctness/useExhaustiveDependencies: the reset is keyed on what the list shows\n useLayoutEffect(() => {\n if (listRef.current) listRef.current.scrollTop = 0;\n }, [mode, activeFilter, query]);\n\n useInsertionEffect(() => {\n if (open) ensureFilterSearchStyles();\n }, [open]);\n\n const scrollToRow = (index: number) => {\n requestAnimationFrame(() => {\n const row = optionRefs.current[index];\n const list = listRef.current;\n if (!row || !list) return;\n const top = row.offsetTop;\n const bottom = top + row.offsetHeight;\n if (bottom > list.scrollTop + list.clientHeight) {\n list.scrollTop = bottom - list.clientHeight;\n } else if (top < list.scrollTop) {\n list.scrollTop = top;\n }\n });\n };\n\n const choose = (row: Row) => {\n if (row.kind === 'filter') {\n setActiveFilter(row.filter.value);\n setQuery('');\n setHighlighted(0);\n return;\n }\n\n if (row.kind === 'toggle') {\n const scope = mode === 'items' && activeFilterDef ? [activeFilterDef] : filters;\n emit(\n row.toggle === 'select'\n ? selectAll(scope, value, query)\n : deselectAll(scope, value, query),\n );\n setQuery('');\n setHighlighted(0);\n return;\n }\n\n const { item, filter } = row.row;\n if (item.disabled) return;\n const update = toggleValue(value, filter.value, item.value);\n emit(update);\n setQuery('');\n\n if (mode !== 'items') {\n setHighlighted(0);\n return;\n }\n // The query is cleared, so the list grows back: keep the cursor on the value just chosen.\n const { toggle, items } = filterRows(filter, update.next, '');\n const index = items.findIndex((candidate) => candidate.item.value === item.value);\n const nextIndex = index < 0 ? 0 : index + (toggle ? 1 : 0);\n setHighlighted(nextIndex);\n scrollToRow(nextIndex);\n };\n\n const moveHighlight = (direction: 1 | -1) => {\n if (rows.length === 0) return;\n let next = activeRow < 0 ? highlighted : activeRow;\n for (let step = 0; step < rows.length; step++) {\n next = (next + direction + rows.length) % rows.length;\n if (isEnabled(rows[next])) {\n setHighlighted(next);\n scrollToRow(next);\n return;\n }\n }\n };\n\n const removeChip = (filter: string) => {\n if (filter === activeFilter) setActiveFilter(null);\n emit(removeFilter(value, filter));\n };\n\n const editChip = (filter: string) => {\n if (disabled || loading) return;\n setActiveFilter(filter);\n setQuery('');\n setHighlighted(0);\n setOpen(true);\n inputRef.current?.focus();\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n // Enter and the arrows belong to the input method while a composition is in progress;\n // Safari reports the committing Enter as keyCode 229 with `isComposing` already false.\n if (event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229) return;\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp': {\n event.preventDefault();\n if (!open) {\n openMenu();\n return;\n }\n moveHighlight(event.key === 'ArrowDown' ? 1 : -1);\n return;\n }\n case 'Enter': {\n event.preventDefault();\n if (!open) {\n openMenu();\n return;\n }\n const row = rows[activeRow];\n if (isEnabled(row)) choose(row as Row);\n return;\n }\n case 'Backspace': {\n if (query !== '') return;\n const pending =\n activeFilter !== null && !value.some((s) => s.filter === activeFilter);\n if (pending) {\n event.preventDefault();\n setActiveFilter(null);\n setHighlighted(0);\n return;\n }\n // The last chip on screen: one hidden while its labels load cannot be removed unseen.\n const shown = chips.filter((chip) => value.some((s) => s.filter === chip.filter));\n const last = shown[shown.length - 1];\n if (!last) return;\n event.preventDefault();\n removeChip(last.filter);\n return;\n }\n }\n };\n\n const handleClear = (event: React.MouseEvent) => {\n event.stopPropagation();\n emit(clearAll(value));\n setActiveFilter(null);\n setQuery('');\n onClear?.();\n };\n\n const backToFilters = () => {\n setActiveFilter(null);\n setQuery('');\n setHighlighted(0);\n };\n\n const showsClear = clearable && value.length > 0 && !disabled && !loading;\n // A disabled row cannot hold the cursor: it falls through to the next enabled one.\n const activeRow = open ? firstEnabledFrom(rows, highlighted) : -1;\n\n const triggerVisual = getTriggerVisual({ disabled, open });\n\n const emptyMessage = mode === 'filters' ? 'No filters available' : 'No matching values';\n\n const popoverStyle: React.CSSProperties = {\n position: 'fixed',\n top: position?.top ?? 0,\n left: position?.left ?? 0,\n width: position?.width,\n background: MENU_SPECS.standard.background,\n border: MENU_SPECS.standard.border,\n borderRadius: MENU_SPECS.standard.radius,\n boxShadow: MENU_SPECS.standard.shadow,\n padding: MENU_SPECS.standard.padding,\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n maxHeight: position?.maxHeight ?? MENU_MAX_HEIGHT_PX,\n fontSize: CONTROL_TEXT_SIZE[size],\n visibility: position ? 'visible' : 'hidden',\n opacity: position ? 1 : 0,\n };\n\n return (\n <>\n <div\n className={`relative min-w-0 ${className}`}\n style={{ ...controlWidthStyle(width), ...style }}\n >\n <div\n ref={fieldRef}\n {...{ [DROPDOWN_TRIGGER_ATTR]: '' }}\n data-open={open || undefined}\n // On the field, not the input: focus can move on to a chip's own buttons.\n onBlur={(event) => {\n const next = event.relatedTarget as Node | null;\n if (\n next &&\n (fieldRef.current?.contains(next) || popoverRef.current?.contains(next))\n ) {\n return;\n }\n close();\n }}\n onMouseDown={(event) => {\n if (disabled) return;\n if (event.target !== inputRef.current) event.preventDefault();\n inputRef.current?.focus();\n openMenu();\n }}\n style={{\n transition: 'border-color 0.15s ease, box-shadow 0.15s ease',\n ...triggerVisual,\n }}\n className={`w-full min-w-0 flex items-center border border-solid font-normal ${FIELD_SIZE_CLASSES[size]} ${disabled ? 'cursor-not-allowed' : 'cursor-text'}`}\n >\n <SearchIcon\n size={13}\n className=\"shrink-0 mr-1\"\n style={{ color: 'var(--malachite-text-placeholder, rgb(187, 187, 187))' }}\n />\n {/* Chips wrap here, never into the icon or caret; the reserve keeps the clear button off them. */}\n <div\n className={`flex flex-1 min-w-0 flex-wrap items-center ${CHIP_GAP[size]} ${showsClear ? 'pr-[18px]' : ''}`}\n >\n {visibleChips.map((chip) => {\n const active = open && chip.filter === activeFilter;\n return (\n <span\n key={chip.filter}\n onMouseDown={keepChipClick}\n className={`inline-flex items-center gap-1 max-w-[max(60px,calc(100%-64px))] min-w-0 h-[22px] pl-1.5 pr-1 rounded-md text-xs ${active ? CHIP_CLASSES.active : CHIP_CLASSES.resting}`}\n >\n <button\n type=\"button\"\n disabled={disabled}\n title={chip.text}\n aria-label={`Edit filter ${chip.text}`}\n onClick={() => editChip(chip.filter)}\n className={`truncate min-w-0 bg-transparent border-none p-0 text-[length:inherit] text-current ${disabled || loading ? 'cursor-default' : 'cursor-pointer'} ${FOCUS_RING}`}\n >\n {chip.text}\n </button>\n {!disabled && (\n <button\n type=\"button\"\n aria-label={`Remove filter ${chip.text}`}\n onClick={(event) => {\n event.stopPropagation();\n removeChip(chip.filter);\n // The button unmounts with its chip; keep focus in the field.\n inputRef.current?.focus();\n }}\n className={`flex items-center justify-center shrink-0 bg-transparent border-none p-0 text-current opacity-70 hover:opacity-100 cursor-pointer ${FOCUS_RING}`}\n >\n <DismissIcon size={10} />\n </button>\n )}\n </span>\n );\n })}\n {hiddenChipCount > 0 && (\n <span\n className={`inline-flex items-center h-[22px] px-1.5 rounded-md text-xs ${CHIP_CLASSES.resting}`}\n >\n +{hiddenChipCount}\n </span>\n )}\n <input\n ref={inputRef}\n id={id}\n type=\"text\"\n role=\"combobox\"\n value={query}\n disabled={disabled}\n placeholder={chips.length === 0 ? placeholder : ''}\n autoComplete=\"off\"\n spellCheck={false}\n aria-label={ariaLabelledBy ? undefined : (ariaLabel ?? placeholder)}\n aria-labelledby={ariaLabelledBy}\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n aria-expanded={open}\n aria-controls={open ? listboxId : undefined}\n aria-activedescendant={activeRow >= 0 ? optionId(activeRow) : undefined}\n aria-busy={loading || undefined}\n onChange={(event) => {\n setQuery(event.target.value);\n setHighlighted(0);\n openMenu();\n }}\n onKeyDown={handleKeyDown}\n className=\"flex-1 min-w-[60px] border-none outline-none bg-transparent p-0 text-[length:inherit] text-[var(--malachite-text-primary,rgb(10,10,10))] placeholder:text-[var(--malachite-text-placeholder,rgb(187,187,187))] disabled:cursor-not-allowed\"\n />\n </div>\n <span className=\"flex items-center justify-center shrink-0 size-[14px] ml-1\">\n {loading ? (\n <Spinner size=\"xxxsmall\" />\n ) : (\n <CaretDownIcon\n size={13}\n style={{\n color: open\n ? 'var(--malachite-text-primary, rgb(10, 10, 10))'\n : 'var(--malachite-text-placeholder, rgb(187, 187, 187))',\n transition: 'transform 0.2s ease, color 0.2s ease',\n transform: open ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n />\n )}\n </span>\n </div>\n {showsClear && (\n <button\n type=\"button\"\n aria-label=\"Clear filters\"\n onMouseDown={keepFocus}\n onClick={handleClear}\n className={`absolute top-0 bottom-0 right-[30px] flex items-center justify-center px-[2px] bg-transparent border-none text-[var(--malachite-text-placeholder)] hover:text-[var(--malachite-text-primary)] cursor-pointer ${FOCUS_RING}`}\n >\n <DismissIcon size={10} />\n </button>\n )}\n </div>\n {open &&\n createPortal(\n <div\n ref={popoverRef}\n {...popupIdentity}\n style={popoverStyle}\n onMouseDown={keepFocus}\n >\n <div\n style={{\n padding: '4px 10px 2px',\n color: 'var(--malachite-text-placeholder, rgb(187, 187, 187))',\n display: 'flex',\n gap: 4,\n minWidth: 0,\n }}\n >\n {mode === 'items' ? (\n <>\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={backToFilters}\n className={FILTER_SEARCH_CLASS.crumb}\n style={{\n background: 'none',\n border: 'none',\n padding: 0,\n font: 'inherit',\n cursor: 'pointer',\n }}\n >\n Filters\n </button>\n <span style={ellipsis}>\n {`> ${activeFilterDef?.label ?? labels.get(activeFilter ?? '')?.label ?? ''}`}\n </span>\n </>\n ) : (\n 'Filters'\n )}\n </div>\n <div\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-multiselectable={mode !== 'filters'}\n aria-label={ariaLabel ?? placeholder}\n aria-busy={loading || undefined}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n overflowY: 'auto',\n overscrollBehavior: 'contain',\n minHeight: 0,\n flex: 1,\n scrollbarWidth: 'thin',\n }}\n >\n {loading &&\n Array.from({ length: LOADING_ROWS }, (_, index) => (\n <div\n key={index}\n role=\"presentation\"\n className={FILTER_SEARCH_CLASS.loading}\n style={{\n height: 24,\n margin: '4px 10px',\n borderRadius: 6,\n background:\n 'var(--malachite-tag-default-background, rgba(123, 123, 123, 0.1))',\n }}\n />\n ))}\n {!loading && rows.length === 0 && (\n <div\n role=\"presentation\"\n style={{\n padding: '6px 10px',\n color: 'var(--malachite-text-secondary, rgb(123, 123, 123))',\n }}\n >\n {emptyMessage}\n </div>\n )}\n {rows.map((row, index) => {\n const key =\n row.kind === 'filter'\n ? `filter:${row.filter.value}`\n : row.kind === 'toggle'\n ? 'toggle'\n : `item:${row.row.filter.value}:${row.row.item.value}`;\n const itemDisabled = row.kind === 'item' && !!row.row.item.disabled;\n return (\n <button\n key={key}\n id={optionId(index)}\n ref={(element) => {\n optionRefs.current[index] = element;\n }}\n type=\"button\"\n tabIndex={-1}\n role=\"option\"\n aria-selected={\n row.kind === 'item' ? row.row.selected : false\n }\n aria-disabled={itemDisabled || undefined}\n data-highlighted={index === activeRow}\n data-disabled={itemDisabled}\n className={FILTER_SEARCH_CLASS.row}\n // Exception to \"no JS for styling\": the highlight IS the\n // keyboard cursor, so a bare :hover would light a second row.\n onMouseEnter={() => {\n if (!itemDisabled) setHighlighted(index);\n }}\n onClick={() => choose(row)}\n style={rowStyle}\n >\n <RowContent row={row} showFilter={mode === 'search'} />\n </button>\n );\n })}\n </div>\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport default FilterSearch;\nexport { FilterSearch };\nexport type {\n FilterSearchChange,\n FilterSearchFilter,\n FilterSearchItem,\n FilterSearchSelection,\n} from './filterSearchModel';\n"],"names":["FIELD_SIZE_CLASSES","CONTROL_TEXT_SIZE_CLASS","CHIP_GAP","CHIP_CLASSES","LOADING_ROWS","isEnabled","row","firstEnabledFrom","rows","start","index","rowStyle","pillStyle","ellipsis","trailing","keepFocus","event","keepChipClick","RowContent","showFilter","jsxs","Fragment","jsx","FILTER_SEARCH_CLASS","item","filter","selected","CheckmarkIcon","FilterSearch","filters","value","onChange","onClear","onActiveFilterChange","placeholder","size","width","loading","disabled","clearable","maxVisibleChips","className","style","id","ariaLabel","ariaLabelledBy","instanceId","useId","listboxId","optionId","open","setOpen","useState","query","setQuery","activeFilter","setActiveFilterState","highlighted","setHighlighted","position","setPosition","fieldRef","useRef","inputRef","popoverRef","listRef","optionRefs","useTopLayer","popupIdentity","usePopupLayer","previousLabels","labels","useMemo","next","known","_a","useEffect","previousOrder","order","orderSelections","mode","resolveMode","activeFilterDef","activeFilterRef","onActiveFilterChangeRef","useLatestRef","setActiveFilter","useCallback","toggle","items","filterRows","searchRows","chips","applied","selection","chipFor","entry","itemLabels","chipText","pendingIsNew","visibleChips","hiddenChipCount","emit","changes","close","openMenu","updatePosition","field","measureMenuGeometry","handleClickOutside","path","popover","frame","handleScrollOrResize","popEscapeLayer","pushEscapeLayer","useLayoutEffect","observer","useInsertionEffect","ensureFilterSearchStyles","scrollToRow","list","top","bottom","choose","scope","selectAll","deselectAll","update","toggleValue","candidate","nextIndex","moveHighlight","direction","activeRow","step","removeChip","removeFilter","editChip","handleKeyDown","s","shown","chip","last","handleClear","clearAll","backToFilters","showsClear","triggerVisual","getTriggerVisual","emptyMessage","popoverStyle","MENU_SPECS","MENU_MAX_HEIGHT_PX","CONTROL_TEXT_SIZE","controlWidthStyle","DROPDOWN_TRIGGER_ATTR","_b","SearchIcon","active","FOCUS_RING","DismissIcon","Spinner","CaretDownIcon","createPortal","_","key","itemDisabled","element"],"mappings":"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"}
|
|
@@ -1,59 +1,56 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import
|
|
3
|
-
import { Alert as
|
|
4
|
-
import { Breadcrumbs as
|
|
5
|
-
import { hasBackButton as
|
|
6
|
-
import { Button as
|
|
1
|
+
import { jsx as l, jsxs as s } from "react/jsx-runtime";
|
|
2
|
+
import $ from "../ActionMenu.js";
|
|
3
|
+
import { Alert as D } from "../Alert.js";
|
|
4
|
+
import { Breadcrumbs as O } from "../Breadcrumbs.js";
|
|
5
|
+
import { hasBackButton as M } from "../breadcrumbsNav.js";
|
|
6
|
+
import { Button as u } from "../Button.js";
|
|
7
7
|
import P from "../OverflowRow.js";
|
|
8
|
-
import
|
|
8
|
+
import h from "../Skeleton.js";
|
|
9
9
|
import j from "../Typography/PageTitle.js";
|
|
10
|
-
import
|
|
11
|
-
import { safeHref as
|
|
12
|
-
import { CARD_MIN_HEIGHT as G, CARD_RADIUS as L, CARD_CLASSES as z, HEADER_HEIGHT as U, DIVIDER_CLASSES as
|
|
10
|
+
import N from "../Typography/Text.js";
|
|
11
|
+
import { safeHref as y } from "../safeHref.js";
|
|
12
|
+
import { CARD_MIN_HEIGHT as G, CARD_RADIUS as L, CARD_CLASSES as z, HEADER_HEIGHT as U, DIVIDER_CLASSES as x, CONTENT_MIN_HEIGHT as V, CONTENT_INSET_VAR as K } from "./constants.js";
|
|
13
13
|
const q = {
|
|
14
14
|
small: 8,
|
|
15
15
|
medium: 16,
|
|
16
16
|
large: 24,
|
|
17
17
|
xlarge: 40
|
|
18
|
-
}, F = (
|
|
19
|
-
const
|
|
20
|
-
return e ? () => window.open(e, l.target ?? "_blank", "noopener,noreferrer") : l.onClick;
|
|
21
|
-
}, Q = (l) => l.flatMap((e, r) => {
|
|
22
|
-
const i = {
|
|
18
|
+
}, F = (a) => a.variant === "destructive" || a.variant === "error", J = (a) => a.flatMap((e, r) => {
|
|
19
|
+
const i = y(e.href), c = {
|
|
23
20
|
key: `${r}-${e.label}`,
|
|
24
21
|
label: e.label,
|
|
25
|
-
onClick:
|
|
22
|
+
...i ? { href: i, target: e.target ?? "_blank" } : { onClick: e.onClick },
|
|
26
23
|
disabled: e.disabled,
|
|
27
24
|
icon: e.icon,
|
|
28
25
|
tooltip: e.tooltip,
|
|
29
26
|
danger: F(e)
|
|
30
27
|
};
|
|
31
|
-
return e.dividerBefore && r > 0 ? [{ type: "divider", key: `divider-${r}-${e.label}` },
|
|
32
|
-
}),
|
|
28
|
+
return e.dividerBefore && r > 0 ? [{ type: "divider", key: `divider-${r}-${e.label}` }, c] : [c];
|
|
29
|
+
}), Q = ({ buttons: a }) => a.length === 0 ? null : /* @__PURE__ */ l("div", { className: "min-w-0", children: /* @__PURE__ */ l(
|
|
33
30
|
P,
|
|
34
31
|
{
|
|
35
32
|
gap: 8,
|
|
36
33
|
justify: "end",
|
|
37
|
-
renderOverflow: (e) => /* @__PURE__ */
|
|
38
|
-
|
|
34
|
+
renderOverflow: (e) => /* @__PURE__ */ l(
|
|
35
|
+
$,
|
|
39
36
|
{
|
|
40
|
-
items:
|
|
41
|
-
|
|
37
|
+
items: J(
|
|
38
|
+
a.slice(Math.max(0, a.length - e))
|
|
42
39
|
)
|
|
43
40
|
}
|
|
44
41
|
),
|
|
45
|
-
children:
|
|
46
|
-
const i =
|
|
42
|
+
children: a.map((e, r) => {
|
|
43
|
+
const i = y(e.href);
|
|
47
44
|
return /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
|
|
48
|
-
e.dividerBefore && r > 0 ? /* @__PURE__ */
|
|
45
|
+
e.dividerBefore && r > 0 ? /* @__PURE__ */ l(
|
|
49
46
|
"span",
|
|
50
47
|
{
|
|
51
48
|
"aria-hidden": "true",
|
|
52
49
|
className: "h-4 w-px bg-[var(--malachite-card-border)]"
|
|
53
50
|
}
|
|
54
51
|
) : null,
|
|
55
|
-
/* @__PURE__ */
|
|
56
|
-
|
|
52
|
+
/* @__PURE__ */ l(
|
|
53
|
+
u,
|
|
57
54
|
{
|
|
58
55
|
variant: e.variant ?? "filled",
|
|
59
56
|
size: "medium",
|
|
@@ -70,54 +67,54 @@ const q = {
|
|
|
70
67
|
] }, `${r}-${e.label}`);
|
|
71
68
|
})
|
|
72
69
|
}
|
|
73
|
-
) }),
|
|
74
|
-
breadcrumbLinks:
|
|
70
|
+
) }), W = [], X = [], de = ({
|
|
71
|
+
breadcrumbLinks: a = W,
|
|
75
72
|
breadcrumbActions: e,
|
|
76
73
|
renderLink: r,
|
|
77
74
|
title: i,
|
|
78
|
-
titleSuffix:
|
|
79
|
-
subtitle:
|
|
80
|
-
description:
|
|
81
|
-
buttons:
|
|
75
|
+
titleSuffix: c,
|
|
76
|
+
subtitle: t,
|
|
77
|
+
description: d,
|
|
78
|
+
buttons: o = X,
|
|
82
79
|
loading: n = !1,
|
|
83
|
-
children:
|
|
80
|
+
children: I,
|
|
84
81
|
centered: f = !1,
|
|
85
|
-
noPadding:
|
|
86
|
-
contentGap:
|
|
87
|
-
alert:
|
|
82
|
+
noPadding: p = !1,
|
|
83
|
+
contentGap: w = "small",
|
|
84
|
+
alert: m,
|
|
88
85
|
role: _,
|
|
89
86
|
"aria-label": T,
|
|
90
|
-
"aria-labelledby":
|
|
91
|
-
className:
|
|
92
|
-
style:
|
|
87
|
+
"aria-labelledby": E,
|
|
88
|
+
className: S = "",
|
|
89
|
+
style: k
|
|
93
90
|
}) => {
|
|
94
|
-
const
|
|
95
|
-
/* @__PURE__ */
|
|
96
|
-
|
|
97
|
-
] }) : null, R =
|
|
91
|
+
const A = M(a), C = p ? 0 : f ? "5vh 14vw" : "40px", H = p ? "0px" : f ? "14vw" : "40px", B = !!(n || i || t || d || o.length > 0), g = t ? n ? /* @__PURE__ */ l(h.Input, { width: 120, height: 24 }) : /* @__PURE__ */ l(N, { color: "secondary", size: "small", children: t }) : null, v = n ? /* @__PURE__ */ l(h.Input, { width: 200, height: 40 }) : i ? /* @__PURE__ */ s("div", { className: "flex items-center", style: { gap: 12 }, children: [
|
|
92
|
+
/* @__PURE__ */ l(j, { children: i }),
|
|
93
|
+
c
|
|
94
|
+
] }) : null, R = d ? n ? /* @__PURE__ */ l(h.Input, { width: 120, height: 24 }) : /* @__PURE__ */ l(N, { color: "secondary", style: { lineHeight: 1.6 }, children: d }) : null;
|
|
98
95
|
return /* @__PURE__ */ s(
|
|
99
96
|
"main",
|
|
100
97
|
{
|
|
101
|
-
className: `${z} ${
|
|
102
|
-
style: { borderRadius: L, minHeight: G, ...
|
|
98
|
+
className: `${z} ${S}`,
|
|
99
|
+
style: { borderRadius: L, minHeight: G, ...k },
|
|
103
100
|
role: _,
|
|
104
101
|
"aria-label": T,
|
|
105
|
-
"aria-labelledby":
|
|
102
|
+
"aria-labelledby": E,
|
|
106
103
|
"aria-busy": n || void 0,
|
|
107
104
|
children: [
|
|
108
|
-
/* @__PURE__ */
|
|
105
|
+
/* @__PURE__ */ l(
|
|
109
106
|
"div",
|
|
110
107
|
{
|
|
111
|
-
className: `flex items-center ${
|
|
108
|
+
className: `flex items-center ${x}`,
|
|
112
109
|
style: {
|
|
113
110
|
height: U,
|
|
114
|
-
paddingInlineStart:
|
|
111
|
+
paddingInlineStart: A ? 16 : 28,
|
|
115
112
|
paddingInlineEnd: 16
|
|
116
113
|
},
|
|
117
|
-
children: /* @__PURE__ */
|
|
118
|
-
|
|
114
|
+
children: /* @__PURE__ */ l(
|
|
115
|
+
O,
|
|
119
116
|
{
|
|
120
|
-
links:
|
|
117
|
+
links: a,
|
|
121
118
|
actions: e,
|
|
122
119
|
renderLink: r,
|
|
123
120
|
className: "flex-1 min-w-0"
|
|
@@ -125,7 +122,7 @@ const q = {
|
|
|
125
122
|
)
|
|
126
123
|
}
|
|
127
124
|
),
|
|
128
|
-
|
|
125
|
+
m ? /* @__PURE__ */ l("div", { className: x, style: { padding: "10px 16px" }, children: /* @__PURE__ */ l(D, { message: m.message, type: m.type, hasMargin: !1 }) }) : null,
|
|
129
126
|
/* @__PURE__ */ s(
|
|
130
127
|
"div",
|
|
131
128
|
{
|
|
@@ -133,12 +130,12 @@ const q = {
|
|
|
133
130
|
style: {
|
|
134
131
|
padding: C,
|
|
135
132
|
minHeight: V,
|
|
136
|
-
gap: q[
|
|
133
|
+
gap: q[w],
|
|
137
134
|
[K]: H
|
|
138
135
|
},
|
|
139
136
|
children: [
|
|
140
137
|
B ? /* @__PURE__ */ s("div", { className: "flex flex-col", style: { gap: 12 }, children: [
|
|
141
|
-
|
|
138
|
+
v || g || o.length > 0 ? /* @__PURE__ */ s(
|
|
142
139
|
"div",
|
|
143
140
|
{
|
|
144
141
|
className: "flex flex-wrap items-center justify-between",
|
|
@@ -150,18 +147,18 @@ const q = {
|
|
|
150
147
|
className: "flex flex-col flex-auto min-w-0 overflow-hidden",
|
|
151
148
|
style: { gap: 4 },
|
|
152
149
|
children: [
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
g,
|
|
151
|
+
v
|
|
155
152
|
]
|
|
156
153
|
}
|
|
157
154
|
),
|
|
158
|
-
n ? null : /* @__PURE__ */
|
|
155
|
+
n ? null : /* @__PURE__ */ l(Q, { buttons: o })
|
|
159
156
|
]
|
|
160
157
|
}
|
|
161
158
|
) : null,
|
|
162
159
|
R
|
|
163
160
|
] }) : null,
|
|
164
|
-
|
|
161
|
+
I
|
|
165
162
|
]
|
|
166
163
|
}
|
|
167
164
|
)
|
|
@@ -170,7 +167,7 @@ const q = {
|
|
|
170
167
|
);
|
|
171
168
|
};
|
|
172
169
|
export {
|
|
173
|
-
|
|
170
|
+
Q as PageActions,
|
|
174
171
|
de as RegularLayout,
|
|
175
172
|
de as default
|
|
176
173
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"regularLayout.js","sources":["../../../src/components/PageLayout/regularLayout.tsx"],"sourcesContent":["import React from 'react';\nimport ActionMenu, { type ActionMenuItem } from '../ActionMenu';\nimport Alert, { type AlertType } from '../Alert';\nimport Breadcrumbs from '../Breadcrumbs';\nimport { hasBackButton } from '../breadcrumbsNav';\nimport Button from '../Button';\nimport OverflowRow from '../OverflowRow';\nimport Skeleton from '../Skeleton';\nimport PageTitle from '../Typography/PageTitle';\nimport Text from '../Typography/Text';\nimport { safeHref } from '../safeHref';\nimport {\n CARD_CLASSES,\n CARD_MIN_HEIGHT,\n CARD_RADIUS,\n CONTENT_INSET_VAR,\n CONTENT_MIN_HEIGHT,\n DIVIDER_CLASSES,\n HEADER_HEIGHT,\n} from './constants';\nimport type { BreadcrumbLink, PageAction, RenderBreadcrumbLink } from './types';\n\nexport type PageContentGap = 'small' | 'medium' | 'large' | 'xlarge';\n\nexport interface RegularLayoutProps {\n breadcrumbLinks?: BreadcrumbLink[];\n breadcrumbActions?: PageAction[];\n renderLink?: RenderBreadcrumbLink;\n title?: React.ReactNode;\n titleSuffix?: React.ReactNode;\n subtitle?: string;\n description?: React.ReactNode;\n buttons?: PageAction[];\n /**\n * Hides the buttons and skeletons the title. `subtitle` and `description` are only\n * skeletoned when those props are also passed.\n */\n loading?: boolean;\n children: React.ReactNode;\n centered?: boolean;\n noPadding?: boolean;\n contentGap?: PageContentGap;\n alert?: { message: string; type?: AlertType };\n /** Demotes the default `main` landmark — pass e.g. `region` when the app owns its own. */\n role?: React.AriaRole;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst CONTENT_GAPS: Record<PageContentGap, number> = {\n small: 8,\n medium: 16,\n large: 24,\n xlarge: 40,\n};\n\nconst isDanger = (button: PageAction): boolean =>\n button.variant === 'destructive' || button.variant === 'error';\n\n// ActionMenuItem has no link form, so a collapsed link action opens the tab itself.\nconst menuAction = (button: PageAction): (() => void) | undefined => {\n const href = safeHref(button.href);\n if (!href) {\n return button.onClick;\n }\n return () => window.open(href, button.target ?? '_blank', 'noopener,noreferrer');\n};\n\nconst toMenuItems = (buttons: PageAction[]): ActionMenuItem[] =>\n buttons.flatMap((button, index) => {\n const item: ActionMenuItem = {\n key: `${index}-${button.label}`,\n label: button.label,\n onClick: menuAction(button),\n disabled: button.disabled,\n icon: button.icon,\n tooltip: button.tooltip,\n danger: isDanger(button),\n };\n return button.dividerBefore && index > 0\n ? [{ type: 'divider' as const, key: `divider-${index}-${button.label}` }, item]\n : [item];\n });\n\n// Not `ActionBar`: it measures by walking ancestors for `clientWidth`, and this chrome\n// mounts on every page. OverflowRow batches its measurement instead.\n// A divider must live in the same OverflowRow child as its button — a standalone child\n// would survive its hidden button and break the child-index-to-button mapping.\n/**\n * The page's action buttons, collapsing into an overflow menu as the row narrows. Exported so\n * a page that renders its own header block — e.g. one that scrolls the title away — keeps the\n * same behaviour instead of hand-rolling `buttons.map(...)` and losing the collapse, the\n * dividers and the href handling.\n */\nexport const PageActions: React.FC<{ buttons: PageAction[] }> = ({ buttons }) => {\n if (buttons.length === 0) {\n return null;\n }\n\n // min-w-0 gives OverflowRow a shrinkable container to collapse against.\n return (\n <div className=\"min-w-0\">\n <OverflowRow\n gap={8}\n justify=\"end\"\n renderOverflow={(hiddenCount) => (\n <ActionMenu\n items={toMenuItems(\n buttons.slice(Math.max(0, buttons.length - hiddenCount)),\n )}\n />\n )}\n >\n {buttons.map((button, index) => {\n const href = safeHref(button.href);\n return (\n <div key={`${index}-${button.label}`} className=\"flex items-center gap-2\">\n {button.dividerBefore && index > 0 ? (\n <span\n aria-hidden=\"true\"\n className=\"h-4 w-px bg-[var(--malachite-card-border)]\"\n />\n ) : null}\n <Button\n variant={button.variant ?? 'filled'}\n size=\"medium\"\n disabled={button.disabled}\n icon={button.icon}\n tooltip={button.tooltip}\n tooltipPlacement={button.tooltipPlacement}\n href={href}\n target={href ? (button.target ?? '_blank') : undefined}\n onClick={href ? undefined : button.onClick}\n >\n {button.label}\n </Button>\n </div>\n );\n })}\n </OverflowRow>\n </div>\n );\n};\n\nconst NO_LINKS: BreadcrumbLink[] = [];\nconst NO_BUTTONS: PageAction[] = [];\n\nconst RegularLayout: React.FC<RegularLayoutProps> = ({\n breadcrumbLinks = NO_LINKS,\n breadcrumbActions,\n renderLink,\n title,\n titleSuffix,\n subtitle,\n description,\n buttons = NO_BUTTONS,\n loading = false,\n children,\n centered = false,\n noPadding = false,\n contentGap = 'small',\n alert,\n role,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className = '',\n style,\n}) => {\n const hasBack = hasBackButton(breadcrumbLinks);\n const contentPadding = noPadding ? 0 : centered ? '5vh 14vw' : '40px';\n // Published so a full-bleed child (CardStrip's bottom rule) can cancel it and re-apply\n // it as its own padding, instead of hardcoding the gutter at the call site.\n const contentInset = noPadding ? '0px' : centered ? '14vw' : '40px';\n const hasHeaderBlock = Boolean(\n loading || title || subtitle || description || buttons.length > 0,\n );\n\n const subtitleNode = subtitle ? (\n loading ? (\n <Skeleton.Input width={120} height={24} />\n ) : (\n <Text color=\"secondary\" size=\"small\">\n {subtitle}\n </Text>\n )\n ) : null;\n\n const titleNode = loading ? (\n <Skeleton.Input width={200} height={40} />\n ) : title ? (\n <div className=\"flex items-center\" style={{ gap: 12 }}>\n <PageTitle>{title}</PageTitle>\n {titleSuffix}\n </div>\n ) : null;\n\n const descriptionNode = description ? (\n loading ? (\n <Skeleton.Input width={120} height={24} />\n ) : (\n <Text color=\"secondary\" style={{ lineHeight: 1.6 }}>\n {description}\n </Text>\n )\n ) : null;\n\n return (\n <main\n className={`${CARD_CLASSES} ${className}`}\n style={{ borderRadius: CARD_RADIUS, minHeight: CARD_MIN_HEIGHT, ...style }}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-busy={loading || undefined}\n >\n <div\n className={`flex items-center ${DIVIDER_CLASSES}`}\n style={{\n height: HEADER_HEIGHT,\n paddingInlineStart: hasBack ? 16 : 28,\n paddingInlineEnd: 16,\n }}\n >\n <Breadcrumbs\n links={breadcrumbLinks}\n actions={breadcrumbActions}\n renderLink={renderLink}\n className=\"flex-1 min-w-0\"\n />\n </div>\n\n {alert ? (\n <div className={DIVIDER_CLASSES} style={{ padding: '10px 16px' }}>\n <Alert message={alert.message} type={alert.type} hasMargin={false} />\n </div>\n ) : null}\n\n <div\n className=\"flex flex-col\"\n style={\n {\n padding: contentPadding,\n minHeight: CONTENT_MIN_HEIGHT,\n gap: CONTENT_GAPS[contentGap],\n [CONTENT_INSET_VAR]: contentInset,\n } as React.CSSProperties\n }\n >\n {hasHeaderBlock ? (\n <div className=\"flex flex-col\" style={{ gap: 12 }}>\n {titleNode || subtitleNode || buttons.length > 0 ? (\n <div\n className=\"flex flex-wrap items-center justify-between\"\n style={{ gap: 12 }}\n >\n <div\n className=\"flex flex-col flex-auto min-w-0 overflow-hidden\"\n style={{ gap: 4 }}\n >\n {subtitleNode}\n {titleNode}\n </div>\n {loading ? null : <PageActions buttons={buttons} />}\n </div>\n ) : null}\n {descriptionNode}\n </div>\n ) : null}\n {children}\n </div>\n </main>\n );\n};\n\nexport default RegularLayout;\nexport { RegularLayout };\n"],"names":["CONTENT_GAPS","isDanger","button","menuAction","href","safeHref","toMenuItems","buttons","index","item","PageActions","jsx","OverflowRow","hiddenCount","ActionMenu","jsxs","Button","NO_LINKS","NO_BUTTONS","RegularLayout","breadcrumbLinks","breadcrumbActions","renderLink","title","titleSuffix","subtitle","description","loading","children","centered","noPadding","contentGap","alert","role","ariaLabel","ariaLabelledBy","className","style","hasBack","hasBackButton","contentPadding","contentInset","hasHeaderBlock","subtitleNode","Skeleton","Text","titleNode","PageTitle","descriptionNode","CARD_CLASSES","CARD_RADIUS","CARD_MIN_HEIGHT","DIVIDER_CLASSES","HEADER_HEIGHT","Breadcrumbs","Alert","CONTENT_MIN_HEIGHT","CONTENT_INSET_VAR"],"mappings":";;;;;;;;;;;;AAmDA,MAAMA,IAA+C;AAAA,EACjD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AACZ,GAEMC,IAAW,CAACC,MACdA,EAAO,YAAY,iBAAiBA,EAAO,YAAY,SAGrDC,IAAa,CAACD,MAAiD;AACjE,QAAME,IAAOC,EAASH,EAAO,IAAI;AACjC,SAAKE,IAGE,MAAM,OAAO,KAAKA,GAAMF,EAAO,UAAU,UAAU,qBAAqB,IAFpEA,EAAO;AAGtB,GAEMI,IAAc,CAACC,MACjBA,EAAQ,QAAQ,CAACL,GAAQM,MAAU;AAC/B,QAAMC,IAAuB;AAAA,IACzB,KAAK,GAAGD,CAAK,IAAIN,EAAO,KAAK;AAAA,IAC7B,OAAOA,EAAO;AAAA,IACd,SAASC,EAAWD,CAAM;AAAA,IAC1B,UAAUA,EAAO;AAAA,IACjB,MAAMA,EAAO;AAAA,IACb,SAASA,EAAO;AAAA,IAChB,QAAQD,EAASC,CAAM;AAAA,EAAA;AAE3B,SAAOA,EAAO,iBAAiBM,IAAQ,IACjC,CAAC,EAAE,MAAM,WAAoB,KAAK,WAAWA,CAAK,IAAIN,EAAO,KAAK,GAAA,GAAMO,CAAI,IAC5E,CAACA,CAAI;AACf,CAAC,GAYQC,IAAmD,CAAC,EAAE,SAAAH,QAC3DA,EAAQ,WAAW,IACZ,OAKP,gBAAAI,EAAC,OAAA,EAAI,WAAU,WACX,UAAA,gBAAAA;AAAA,EAACC;AAAA,EAAA;AAAA,IACG,KAAK;AAAA,IACL,SAAQ;AAAA,IACR,gBAAgB,CAACC,MACb,gBAAAF;AAAA,MAACG;AAAA,MAAA;AAAA,QACG,OAAOR;AAAA,UACHC,EAAQ,MAAM,KAAK,IAAI,GAAGA,EAAQ,SAASM,CAAW,CAAC;AAAA,QAAA;AAAA,MAC3D;AAAA,IAAA;AAAA,IAIP,UAAAN,EAAQ,IAAI,CAACL,GAAQM,MAAU;AAC5B,YAAMJ,IAAOC,EAASH,EAAO,IAAI;AACjC,aACI,gBAAAa,EAAC,OAAA,EAAqC,WAAU,2BAC3C,UAAA;AAAA,QAAAb,EAAO,iBAAiBM,IAAQ,IAC7B,gBAAAG;AAAA,UAAC;AAAA,UAAA;AAAA,YACG,eAAY;AAAA,YACZ,WAAU;AAAA,UAAA;AAAA,QAAA,IAEd;AAAA,QACJ,gBAAAA;AAAA,UAACK;AAAA,UAAA;AAAA,YACG,SAASd,EAAO,WAAW;AAAA,YAC3B,MAAK;AAAA,YACL,UAAUA,EAAO;AAAA,YACjB,MAAMA,EAAO;AAAA,YACb,SAASA,EAAO;AAAA,YAChB,kBAAkBA,EAAO;AAAA,YACzB,MAAAE;AAAA,YACA,QAAQA,IAAQF,EAAO,UAAU,WAAY;AAAA,YAC7C,SAASE,IAAO,SAAYF,EAAO;AAAA,YAElC,UAAAA,EAAO;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,EAAA,GAnBM,GAAGM,CAAK,IAAIN,EAAO,KAAK,EAoBlC;AAAA,IAER,CAAC;AAAA,EAAA;AAAA,GAET,GAIFe,IAA6B,CAAA,GAC7BC,IAA2B,CAAA,GAE3BC,KAA8C,CAAC;AAAA,EACjD,iBAAAC,IAAkBH;AAAA,EAClB,mBAAAI;AAAA,EACA,YAAAC;AAAA,EACA,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAnB,IAAUW;AAAA,EACV,SAAAS,IAAU;AAAA,EACV,UAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,WAAAC,IAAY;AAAA,EACZ,YAAAC,IAAa;AAAA,EACb,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,cAAcC;AAAA,EACd,mBAAmBC;AAAA,EACnB,WAAAC,IAAY;AAAA,EACZ,OAAAC;AACJ,MAAM;AACF,QAAMC,IAAUC,EAAcnB,CAAe,GACvCoB,IAAiBV,IAAY,IAAID,IAAW,aAAa,QAGzDY,IAAeX,IAAY,QAAQD,IAAW,SAAS,QACvDa,IAAiB,GACnBf,KAAWJ,KAASE,KAAYC,KAAenB,EAAQ,SAAS,IAG9DoC,IAAelB,IACjBE,sBACKiB,EAAS,OAAT,EAAe,OAAO,KAAK,QAAQ,IAAI,sBAEvCC,GAAA,EAAK,OAAM,aAAY,MAAK,SACxB,aACL,IAEJ,MAEEC,IAAYnB,IACd,gBAAAhB,EAACiC,EAAS,OAAT,EAAe,OAAO,KAAK,QAAQ,GAAA,CAAI,IACxCrB,IACA,gBAAAR,EAAC,SAAI,WAAU,qBAAoB,OAAO,EAAE,KAAK,MAC7C,UAAA;AAAA,IAAA,gBAAAJ,EAACoC,KAAW,UAAAxB,EAAA,CAAM;AAAA,IACjBC;AAAA,EAAA,EAAA,CACL,IACA,MAEEwB,IAAkBtB,IACpBC,IACI,gBAAAhB,EAACiC,EAAS,OAAT,EAAe,OAAO,KAAK,QAAQ,GAAA,CAAI,IAExC,gBAAAjC,EAACkC,GAAA,EAAK,OAAM,aAAY,OAAO,EAAE,YAAY,OACxC,UAAAnB,EAAA,CACL,IAEJ;AAEJ,SACI,gBAAAX;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,WAAW,GAAGkC,CAAY,IAAIb,CAAS;AAAA,MACvC,OAAO,EAAE,cAAcc,GAAa,WAAWC,GAAiB,GAAGd,EAAA;AAAA,MACnE,MAAAJ;AAAA,MACA,cAAYC;AAAA,MACZ,mBAAiBC;AAAA,MACjB,aAAWR,KAAW;AAAA,MAEtB,UAAA;AAAA,QAAA,gBAAAhB;AAAA,UAAC;AAAA,UAAA;AAAA,YACG,WAAW,qBAAqByC,CAAe;AAAA,YAC/C,OAAO;AAAA,cACH,QAAQC;AAAA,cACR,oBAAoBf,IAAU,KAAK;AAAA,cACnC,kBAAkB;AAAA,YAAA;AAAA,YAGtB,UAAA,gBAAA3B;AAAA,cAAC2C;AAAA,cAAA;AAAA,gBACG,OAAOlC;AAAA,gBACP,SAASC;AAAA,gBACT,YAAAC;AAAA,gBACA,WAAU;AAAA,cAAA;AAAA,YAAA;AAAA,UACd;AAAA,QAAA;AAAA,QAGHU,sBACI,OAAA,EAAI,WAAWoB,GAAiB,OAAO,EAAE,SAAS,YAAA,GAC/C,4BAACG,GAAA,EAAM,SAASvB,EAAM,SAAS,MAAMA,EAAM,MAAM,WAAW,IAAO,EAAA,CACvE,IACA;AAAA,QAEJ,gBAAAjB;AAAA,UAAC;AAAA,UAAA;AAAA,YACG,WAAU;AAAA,YACV,OACI;AAAA,cACI,SAASyB;AAAA,cACT,WAAWgB;AAAA,cACX,KAAKxD,EAAa+B,CAAU;AAAA,cAC5B,CAAC0B,CAAiB,GAAGhB;AAAA,YAAA;AAAA,YAI5B,UAAA;AAAA,cAAAC,IACG,gBAAA3B,EAAC,SAAI,WAAU,iBAAgB,OAAO,EAAE,KAAK,MACxC,UAAA;AAAA,gBAAA+B,KAAaH,KAAgBpC,EAAQ,SAAS,IAC3C,gBAAAQ;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACG,WAAU;AAAA,oBACV,OAAO,EAAE,KAAK,GAAA;AAAA,oBAEd,UAAA;AAAA,sBAAA,gBAAAA;AAAA,wBAAC;AAAA,wBAAA;AAAA,0BACG,WAAU;AAAA,0BACV,OAAO,EAAE,KAAK,EAAA;AAAA,0BAEb,UAAA;AAAA,4BAAA4B;AAAA,4BACAG;AAAA,0BAAA;AAAA,wBAAA;AAAA,sBAAA;AAAA,sBAEJnB,IAAU,OAAO,gBAAAhB,EAACD,GAAA,EAAY,SAAAH,EAAA,CAAkB;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA,IAErD;AAAA,gBACHyC;AAAA,cAAA,EAAA,CACL,IACA;AAAA,cACHpB;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACL;AAAA,IAAA;AAAA,EAAA;AAGZ;"}
|
|
1
|
+
{"version":3,"file":"regularLayout.js","sources":["../../../src/components/PageLayout/regularLayout.tsx"],"sourcesContent":["import React from 'react';\nimport ActionMenu, { type ActionMenuItem } from '../ActionMenu';\nimport Alert, { type AlertType } from '../Alert';\nimport Breadcrumbs from '../Breadcrumbs';\nimport { hasBackButton } from '../breadcrumbsNav';\nimport Button from '../Button';\nimport OverflowRow from '../OverflowRow';\nimport Skeleton from '../Skeleton';\nimport PageTitle from '../Typography/PageTitle';\nimport Text from '../Typography/Text';\nimport { safeHref } from '../safeHref';\nimport {\n CARD_CLASSES,\n CARD_MIN_HEIGHT,\n CARD_RADIUS,\n CONTENT_INSET_VAR,\n CONTENT_MIN_HEIGHT,\n DIVIDER_CLASSES,\n HEADER_HEIGHT,\n} from './constants';\nimport type { BreadcrumbLink, PageAction, RenderBreadcrumbLink } from './types';\n\nexport type PageContentGap = 'small' | 'medium' | 'large' | 'xlarge';\n\nexport interface RegularLayoutProps {\n breadcrumbLinks?: BreadcrumbLink[];\n breadcrumbActions?: PageAction[];\n renderLink?: RenderBreadcrumbLink;\n title?: React.ReactNode;\n titleSuffix?: React.ReactNode;\n subtitle?: string;\n description?: React.ReactNode;\n buttons?: PageAction[];\n /**\n * Hides the buttons and skeletons the title. `subtitle` and `description` are only\n * skeletoned when those props are also passed.\n */\n loading?: boolean;\n children: React.ReactNode;\n centered?: boolean;\n noPadding?: boolean;\n contentGap?: PageContentGap;\n alert?: { message: string; type?: AlertType };\n /** Demotes the default `main` landmark — pass e.g. `region` when the app owns its own. */\n role?: React.AriaRole;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst CONTENT_GAPS: Record<PageContentGap, number> = {\n small: 8,\n medium: 16,\n large: 24,\n xlarge: 40,\n};\n\nconst isDanger = (button: PageAction): boolean =>\n button.variant === 'destructive' || button.variant === 'error';\n\nconst toMenuItems = (buttons: PageAction[]): ActionMenuItem[] =>\n buttons.flatMap((button, index) => {\n const href = safeHref(button.href);\n const item: ActionMenuItem = {\n key: `${index}-${button.label}`,\n label: button.label,\n ...(href ? { href, target: button.target ?? '_blank' } : { onClick: button.onClick }),\n disabled: button.disabled,\n icon: button.icon,\n tooltip: button.tooltip,\n danger: isDanger(button),\n };\n return button.dividerBefore && index > 0\n ? [{ type: 'divider' as const, key: `divider-${index}-${button.label}` }, item]\n : [item];\n });\n\n// Not `ActionBar`: it measures by walking ancestors for `clientWidth`, and this chrome\n// mounts on every page. OverflowRow batches its measurement instead.\n// A divider must live in the same OverflowRow child as its button — a standalone child\n// would survive its hidden button and break the child-index-to-button mapping.\n/**\n * The page's action buttons, collapsing into an overflow menu as the row narrows. Exported so\n * a page that renders its own header block — e.g. one that scrolls the title away — keeps the\n * same behaviour instead of hand-rolling `buttons.map(...)` and losing the collapse, the\n * dividers and the href handling.\n */\nexport const PageActions: React.FC<{ buttons: PageAction[] }> = ({ buttons }) => {\n if (buttons.length === 0) {\n return null;\n }\n\n // min-w-0 gives OverflowRow a shrinkable container to collapse against.\n return (\n <div className=\"min-w-0\">\n <OverflowRow\n gap={8}\n justify=\"end\"\n renderOverflow={(hiddenCount) => (\n <ActionMenu\n items={toMenuItems(\n buttons.slice(Math.max(0, buttons.length - hiddenCount)),\n )}\n />\n )}\n >\n {buttons.map((button, index) => {\n const href = safeHref(button.href);\n return (\n <div key={`${index}-${button.label}`} className=\"flex items-center gap-2\">\n {button.dividerBefore && index > 0 ? (\n <span\n aria-hidden=\"true\"\n className=\"h-4 w-px bg-[var(--malachite-card-border)]\"\n />\n ) : null}\n <Button\n variant={button.variant ?? 'filled'}\n size=\"medium\"\n disabled={button.disabled}\n icon={button.icon}\n tooltip={button.tooltip}\n tooltipPlacement={button.tooltipPlacement}\n href={href}\n target={href ? (button.target ?? '_blank') : undefined}\n onClick={href ? undefined : button.onClick}\n >\n {button.label}\n </Button>\n </div>\n );\n })}\n </OverflowRow>\n </div>\n );\n};\n\nconst NO_LINKS: BreadcrumbLink[] = [];\nconst NO_BUTTONS: PageAction[] = [];\n\nconst RegularLayout: React.FC<RegularLayoutProps> = ({\n breadcrumbLinks = NO_LINKS,\n breadcrumbActions,\n renderLink,\n title,\n titleSuffix,\n subtitle,\n description,\n buttons = NO_BUTTONS,\n loading = false,\n children,\n centered = false,\n noPadding = false,\n contentGap = 'small',\n alert,\n role,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className = '',\n style,\n}) => {\n const hasBack = hasBackButton(breadcrumbLinks);\n const contentPadding = noPadding ? 0 : centered ? '5vh 14vw' : '40px';\n // Published so a full-bleed child (CardStrip's bottom rule) can cancel it and re-apply\n // it as its own padding, instead of hardcoding the gutter at the call site.\n const contentInset = noPadding ? '0px' : centered ? '14vw' : '40px';\n const hasHeaderBlock = Boolean(\n loading || title || subtitle || description || buttons.length > 0,\n );\n\n const subtitleNode = subtitle ? (\n loading ? (\n <Skeleton.Input width={120} height={24} />\n ) : (\n <Text color=\"secondary\" size=\"small\">\n {subtitle}\n </Text>\n )\n ) : null;\n\n const titleNode = loading ? (\n <Skeleton.Input width={200} height={40} />\n ) : title ? (\n <div className=\"flex items-center\" style={{ gap: 12 }}>\n <PageTitle>{title}</PageTitle>\n {titleSuffix}\n </div>\n ) : null;\n\n const descriptionNode = description ? (\n loading ? (\n <Skeleton.Input width={120} height={24} />\n ) : (\n <Text color=\"secondary\" style={{ lineHeight: 1.6 }}>\n {description}\n </Text>\n )\n ) : null;\n\n return (\n <main\n className={`${CARD_CLASSES} ${className}`}\n style={{ borderRadius: CARD_RADIUS, minHeight: CARD_MIN_HEIGHT, ...style }}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-busy={loading || undefined}\n >\n <div\n className={`flex items-center ${DIVIDER_CLASSES}`}\n style={{\n height: HEADER_HEIGHT,\n paddingInlineStart: hasBack ? 16 : 28,\n paddingInlineEnd: 16,\n }}\n >\n <Breadcrumbs\n links={breadcrumbLinks}\n actions={breadcrumbActions}\n renderLink={renderLink}\n className=\"flex-1 min-w-0\"\n />\n </div>\n\n {alert ? (\n <div className={DIVIDER_CLASSES} style={{ padding: '10px 16px' }}>\n <Alert message={alert.message} type={alert.type} hasMargin={false} />\n </div>\n ) : null}\n\n <div\n className=\"flex flex-col\"\n style={\n {\n padding: contentPadding,\n minHeight: CONTENT_MIN_HEIGHT,\n gap: CONTENT_GAPS[contentGap],\n [CONTENT_INSET_VAR]: contentInset,\n } as React.CSSProperties\n }\n >\n {hasHeaderBlock ? (\n <div className=\"flex flex-col\" style={{ gap: 12 }}>\n {titleNode || subtitleNode || buttons.length > 0 ? (\n <div\n className=\"flex flex-wrap items-center justify-between\"\n style={{ gap: 12 }}\n >\n <div\n className=\"flex flex-col flex-auto min-w-0 overflow-hidden\"\n style={{ gap: 4 }}\n >\n {subtitleNode}\n {titleNode}\n </div>\n {loading ? null : <PageActions buttons={buttons} />}\n </div>\n ) : null}\n {descriptionNode}\n </div>\n ) : null}\n {children}\n </div>\n </main>\n );\n};\n\nexport default RegularLayout;\nexport { RegularLayout };\n"],"names":["CONTENT_GAPS","isDanger","button","toMenuItems","buttons","index","href","safeHref","item","PageActions","jsx","OverflowRow","hiddenCount","ActionMenu","jsxs","Button","NO_LINKS","NO_BUTTONS","RegularLayout","breadcrumbLinks","breadcrumbActions","renderLink","title","titleSuffix","subtitle","description","loading","children","centered","noPadding","contentGap","alert","role","ariaLabel","ariaLabelledBy","className","style","hasBack","hasBackButton","contentPadding","contentInset","hasHeaderBlock","subtitleNode","Skeleton","Text","titleNode","PageTitle","descriptionNode","CARD_CLASSES","CARD_RADIUS","CARD_MIN_HEIGHT","DIVIDER_CLASSES","HEADER_HEIGHT","Breadcrumbs","Alert","CONTENT_MIN_HEIGHT","CONTENT_INSET_VAR"],"mappings":"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"}
|
package/dist/components/Tag.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as n, jsxs as W } from "react/jsx-runtime";
|
|
2
|
-
import { useRef as
|
|
2
|
+
import { useRef as C, useState as A, useCallback as B } from "react";
|
|
3
3
|
import U from "./CustomIcons/DismissIcon.js";
|
|
4
4
|
import { FOCUS_RING as E } from "./focusRing.js";
|
|
5
5
|
import { activateOnEnterOrSpace as G } from "./keyboardActivation.js";
|
|
@@ -79,62 +79,63 @@ const q = (e) => {
|
|
|
79
79
|
bordered: i = !1,
|
|
80
80
|
onClick: r,
|
|
81
81
|
shadow: s = !1,
|
|
82
|
-
textTransform:
|
|
82
|
+
textTransform: x = "uppercase",
|
|
83
83
|
width: N,
|
|
84
|
-
paddingSize:
|
|
84
|
+
paddingSize: p = "default",
|
|
85
85
|
icon: l,
|
|
86
|
-
iconPosition:
|
|
87
|
-
iconColor:
|
|
86
|
+
iconPosition: g = "left",
|
|
87
|
+
iconColor: h,
|
|
88
88
|
pointerType: u,
|
|
89
|
-
onRemove:
|
|
89
|
+
onRemove: d,
|
|
90
90
|
tooltip: m,
|
|
91
91
|
tooltipDescribesTag: z = !0,
|
|
92
92
|
className: O = ""
|
|
93
93
|
}) => {
|
|
94
|
-
const b =
|
|
94
|
+
const b = h ? { color: _(h) } : void 0, f = C(null), o = C(null), [T, j] = A(!1), v = typeof e == "string" || typeof e == "number", I = B((t) => {
|
|
95
95
|
var S;
|
|
96
|
-
if ((S =
|
|
96
|
+
if ((S = f.current) == null || S.disconnect(), f.current = null, o.current !== null && (cancelAnimationFrame(o.current), o.current = null), !t || typeof ResizeObserver > "u")
|
|
97
97
|
return;
|
|
98
98
|
const L = () => {
|
|
99
99
|
o.current = null, t.clientWidth !== 0 && j((R) => {
|
|
100
|
-
const
|
|
101
|
-
return R ===
|
|
100
|
+
const $ = t.scrollWidth > t.clientWidth;
|
|
101
|
+
return R === $ ? R : $;
|
|
102
102
|
});
|
|
103
103
|
}, w = () => {
|
|
104
104
|
o.current === null && (o.current = requestAnimationFrame(L));
|
|
105
105
|
};
|
|
106
|
-
w(),
|
|
107
|
-
}, []),
|
|
106
|
+
w(), f.current = Y(t, w);
|
|
107
|
+
}, []), k = (t) => {
|
|
108
108
|
r && (t.stopPropagation(), t.preventDefault(), r());
|
|
109
109
|
}, D = [
|
|
110
110
|
K(N),
|
|
111
|
-
M(a,
|
|
112
|
-
|
|
111
|
+
M(a, p, c),
|
|
112
|
+
x === "uppercase" ? "uppercase" : "normal-case",
|
|
113
113
|
r ? `cursor-pointer ${E}` : u ? `cursor-${u}` : "",
|
|
114
114
|
v ? "min-w-0 max-w-full" : "",
|
|
115
115
|
O
|
|
116
116
|
].filter(Boolean).join(" "), F = {
|
|
117
|
-
...X(a, i, s,
|
|
117
|
+
...X(a, i, s, p),
|
|
118
118
|
...!r && !u && { cursor: V }
|
|
119
119
|
}, y = /* @__PURE__ */ W(
|
|
120
120
|
"span",
|
|
121
121
|
{
|
|
122
122
|
className: D,
|
|
123
|
-
onClick:
|
|
123
|
+
onClick: k,
|
|
124
|
+
role: r && !d ? "button" : void 0,
|
|
124
125
|
tabIndex: r ? 0 : void 0,
|
|
125
126
|
onKeyDown: r ? (t) => G(t, r) : void 0,
|
|
126
127
|
style: F,
|
|
127
128
|
children: [
|
|
128
|
-
l &&
|
|
129
|
-
v ? /* @__PURE__ */ n("span", { className: "flex items-center min-w-0", children: /* @__PURE__ */ n("span", { ref:
|
|
130
|
-
l &&
|
|
131
|
-
|
|
129
|
+
l && g === "left" && /* @__PURE__ */ n("span", { className: "mr-1 flex items-center", style: b, children: l }),
|
|
130
|
+
v ? /* @__PURE__ */ n("span", { className: "flex items-center min-w-0", children: /* @__PURE__ */ n("span", { ref: I, className: "block min-w-0 truncate", children: e }, String(e)) }) : /* @__PURE__ */ n("span", { className: "flex items-center", children: e }),
|
|
131
|
+
l && g === "right" && /* @__PURE__ */ n("span", { className: "ml-1 flex items-center", style: b, children: l }),
|
|
132
|
+
d && /* @__PURE__ */ n(
|
|
132
133
|
"button",
|
|
133
134
|
{
|
|
134
135
|
type: "button",
|
|
135
136
|
"aria-label": `Remove ${typeof e == "string" ? e : ""}`,
|
|
136
137
|
onClick: (t) => {
|
|
137
|
-
t.stopPropagation(),
|
|
138
|
+
t.stopPropagation(), d(t);
|
|
138
139
|
},
|
|
139
140
|
className: "ml-0.5 flex items-center justify-center shrink-0 border-none bg-transparent text-current cursor-pointer p-0 leading-none opacity-70 hover:opacity-100",
|
|
140
141
|
children: /* @__PURE__ */ n(U, { size: 9 })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tag.js","sources":["../../src/components/Tag.tsx"],"sourcesContent":["import React, { useCallback, useRef, useState } from 'react';\nimport DismissIcon from './CustomIcons/DismissIcon';\nimport { FOCUS_RING } from './focusRing';\nimport { activateOnEnterOrSpace } from './keyboardActivation';\nimport Tooltip from './Tooltip';\nimport type { TextColor } from './Typography/Text';\nimport { getTextColor } from './Typography/textStyles';\n\nexport type TagType =\n | 'primary'\n | 'secondary'\n | 'default'\n | 'error'\n | 'warning'\n | 'success'\n | 'emphasis'\n | 'info'\n /** Marks content a machine produced rather than a person — provenance, not severity. */\n | 'assistant';\n\nexport type WidthSize = 'large' | 'medium' | 'small' | 'xsmall';\n\nexport type PaddingSize = 'default' | 'compact';\n\ntype TagFontSize = 'xsmall' | 'small' | 'medium';\n\ninterface TagProps {\n value: string | number | React.ReactNode;\n /** Defaults to 12px. Use `xsmall` for a secondary badge beside a primary one. */\n fontSize?: TagFontSize;\n type?: TagType;\n bordered?: boolean;\n shadow?: boolean;\n textTransform?: 'none' | 'uppercase';\n width?: WidthSize;\n paddingSize?: PaddingSize;\n icon?: React.ReactNode;\n iconPosition?: 'left' | 'right';\n iconColor?: TextColor;\n /** The cursor over a tag that is not clickable. Unset, it is whatever an ancestor sets\n * through `--malachite-ctx-tag-cursor` (a `NavItem` row sets its pointer), else the arrow. */\n pointerType?: 'pointer' | 'default';\n onClick?: () => void;\n onRemove?: (e: React.MouseEvent) => void;\n /** Explains the tag on hover. Takes the place of the truncation tooltip, which only repeats\n * the label. */\n tooltip?: string;\n /** False when something else already reads `tooltip` to assistive tech, such as a card's\n * description, so it is not announced twice. */\n tooltipDescribesTag?: boolean;\n className?: string;\n}\n\nconst getFontSizeClass = (fontSize?: TagFontSize): string => {\n switch (fontSize) {\n case 'xsmall':\n return 'text-[length:var(--malachite-font-size-xsmall)]';\n case 'small':\n return 'text-[length:var(--malachite-font-size-small)]';\n case 'medium':\n return 'text-[length:var(--malachite-font-size-medium)]';\n default:\n return 'text-xs';\n }\n};\n\nconst getWidthClasses = (width?: WidthSize): string => {\n switch (width) {\n case 'large':\n return 'w-[88px]';\n case 'medium':\n return 'w-[44px]';\n case 'small':\n return 'w-[24px]';\n case 'xsmall':\n return 'w-[20px]';\n default:\n return 'w-fit';\n }\n};\n\nconst getPaddingClasses = (paddingSize?: PaddingSize): string => {\n return paddingSize === 'compact' ? 'px-[6px] py-[1px]' : 'px-2 py-1';\n};\n\nconst getBorderRadiusClasses = (paddingSize?: PaddingSize): React.CSSProperties => {\n return {\n borderRadius:\n paddingSize === 'compact' ? 'var(--malachite-radius-md)' : 'var(--malachite-radius-lg)',\n };\n};\n\nconst getTypeClasses = (\n type: TagType,\n paddingSize?: PaddingSize,\n fontSize?: TagFontSize,\n) => {\n const baseClasses = `inline-flex items-center justify-center ${getPaddingClasses(paddingSize)} ${getFontSizeClass(fontSize)} font-medium leading-normal tracking-[0.11px]`;\n\n const typeStyles = {\n primary: {\n text: 'text-[var(--malachite-tag-primary-foreground)]',\n },\n secondary: {\n text: 'text-[var(--malachite-tag-secondary-foreground)]',\n },\n default: {\n text: 'text-[var(--malachite-tag-default-foreground)]',\n },\n error: {\n text: 'text-[var(--malachite-tag-error-foreground)]',\n },\n warning: {\n text: 'text-[var(--malachite-tag-warning-foreground)]',\n },\n success: {\n text: 'text-[var(--malachite-tag-success-foreground)]',\n },\n emphasis: {\n text: 'text-[var(--malachite-tag-emphasis-foreground)]',\n },\n info: {\n text: 'text-[var(--malachite-tag-info-foreground)]',\n },\n assistant: {\n text: 'text-[var(--malachite-tag-assistant-foreground)]',\n },\n };\n\n const style = typeStyles[type];\n const classes = [baseClasses, style.text].filter(Boolean);\n\n return classes.join(' ');\n};\n\n/*\n * Context channels, not theme tokens: no palette value, not settable through `applyTheme`,\n * absent from `getCurrentTheme`. The ground goes under the tint, which is translucent and on\n * its own takes the colour of whatever is behind the tag, a row's hover or current tint included.\n */\nconst GROUND = 'var(--malachite-ctx-tag-ground, transparent)';\nconst IDLE_CURSOR = 'var(--malachite-ctx-tag-cursor, default)';\n\nconst getTypeStyles = (\n type: TagType,\n bordered?: boolean,\n shadow?: boolean,\n paddingSize?: PaddingSize,\n): React.CSSProperties => {\n const tint = `var(--malachite-tag-${type}-background)`;\n const styles: React.CSSProperties = {\n ...getBorderRadiusClasses(paddingSize),\n backgroundColor: GROUND,\n backgroundImage: `linear-gradient(${tint}, ${tint})`,\n };\n\n if (bordered) {\n styles.border = `2px solid var(--malachite-tag-${type}-border)`;\n }\n\n if (type === 'emphasis') {\n styles.boxShadow = '0px 0px 10px 0px var(--malachite-tag-emphasis-shadow)';\n } else if (shadow) {\n styles.boxShadow = `0 10px 15px -3px var(--malachite-tag-${type}-shadow)`;\n }\n\n return styles;\n};\n\nconst observeLabelSize = (el: HTMLSpanElement, onResize: () => void): ResizeObserver => {\n const observer = new ResizeObserver(onResize);\n observer.observe(el);\n return observer;\n};\n\nconst Tag: React.FC<TagProps> = ({\n value,\n fontSize,\n type = 'default',\n bordered = false,\n onClick,\n shadow = false,\n textTransform = 'uppercase',\n width,\n paddingSize = 'default',\n icon,\n iconPosition = 'left',\n iconColor,\n pointerType,\n onRemove,\n tooltip,\n tooltipDescribesTag = true,\n className = '',\n}) => {\n const iconColorStyle = iconColor ? { color: getTextColor(iconColor) } : undefined;\n const observerRef = useRef<ResizeObserver | null>(null);\n const frameRef = useRef<number | null>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n // Truncation applies to plain text labels; ReactNode values render untouched.\n const isTextLabel = typeof value === 'string' || typeof value === 'number';\n\n // Memoized so the ref keeps a stable identity. An inline ref callback would be\n // re-invoked (null, then the node) on every render, tearing down and recreating\n // the ResizeObserver each time; this way it only runs on mount/unmount.\n const setLabelRef = useCallback((el: HTMLSpanElement | null) => {\n observerRef.current?.disconnect();\n observerRef.current = null;\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current);\n frameRef.current = null;\n }\n if (!el || typeof ResizeObserver === 'undefined') {\n return;\n }\n const measure = (): void => {\n frameRef.current = null;\n if (el.clientWidth === 0) {\n return;\n }\n setIsTruncated((prev) => {\n const next = el.scrollWidth > el.clientWidth;\n return prev === next ? prev : next;\n });\n };\n const check = (): void => {\n if (frameRef.current !== null) {\n return;\n }\n frameRef.current = requestAnimationFrame(measure);\n };\n check();\n observerRef.current = observeLabelSize(el, check);\n }, []);\n\n const handleClick = (e: React.MouseEvent) => {\n if (onClick) {\n e.stopPropagation();\n e.preventDefault();\n onClick();\n }\n };\n\n const baseClasses = [\n getWidthClasses(width),\n getTypeClasses(type, paddingSize, fontSize),\n textTransform === 'uppercase' ? 'uppercase' : 'normal-case',\n onClick ? `cursor-pointer ${FOCUS_RING}` : pointerType ? `cursor-${pointerType}` : '',\n isTextLabel ? 'min-w-0 max-w-full' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const typeStyles = {\n ...getTypeStyles(type, bordered, shadow, paddingSize),\n ...(!onClick && !pointerType && { cursor: IDLE_CURSOR }),\n };\n\n const tag = (\n <span\n className={baseClasses}\n onClick={handleClick}\n // No `role=\"button\"`: it takes presentational children, so a Tag carrying an\n // `onRemove` close button would hide that button from assistive tech.\n tabIndex={onClick ? 0 : undefined}\n onKeyDown={onClick ? (event) => activateOnEnterOrSpace(event, onClick) : undefined}\n style={typeStyles}\n >\n {icon && iconPosition === 'left' && (\n <span className=\"mr-1 flex items-center\" style={iconColorStyle}>\n {icon}\n </span>\n )}\n {isTextLabel ? (\n <span className=\"flex items-center min-w-0\">\n <span key={String(value)} ref={setLabelRef} className=\"block min-w-0 truncate\">\n {value}\n </span>\n </span>\n ) : (\n <span className=\"flex items-center\">{value}</span>\n )}\n {icon && iconPosition === 'right' && (\n <span className=\"ml-1 flex items-center\" style={iconColorStyle}>\n {icon}\n </span>\n )}\n {onRemove && (\n <button\n type=\"button\"\n aria-label={`Remove ${typeof value === 'string' ? value : ''}`}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(e);\n }}\n className=\"ml-0.5 flex items-center justify-center shrink-0 border-none bg-transparent text-current cursor-pointer p-0 leading-none opacity-70 hover:opacity-100\"\n >\n {/* A bare cross, not `CloseIcon`'s circled one: this sits inside the chip\n it removes, where a second enclosing ring reads as an object of its own\n rather than as part of the label. */}\n <DismissIcon size={9} />\n </button>\n )}\n </span>\n );\n\n if (!tooltip && !isTruncated) {\n return tag;\n }\n\n return (\n <Tooltip\n text={tooltip ?? value}\n placement=\"top\"\n wrapChildren={false}\n isShrinkable\n inline={tooltip !== undefined}\n describesTrigger={tooltip === undefined || tooltipDescribesTag}\n triggerAs=\"span\"\n >\n {tag}\n </Tooltip>\n );\n};\n\nexport default Tag;\nexport { Tag };\nexport type { TagProps };\n"],"names":["getFontSizeClass","fontSize","getWidthClasses","width","getPaddingClasses","paddingSize","getBorderRadiusClasses","getTypeClasses","type","baseClasses","style","GROUND","IDLE_CURSOR","getTypeStyles","bordered","shadow","tint","styles","observeLabelSize","el","onResize","observer","Tag","value","onClick","textTransform","icon","iconPosition","iconColor","pointerType","onRemove","tooltip","tooltipDescribesTag","className","iconColorStyle","getTextColor","observerRef","useRef","frameRef","isTruncated","setIsTruncated","useState","isTextLabel","setLabelRef","useCallback","_a","measure","prev","next","check","handleClick","e","FOCUS_RING","typeStyles","tag","jsxs","event","activateOnEnterOrSpace","jsx","DismissIcon","Tooltip"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tag.js","sources":["../../src/components/Tag.tsx"],"sourcesContent":["import React, { useCallback, useRef, useState } from 'react';\nimport DismissIcon from './CustomIcons/DismissIcon';\nimport { FOCUS_RING } from './focusRing';\nimport { activateOnEnterOrSpace } from './keyboardActivation';\nimport Tooltip from './Tooltip';\nimport type { TextColor } from './Typography/Text';\nimport { getTextColor } from './Typography/textStyles';\n\nexport type TagType =\n | 'primary'\n | 'secondary'\n | 'default'\n | 'error'\n | 'warning'\n | 'success'\n | 'emphasis'\n | 'info'\n /** Marks content a machine produced rather than a person — provenance, not severity. */\n | 'assistant';\n\nexport type WidthSize = 'large' | 'medium' | 'small' | 'xsmall';\n\nexport type PaddingSize = 'default' | 'compact';\n\ntype TagFontSize = 'xsmall' | 'small' | 'medium';\n\ninterface TagProps {\n value: string | number | React.ReactNode;\n /** Defaults to 12px. Use `xsmall` for a secondary badge beside a primary one. */\n fontSize?: TagFontSize;\n type?: TagType;\n bordered?: boolean;\n shadow?: boolean;\n textTransform?: 'none' | 'uppercase';\n width?: WidthSize;\n paddingSize?: PaddingSize;\n icon?: React.ReactNode;\n iconPosition?: 'left' | 'right';\n iconColor?: TextColor;\n /** The cursor over a tag that is not clickable. Unset, it is whatever an ancestor sets\n * through `--malachite-ctx-tag-cursor` (a `NavItem` row sets its pointer), else the arrow. */\n pointerType?: 'pointer' | 'default';\n /** Makes it a button, unless `onRemove` is set; keep `value` and `icon` non-interactive. */\n onClick?: () => void;\n onRemove?: (e: React.MouseEvent) => void;\n /** Explains the tag on hover. Takes the place of the truncation tooltip, which only repeats\n * the label. */\n tooltip?: string;\n /** False when something else already reads `tooltip` to assistive tech, such as a card's\n * description, so it is not announced twice. */\n tooltipDescribesTag?: boolean;\n className?: string;\n}\n\nconst getFontSizeClass = (fontSize?: TagFontSize): string => {\n switch (fontSize) {\n case 'xsmall':\n return 'text-[length:var(--malachite-font-size-xsmall)]';\n case 'small':\n return 'text-[length:var(--malachite-font-size-small)]';\n case 'medium':\n return 'text-[length:var(--malachite-font-size-medium)]';\n default:\n return 'text-xs';\n }\n};\n\nconst getWidthClasses = (width?: WidthSize): string => {\n switch (width) {\n case 'large':\n return 'w-[88px]';\n case 'medium':\n return 'w-[44px]';\n case 'small':\n return 'w-[24px]';\n case 'xsmall':\n return 'w-[20px]';\n default:\n return 'w-fit';\n }\n};\n\nconst getPaddingClasses = (paddingSize?: PaddingSize): string => {\n return paddingSize === 'compact' ? 'px-[6px] py-[1px]' : 'px-2 py-1';\n};\n\nconst getBorderRadiusClasses = (paddingSize?: PaddingSize): React.CSSProperties => {\n return {\n borderRadius:\n paddingSize === 'compact' ? 'var(--malachite-radius-md)' : 'var(--malachite-radius-lg)',\n };\n};\n\nconst getTypeClasses = (\n type: TagType,\n paddingSize?: PaddingSize,\n fontSize?: TagFontSize,\n) => {\n const baseClasses = `inline-flex items-center justify-center ${getPaddingClasses(paddingSize)} ${getFontSizeClass(fontSize)} font-medium leading-normal tracking-[0.11px]`;\n\n const typeStyles = {\n primary: {\n text: 'text-[var(--malachite-tag-primary-foreground)]',\n },\n secondary: {\n text: 'text-[var(--malachite-tag-secondary-foreground)]',\n },\n default: {\n text: 'text-[var(--malachite-tag-default-foreground)]',\n },\n error: {\n text: 'text-[var(--malachite-tag-error-foreground)]',\n },\n warning: {\n text: 'text-[var(--malachite-tag-warning-foreground)]',\n },\n success: {\n text: 'text-[var(--malachite-tag-success-foreground)]',\n },\n emphasis: {\n text: 'text-[var(--malachite-tag-emphasis-foreground)]',\n },\n info: {\n text: 'text-[var(--malachite-tag-info-foreground)]',\n },\n assistant: {\n text: 'text-[var(--malachite-tag-assistant-foreground)]',\n },\n };\n\n const style = typeStyles[type];\n const classes = [baseClasses, style.text].filter(Boolean);\n\n return classes.join(' ');\n};\n\n/*\n * Context channels, not theme tokens: no palette value, not settable through `applyTheme`,\n * absent from `getCurrentTheme`. The ground goes under the tint, which is translucent and on\n * its own takes the colour of whatever is behind the tag, a row's hover or current tint included.\n */\nconst GROUND = 'var(--malachite-ctx-tag-ground, transparent)';\nconst IDLE_CURSOR = 'var(--malachite-ctx-tag-cursor, default)';\n\nconst getTypeStyles = (\n type: TagType,\n bordered?: boolean,\n shadow?: boolean,\n paddingSize?: PaddingSize,\n): React.CSSProperties => {\n const tint = `var(--malachite-tag-${type}-background)`;\n const styles: React.CSSProperties = {\n ...getBorderRadiusClasses(paddingSize),\n backgroundColor: GROUND,\n backgroundImage: `linear-gradient(${tint}, ${tint})`,\n };\n\n if (bordered) {\n styles.border = `2px solid var(--malachite-tag-${type}-border)`;\n }\n\n if (type === 'emphasis') {\n styles.boxShadow = '0px 0px 10px 0px var(--malachite-tag-emphasis-shadow)';\n } else if (shadow) {\n styles.boxShadow = `0 10px 15px -3px var(--malachite-tag-${type}-shadow)`;\n }\n\n return styles;\n};\n\nconst observeLabelSize = (el: HTMLSpanElement, onResize: () => void): ResizeObserver => {\n const observer = new ResizeObserver(onResize);\n observer.observe(el);\n return observer;\n};\n\nconst Tag: React.FC<TagProps> = ({\n value,\n fontSize,\n type = 'default',\n bordered = false,\n onClick,\n shadow = false,\n textTransform = 'uppercase',\n width,\n paddingSize = 'default',\n icon,\n iconPosition = 'left',\n iconColor,\n pointerType,\n onRemove,\n tooltip,\n tooltipDescribesTag = true,\n className = '',\n}) => {\n const iconColorStyle = iconColor ? { color: getTextColor(iconColor) } : undefined;\n const observerRef = useRef<ResizeObserver | null>(null);\n const frameRef = useRef<number | null>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n\n // Truncation applies to plain text labels; ReactNode values render untouched.\n const isTextLabel = typeof value === 'string' || typeof value === 'number';\n\n // Memoized so the ref keeps a stable identity. An inline ref callback would be\n // re-invoked (null, then the node) on every render, tearing down and recreating\n // the ResizeObserver each time; this way it only runs on mount/unmount.\n const setLabelRef = useCallback((el: HTMLSpanElement | null) => {\n observerRef.current?.disconnect();\n observerRef.current = null;\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current);\n frameRef.current = null;\n }\n if (!el || typeof ResizeObserver === 'undefined') {\n return;\n }\n const measure = (): void => {\n frameRef.current = null;\n if (el.clientWidth === 0) {\n return;\n }\n setIsTruncated((prev) => {\n const next = el.scrollWidth > el.clientWidth;\n return prev === next ? prev : next;\n });\n };\n const check = (): void => {\n if (frameRef.current !== null) {\n return;\n }\n frameRef.current = requestAnimationFrame(measure);\n };\n check();\n observerRef.current = observeLabelSize(el, check);\n }, []);\n\n const handleClick = (e: React.MouseEvent) => {\n if (onClick) {\n e.stopPropagation();\n e.preventDefault();\n onClick();\n }\n };\n\n const baseClasses = [\n getWidthClasses(width),\n getTypeClasses(type, paddingSize, fontSize),\n textTransform === 'uppercase' ? 'uppercase' : 'normal-case',\n onClick ? `cursor-pointer ${FOCUS_RING}` : pointerType ? `cursor-${pointerType}` : '',\n isTextLabel ? 'min-w-0 max-w-full' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const typeStyles = {\n ...getTypeStyles(type, bordered, shadow, paddingSize),\n ...(!onClick && !pointerType && { cursor: IDLE_CURSOR }),\n };\n\n const tag = (\n <span\n className={baseClasses}\n onClick={handleClick}\n // Not with `onRemove`: the role would hide its close button from assistive tech.\n role={onClick && !onRemove ? 'button' : undefined}\n tabIndex={onClick ? 0 : undefined}\n onKeyDown={onClick ? (event) => activateOnEnterOrSpace(event, onClick) : undefined}\n style={typeStyles}\n >\n {icon && iconPosition === 'left' && (\n <span className=\"mr-1 flex items-center\" style={iconColorStyle}>\n {icon}\n </span>\n )}\n {isTextLabel ? (\n <span className=\"flex items-center min-w-0\">\n <span key={String(value)} ref={setLabelRef} className=\"block min-w-0 truncate\">\n {value}\n </span>\n </span>\n ) : (\n <span className=\"flex items-center\">{value}</span>\n )}\n {icon && iconPosition === 'right' && (\n <span className=\"ml-1 flex items-center\" style={iconColorStyle}>\n {icon}\n </span>\n )}\n {onRemove && (\n <button\n type=\"button\"\n aria-label={`Remove ${typeof value === 'string' ? value : ''}`}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(e);\n }}\n className=\"ml-0.5 flex items-center justify-center shrink-0 border-none bg-transparent text-current cursor-pointer p-0 leading-none opacity-70 hover:opacity-100\"\n >\n {/* A bare cross, not `CloseIcon`'s circled one: this sits inside the chip\n it removes, where a second enclosing ring reads as an object of its own\n rather than as part of the label. */}\n <DismissIcon size={9} />\n </button>\n )}\n </span>\n );\n\n if (!tooltip && !isTruncated) {\n return tag;\n }\n\n return (\n <Tooltip\n text={tooltip ?? value}\n placement=\"top\"\n wrapChildren={false}\n isShrinkable\n inline={tooltip !== undefined}\n describesTrigger={tooltip === undefined || tooltipDescribesTag}\n triggerAs=\"span\"\n >\n {tag}\n </Tooltip>\n );\n};\n\nexport default Tag;\nexport { Tag };\nexport type { TagProps };\n"],"names":["getFontSizeClass","fontSize","getWidthClasses","width","getPaddingClasses","paddingSize","getBorderRadiusClasses","getTypeClasses","type","baseClasses","style","GROUND","IDLE_CURSOR","getTypeStyles","bordered","shadow","tint","styles","observeLabelSize","el","onResize","observer","Tag","value","onClick","textTransform","icon","iconPosition","iconColor","pointerType","onRemove","tooltip","tooltipDescribesTag","className","iconColorStyle","getTextColor","observerRef","useRef","frameRef","isTruncated","setIsTruncated","useState","isTextLabel","setLabelRef","useCallback","_a","measure","prev","next","check","handleClick","e","FOCUS_RING","typeStyles","tag","jsxs","event","activateOnEnterOrSpace","jsx","DismissIcon","Tooltip"],"mappings":"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"}
|