@stackone/malachite 2.23.3 → 2.24.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.
Files changed (33) hide show
  1. package/COMPONENTS.md +7 -7
  2. package/dist/components/ActionMenu.js +103 -87
  3. package/dist/components/ActionMenu.js.map +1 -1
  4. package/dist/components/AppLogo.js.map +1 -1
  5. package/dist/components/CodeBlockHighlighter.js +4 -3
  6. package/dist/components/CodeBlockHighlighter.js.map +1 -1
  7. package/dist/components/Dropdown.js +374 -360
  8. package/dist/components/Dropdown.js.map +1 -1
  9. package/dist/components/MultiSelect.js +295 -284
  10. package/dist/components/MultiSelect.js.map +1 -1
  11. package/dist/components/Search.js +17 -14
  12. package/dist/components/Search.js.map +1 -1
  13. package/dist/components/Tabs.js +52 -31
  14. package/dist/components/Tabs.js.map +1 -1
  15. package/dist/components/Toolbar.js +47 -14
  16. package/dist/components/Toolbar.js.map +1 -1
  17. package/dist/components/Tooltip.js +55 -55
  18. package/dist/components/Tooltip.js.map +1 -1
  19. package/dist/components/Typography/EllipsisText.js +32 -17
  20. package/dist/components/Typography/EllipsisText.js.map +1 -1
  21. package/dist/components/controlWidth.js +5 -0
  22. package/dist/components/controlWidth.js.map +1 -0
  23. package/dist/components/floatingMenuGeometry.js +71 -0
  24. package/dist/components/floatingMenuGeometry.js.map +1 -0
  25. package/dist/components/portalOverlay.js +25 -23
  26. package/dist/components/portalOverlay.js.map +1 -1
  27. package/dist/components/queryInputGeometry.js +6 -6
  28. package/dist/components/queryInputGeometry.js.map +1 -1
  29. package/dist/index.d.ts +52 -3
  30. package/dist/index.js +360 -356
  31. package/package.json +1 -1
  32. package/dist/components/dropdownPanelPosition.js +0 -38
  33. package/dist/components/dropdownPanelPosition.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"portalOverlay.js","sources":["../../src/components/portalOverlay.ts"],"sourcesContent":["// Host \"kill the ad overlay\" CSS erases anything portaled into document.body: `body >\n// div:not([class])` matches an unclassed body child, `[style*=\"2147483\"]` a max-int z-index.\n// The second matches the style ATTRIBUTE, so declaring z-index here keeps max-int stacking.\n\nimport { injectStyleSheet } from './injectStyleSheet';\n\n/** One selector for every malachite overlay, so a host allow-lists them in one rule. */\nexport const OVERLAY_ATTR = 'data-malachite-overlay';\n\n// Values avoid `panel`/`popup`/`overlay`/`tooltip`: a class defeats `:not([class])`, but one\n// matching `[class*=\"panel\"]` trades that hole for another these elements did not have.\nexport const OVERLAY_CLASS = {\n dropdown: 'malachite-dropdown-surface',\n multiselect: 'malachite-multiselect-surface',\n actionmenu: 'malachite-actionmenu-surface',\n tooltip: 'malachite-tip-surface',\n sidepanel: 'malachite-drawer-surface',\n modal: 'malachite-modal-surface',\n} as const;\n\nexport type OverlayName = keyof typeof OVERLAY_CLASS;\n\nexport const overlayIdentity = (name: OverlayName) => ({\n className: OVERLAY_CLASS[name],\n [OVERLAY_ATTR]: name,\n});\n\nconst OVERLAY_STYLE_ID = 'malachite-overlay-styles';\n\n/**\n * Where SidePanel and Modal start. `useOverlayBehaviour` steps one per stacked overlay, so\n * paint order follows the focus stack rather than body order — a handful above this at most.\n */\nexport const OVERLAY_Z_BASE = 1000;\n\n/**\n * The dropdown band, which clears app chrome pinned just under max-int. One integer wide: a host\n * pins its chrome at max-int-1 and the tooltip band sits at max-int, so the stack cannot step\n * per layer the way the base band does — the top layer orders it, and where popover is\n * unsupported, document order does.\n */\nexport const OVERLAY_Z_ELEVATED = 2147483646;\n\n/** Marks a host in that band — an attribute, not an inline z-index; see above. */\nexport const OVERLAY_ELEVATED_ATTR = 'data-malachite-elevated';\n\n// Every overlay class, not the four promoted by default: one the reset misses wears the UA box.\nconst promotedSelector = (suffix: string) =>\n Object.values(OVERLAY_CLASS)\n .map((name) => `.${name}:popover-open${suffix}`)\n .join(', ');\n\n// Promotion drags in the UA `[popover]` box: `inset: 0` (which survives as right/bottom and\n// stretches a panel to the viewport edge), auto margins, a border, padding and fit-content\n// sizing. Reset to what these computed before promotion; their own inline styles still win.\nconst POPOVER_RESET =\n 'inset: auto; margin: 0; border: 0; padding: 0; width: auto; height: auto; ' +\n 'overflow: visible; background: none; color: inherit;';\n\nconst OVERLAY_RULES = [\n `.${OVERLAY_CLASS.dropdown}, .${OVERLAY_CLASS.multiselect}, .${OVERLAY_CLASS.actionmenu} { z-index: 2147483646; }`,\n `.${OVERLAY_CLASS.tooltip} { z-index: 2147483647; }`,\n];\n\nexport const ensureOverlayStyles = (): CSSStyleSheet | null =>\n injectStyleSheet(OVERLAY_STYLE_ID, OVERLAY_RULES);\n\n// Its own id like TOP_LAYER_STYLE_ID: a copy predating elevation would own OVERLAY_STYLE_ID.\nconst ELEVATED_STYLE_ID = 'malachite-overlay-elevated';\n\nconst ELEVATED_RULES = [\n `.${OVERLAY_CLASS.sidepanel}[${OVERLAY_ELEVATED_ATTR}], .${OVERLAY_CLASS.modal}[${OVERLAY_ELEVATED_ATTR}] { z-index: ${OVERLAY_Z_ELEVATED}; }`,\n];\n\nexport const ensureElevatedOverlayStyles = (): CSSStyleSheet | null =>\n injectStyleSheet(ELEVATED_STYLE_ID, ELEVATED_RULES);\n\n// Its own id, never folded into OVERLAY_STYLE_ID: injectStyleSheet keeps one sheet per id across\n// malachite copies sharing a realm, so a copy predating the reset would win that id and leave a\n// promoted overlay wearing the raw UA box. No copy has ever registered this one.\nconst TOP_LAYER_STYLE_ID = 'malachite-overlay-top-layer';\n\nconst TOP_LAYER_RULES = [\n `${promotedSelector('')} { ${POPOVER_RESET} }`,\n `${promotedSelector('::backdrop')} { display: none; }`,\n];\n\nexport const ensureTopLayerStyles = (): CSSStyleSheet | null => {\n // A sheet that installed does not mean its rules parsed: replaceSync (and the <style> path)\n // drop an unparseable rule silently rather than throwing, so an engine that chokes on\n // `:popover-open` or `::backdrop` hands back a valid, empty sheet.\n const sheet = injectStyleSheet(TOP_LAYER_STYLE_ID, TOP_LAYER_RULES);\n return sheet && sheet.cssRules.length > 0 ? sheet : null;\n};\n"],"names":["OVERLAY_ATTR","OVERLAY_CLASS","overlayIdentity","name","OVERLAY_STYLE_ID","OVERLAY_Z_BASE","OVERLAY_Z_ELEVATED","OVERLAY_ELEVATED_ATTR","promotedSelector","suffix","POPOVER_RESET","OVERLAY_RULES","ensureOverlayStyles","injectStyleSheet","ELEVATED_STYLE_ID","ELEVATED_RULES","ensureElevatedOverlayStyles","TOP_LAYER_STYLE_ID","TOP_LAYER_RULES","ensureTopLayerStyles","sheet"],"mappings":";AAOO,MAAMA,IAAe,0BAIfC,IAAgB;AAAA,EACzB,UAAU;AAAA,EACV,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,WAAW;AAAA,EACX,OAAO;AACX,GAIaC,IAAkB,CAACC,OAAuB;AAAA,EACnD,WAAWF,EAAcE,CAAI;AAAA,EAC7B,CAACH,CAAY,GAAGG;AACpB,IAEMC,IAAmB,4BAMZC,IAAiB,KAQjBC,IAAqB,YAGrBC,IAAwB,2BAG/BC,IAAmB,CAACC,MACtB,OAAO,OAAOR,CAAa,EACtB,IAAI,CAACE,MAAS,IAAIA,CAAI,gBAAgBM,CAAM,EAAE,EAC9C,KAAK,IAAI,GAKZC,IACF,kIAGEC,IAAgB;AAAA,EAClB,IAAIV,EAAc,QAAQ,MAAMA,EAAc,WAAW,MAAMA,EAAc,UAAU;AAAA,EACvF,IAAIA,EAAc,OAAO;AAC7B,GAEaW,IAAsB,MAC/BC,EAAiBT,GAAkBO,CAAa,GAG9CG,IAAoB,8BAEpBC,IAAiB;AAAA,EACnB,IAAId,EAAc,SAAS,IAAIM,CAAqB,OAAON,EAAc,KAAK,IAAIM,CAAqB,gBAAgBD,CAAkB;AAC7I,GAEaU,IAA8B,MACvCH,EAAiBC,GAAmBC,CAAc,GAKhDE,IAAqB,+BAErBC,IAAkB;AAAA,EACpB,GAAGV,EAAiB,EAAE,CAAC,MAAME,CAAa;AAAA,EAC1C,GAAGF,EAAiB,YAAY,CAAC;AACrC,GAEaW,IAAuB,MAA4B;AAI5D,QAAMC,IAAQP,EAAiBI,GAAoBC,CAAe;AAClE,SAAOE,KAASA,EAAM,SAAS,SAAS,IAAIA,IAAQ;AACxD;"}
1
+ {"version":3,"file":"portalOverlay.js","sources":["../../src/components/portalOverlay.ts"],"sourcesContent":["// Host \"kill the ad overlay\" CSS erases anything portaled into document.body: `body >\n// div:not([class])` matches an unclassed body child, `[style*=\"2147483\"]` a max-int z-index.\n// The second matches the style ATTRIBUTE, so declaring z-index here keeps max-int stacking.\n\nimport { injectStyleSheet } from './injectStyleSheet';\n\n/** One selector for every malachite overlay, so a host allow-lists them in one rule. */\nexport const OVERLAY_ATTR = 'data-malachite-overlay';\n\n// Values avoid `panel`/`popup`/`overlay`/`tooltip`: a class defeats `:not([class])`, but one\n// matching `[class*=\"panel\"]` trades that hole for another these elements did not have.\nexport const OVERLAY_CLASS = {\n dropdown: 'malachite-dropdown-surface',\n multiselect: 'malachite-multiselect-surface',\n actionmenu: 'malachite-actionmenu-surface',\n tooltip: 'malachite-tip-surface',\n sidepanel: 'malachite-drawer-surface',\n modal: 'malachite-modal-surface',\n} as const;\n\nexport type OverlayName = keyof typeof OVERLAY_CLASS;\n\nexport const overlayIdentity = (name: OverlayName) => ({\n className: OVERLAY_CLASS[name],\n [OVERLAY_ATTR]: name,\n});\n\nconst OVERLAY_STYLE_ID = 'malachite-overlay-styles';\n\n/**\n * Where SidePanel and Modal start. `useOverlayBehaviour` steps one per stacked overlay, so\n * paint order follows the focus stack rather than body order — a handful above this at most.\n */\nexport const OVERLAY_Z_BASE = 1000;\n\n/**\n * The dropdown band, which clears app chrome pinned just under max-int. One integer wide: a host\n * pins its chrome at max-int-1 and the tooltip band sits at max-int, so the stack cannot step\n * per layer the way the base band does — the top layer orders it, and where popover is\n * unsupported, document order does.\n */\nexport const OVERLAY_Z_ELEVATED = 2147483646;\n\n/** Marks a host in that band — an attribute, not an inline z-index; see above. */\nexport const OVERLAY_ELEVATED_ATTR = 'data-malachite-elevated';\n\n// Every overlay class, not the four promoted by default: one the reset misses wears the UA box.\nconst promotedSelector = (suffix: string) =>\n Object.values(OVERLAY_CLASS)\n .map((name) => `.${name}:popover-open${suffix}`)\n .join(', ');\n\n// Promotion drags in the UA `[popover]` box: `inset: 0` (which survives as right/bottom and\n// stretches a panel to the viewport edge), auto margins, a border, padding and fit-content\n// sizing. Reset to what these computed before promotion; their own inline styles still win.\nconst POPOVER_RESET =\n 'inset: auto; margin: 0; border: 0; padding: 0; width: auto; height: auto; ' +\n 'overflow: visible; background: none; color: inherit;';\n\nconst OVERLAY_RULES = [\n `.${OVERLAY_CLASS.dropdown}, .${OVERLAY_CLASS.multiselect}, .${OVERLAY_CLASS.actionmenu} { z-index: 2147483646; }`,\n `.${OVERLAY_CLASS.tooltip} { z-index: 2147483647; }`,\n];\n\n// Its own id, never folded into OVERLAY_STYLE_ID: injectStyleSheet keeps one sheet per id across\n// malachite copies sharing a realm, so a copy predating this rule would win that id and leave a\n// portaled menu on the host page's box model — a 280px Options menu painting 298. No copy has\n// ever registered this one.\nconst MENU_BOX_STYLE_ID = 'malachite-overlay-menu-box';\n\n// The scoped stylesheet makes everything border-box; a portal escapes it onto a host page that\n// may have no reset at all, while the geometry is computed as a CSS width.\nconst MENU_BOX_RULES = [\n `.${OVERLAY_CLASS.dropdown}, .${OVERLAY_CLASS.dropdown} *,` +\n ` .${OVERLAY_CLASS.multiselect}, .${OVERLAY_CLASS.multiselect} *,` +\n ` .${OVERLAY_CLASS.actionmenu}, .${OVERLAY_CLASS.actionmenu} *` +\n ' { box-sizing: border-box; }',\n];\n\nexport const ensureOverlayStyles = (): CSSStyleSheet | null => {\n injectStyleSheet(MENU_BOX_STYLE_ID, MENU_BOX_RULES);\n return injectStyleSheet(OVERLAY_STYLE_ID, OVERLAY_RULES);\n};\n\n// Its own id like TOP_LAYER_STYLE_ID: a copy predating elevation would own OVERLAY_STYLE_ID.\nconst ELEVATED_STYLE_ID = 'malachite-overlay-elevated';\n\nconst ELEVATED_RULES = [\n `.${OVERLAY_CLASS.sidepanel}[${OVERLAY_ELEVATED_ATTR}], .${OVERLAY_CLASS.modal}[${OVERLAY_ELEVATED_ATTR}] { z-index: ${OVERLAY_Z_ELEVATED}; }`,\n];\n\nexport const ensureElevatedOverlayStyles = (): CSSStyleSheet | null =>\n injectStyleSheet(ELEVATED_STYLE_ID, ELEVATED_RULES);\n\n// Its own id, never folded into OVERLAY_STYLE_ID: injectStyleSheet keeps one sheet per id across\n// malachite copies sharing a realm, so a copy predating the reset would win that id and leave a\n// promoted overlay wearing the raw UA box. No copy has ever registered this one.\nconst TOP_LAYER_STYLE_ID = 'malachite-overlay-top-layer';\n\nconst TOP_LAYER_RULES = [\n `${promotedSelector('')} { ${POPOVER_RESET} }`,\n `${promotedSelector('::backdrop')} { display: none; }`,\n];\n\nexport const ensureTopLayerStyles = (): CSSStyleSheet | null => {\n // A sheet that installed does not mean its rules parsed: replaceSync (and the <style> path)\n // drop an unparseable rule silently rather than throwing, so an engine that chokes on\n // `:popover-open` or `::backdrop` hands back a valid, empty sheet.\n const sheet = injectStyleSheet(TOP_LAYER_STYLE_ID, TOP_LAYER_RULES);\n return sheet && sheet.cssRules.length > 0 ? sheet : null;\n};\n"],"names":["OVERLAY_ATTR","OVERLAY_CLASS","overlayIdentity","name","OVERLAY_STYLE_ID","OVERLAY_Z_BASE","OVERLAY_Z_ELEVATED","OVERLAY_ELEVATED_ATTR","promotedSelector","suffix","POPOVER_RESET","OVERLAY_RULES","MENU_BOX_STYLE_ID","MENU_BOX_RULES","ensureOverlayStyles","injectStyleSheet","ELEVATED_STYLE_ID","ELEVATED_RULES","ensureElevatedOverlayStyles","TOP_LAYER_STYLE_ID","TOP_LAYER_RULES","ensureTopLayerStyles","sheet"],"mappings":";AAOO,MAAMA,IAAe,0BAIfC,IAAgB;AAAA,EACzB,UAAU;AAAA,EACV,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,WAAW;AAAA,EACX,OAAO;AACX,GAIaC,IAAkB,CAACC,OAAuB;AAAA,EACnD,WAAWF,EAAcE,CAAI;AAAA,EAC7B,CAACH,CAAY,GAAGG;AACpB,IAEMC,IAAmB,4BAMZC,IAAiB,KAQjBC,IAAqB,YAGrBC,IAAwB,2BAG/BC,IAAmB,CAACC,MACtB,OAAO,OAAOR,CAAa,EACtB,IAAI,CAACE,MAAS,IAAIA,CAAI,gBAAgBM,CAAM,EAAE,EAC9C,KAAK,IAAI,GAKZC,IACF,kIAGEC,IAAgB;AAAA,EAClB,IAAIV,EAAc,QAAQ,MAAMA,EAAc,WAAW,MAAMA,EAAc,UAAU;AAAA,EACvF,IAAIA,EAAc,OAAO;AAC7B,GAMMW,IAAoB,8BAIpBC,IAAiB;AAAA,EACnB,IAAIZ,EAAc,QAAQ,MAAMA,EAAc,QAAQ,QAC7CA,EAAc,WAAW,MAAMA,EAAc,WAAW,QACxDA,EAAc,UAAU,MAAMA,EAAc,UAAU;AAEnE,GAEaa,IAAsB,OAC/BC,EAAiBH,GAAmBC,CAAc,GAC3CE,EAAiBX,GAAkBO,CAAa,IAIrDK,IAAoB,8BAEpBC,IAAiB;AAAA,EACnB,IAAIhB,EAAc,SAAS,IAAIM,CAAqB,OAAON,EAAc,KAAK,IAAIM,CAAqB,gBAAgBD,CAAkB;AAC7I,GAEaY,IAA8B,MACvCH,EAAiBC,GAAmBC,CAAc,GAKhDE,IAAqB,+BAErBC,IAAkB;AAAA,EACpB,GAAGZ,EAAiB,EAAE,CAAC,MAAME,CAAa;AAAA,EAC1C,GAAGF,EAAiB,YAAY,CAAC;AACrC,GAEaa,IAAuB,MAA4B;AAI5D,QAAMC,IAAQP,EAAiBI,GAAoBC,CAAe;AAClE,SAAOE,KAASA,EAAM,SAAS,SAAS,IAAIA,IAAQ;AACxD;"}
@@ -1,24 +1,24 @@
1
- import { PANEL_VIEWPORT_PADDING_PX as t } from "./dropdownPanelPosition.js";
2
- const c = 8, A = ({
1
+ import { MENU_VIEWPORT_PADDING_PX as t } from "./floatingMenuGeometry.js";
2
+ const c = 8, E = ({
3
3
  inputRect: o,
4
4
  caretOffsetPx: r,
5
- menuWidth: P,
5
+ menuWidth: M,
6
6
  menuHeight: m,
7
7
  viewportWidth: s,
8
8
  viewportHeight: _
9
9
  }) => {
10
- const a = Math.min(P, s - t * 2), e = s - a - t, M = Math.max(
10
+ const a = Math.min(M, s - t * 2), e = s - a - t, P = Math.max(
11
11
  t,
12
12
  Math.min(o.left + r, e)
13
13
  ), f = _ - o.bottom, n = m > 0 && f < m + t;
14
14
  return {
15
15
  top: n ? o.top - m - c : o.bottom + c,
16
- left: M,
16
+ left: P,
17
17
  width: a,
18
18
  openUp: n
19
19
  };
20
20
  };
21
21
  export {
22
- A as computeCaretMenuGeometry
22
+ E as computeCaretMenuGeometry
23
23
  };
24
24
  //# sourceMappingURL=queryInputGeometry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryInputGeometry.js","sources":["../../src/components/queryInputGeometry.ts"],"sourcesContent":["// Pure geometry for the caret-anchored suggestion menu. No DOM access, no React, so it can be\n// unit tested directly even though jsdom cannot lay out text (see QueryInput.tsx's caret\n// measurement, which always reads 0 there).\n\nimport { PANEL_VIEWPORT_PADDING_PX } from './dropdownPanelPosition';\n\nconst CARET_MENU_GAP_PX = 8;\n\nexport interface CaretMenuGeometryInput {\n inputRect: Pick<DOMRect, 'top' | 'left' | 'right' | 'bottom'>;\n /** Caret distance from the start of the text box, already adjusted for scrollLeft. */\n caretOffsetPx: number;\n menuWidth: number;\n menuHeight: number;\n viewportWidth: number;\n viewportHeight: number;\n}\n\nexport interface CaretMenuGeometry {\n top: number;\n left: number;\n /** What the menu may occupy once the viewport has had its say. */\n width: number;\n openUp: boolean;\n}\n\nexport const computeCaretMenuGeometry = ({\n inputRect,\n caretOffsetPx,\n menuWidth,\n menuHeight,\n viewportWidth,\n viewportHeight,\n}: CaretMenuGeometryInput): CaretMenuGeometry => {\n // Capped before `left` is derived, the way `computePanelGeometry` does it: a menu wider\n // than the viewport otherwise pins to the left padding and still runs off the right edge.\n const width = Math.min(menuWidth, viewportWidth - PANEL_VIEWPORT_PADDING_PX * 2);\n const maxLeft = viewportWidth - width - PANEL_VIEWPORT_PADDING_PX;\n const left = Math.max(\n PANEL_VIEWPORT_PADDING_PX,\n Math.min(inputRect.left + caretOffsetPx, maxLeft),\n );\n\n const spaceBelow = viewportHeight - inputRect.bottom;\n const openUp = menuHeight > 0 && spaceBelow < menuHeight + PANEL_VIEWPORT_PADDING_PX;\n\n return {\n top: openUp\n ? inputRect.top - menuHeight - CARET_MENU_GAP_PX\n : inputRect.bottom + CARET_MENU_GAP_PX,\n left,\n width,\n openUp,\n };\n};\n"],"names":["CARET_MENU_GAP_PX","computeCaretMenuGeometry","inputRect","caretOffsetPx","menuWidth","menuHeight","viewportWidth","viewportHeight","width","PANEL_VIEWPORT_PADDING_PX","maxLeft","left","spaceBelow","openUp"],"mappings":";AAMA,MAAMA,IAAoB,GAoBbC,IAA2B,CAAC;AAAA,EACrC,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,eAAAC;AAAA,EACA,gBAAAC;AACJ,MAAiD;AAG7C,QAAMC,IAAQ,KAAK,IAAIJ,GAAWE,IAAgBG,IAA4B,CAAC,GACzEC,IAAUJ,IAAgBE,IAAQC,GAClCE,IAAO,KAAK;AAAA,IACdF;AAAA,IACA,KAAK,IAAIP,EAAU,OAAOC,GAAeO,CAAO;AAAA,EAAA,GAG9CE,IAAaL,IAAiBL,EAAU,QACxCW,IAASR,IAAa,KAAKO,IAAaP,IAAaI;AAE3D,SAAO;AAAA,IACH,KAAKI,IACCX,EAAU,MAAMG,IAAaL,IAC7BE,EAAU,SAASF;AAAA,IACzB,MAAAW;AAAA,IACA,OAAAH;AAAA,IACA,QAAAK;AAAA,EAAA;AAER;"}
1
+ {"version":3,"file":"queryInputGeometry.js","sources":["../../src/components/queryInputGeometry.ts"],"sourcesContent":["// Pure geometry for the caret-anchored suggestion menu. No DOM access, no React, so it can be\n// unit tested directly even though jsdom cannot lay out text (see QueryInput.tsx's caret\n// measurement, which always reads 0 there).\n\nimport { MENU_VIEWPORT_PADDING_PX } from './floatingMenuGeometry';\n\nconst CARET_MENU_GAP_PX = 8;\n\nexport interface CaretMenuGeometryInput {\n inputRect: Pick<DOMRect, 'top' | 'left' | 'right' | 'bottom'>;\n /** Caret distance from the start of the text box, already adjusted for scrollLeft. */\n caretOffsetPx: number;\n menuWidth: number;\n menuHeight: number;\n viewportWidth: number;\n viewportHeight: number;\n}\n\nexport interface CaretMenuGeometry {\n top: number;\n left: number;\n /** What the menu may occupy once the viewport has had its say. */\n width: number;\n openUp: boolean;\n}\n\nexport const computeCaretMenuGeometry = ({\n inputRect,\n caretOffsetPx,\n menuWidth,\n menuHeight,\n viewportWidth,\n viewportHeight,\n}: CaretMenuGeometryInput): CaretMenuGeometry => {\n // Capped before `left` is derived: a menu wider than the viewport\n // otherwise pins to the left padding and still runs off the right edge.\n const width = Math.min(menuWidth, viewportWidth - MENU_VIEWPORT_PADDING_PX * 2);\n const maxLeft = viewportWidth - width - MENU_VIEWPORT_PADDING_PX;\n const left = Math.max(\n MENU_VIEWPORT_PADDING_PX,\n Math.min(inputRect.left + caretOffsetPx, maxLeft),\n );\n\n const spaceBelow = viewportHeight - inputRect.bottom;\n const openUp = menuHeight > 0 && spaceBelow < menuHeight + MENU_VIEWPORT_PADDING_PX;\n\n return {\n top: openUp\n ? inputRect.top - menuHeight - CARET_MENU_GAP_PX\n : inputRect.bottom + CARET_MENU_GAP_PX,\n left,\n width,\n openUp,\n };\n};\n"],"names":["CARET_MENU_GAP_PX","computeCaretMenuGeometry","inputRect","caretOffsetPx","menuWidth","menuHeight","viewportWidth","viewportHeight","width","MENU_VIEWPORT_PADDING_PX","maxLeft","left","spaceBelow","openUp"],"mappings":";AAMA,MAAMA,IAAoB,GAoBbC,IAA2B,CAAC;AAAA,EACrC,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,eAAAC;AAAA,EACA,gBAAAC;AACJ,MAAiD;AAG7C,QAAMC,IAAQ,KAAK,IAAIJ,GAAWE,IAAgBG,IAA2B,CAAC,GACxEC,IAAUJ,IAAgBE,IAAQC,GAClCE,IAAO,KAAK;AAAA,IACdF;AAAA,IACA,KAAK,IAAIP,EAAU,OAAOC,GAAeO,CAAO;AAAA,EAAA,GAG9CE,IAAaL,IAAiBL,EAAU,QACxCW,IAASR,IAAa,KAAKO,IAAaP,IAAaI;AAE3D,SAAO;AAAA,IACH,KAAKI,IACCX,EAAU,MAAMG,IAAaL,IAC7BE,EAAU,SAASF;AAAA,IACzB,MAAAW;AAAA,IACA,OAAAH;AAAA,IACA,QAAAK;AAAA,EAAA;AAER;"}
package/dist/index.d.ts CHANGED
@@ -1192,7 +1192,7 @@ export declare const DoubleCheckIcon: React.FC<IconProps_36>;
1192
1192
 
1193
1193
  export declare const DownloadIcon: React.FC<IconProps_37>;
1194
1194
 
1195
- export declare const Dropdown: ({ items, onItemSelected, defaultValue, value, disabled, error, tone, label, hint, rightSideContent, tooltip, name, required, requiredIndicator, loading, menuLoading, formControl, description, helperText, placeholder, search, showSubtitleInTrigger, subtitleLayout, clearable, size, fullWidth, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, }: DropdownProps) => JSX_2.Element;
1195
+ export declare const Dropdown: ({ items, onItemSelected, defaultValue, value, disabled, error, tone, label, hint, rightSideContent, tooltip, name, required, requiredIndicator, loading, menuLoading, formControl, description, helperText, placeholder, search, showSubtitleInTrigger, subtitleLayout, clearable, size, fullWidth, width, minWidth, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, }: DropdownProps) => JSX_2.Element;
1196
1196
 
1197
1197
  declare interface DropdownBaseProps {
1198
1198
  label?: string;
@@ -1224,8 +1224,14 @@ declare interface DropdownBaseProps {
1224
1224
  clearable?: boolean;
1225
1225
  /** 'large' (42px) for form inputs; 'medium' (32px) for toolbar chips; 'small' (28px) beside a title. */
1226
1226
  size?: DropdownSize;
1227
- /** Fills the container instead of sizing to content, and matches the panel to the trigger. */
1228
1227
  fullWidth?: boolean;
1228
+ width?: string | number;
1229
+ /**
1230
+ * Raises the open menu's floor above the shared 160px one, without widening the trigger.
1231
+ * For a control pinned narrow by its column — a role picker in a 160px cell, a member
1232
+ * picker in a 200px slot — whose options carry a subtitle the trigger never has to show.
1233
+ */
1234
+ minWidth?: number;
1229
1235
  /** Names the trigger from the light DOM, where `htmlFor` cannot reach into the shadow root. */
1230
1236
  id?: string;
1231
1237
  'aria-label'?: string;
@@ -1280,6 +1286,13 @@ declare interface EllipsisTextProps {
1280
1286
  */
1281
1287
  maxWidth?: string;
1282
1288
  color?: TextColor;
1289
+ size?: FontSize;
1290
+ /**
1291
+ * Show `tooltip` only when the text is actually cut off. Opt-in, because `tooltip` is any
1292
+ * node: a caller repeating the label wants this, and one supplying something the label does
1293
+ * not say — a full path, a timestamp — would lose it.
1294
+ */
1295
+ tooltipWhenTruncated?: boolean;
1283
1296
  className?: string;
1284
1297
  style?: default_2.CSSProperties;
1285
1298
  }
@@ -3480,6 +3493,7 @@ export declare interface SearchProps {
3480
3493
  disabled?: boolean;
3481
3494
  autoFocus?: boolean;
3482
3495
  className?: string;
3496
+ width?: string | number;
3483
3497
  style?: default_2.CSSProperties;
3484
3498
  }
3485
3499
 
@@ -4166,6 +4180,7 @@ export declare interface TabsProps {
4166
4180
  items: TabItem[];
4167
4181
  activeKey: string;
4168
4182
  onChange: (key: string) => void;
4183
+ trailing?: default_2.ReactNode;
4169
4184
  className?: string;
4170
4185
  style?: default_2.CSSProperties;
4171
4186
  }
@@ -4356,7 +4371,40 @@ export declare type ToggleTone = 'default' | 'pending';
4356
4371
  */
4357
4372
  export declare type ToggleVariant = 'pill' | 'button';
4358
4373
 
4359
- export declare const Toolbar: default_2.FC<ToolbarProps>;
4374
+ export declare const Toolbar: ToolbarComponent;
4375
+
4376
+ export declare const TOOLBAR_FILL_BASIS_PX = 260;
4377
+
4378
+ export declare const TOOLBAR_FILL_MIN_WIDTH_PX = 200;
4379
+
4380
+ export declare const TOOLBAR_FILTER_MIN_WIDTH_PX = 160;
4381
+
4382
+ export declare const TOOLBAR_FILTER_WIDTH_PX = 200;
4383
+
4384
+ declare interface ToolbarComponent extends default_2.FC<ToolbarProps> {
4385
+ Fill: typeof ToolbarFill;
4386
+ Item: typeof ToolbarItem;
4387
+ }
4388
+
4389
+ declare const ToolbarFill: default_2.FC<ToolbarFillProps>;
4390
+
4391
+ export declare interface ToolbarFillProps {
4392
+ children?: default_2.ReactNode;
4393
+ minWidth?: number;
4394
+ className?: string;
4395
+ style?: default_2.CSSProperties;
4396
+ }
4397
+
4398
+ declare const ToolbarItem: default_2.FC<ToolbarItemProps>;
4399
+
4400
+ export declare interface ToolbarItemProps {
4401
+ children?: default_2.ReactNode;
4402
+ width?: number;
4403
+ minWidth?: number;
4404
+ grow?: boolean;
4405
+ className?: string;
4406
+ style?: default_2.CSSProperties;
4407
+ }
4360
4408
 
4361
4409
  export declare interface ToolbarProps {
4362
4410
  children?: default_2.ReactNode;
@@ -4365,6 +4413,7 @@ export declare interface ToolbarProps {
4365
4413
  /** Padding preset (applies to both axes). `none` for a bar that must sit flush with
4366
4414
  * the content it pins over — the consumer then owns the gutter. */
4367
4415
  padding?: 'none' | 'compact' | 'default';
4416
+ layout?: 'plain' | 'filters';
4368
4417
  className?: string;
4369
4418
  style?: default_2.CSSProperties;
4370
4419
  }