@kanso-labs/kanso-ui 0.44.1 → 0.45.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 (135) hide show
  1. package/README.md +69 -18
  2. package/dist/chip/index.js +24 -4
  3. package/dist/chip/index.js.map +1 -1
  4. package/dist/chip/styles.js +13 -5
  5. package/dist/chip/styles.js.map +1 -1
  6. package/dist/components/app-bar/index.d.ts +14 -2
  7. package/dist/components/app-bar/index.js +36 -7
  8. package/dist/components/app-bar/index.js.map +1 -1
  9. package/dist/components/autocomplete/index.d.ts +44 -0
  10. package/dist/components/autocomplete/index.js +44 -0
  11. package/dist/components/autocomplete/index.js.map +1 -1
  12. package/dist/components/button/index.d.ts +3 -2
  13. package/dist/components/button/index.js +53 -59
  14. package/dist/components/button/index.js.map +1 -1
  15. package/dist/components/card/index.d.ts +11 -3
  16. package/dist/components/card/index.js +23 -1
  17. package/dist/components/card/index.js.map +1 -1
  18. package/dist/components/checkbox/index.js +65 -58
  19. package/dist/components/checkbox/index.js.map +1 -1
  20. package/dist/components/chip/index.d.ts +46 -30
  21. package/dist/components/chip/index.js +38 -17
  22. package/dist/components/chip/index.js.map +1 -1
  23. package/dist/components/chip-group/index.d.ts +5 -2
  24. package/dist/components/chip-group/index.js +8 -2
  25. package/dist/components/chip-group/index.js.map +1 -1
  26. package/dist/components/dialog/index.d.ts +27 -0
  27. package/dist/components/dialog/index.js +81 -37
  28. package/dist/components/dialog/index.js.map +1 -1
  29. package/dist/components/fab/index.d.ts +1 -1
  30. package/dist/components/fab/index.js.map +1 -1
  31. package/dist/components/form/index.d.ts +14 -4
  32. package/dist/components/form/index.js +6 -3
  33. package/dist/components/form/index.js.map +1 -1
  34. package/dist/components/icon-button/index.d.ts +15 -1
  35. package/dist/components/icon-button/index.js +15 -1
  36. package/dist/components/icon-button/index.js.map +1 -1
  37. package/dist/components/link/index.d.ts +4 -0
  38. package/dist/components/link/index.js +4 -0
  39. package/dist/components/link/index.js.map +1 -1
  40. package/dist/components/list/index.d.ts +34 -0
  41. package/dist/components/list/index.js +47 -13
  42. package/dist/components/list/index.js.map +1 -1
  43. package/dist/components/list-detail/index.d.ts +34 -1
  44. package/dist/components/list-detail/index.js +34 -1
  45. package/dist/components/list-detail/index.js.map +1 -1
  46. package/dist/components/list-item/index.d.ts +21 -2
  47. package/dist/components/list-item/index.js +6 -0
  48. package/dist/components/list-item/index.js.map +1 -1
  49. package/dist/components/menu/index.d.ts +6 -3
  50. package/dist/components/menu/index.js +3 -1
  51. package/dist/components/menu/index.js.map +1 -1
  52. package/dist/components/meter/index.d.ts +4 -0
  53. package/dist/components/meter/index.js +4 -0
  54. package/dist/components/meter/index.js.map +1 -1
  55. package/dist/components/navigation-bar/index.d.ts +14 -2
  56. package/dist/components/navigation-bar/index.js +14 -2
  57. package/dist/components/navigation-bar/index.js.map +1 -1
  58. package/dist/components/navigation-tree/index.js +2 -9
  59. package/dist/components/navigation-tree/index.js.map +1 -1
  60. package/dist/components/number-field/index.d.ts +7 -1
  61. package/dist/components/number-field/index.js +7 -1
  62. package/dist/components/number-field/index.js.map +1 -1
  63. package/dist/components/popover/index.d.ts +15 -1
  64. package/dist/components/popover/index.js +15 -1
  65. package/dist/components/popover/index.js.map +1 -1
  66. package/dist/components/product-icon/index.d.ts +8 -1
  67. package/dist/components/product-icon/index.js +8 -1
  68. package/dist/components/product-icon/index.js.map +1 -1
  69. package/dist/components/progress-indicator/index.d.ts +12 -6
  70. package/dist/components/progress-indicator/index.js +57 -46
  71. package/dist/components/progress-indicator/index.js.map +1 -1
  72. package/dist/components/radio-group/index.d.ts +7 -0
  73. package/dist/components/radio-group/index.js +23 -14
  74. package/dist/components/radio-group/index.js.map +1 -1
  75. package/dist/components/search-field/index.d.ts +13 -4
  76. package/dist/components/search-field/index.js +10 -4
  77. package/dist/components/search-field/index.js.map +1 -1
  78. package/dist/components/search-view/index.d.ts +2 -0
  79. package/dist/components/search-view/index.js.map +1 -1
  80. package/dist/components/segmented-button/index.d.ts +1 -1
  81. package/dist/components/segmented-button/index.js.map +1 -1
  82. package/dist/components/separator/index.d.ts +31 -6
  83. package/dist/components/separator/index.js +30 -6
  84. package/dist/components/separator/index.js.map +1 -1
  85. package/dist/components/sheet/index.d.ts +96 -37
  86. package/dist/components/sheet/index.js +420 -136
  87. package/dist/components/sheet/index.js.map +1 -1
  88. package/dist/components/snackbar/index.d.ts +8 -1
  89. package/dist/components/snackbar/index.js +7 -0
  90. package/dist/components/snackbar/index.js.map +1 -1
  91. package/dist/components/stack/index.d.ts +21 -5
  92. package/dist/components/stack/index.js +10 -0
  93. package/dist/components/stack/index.js.map +1 -1
  94. package/dist/components/switch/index.d.ts +12 -0
  95. package/dist/components/switch/index.js +12 -0
  96. package/dist/components/switch/index.js.map +1 -1
  97. package/dist/components/text-field/index.d.ts +39 -9
  98. package/dist/components/text-field/index.js +29 -7
  99. package/dist/components/text-field/index.js.map +1 -1
  100. package/dist/components/tree/index.js +11 -15
  101. package/dist/components/tree/index.js.map +1 -1
  102. package/dist/field/styles.js.map +1 -1
  103. package/dist/glyphs/index.js +19 -18
  104. package/dist/glyphs/index.js.map +1 -1
  105. package/dist/hooks/useBottomEdge.js +6 -3
  106. package/dist/hooks/useBottomEdge.js.map +1 -1
  107. package/dist/hooks/useRipple.js +216 -192
  108. package/dist/hooks/useRipple.js.map +1 -1
  109. package/dist/i18n/index.js +1 -0
  110. package/dist/i18n/index.js.map +1 -1
  111. package/dist/i18n/messages.js +34 -0
  112. package/dist/i18n/messages.js.map +1 -1
  113. package/dist/index.d.ts +3 -3
  114. package/dist/indicator/styles.js +7 -4
  115. package/dist/indicator/styles.js.map +1 -1
  116. package/dist/{tokens/theme.d.ts → kanso-ui-core/defaults-DMH0HWCw.d.ts} +3 -3
  117. package/dist/kanso-ui-core/glyphs.js +48 -0
  118. package/dist/kanso-ui-core/glyphs.js.map +1 -0
  119. package/dist/mark/styles.js +11 -5
  120. package/dist/mark/styles.js.map +1 -1
  121. package/dist/react-aria.d.ts +2 -2
  122. package/dist/row/index.js +90 -62
  123. package/dist/row/index.js.map +1 -1
  124. package/dist/row/styles.js +6 -1
  125. package/dist/row/styles.js.map +1 -1
  126. package/dist/styles/focus.js.map +1 -1
  127. package/dist/styles/overlay.js +8 -0
  128. package/dist/styles/overlay.js.map +1 -1
  129. package/dist/styles.css +135 -114
  130. package/dist/theme-scope.d.ts +15 -3
  131. package/dist/theme-scope.js +86 -98
  132. package/dist/theme-scope.js.map +1 -1
  133. package/dist/tokens/design.tokens.stylex.js.map +1 -1
  134. package/dist/tokens/values.js.map +1 -1
  135. package/package.json +12 -10
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","ReactNode","stylex","createElement","useLayoutEffect","useRef","RenderComponentProps","COLLAPSED_BLOCK_SIZE","hasContent","useRender","layers","mergeStyles","colors","motion","sizing","spacing","motionDurationMs","motionEasing","Text","ICON_BUTTON_TARGET","ICON_SIZE","GLYPH_INSET","HEIGHTS","lg","plain","withSubtitle","md","sm","const","COLLAPSED_HEIGHT","FORCED_COLORS","styles","pinned","k87sOh","kVAEAm","kY2c9j","$$css","root","k6CgDc","kGNEyG","kWkggS","kB7OPa","k1xSpc","kjj79g","kIyJzY","k1ekBW","kAMwcw","row","kfiyM8","kC13JO","kumcoG","kzqmXN","kUOVxO","scrolled","kL6WhQ","kfdmCh","kt9PQ7","text","kSGwAc","kXwgrk","kJuA4N","kE4Cay","k7Eaqz","kHjlTd","k8WAf4","textBelow","textCenter","k9WMMc","twoRows","kTDh7v","k4zj60","kWgvks","k5JduY","kVb13B","k5jvz2","HEADLINE_VARIANT","SUBTITLE_VARIANT","HEADINGS","heading","level","known","Number","isInteger","PARAGRAPH","_temp","kAzted","heightStyles","minBlockSize","val","undefined","_temp2","ks0D6T","rowStyles","start","end","maxInlineSize","kwRFfy","kZCmMZ","tracks","gridTemplateRows","k9llMU","_temp3","keoZOQ","textStyles","inset","reach","marginBlockStart","UNDER_TARGETS","AppBarProps","Omit","align","collapsed","contentInset","contentMaxInlineSize","headingLevel","headline","leading","size","subtitle","trailing","LINES","Geometry","height","lines","Line","x","y","AppBar","t0","$","t1","t2","t3","t4","t5","t6","render","t7","t8","props","collapse","below","expandedHeight","hasLeading","hasTrailing","textRef","useCollapseMotion","t9","t10","edgePadding","t11","t12","glyphRoom","t13","t14","t15","t16","t17","t18","t19","children","t20","defaultTagName","drawnAt","bar","HTMLElement","settled","getBoundingClientRect","map","selector","index","line","element","querySelector","moved","matrixOf","a","e","f","hasSlot","withUnit","geometryOf","frame","box","edge","left","right","isRightToLeft","parseFloat","getComputedStyle","fontSize","glyphTopOf","top","Element","range","document","createRange","selectNodeContents","first","getClientRects","item","direction","DOMMatrixReadOnly","transform","originOf","glyphs","prefersReducedMotion","window","matchMedia","matches","collapsedBefore","Symbol","for","animations","current","parentElement","moving","some","_temp4","last","from","animation_0","animation","cancel","to","timing","duration","medium1","easing","emphasized","heights","animate","blockSize","clipPath","entries","was","is","origin","push","transformOrigin","playState","trim","_c","props","stylex.props"],"sources":["../../../src/components/app-bar/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport * as stylex from '@stylexjs/stylex';\nimport { createElement, useLayoutEffect, useRef } from 'react';\nimport type { RenderComponentProps } from '../../render/useRender';\nimport { COLLAPSED_BLOCK_SIZE } from '../../hooks/useAppBarScroll';\nimport { hasContent } from '../../render/content';\nimport { useRender } from '../../render/useRender';\nimport '../../styles/layers.stylex';\nimport { layers } from '../../styles/layers.stylex';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, sizing, spacing } from '../../tokens/design.tokens.stylex';\nimport { motionDurationMs, motionEasing } from '../../tokens/values';\nimport Text from '../text';\n\n// Material Design's app bar, in the three sizes the spec recommends.\n//\n// `md` and `lg` are Material Design's medium and large *flexible* bars, the\n// newer of the two sets the spec gives and the one it recommends, which is why\n// those two steps are theirs: their heights, their two rows, and their type\n// roles, which HEADLINE_VARIANT and SUBTITLE_VARIANT name.\n//\n// Material Design also merged the old center-aligned variant into small as a\n// configuration rather than a variant, which is why alignment is a prop here\n// and applies to every size.\n//\n// Heights are Material Design's, and they are minimums rather than fixed. The\n// spec says the flexible bars \"hug the text contents\" and gives them multi-line\n// support and text wrapping, so a headline long enough to wrap has to be able\n// to make its bar taller. Fixing the height would truncate exactly the case\n// the variant was redesigned for.\n//\n// The small bar is one row: the leading slot, the text and the trailing slot\n// side by side in a 64px strip. The flexible bars are two, as Material Design\n// lays them out. The first is that same strip holding the slots alone, and the\n// second runs the text under it across the whole measure, so a long headline\n// wraps against the bar's width rather than against what the slots leave.\n// Collapsing moves the text up into the strip, which is the small bar exactly,\n// and the slots never move: they are in the strip in both states.\n\n// The geometry Material Design lays a bar's icon buttons out on. Its tokens\n// give a 4dp leading and trailing space between the bar's edge and the first\n// button's 48dp target, no space between one target and the next, and a 24dp\n// icon centred in each — so a glyph lands 4 + 12 = 16dp in, on the page's own\n// margin.\n//\n// The library's icon button draws a 40dp box with its 48dp target out of\n// flow, so a slot pads half the difference either side and puts the whole\n// difference between two buttons, which lays the targets edge to edge as the\n// tokens do. The target is IconButton's TARGET_SIZE, a literal there for the\n// reason it gives: it is a floor the page states, not a step of the control\n// scale.\nconst ICON_BUTTON_TARGET = '48px';\nconst ICON_SIZE = '24px';\n\n// How far an icon sits inside its target, which is how much less than the\n// content inset the row is padded on an edge that holds a slot. That is what\n// puts a leading glyph, rather than the edge of its target, at the inset.\nconst GLYPH_INSET = `(${ICON_BUTTON_TARGET} - ${ICON_SIZE}) / 2`;\nconst HEIGHTS = {\n lg: {\n plain: '120px',\n withSubtitle: '152px'\n },\n md: {\n plain: '112px',\n withSubtitle: '136px'\n },\n sm: {\n plain: `${COLLAPSED_BLOCK_SIZE}px`,\n withSubtitle: `${COLLAPSED_BLOCK_SIZE}px`\n }\n} as const;\n\n// What a flexible bar collapses to, which is the small bar exactly. Material\n// Design does not describe the collapsed large bar as a state of its own — it\n// describes it as becoming the small bar, which is why this reads off the same\n// table rather than being a fourth height.\nconst COLLAPSED_HEIGHT = HEIGHTS.sm.plain;\n\n// Windows High Contrast and the rest of the forced-colours modes. Spelled\n// here rather than imported, for the reason src/field/styles.ts records: the\n// StyleX compiler resolves a constant across files only out of a `.stylex.ts`\n// module, and the generated one holds design tokens rather than queries.\nconst FORCED_COLORS = '@media (forced-colors: active)';\nconst styles = {\n pinned: {\n k87sOh: \"x13vifvy\",\n kVAEAm: \"x7wzq59\",\n kY2c9j: \"xfj7q76\",\n $$css: true\n },\n root: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x1qjc9v5\",\n kWkggS: \"x14s9m32\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kjj79g: \"xl56j7k\",\n kIyJzY: \"xioksi3\",\n k1ekBW: \"x15406qy\",\n kAMwcw: \"x1seskgd\",\n $$css: true\n },\n row: {\n kfiyM8: \"x10ukxgv\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"xrvj5dj\",\n kC13JO: \"x97ohe\",\n kumcoG: \"xx9t13c\",\n kzqmXN: \"xh8yej3\",\n kUOVxO: \"xvueqy4\",\n $$css: true\n },\n scrolled: {\n kWkggS: \"x1mjdul6\",\n kL6WhQ: \"xszdk7l\",\n kfdmCh: \"xe3zi7u\",\n kt9PQ7: \"x15anc7y\",\n $$css: true\n },\n text: {\n kSGwAc: \"xamitd3\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kJuA4N: \"x12gd1sl\",\n kE4Cay: \"xkjl1po\",\n k7Eaqz: \"xeuugli\",\n kHjlTd: \"xj0a0fe\",\n k8WAf4: \"x1cmllll\",\n $$css: true\n },\n textBelow: {\n kSGwAc: \"xnav3zx\",\n k8WAf4: \"xt970qd\",\n $$css: true\n },\n textCenter: {\n k9WMMc: \"x2b8uid\",\n $$css: true\n }\n};\n\n// The flexible bars' two rows: the strip with the slots at either end, and the\n// text under it across all three columns. The second row takes whatever height\n// the bar has beyond the strip, and the text sits at its bottom.\n//\n// Material Design places that text by its last baseline, 28px above the large\n// bar's bottom edge and 24px above the medium one's, and that is the reading\n// that makes the heights above come out, together with the reach textStyles\n// gives the text: the same figures as padding under the line box would make a\n// plain large bar 64 + 44 + 28 = 136px rather than 120px. CSS gives a box no\n// margin below its baseline, so the strut does it.\n// An empty box in the same grid area, aligned on its last baseline with the\n// text, has its baseline at its own bottom edge and the margin under that, so\n// the pair is held that far off the row's end. Literals rather than tokens,\n// like HEIGHTS: they are measurements the spec gives this component, not steps\n// of the spacing scale, which has no 28.\nconst twoRows = {\n lg: {\n kTDh7v: \"x1mna9mr\",\n k4zj60: \"x1gmr53x\",\n kWgvks: \"xx38sju\",\n k5JduY: \"x1s928wv\",\n kVb13B: \"x1vlsijy\",\n k5jvz2: \"x1fh8phi\",\n kC13JO: \"xc3o5yk\",\n $$css: true\n },\n md: {\n kTDh7v: \"x1mna9mr\",\n k4zj60: \"x1gmr53x\",\n kWgvks: \"xx38sju\",\n k5JduY: \"x1s928wv\",\n kVb13B: \"x1vlsijy\",\n k5jvz2: \"x1v6yq59\",\n kC13JO: \"xc3o5yk\",\n $$css: true\n }\n};\n\n// One entry per size, and each names a type role rather than a figure.\n// Material Design's own tokens are `md.comp.app-bar.<size>.title.font`,\n// aliases onto the type scale rather than sizes of their own, so this maps to\n// the scale the same way and lets Text apply it. The roles are the flexible\n// bars': headlineMedium on medium and displaySmall on large, which is a step\n// up from what the spec's other medium and large bars take, and the small\n// bar's titleLarge.\nconst HEADLINE_VARIANT = {\n lg: 'displaySmall',\n md: 'headlineMedium',\n sm: 'titleLarge'\n} as const;\n\n// The subtitle's role, by the same tokens' `subtitle.font`. Material Design\n// gives each size its own rather than one role at every size, and a collapsed\n// bar takes the small bar's, as it takes its headline's.\nconst SUBTITLE_VARIANT = {\n lg: 'titleMedium',\n md: 'labelLarge',\n sm: 'labelMedium'\n} as const;\n\n// The headline is the page's title in Material Design's model, so it is the\n// page's <h1> unless the call site says otherwise. `headingLevel` is what says\n// otherwise, and a bar drawn beside another bar — one per pane in a\n// `ListDetail` or a `SupportingPane` — or under a page heading of its own\n// should lower it.\n//\n// Built here rather than kept as a constant per level: `headline` becomes the\n// heading's children, so a call site cannot demote the heading by passing one\n// of its own. `headline={<h2>…</h2>}` renders an h2 inside the h1 — two\n// headings where one was wanted, which React does not warn about.\n//\n// The level is looked up rather than interpolated into a tag name. `h7` is a\n// custom element as far as React is concerned, so it renders without a word\n// said and leaves the outline worse than the default would have. The prop's\n// type is the six levels, and a value outside them from a call site the type\n// does not reach — `NaN`, which rounded and clamped to no element at all and\n// took the headline out of the outline — falls back to the default h1.\n// Disclosure's own `headingLevel` hands the number to React Aria, which is\n// why that one needs no equivalent.\nconst HEADINGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;\nfunction heading(level: number) {\n const known = Number.isInteger(level) && level >= 1 && level <= 6;\n return createElement(known ? HEADINGS[level - 1] : HEADINGS[0]);\n}\nconst PARAGRAPH = <p />;\n\n// Height is the one value the call site does not choose, and it depends on two\n// props at once, so it is a function style rather than one key per\n// combination. StyleX writes it to a custom property inline, the same\n// mechanism Feed uses for its cell minimum.\n//\n// The row takes it too, and that is for the collapse's motion. The bar's\n// height is animated, and a row that only stretched to it would be laid out\n// at every height the bar passed through: the second row is the room the bar\n// has beyond the strip, so its text would ride up and down with the bar\n// rather than holding the place the animation moves it to. With the minimum\n// of its own, the row is laid out once, at the height the bar is heading for,\n// and the bar clips it until it gets there.\nconst _temp = {\n kAzted: \"x1chvrdh\",\n \"$$css\": true\n};\nconst heightStyles = {\n root: (minBlockSize: string) => [_temp, {\n \"--x-minBlockSize\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(minBlockSize)\n }]\n};\n\n// The row's measure and inset both come from the call site, so both are\n// function styles too. Each edge is worked out on its own: where it holds a\n// slot the row stops short of the inset by GLYPH_INSET, so the glyph rather\n// than its target is what sits at the inset, and where it holds none the\n// headline itself starts there. Clamped at zero, since an inset smaller than\n// a glyph's own room would otherwise ask for a negative padding, which CSS\n// throws away whole.\n//\n// The tracks are a function style for a different reason: the strip is the\n// small bar's height, which is the hook's constant, and the compiler cannot\n// read a constant out of another module — see FORCED_COLORS.\nconst _temp2 = {\n ks0D6T: \"x13i5qev\",\n \"$$css\": true\n};\nconst rowStyles = {\n root: (start: string, end: string, maxInlineSize: string) => [_temp2, {\n kwRFfy: end != null ? \"x120eax6\" : end,\n kZCmMZ: start != null ? \"xnvo3vl\" : start,\n $$css: true\n }, {\n \"--x-maxInlineSize\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(maxInlineSize),\n \"--x-paddingInlineEnd\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(end),\n \"--x-paddingInlineStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(start)\n }],\n tracks: (gridTemplateRows: string) => [{\n k9llMU: gridTemplateRows != null ? \"x1xxtoay\" : gridTemplateRows,\n $$css: true\n }, {\n \"--x-gridTemplateRows\": gridTemplateRows != null ? gridTemplateRows : undefined\n }]\n};\n\n// The text in the second row runs under the slots as well as between them, so\n// it puts back what the row's padding held off an edge for a slot's glyph, and\n// the headline starts on the inset again. A function style for the reason the\n// row's padding is one.\n//\n// It also reaches up into the strip, by the band under the slots' targets,\n// and Material Design's heights depend on that. A large bar's 36/44 headline\n// with its baseline 28px above a 120px bar's edge has the top of its line box\n// inside the strip, and so does the medium bar's 28/36 one: measured, the two\n// bars came out 126px and 115px tall without it. What reaches in is the line's\n// leading and the room above its capitals rather than any glyph, and it stops\n// where the targets do, so nothing a reader can press is under it. A function\n// style because the strip's height is the hook's constant — see rowStyles.\nconst _temp3 = {\n keoZOQ: \"x1vhfslr\",\n \"$$css\": true\n};\nconst textStyles = {\n inset: (start: string, end: string) => [{\n kwRFfy: end != null ? \"x120eax6\" : end,\n kZCmMZ: start != null ? \"xnvo3vl\" : start,\n $$css: true\n }, {\n \"--x-paddingInlineEnd\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(end),\n \"--x-paddingInlineStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(start)\n }],\n reach: (marginBlockStart: string) => [_temp3, {\n \"--x-marginBlockStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(marginBlockStart)\n }]\n};\n\n// How far the strip runs on below the slots' targets, which are centred in it.\nconst UNDER_TARGETS = `calc((${COLLAPSED_HEIGHT} - ${ICON_BUTTON_TARGET}) / 2)`;\ntype AppBarProps = Omit<RenderComponentProps<'header'>, 'children'> & {\n /**\n * Which of Material Design's alignments the text takes. `center` is the\n * configuration that replaced the old center-aligned variant.\n * @default 'start'\n */\n align?: 'center' | 'start';\n /**\n * Collapses a flexible bar to the height and headline of the small one, for\n * a bar `pinned` over content that has been scrolled. Material Design\n * specifies it for the flexible sizes, and without it a pinned `lg` costs\n * 152px of the viewport for as long as the page is open.\n *\n * Controlled, and for the same reason `scrolled` is: only the app knows\n * which element scrolls, and how far into it the bar should have finished\n * collapsing. `useAppBarScroll` derives both from that element's scroll,\n * and is the way to set them unless the app needs a rule of its own.\n *\n * Ignored on `sm`, which is already the height this collapses to. The\n * headline and the subtitle move up into the row the slots sit in and take\n * the small bar's type roles, which fit both lines in its 64px, and the\n * slots never leave that row: they stay where they are while the bar\n * shrinks under them.\n *\n * Collapsing hands the page back the height the bar gives up, and a bar\n * whose state is read off the scroll offset can then undo itself in two\n * ways. Both move the offset back under the threshold, so the bar expands,\n * the page regains its height, and the two take turns for as long as the\n * reader stays there.\n *\n * - **Scroll anchoring.** Browsers answer a change in height above the\n * viewport by moving the offset by the same amount, to keep the content\n * in place. Give the scroll container `overflow-anchor: none`, which is\n * also the movement you want: the content follows the bar's bottom edge\n * up rather than standing still while the bar shrinks behind it.\n * - **The shorter page.** A page that overflows by less than the threshold\n * plus the height the bar gives back cannot scroll that far once the bar\n * has collapsed, so the browser pulls the offset back inside it. No\n * threshold avoids this, since the band moves with it; what does is not\n * collapsing on such a page, which is the rule `useAppBarScroll` applies.\n * @default false\n */\n collapsed?: boolean;\n /**\n * Where the bar's content starts on each edge: the headline where nothing\n * comes before it, and the leading icon's glyph where something does, with\n * the headline after the icon button's target. The trailing edge is the\n * same mirrored. Any length works, `0` included, for a bar drawn flush.\n *\n * The default is Material Design's own margin for a top app bar, the\n * spacing scale's `lg` step, which is also the margin it gives body\n * content, so a bar and the page beneath line up without either being told\n * about the other. Set it to the page's gutter where that differs.\n * @default spacing.lg\n */\n contentInset?: string;\n /**\n * How wide the bar's contents may run before they stop growing, with the\n * row centred in whatever is left. The bar's own surface still paints edge\n * to edge.\n *\n * This is what lines a full-bleed bar up with a page whose content sits in\n * a measure: give it the page's measure, and `contentInset` the page's\n * gutter. Unset, the row is as wide as the bar.\n */\n contentMaxInlineSize?: string;\n /**\n * Where the headline sits in the page's outline, as one of the six heading\n * levels. A screen reader moves between headings, so a bar drawn beside\n * another bar, or under a page heading of its own, should lower it. A value\n * outside the six that reaches it untyped falls back to 1.\n * @default 1\n */\n headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n /** The page's title. Wraps rather than truncating, and grows the bar with it. */\n headline?: ReactNode;\n /** Usually a back or menu icon button. Sits before the text. */\n leading?: ReactNode;\n /**\n * Holds the bar at the top of its scroll container while the content\n * scrolls beneath it, and keeps it painted over that content. The bar\n * still needs a scrolling ancestor to stick inside: the window, or an\n * element with its own overflow. A pinned bar is the one `collapsed` and\n * `scrolled` are for.\n * @default false\n */\n pinned?: boolean;\n /**\n * Whether the content beneath has been scrolled. Material Design separates\n * a bar from scrolled content with a fill colour rather than a shadow, and\n * this is what applies it.\n *\n * Controlled, with no listener of its own: only the app knows which element\n * scrolls, and a bar that watched the window would be wrong inside every\n * pane and dialog that scrolls independently.\n * @default false\n */\n scrolled?: boolean;\n /**\n * Height and headline size, as steps of the library's size scale. `sm` is\n * Material Design's small bar, a fixed 64px row; `md` and `lg` are its\n * medium and large flexible bars, which put the text in a row of its own\n * under the slots and hug it.\n * @default 'sm'\n */\n size?: 'lg' | 'md' | 'sm';\n /** A second line under the headline. Makes `md` and `lg` taller. */\n subtitle?: ReactNode;\n /** Actions, at the far end. Usually icon buttons. */\n trailing?: ReactNode;\n};\n\n// The text block's two lines: the headline, and the subtitle beside it. The\n// block holds nothing else, and each is drawn as one kind of element.\nconst LINES = [':scope > :is(h1, h2, h3, h4, h5, h6)', ':scope > p'] as const;\n\n/**\n * What collapsing moves, and so what its animation runs between: the bar's\n * height, and each of the text's lines, in the order LINES gives them, with\n * `null` for a line the bar does not draw.\n */\ntype Geometry = {\n height: number;\n lines: (Line | null)[];\n};\n\n/**\n * Where one of the text's lines is drawn: the point its glyphs hang from,\n * measured from the bar's own corner, and its type size. The point is the\n * top of the line's first glyphs, on the edge the text hangs from.\n */\ntype Line = {\n size: number;\n x: number;\n y: number;\n};\n\n/**\n * Material Design's app bar: the container at the top of a page carrying its\n * title, one or two actions, and the way back out.\n *\n * Three sizes. `sm` is a fixed 64px bar for a page whose title is a label;\n * `md` and `lg` are the flexible bars, which give the headline a larger\n * type role in a row of its own under the slots, and grow to fit a subtitle\n * or a headline that wraps.\n *\n * It paints its own surface, unlike the layout components, because separating\n * itself from the content beneath is the job — which is also why `scrolled`\n * and `collapsed` exist. Neither watches the page: only the app knows which\n * element scrolls, so both are set from its own scroll handler.\n */\nfunction AppBar({\n align = 'start',\n collapsed = false,\n contentInset = spacing.lg,\n contentMaxInlineSize = 'none',\n headingLevel = 1,\n headline,\n leading,\n pinned = false,\n render,\n scrolled = false,\n size = 'sm',\n subtitle,\n trailing,\n ...props\n}: AppBarProps) {\n // `sm` is already what the flexible bars collapse to, so collapsing it is\n // a no-op rather than an error. A bar whose size is chosen at the call site\n // from a breakpoint would otherwise have to guard the prop as well.\n const collapse = collapsed && size !== 'sm';\n // The flexible bars at their full height are the only state with a second\n // row. Collapsed, they are the small bar.\n const below = size !== 'sm' && !collapse;\n const expandedHeight = hasContent(subtitle) ? HEIGHTS[size].withSubtitle : HEIGHTS[size].plain;\n const height = collapse ? COLLAPSED_HEIGHT : expandedHeight;\n const hasLeading = hasContent(leading);\n const hasTrailing = hasContent(trailing);\n const textRef = useCollapseMotion(collapse, align);\n return useRender({\n defaultTagName: 'header',\n props: {\n ...props,\n children: <div {...stylex.props(styles.row, rowStyles.root(edgePadding(contentInset, hasLeading), edgePadding(contentInset, hasTrailing), contentMaxInlineSize), rowStyles.tracks(below ? `minmax(${COLLAPSED_HEIGHT}, auto) 1fr` : `minmax(${COLLAPSED_HEIGHT}, auto)`), heightStyles.root(height), below && twoRows[size])}>\n {!hasLeading ? null : <div className=\"x6s0dn4 xamitd3 x9f619 x78zum5 x1r8zjiw x1let9r4 x1kxrqrs x15ir4sr\">{leading}</div>}\n <div {...stylex.props(styles.text, below && styles.textBelow, below && textStyles.inset(glyphRoom(contentInset, hasLeading), glyphRoom(contentInset, hasTrailing)), below && textStyles.reach(`calc(-1 * ${UNDER_TARGETS})`), align === 'center' && styles.textCenter)} ref={textRef}>\n {!hasContent(headline) ? null : <Text render={heading(headingLevel)} variant={collapse ? HEADLINE_VARIANT.sm : HEADLINE_VARIANT[size]}>\n {headline}\n </Text>}\n {!hasContent(subtitle) ? null : <Text render={PARAGRAPH} tone=\"muted\" variant={collapse ? SUBTITLE_VARIANT.sm : SUBTITLE_VARIANT[size]}>\n {subtitle}\n </Text>}\n </div>\n {!hasTrailing ? null : <div className=\"x6s0dn4 xamitd3 x9f619 x78zum5 x1r8zjiw x1let9r4 x1txd71x x6aqprb\">\n {trailing}\n </div>}\n </div>,\n ...mergeStyles(stylex.props(styles.root, heightStyles.root(height), scrolled && styles.scrolled, pinned && styles.pinned), props)\n },\n render\n });\n}\n\n/**\n * Where an animation still under way has the bar and the text drawn: the\n * height it holds the bar at, and each line where its transform has taken it\n * and at the size its scale has reached. A line scales about the point it\n * hangs from, so the transform's translation is how far that point has moved.\n */\nfunction drawnAt(bar: HTMLElement, text: HTMLElement, settled: Geometry): Geometry {\n return {\n height: bar.getBoundingClientRect().height,\n lines: LINES.map((selector, index) => {\n const line = settled.lines[index];\n const element = text.querySelector(selector);\n if (line === null || element === null) {\n return null;\n }\n const moved = matrixOf(element);\n return {\n size: line.size * moved.a,\n x: line.x + moved.e,\n y: line.y + moved.f\n };\n })\n };\n}\n\n/** The row's padding on one edge, for the inset the call site gave. */\nfunction edgePadding(contentInset: string, hasSlot: boolean) {\n const inset = withUnit(contentInset);\n return hasSlot ? `max(0px, ${inset} - ${GLYPH_INSET})` : inset;\n}\n\n/**\n * Where the bar and each of the text's lines are drawn. A line's point is on\n * the edge its text hangs from: the middle when it is centred, and the start\n * edge otherwise, which is the right edge in a right-to-left page. Each line\n * is as wide as the text block, so that edge is its box's.\n */\nfunction geometryOf(bar: HTMLElement, text: HTMLElement, align: 'center' | 'start'): Geometry {\n const frame = bar.getBoundingClientRect();\n return {\n height: frame.height,\n lines: LINES.map(selector => {\n const element = text.querySelector(selector);\n if (element === null) {\n return null;\n }\n const box = element.getBoundingClientRect();\n const edge = align === 'center' ? (box.left + box.right) / 2 : isRightToLeft(element) ? box.right : box.left;\n return {\n size: Number.parseFloat(getComputedStyle(element).fontSize),\n x: edge - frame.left,\n y: glyphTopOf(element) - frame.top\n };\n })\n };\n}\n\n/**\n * What the row's padding held back on one edge for a slot's glyph, which the\n * text in the second row puts back: the inset less `edgePadding`, so the\n * smaller of the inset and GLYPH_INSET.\n */\nfunction glyphRoom(contentInset: string, hasSlot: boolean) {\n return hasSlot ? `min(${withUnit(contentInset)}, ${GLYPH_INSET})` : '0px';\n}\n\n/**\n * Where an element's first glyphs start, which is below its box's top by\n * half its line's leading. The leading is a share of the line height, and\n * the two roles a line moves between do not keep line height and type size\n * in one ratio, so a line scaled by its type size from its box's corner\n * starts its glyphs off where they were drawn: about a pixel, for a large\n * bar's headline.\n */\nfunction glyphTopOf(element: Element) {\n const range = document.createRange();\n range.selectNodeContents(element);\n const first = range.getClientRects().item(0);\n return first === null ? element.getBoundingClientRect().top : first.top;\n}\n\n/** Whether the text runs right to left, which decides the edge it hangs from. */\nfunction isRightToLeft(element: Element) {\n return getComputedStyle(element).direction === 'rtl';\n}\n\n/** The transform an element is drawn with, `none` reading as no change. */\nfunction matrixOf(element: Element) {\n return new DOMMatrixReadOnly(getComputedStyle(element).transform);\n}\n\n/**\n * The point a line scales about, in its own box: the top of its glyphs, on\n * the edge its text hangs from.\n */\nfunction originOf(element: Element, align: 'center' | 'start') {\n const edge = align === 'center' ? 'center' : isRightToLeft(element) ? 'right' : 'left';\n const glyphs = glyphTopOf(element) - element.getBoundingClientRect().top;\n return `${edge} ${glyphs}px`;\n}\n\n/**\n * Read when the bar changes state rather than once at mount, so a reader who\n * changes the setting is answered by the next collapse.\n */\nfunction prefersReducedMotion() {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/**\n * Animates a flexible bar between its two states, and returns the ref for the\n * text block whose lines it moves.\n *\n * Collapsing changes the bar's layout rather than a value — the text leaves\n * the second row for the strip, both lines take the small bar's type roles,\n * and the bar's height drops from a minimum to whatever its content takes —\n * so there is nothing for a CSS transition to interpolate. This plays it the\n * other way round: the change has already been laid out when the effect runs,\n * so the bar is animated from the height it had to the one it has, and each\n * line from where and how large it was drawn to where and how large it is,\n * by a transform that starts at the difference and ends at none. A line\n * scales about the point its glyphs hang from, which is what lands its first\n * frame on the glyphs it replaces — see glyphTopOf. A scale rather than a\n * transition of the type itself, which would lay the text out again on every\n * frame and move it away from the place it was measured at. Each line moves\n * on its own rather than with the block, since the subtitle starts under the\n * headline's line, whose height changes with its role. The slots need\n * nothing: they are in the strip in both states.\n *\n * The bar's height is animated through `min-block-size` as well as its\n * height, since the minimum would otherwise hold an expanding bar at its new\n * height from the first frame, and it is clipped while it moves, since an\n * expanding bar's second row is laid out at full height from the start.\n *\n * Where the text was is measured after every commit that leaves the state\n * alone, so it is current when the state does change. A change that lands\n * while the last one is still moving starts from where the bar and the text\n * are drawn at that moment, read off the running animations, so reversing\n * mid-way turns round rather than jumping to the end first.\n *\n * Its timing is the root's `background-color` transition's, the `medium1`\n * duration and the emphasized curve, so the fill and the height move as one.\n * Those come from tokens/values rather than the theme, since `animate()`\n * throws on a var(), and the motion is skipped under reduced motion, as the\n * root's transition is.\n */\nfunction useCollapseMotion(collapse: boolean, align: 'center' | 'start') {\n const textRef = useRef<HTMLDivElement>(null);\n const settled = useRef<Geometry | null>(null);\n const collapsedBefore = useRef(collapse);\n const animations = useRef<Animation[]>([]);\n useLayoutEffect(() => {\n const text = textRef.current;\n const bar = text?.parentElement?.parentElement;\n if (text == null || bar == null) {\n return;\n }\n const moving = animations.current.some(animation => animation.playState === 'running');\n if (collapsedBefore.current === collapse) {\n if (!moving) {\n settled.current = geometryOf(bar, text, align);\n }\n return;\n }\n collapsedBefore.current = collapse;\n const last = settled.current;\n const from = moving && last !== null ? drawnAt(bar, text, last) : last;\n for (const animation of animations.current) {\n animation.cancel();\n }\n animations.current = [];\n const to = geometryOf(bar, text, align);\n settled.current = to;\n if (from === null || prefersReducedMotion()) {\n return;\n }\n const timing = {\n duration: motionDurationMs.medium1,\n easing: motionEasing.emphasized\n };\n const heights = [`${from.height}px`, `${to.height}px`];\n animations.current = [bar.animate({\n blockSize: heights,\n clipPath: ['inset(0)', 'inset(0)'],\n minBlockSize: heights\n }, timing)];\n for (const [index, selector] of LINES.entries()) {\n const element = text.querySelector(selector);\n const was = from.lines[index];\n const is = to.lines[index];\n if (element === null || was == null || is == null || is.size === 0) {\n continue;\n }\n const origin = originOf(element, align);\n animations.current.push(element.animate({\n transform: [`translate(${was.x - is.x}px, ${was.y - is.y}px) scale(${was.size / is.size})`, 'none'],\n transformOrigin: [origin, origin]\n }, timing));\n }\n });\n return textRef;\n}\n\n/**\n * The inset as a length CSS arithmetic accepts. A bare `0` is the one length\n * CSS takes without a unit, and the one it rejects inside `max()` and `min()`,\n * where it reads as a number.\n */\nfunction withUnit(contentInset: string) {\n return contentInset.trim() === '0' ? '0px' : contentInset;\n}\nexport type { AppBarProps };\nexport default AppBar;"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["c","_c","ReactNode","stylex","createElement","useLayoutEffect","useRef","RenderComponentProps","COLLAPSED_BLOCK_SIZE","hasContent","useRender","layers","mergeStyles","colors","motion","sizing","spacing","motionDurationMs","motionEasing","Text","ICON_BUTTON_TARGET","ICON_SIZE","GLYPH_INSET","HEIGHTS","lg","plain","withSubtitle","md","sm","const","COLLAPSED_HEIGHT","FORCED_COLORS","styles","pinned","k87sOh","kVAEAm","kY2c9j","$$css","root","k6CgDc","kGNEyG","kWkggS","kB7OPa","k1xSpc","kjj79g","kIyJzY","k1ekBW","kAMwcw","row","kfiyM8","kC13JO","kzqmXN","kUOVxO","scrolled","kL6WhQ","kfdmCh","kt9PQ7","text","kSGwAc","kXwgrk","kJuA4N","kE4Cay","k7Eaqz","kHjlTd","k8WAf4","textBelow","textCenter","k9WMMc","twoRows","kTDh7v","k4zj60","kWgvks","k5JduY","kVb13B","k5jvz2","HEADLINE_VARIANT","SUBTITLE_VARIANT","HEADINGS","heading","level","known","Number","isInteger","PARAGRAPH","_temp","kAzted","heightStyles","minBlockSize","val","undefined","_temp2","ks0D6T","rowStyles","start","end","maxInlineSize","kwRFfy","kZCmMZ","tracks","gridTemplateColumns","gridTemplateRows","kumcoG","k9llMU","START_COLUMNS","_temp3","keoZOQ","textStyles","inset","reach","marginBlockStart","UNDER_TARGETS","AppBarProps","Omit","align","collapsed","contentInset","contentMaxInlineSize","headingLevel","headline","leading","size","subtitle","trailing","LINES","Geometry","height","lines","Line","x","y","AppBar","t0","$","t1","t2","t3","t4","t5","t6","render","t7","t8","props","collapse","below","expandedHeight","hasLeading","hasTrailing","centred","hasSlot","padsForStart","padsForEnd","textRef","useCollapseMotion","t9","t10","edgePadding","centredColumns","t11","t12","glyphRoom","t13","t14","t15","t16","t17","t18","t19","children","t20","defaultTagName","room","side","drawnAt","bar","HTMLElement","settled","getBoundingClientRect","map","selector","index","line","element","querySelector","moved","matrixOf","a","e","f","withUnit","geometryOf","frame","box","edge","left","right","isRightToLeft","parseFloat","getComputedStyle","fontSize","glyphTopOf","top","Element","range","document","createRange","selectNodeContents","first","getClientRects","item","direction","DOMMatrixReadOnly","transform","originOf","glyphs","prefersReducedMotion","window","matchMedia","matches","collapsedBefore","Symbol","for","animations","current","parentElement","moving","some","_temp4","last","from","animation_0","animation","cancel","to","timing","duration","medium1","easing","emphasized","heights","animate","blockSize","clipPath","entries","was","is","origin","push","transformOrigin","playState","trim","_c","props","stylex.props"],"sources":["../../../src/components/app-bar/index.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport * as stylex from '@stylexjs/stylex';\nimport { createElement, useLayoutEffect, useRef } from 'react';\nimport type { RenderComponentProps } from '../../render/useRender';\nimport { COLLAPSED_BLOCK_SIZE } from '../../hooks/useAppBarScroll';\nimport { hasContent } from '../../render/content';\nimport { useRender } from '../../render/useRender';\nimport '../../styles/layers.stylex';\nimport { layers } from '../../styles/layers.stylex';\nimport { mergeStyles } from '../../styles/merge';\nimport '../../tokens/design.tokens.stylex';\nimport { colors, motion, sizing, spacing } from '../../tokens/design.tokens.stylex';\nimport { motionDurationMs, motionEasing } from '../../tokens/values';\nimport Text from '../text';\n\n// Material Design's app bar, in the three sizes the spec recommends.\n//\n// `md` and `lg` are Material Design's medium and large *flexible* bars, the\n// newer of the two sets the spec gives and the one it recommends, which is why\n// those two steps are theirs: their heights, their two rows, and their type\n// roles, which HEADLINE_VARIANT and SUBTITLE_VARIANT name.\n//\n// Material Design also merged the old center-aligned variant into small as a\n// configuration rather than a variant, which is why alignment is a prop here\n// and applies to every size.\n//\n// Heights are Material Design's, and they are minimums rather than fixed. The\n// spec says the flexible bars \"hug the text contents\" and gives them multi-line\n// support and text wrapping, so a headline long enough to wrap has to be able\n// to make its bar taller. Fixing the height would truncate exactly the case\n// the variant was redesigned for.\n//\n// The small bar is one row: the leading slot, the text and the trailing slot\n// side by side in a 64px strip. The flexible bars are two, as Material Design\n// lays them out. The first is that same strip holding the slots alone, and the\n// second runs the text under it across the whole measure, so a long headline\n// wraps against the bar's width rather than against what the slots leave.\n// Collapsing moves the text up into the strip, which is the small bar exactly,\n// and the slots never move: they are in the strip in both states.\n//\n// Centred text is centred on the bar, not in the room the slots leave, which\n// is how Material Design places it: with a leading icon and no actions, the\n// room between the two is off the bar's middle by half the icon. So a centred\n// strip's side columns share what the text leaves equally, whatever is in\n// them, and the text moves off the middle only where a wide slot needs the\n// room — see `centredColumns`.\n//\n// The slots set the colours the page gives their icons: on surface for the\n// leading one and on surface variant for the trailing ones. The second is a\n// standard icon button's own colour, and the first is not, so the leading\n// slot also sets the property a standard icon button reads its colour from —\n// see `standard` in src/components/icon-button/index.tsx.\n\n// The geometry Material Design lays a bar's icon buttons out on. Its tokens\n// give a 4dp leading and trailing space between the bar's edge and the first\n// button's 48dp target, no space between one target and the next, and a 24dp\n// icon centred in each — so a glyph lands 4 + 12 = 16dp in, on the page's own\n// margin.\n//\n// The library's icon button draws a 40dp box with its 48dp target out of\n// flow, so a slot pads half the difference either side and puts the whole\n// difference between two buttons, which lays the targets edge to edge as the\n// tokens do. The target is IconButton's TARGET_SIZE, a literal there for the\n// reason it gives: it is a floor the page states, not a step of the control\n// scale.\nconst ICON_BUTTON_TARGET = '48px';\nconst ICON_SIZE = '24px';\n\n// How far an icon sits inside its target, which is how much less than the\n// content inset the row is padded on an edge that holds a slot. That is what\n// puts a leading glyph, rather than the edge of its target, at the inset.\nconst GLYPH_INSET = `(${ICON_BUTTON_TARGET} - ${ICON_SIZE}) / 2`;\nconst HEIGHTS = {\n lg: {\n plain: '120px',\n withSubtitle: '152px'\n },\n md: {\n plain: '112px',\n withSubtitle: '136px'\n },\n sm: {\n plain: `${COLLAPSED_BLOCK_SIZE}px`,\n withSubtitle: `${COLLAPSED_BLOCK_SIZE}px`\n }\n} as const;\n\n// What a flexible bar collapses to, which is the small bar exactly. Material\n// Design does not describe the collapsed large bar as a state of its own — it\n// describes it as becoming the small bar, which is why this reads off the same\n// table rather than being a fourth height.\nconst COLLAPSED_HEIGHT = HEIGHTS.sm.plain;\n\n// Windows High Contrast and the rest of the forced-colours modes. Spelled\n// here rather than imported, for the reason src/field/styles.ts records: the\n// StyleX compiler resolves a constant across files only out of a `.stylex.ts`\n// module, and the generated one holds design tokens rather than queries.\nconst FORCED_COLORS = '@media (forced-colors: active)';\nconst styles = {\n pinned: {\n k87sOh: \"x13vifvy\",\n kVAEAm: \"x7wzq59\",\n kY2c9j: \"xfj7q76\",\n $$css: true\n },\n root: {\n k6CgDc: \"x12w9bfk\",\n kGNEyG: \"x1qjc9v5\",\n kWkggS: \"x14s9m32\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kjj79g: \"xl56j7k\",\n kIyJzY: \"xioksi3\",\n k1ekBW: \"x15406qy\",\n kAMwcw: \"x1seskgd\",\n $$css: true\n },\n row: {\n kfiyM8: \"x10ukxgv\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"xrvj5dj\",\n kC13JO: \"x97ohe\",\n kzqmXN: \"xh8yej3\",\n kUOVxO: \"xvueqy4\",\n $$css: true\n },\n scrolled: {\n kWkggS: \"x1mjdul6\",\n kL6WhQ: \"xszdk7l\",\n kfdmCh: \"xe3zi7u\",\n kt9PQ7: \"x15anc7y\",\n $$css: true\n },\n text: {\n kSGwAc: \"xamitd3\",\n kB7OPa: \"x9f619\",\n k1xSpc: \"x78zum5\",\n kXwgrk: \"xdt5ytf\",\n kJuA4N: \"x12gd1sl\",\n kE4Cay: \"xkjl1po\",\n k7Eaqz: \"xeuugli\",\n kHjlTd: \"xj0a0fe\",\n k8WAf4: \"x1cmllll\",\n $$css: true\n },\n textBelow: {\n kSGwAc: \"xnav3zx\",\n k8WAf4: \"xt970qd\",\n $$css: true\n },\n textCenter: {\n k9WMMc: \"x2b8uid\",\n $$css: true\n }\n};\n\n// The flexible bars' two rows: the strip with the slots at either end, and the\n// text under it across all three columns. The second row takes whatever height\n// the bar has beyond the strip, and the text sits at its bottom.\n//\n// Material Design places that text by its last baseline, 28px above the large\n// bar's bottom edge and 24px above the medium one's, and that is the reading\n// that makes the heights above come out, together with the reach textStyles\n// gives the text: the same figures as padding under the line box would make a\n// plain large bar 64 + 44 + 28 = 136px rather than 120px. CSS gives a box no\n// margin below its baseline, so the strut does it.\n// An empty box in the same grid area, aligned on its last baseline with the\n// text, has its baseline at its own bottom edge and the margin under that, so\n// the pair is held that far off the row's end. Literals rather than tokens,\n// like HEIGHTS: they are measurements the spec gives this component, not steps\n// of the spacing scale, which has no 28.\nconst twoRows = {\n lg: {\n kTDh7v: \"x1mna9mr\",\n k4zj60: \"x1gmr53x\",\n kWgvks: \"xx38sju\",\n k5JduY: \"x1s928wv\",\n kVb13B: \"x1vlsijy\",\n k5jvz2: \"x1fh8phi\",\n kC13JO: \"xc3o5yk\",\n $$css: true\n },\n md: {\n kTDh7v: \"x1mna9mr\",\n k4zj60: \"x1gmr53x\",\n kWgvks: \"xx38sju\",\n k5JduY: \"x1s928wv\",\n kVb13B: \"x1vlsijy\",\n k5jvz2: \"x1v6yq59\",\n kC13JO: \"xc3o5yk\",\n $$css: true\n }\n};\n\n// One entry per size, and each names a type role rather than a figure.\n// Material Design's own tokens are `md.comp.app-bar.<size>.title.font`,\n// aliases onto the type scale rather than sizes of their own, so this maps to\n// the scale the same way and lets Text apply it. The roles are the flexible\n// bars': headlineMedium on medium and displaySmall on large, which is a step\n// up from what the spec's other medium and large bars take, and the small\n// bar's titleLarge.\nconst HEADLINE_VARIANT = {\n lg: 'displaySmall',\n md: 'headlineMedium',\n sm: 'titleLarge'\n} as const;\n\n// The subtitle's role, by the same tokens' `subtitle.font`. Material Design\n// gives each size its own rather than one role at every size, and a collapsed\n// bar takes the small bar's, as it takes its headline's.\nconst SUBTITLE_VARIANT = {\n lg: 'titleMedium',\n md: 'labelLarge',\n sm: 'labelMedium'\n} as const;\n\n// The headline is the page's title in Material Design's model, so it is the\n// page's <h1> unless the call site says otherwise. `headingLevel` is what says\n// otherwise, and a bar drawn beside another bar — one per pane in a\n// `ListDetail` or a `SupportingPane` — or under a page heading of its own\n// should lower it.\n//\n// Built here rather than kept as a constant per level: `headline` becomes the\n// heading's children, so a call site cannot demote the heading by passing one\n// of its own. `headline={<h2>…</h2>}` renders an h2 inside the h1 — two\n// headings where one was wanted, which React does not warn about.\n//\n// The level is looked up rather than interpolated into a tag name. `h7` is a\n// custom element as far as React is concerned, so it renders without a word\n// said and leaves the outline worse than the default would have. The prop's\n// type is the six levels, and a value outside them from a call site the type\n// does not reach — `NaN`, which rounded and clamped to no element at all and\n// took the headline out of the outline — falls back to the default h1.\n// Disclosure's own `headingLevel` hands the number to React Aria, which is\n// why that one needs no equivalent.\nconst HEADINGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;\nfunction heading(level: number) {\n const known = Number.isInteger(level) && level >= 1 && level <= 6;\n return createElement(known ? HEADINGS[level - 1] : HEADINGS[0]);\n}\nconst PARAGRAPH = <p />;\n\n// Height is the one value the call site does not choose, and it depends on two\n// props at once, so it is a function style rather than one key per\n// combination. StyleX writes it to a custom property inline, the same\n// mechanism Feed uses for its cell minimum.\n//\n// The row takes it too, and that is for the collapse's motion. The bar's\n// height is animated, and a row that only stretched to it would be laid out\n// at every height the bar passed through: the second row is the room the bar\n// has beyond the strip, so its text would ride up and down with the bar\n// rather than holding the place the animation moves it to. With the minimum\n// of its own, the row is laid out once, at the height the bar is heading for,\n// and the bar clips it until it gets there.\nconst _temp = {\n kAzted: \"x1chvrdh\",\n \"$$css\": true\n};\nconst heightStyles = {\n root: (minBlockSize: string) => [_temp, {\n \"--x-minBlockSize\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(minBlockSize)\n }]\n};\n\n// The row's measure and inset both come from the call site, so both are\n// function styles too. Each edge is worked out on its own: where it holds a\n// slot the row stops short of the inset by GLYPH_INSET, so the glyph rather\n// than its target is what sits at the inset, and where it holds none the\n// headline itself starts there. Clamped at zero, since an inset smaller than\n// a glyph's own room would otherwise ask for a negative padding, which CSS\n// throws away whole.\n//\n// The tracks are a function style for two other reasons: the strip is the\n// small bar's height, which is the hook's constant, and the compiler cannot\n// read a constant out of another module — see FORCED_COLORS; and a centred\n// bar's columns depend on the inset — see `centredColumns`.\nconst _temp2 = {\n ks0D6T: \"x13i5qev\",\n \"$$css\": true\n};\nconst rowStyles = {\n root: (start: string, end: string, maxInlineSize: string) => [_temp2, {\n kwRFfy: end != null ? \"x120eax6\" : end,\n kZCmMZ: start != null ? \"xnvo3vl\" : start,\n $$css: true\n }, {\n \"--x-maxInlineSize\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(maxInlineSize),\n \"--x-paddingInlineEnd\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(end),\n \"--x-paddingInlineStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(start)\n }],\n tracks: (gridTemplateColumns: string, gridTemplateRows: string) => [{\n kumcoG: gridTemplateColumns != null ? \"xqketvx\" : gridTemplateColumns,\n k9llMU: gridTemplateRows != null ? \"x1xxtoay\" : gridTemplateRows,\n $$css: true\n }, {\n \"--x-gridTemplateColumns\": gridTemplateColumns != null ? gridTemplateColumns : undefined,\n \"--x-gridTemplateRows\": gridTemplateRows != null ? gridTemplateRows : undefined\n }]\n};\n\n// A bar's columns with its text at the start: the slots at their own widths\n// and the text taking what they leave.\nconst START_COLUMNS = 'auto minmax(0, 1fr) auto';\n\n// The text in the second row runs under the slots as well as between them, so\n// it puts back what the row's padding held off an edge for a slot's glyph, and\n// the headline starts on the inset again. A function style for the reason the\n// row's padding is one.\n//\n// It also reaches up into the strip, by the band under the slots' targets,\n// and Material Design's heights depend on that. A large bar's 36/44 headline\n// with its baseline 28px above a 120px bar's edge has the top of its line box\n// inside the strip, and so does the medium bar's 28/36 one: measured, the two\n// bars came out 126px and 115px tall without it. What reaches in is the line's\n// leading and the room above its capitals rather than any glyph, and it stops\n// where the targets do, so nothing a reader can press is under it. A function\n// style because the strip's height is the hook's constant — see rowStyles.\nconst _temp3 = {\n keoZOQ: \"x1vhfslr\",\n \"$$css\": true\n};\nconst textStyles = {\n inset: (start: string, end: string) => [{\n kwRFfy: end != null ? \"x120eax6\" : end,\n kZCmMZ: start != null ? \"xnvo3vl\" : start,\n $$css: true\n }, {\n \"--x-paddingInlineEnd\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(end),\n \"--x-paddingInlineStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(start)\n }],\n reach: (marginBlockStart: string) => [_temp3, {\n \"--x-marginBlockStart\": (val => typeof val === \"number\" ? val + \"px\" : val != null ? val : undefined)(marginBlockStart)\n }]\n};\n\n// How far the strip runs on below the slots' targets, which are centred in it.\nconst UNDER_TARGETS = `calc((${COLLAPSED_HEIGHT} - ${ICON_BUTTON_TARGET}) / 2)`;\ntype AppBarProps = Omit<RenderComponentProps<'header'>, 'children'> & {\n /**\n * Which of Material Design's alignments the text takes. `center` is the\n * configuration that replaced the old center-aligned variant, and centres\n * the text on the bar rather than between the slots, so a bar with a\n * leading icon and no actions still has its headline in the middle. The\n * text moves off the middle only as far as a slot wider than the other\n * needs, rather than running under it.\n * @default 'start'\n */\n align?: 'center' | 'start';\n /**\n * Collapses a flexible bar to the height and headline of the small one, for\n * a bar `pinned` over content that has been scrolled. Material Design\n * specifies it for the flexible sizes, and without it a pinned `lg` costs\n * 152px of the viewport for as long as the page is open.\n *\n * Controlled, and for the same reason `scrolled` is: only the app knows\n * which element scrolls, and how far into it the bar should have finished\n * collapsing. `useAppBarScroll` derives both from that element's scroll,\n * and is the way to set them unless the app needs a rule of its own.\n *\n * Ignored on `sm`, which is already the height this collapses to. The\n * headline and the subtitle move up into the row the slots sit in and take\n * the small bar's type roles, which fit both lines in its 64px, and the\n * slots never leave that row: they stay where they are while the bar\n * shrinks under them.\n *\n * Collapsing hands the page back the height the bar gives up, and a bar\n * whose state is read off the scroll offset can then undo itself in two\n * ways. Both move the offset back under the threshold, so the bar expands,\n * the page regains its height, and the two take turns for as long as the\n * reader stays there.\n *\n * - **Scroll anchoring.** Browsers answer a change in height above the\n * viewport by moving the offset by the same amount, to keep the content\n * in place. Give the scroll container `overflow-anchor: none`, which is\n * also the movement you want: the content follows the bar's bottom edge\n * up rather than standing still while the bar shrinks behind it.\n * - **The shorter page.** A page that overflows by less than the threshold\n * plus the height the bar gives back cannot scroll that far once the bar\n * has collapsed, so the browser pulls the offset back inside it. No\n * threshold avoids this, since the band moves with it; what does is not\n * collapsing on such a page, which is the rule `useAppBarScroll` applies.\n * @default false\n */\n collapsed?: boolean;\n /**\n * Where the bar's content starts on each edge: the headline where nothing\n * comes before it, and the leading icon's glyph where something does, with\n * the headline after the icon button's target. The trailing edge is the\n * same mirrored. Any length works, `0` included, for a bar drawn flush.\n *\n * The default is Material Design's own margin for a top app bar, the\n * spacing scale's `lg` step, which is also the margin it gives body\n * content, so a bar and the page beneath line up without either being told\n * about the other. Set it to the page's gutter where that differs.\n * @default spacing.lg\n */\n contentInset?: string;\n /**\n * How wide the bar's contents may run before they stop growing, with the\n * row centred in whatever is left. The bar's own surface still paints edge\n * to edge.\n *\n * This is what lines a full-bleed bar up with a page whose content sits in\n * a measure: give it the page's measure, and `contentInset` the page's\n * gutter. Unset, the row is as wide as the bar.\n */\n contentMaxInlineSize?: string;\n /**\n * Where the headline sits in the page's outline, as one of the six heading\n * levels. A screen reader moves between headings, so a bar drawn beside\n * another bar, or under a page heading of its own, should lower it. A value\n * outside the six that reaches it untyped falls back to 1.\n * @default 1\n */\n headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n /** The page's title. Wraps rather than truncating, and grows the bar with it. */\n headline?: ReactNode;\n /**\n * Usually a back or menu icon button. Sits before the text, and a standard\n * icon button here draws its icon in on surface, the colour the page gives\n * a bar's leading icon, rather than its own on surface variant.\n */\n leading?: ReactNode;\n /**\n * Holds the bar at the top of its scroll container while the content\n * scrolls beneath it, and keeps it painted over that content. The bar\n * still needs a scrolling ancestor to stick inside: the window, or an\n * element with its own overflow. A pinned bar is the one `collapsed` and\n * `scrolled` are for.\n * @default false\n */\n pinned?: boolean;\n /**\n * Whether the content beneath has been scrolled. Material Design separates\n * a bar from scrolled content with a fill colour rather than a shadow, and\n * this is what applies it.\n *\n * Controlled, with no listener of its own: only the app knows which element\n * scrolls, and a bar that watched the window would be wrong inside every\n * pane and dialog that scrolls independently.\n * @default false\n */\n scrolled?: boolean;\n /**\n * Height and headline size, as steps of the library's size scale. `sm` is\n * Material Design's small bar, a fixed 64px row; `md` and `lg` are its\n * medium and large flexible bars, which put the text in a row of its own\n * under the slots and hug it.\n * @default 'sm'\n */\n size?: 'lg' | 'md' | 'sm';\n /** A second line under the headline. Makes `md` and `lg` taller. */\n subtitle?: ReactNode;\n /** Actions, at the far end. Usually icon buttons. */\n trailing?: ReactNode;\n};\n\n// The text block's two lines: the headline, and the subtitle beside it. The\n// block holds nothing else, and each is drawn as one kind of element.\nconst LINES = [':scope > :is(h1, h2, h3, h4, h5, h6)', ':scope > p'] as const;\n\n/**\n * What collapsing moves, and so what its animation runs between: the bar's\n * height, and each of the text's lines, in the order LINES gives them, with\n * `null` for a line the bar does not draw.\n */\ntype Geometry = {\n height: number;\n lines: (Line | null)[];\n};\n\n/**\n * Where one of the text's lines is drawn: the point its glyphs hang from,\n * measured from the bar's own corner, and its type size. The point is the\n * top of the line's first glyphs, on the edge the text hangs from.\n */\ntype Line = {\n size: number;\n x: number;\n y: number;\n};\n\n/**\n * Material Design's app bar: the container at the top of a page carrying its\n * title, one or two actions, and the way back out.\n *\n * ```tsx\n * <AppBar headline=\"Headline\" leading={back} size=\"md\" trailing={actions} />\n * ```\n *\n * Three sizes. `sm` is a fixed 64px bar for a page whose title is a label;\n * `md` and `lg` are the flexible bars, which give the headline a larger\n * type role in a row of its own under the slots, and grow to fit a subtitle\n * or a headline that wraps.\n *\n * It paints its own surface, unlike the layout components, because separating\n * itself from the content beneath is the job — which is also why `scrolled`\n * and `collapsed` exist. Neither watches the page: only the app knows which\n * element scrolls, so both are set from its own scroll handler.\n */\nfunction AppBar({\n align = 'start',\n collapsed = false,\n contentInset = spacing.lg,\n contentMaxInlineSize = 'none',\n headingLevel = 1,\n headline,\n leading,\n pinned = false,\n render,\n scrolled = false,\n size = 'sm',\n subtitle,\n trailing,\n ...props\n}: AppBarProps) {\n // `sm` is already what the flexible bars collapse to, so collapsing it is\n // a no-op rather than an error. A bar whose size is chosen at the call site\n // from a breakpoint would otherwise have to guard the prop as well.\n const collapse = collapsed && size !== 'sm';\n // The flexible bars at their full height are the only state with a second\n // row. Collapsed, they are the small bar.\n const below = size !== 'sm' && !collapse;\n const expandedHeight = hasContent(subtitle) ? HEIGHTS[size].withSubtitle : HEIGHTS[size].plain;\n const height = collapse ? COLLAPSED_HEIGHT : expandedHeight;\n const hasLeading = hasContent(leading);\n const hasTrailing = hasContent(trailing);\n // A centred bar pads both edges as one holding a slot would, so the row\n // is the same either side of the middle — see `centredColumns`.\n const centred = align === 'center';\n const hasSlot = hasLeading || hasTrailing;\n const padsForStart = centred ? hasSlot : hasLeading;\n const padsForEnd = centred ? hasSlot : hasTrailing;\n const textRef = useCollapseMotion(collapse, align);\n return useRender({\n defaultTagName: 'header',\n props: {\n ...props,\n children: <div {...stylex.props(styles.row, rowStyles.root(edgePadding(contentInset, padsForStart), edgePadding(contentInset, padsForEnd), contentMaxInlineSize), rowStyles.tracks(centred ? centredColumns(contentInset, hasLeading, hasTrailing) : START_COLUMNS, below ? `minmax(${COLLAPSED_HEIGHT}, auto) 1fr` : `minmax(${COLLAPSED_HEIGHT}, auto)`), heightStyles.root(height), below && twoRows[size])}>\n {!hasLeading ? null : <div className=\"x6s0dn4 xamitd3 x9f619 x78zum5 x1r8zjiw x1let9r4 x155k8fu x139gbkf x1kxrqrs x1lqcxt8 x15ir4sr\">{leading}</div>}\n <div {...stylex.props(styles.text, below && styles.textBelow, below && textStyles.inset(glyphRoom(contentInset, padsForStart), glyphRoom(contentInset, padsForEnd)), below && textStyles.reach(`calc(-1 * ${UNDER_TARGETS})`), align === 'center' && styles.textCenter)} ref={textRef}>\n {!hasContent(headline) ? null : <Text render={heading(headingLevel)} variant={collapse ? HEADLINE_VARIANT.sm : HEADLINE_VARIANT[size]}>\n {headline}\n </Text>}\n {!hasContent(subtitle) ? null : <Text render={PARAGRAPH} tone=\"muted\" variant={collapse ? SUBTITLE_VARIANT.sm : SUBTITLE_VARIANT[size]}>\n {subtitle}\n </Text>}\n </div>\n {!hasTrailing ? null : <div className=\"x6s0dn4 xamitd3 x9f619 x78zum5 x1r8zjiw x1let9r4 x1w5n3ug x1txd71x x1qab1bc x6aqprb\">\n {trailing}\n </div>}\n </div>,\n ...mergeStyles(stylex.props(styles.root, heightStyles.root(height), scrolled && styles.scrolled, pinned && styles.pinned), props)\n },\n render\n });\n}\n\n/**\n * A centred bar's columns: the text in the middle at its own width, and a\n * column either side sharing what it leaves equally, so the text is centred\n * on the row. A side column is never narrower than its slot, which is what\n * moves the text off the middle when a slot is wider than the other side's\n * share, and never as far as overlapping it.\n *\n * The row pads both edges for a slot, so the two sides match, and an edge\n * with no slot puts back what that padding held off for a glyph as its\n * column's least width. A headline long enough to reach that edge stops on\n * the inset, as it does at the start.\n */\nfunction centredColumns(contentInset: string, hasLeading: boolean, hasTrailing: boolean) {\n const room = glyphRoom(contentInset, hasLeading || hasTrailing);\n const side = (hasSlot: boolean) => hasSlot ? 'minmax(auto, 1fr)' : `minmax(${room}, 1fr)`;\n return `${side(hasLeading)} auto ${side(hasTrailing)}`;\n}\n\n/**\n * Where an animation still under way has the bar and the text drawn: the\n * height it holds the bar at, and each line where its transform has taken it\n * and at the size its scale has reached. A line scales about the point it\n * hangs from, so the transform's translation is how far that point has moved.\n */\nfunction drawnAt(bar: HTMLElement, text: HTMLElement, settled: Geometry): Geometry {\n return {\n height: bar.getBoundingClientRect().height,\n lines: LINES.map((selector, index) => {\n const line = settled.lines[index];\n const element = text.querySelector(selector);\n if (line === null || element === null) {\n return null;\n }\n const moved = matrixOf(element);\n return {\n size: line.size * moved.a,\n x: line.x + moved.e,\n y: line.y + moved.f\n };\n })\n };\n}\n\n/** The row's padding on one edge, for the inset the call site gave. */\nfunction edgePadding(contentInset: string, hasSlot: boolean) {\n const inset = withUnit(contentInset);\n return hasSlot ? `max(0px, ${inset} - ${GLYPH_INSET})` : inset;\n}\n\n/**\n * Where the bar and each of the text's lines are drawn. A line's point is on\n * the edge its text hangs from: the middle when it is centred, and the start\n * edge otherwise, which is the right edge in a right-to-left page. Each line\n * is as wide as the text block, so that edge is its box's.\n */\nfunction geometryOf(bar: HTMLElement, text: HTMLElement, align: 'center' | 'start'): Geometry {\n const frame = bar.getBoundingClientRect();\n return {\n height: frame.height,\n lines: LINES.map(selector => {\n const element = text.querySelector(selector);\n if (element === null) {\n return null;\n }\n const box = element.getBoundingClientRect();\n const edge = align === 'center' ? (box.left + box.right) / 2 : isRightToLeft(element) ? box.right : box.left;\n return {\n size: Number.parseFloat(getComputedStyle(element).fontSize),\n x: edge - frame.left,\n y: glyphTopOf(element) - frame.top\n };\n })\n };\n}\n\n/**\n * What the row's padding held back on one edge for a slot's glyph, which the\n * text in the second row puts back: the inset less `edgePadding`, so the\n * smaller of the inset and GLYPH_INSET.\n */\nfunction glyphRoom(contentInset: string, hasSlot: boolean) {\n return hasSlot ? `min(${withUnit(contentInset)}, ${GLYPH_INSET})` : '0px';\n}\n\n/**\n * Where an element's first glyphs start, which is below its box's top by\n * half its line's leading. The leading is a share of the line height, and\n * the two roles a line moves between do not keep line height and type size\n * in one ratio, so a line scaled by its type size from its box's corner\n * starts its glyphs off where they were drawn: about a pixel, for a large\n * bar's headline.\n */\nfunction glyphTopOf(element: Element) {\n const range = document.createRange();\n range.selectNodeContents(element);\n const first = range.getClientRects().item(0);\n return first === null ? element.getBoundingClientRect().top : first.top;\n}\n\n/** Whether the text runs right to left, which decides the edge it hangs from. */\nfunction isRightToLeft(element: Element) {\n return getComputedStyle(element).direction === 'rtl';\n}\n\n/** The transform an element is drawn with, `none` reading as no change. */\nfunction matrixOf(element: Element) {\n return new DOMMatrixReadOnly(getComputedStyle(element).transform);\n}\n\n/**\n * The point a line scales about, in its own box: the top of its glyphs, on\n * the edge its text hangs from.\n */\nfunction originOf(element: Element, align: 'center' | 'start') {\n const edge = align === 'center' ? 'center' : isRightToLeft(element) ? 'right' : 'left';\n const glyphs = glyphTopOf(element) - element.getBoundingClientRect().top;\n return `${edge} ${glyphs}px`;\n}\n\n/**\n * Read when the bar changes state rather than once at mount, so a reader who\n * changes the setting is answered by the next collapse.\n */\nfunction prefersReducedMotion() {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/**\n * Animates a flexible bar between its two states, and returns the ref for the\n * text block whose lines it moves.\n *\n * Collapsing changes the bar's layout rather than a value — the text leaves\n * the second row for the strip, both lines take the small bar's type roles,\n * and the bar's height drops from a minimum to whatever its content takes —\n * so there is nothing for a CSS transition to interpolate. This plays it the\n * other way round: the change has already been laid out when the effect runs,\n * so the bar is animated from the height it had to the one it has, and each\n * line from where and how large it was drawn to where and how large it is,\n * by a transform that starts at the difference and ends at none. A line\n * scales about the point its glyphs hang from, which is what lands its first\n * frame on the glyphs it replaces — see glyphTopOf. A scale rather than a\n * transition of the type itself, which would lay the text out again on every\n * frame and move it away from the place it was measured at. Each line moves\n * on its own rather than with the block, since the subtitle starts under the\n * headline's line, whose height changes with its role. The slots need\n * nothing: they are in the strip in both states.\n *\n * The bar's height is animated through `min-block-size` as well as its\n * height, since the minimum would otherwise hold an expanding bar at its new\n * height from the first frame, and it is clipped while it moves, since an\n * expanding bar's second row is laid out at full height from the start.\n *\n * Where the text was is measured after every commit that leaves the state\n * alone, so it is current when the state does change. A change that lands\n * while the last one is still moving starts from where the bar and the text\n * are drawn at that moment, read off the running animations, so reversing\n * mid-way turns round rather than jumping to the end first.\n *\n * Its timing is the root's `background-color` transition's, the `medium1`\n * duration and the emphasized curve, so the fill and the height move as one.\n * Those come from tokens/values rather than the theme, since `animate()`\n * throws on a var(), and the motion is skipped under reduced motion, as the\n * root's transition is.\n */\nfunction useCollapseMotion(collapse: boolean, align: 'center' | 'start') {\n const textRef = useRef<HTMLDivElement>(null);\n const settled = useRef<Geometry | null>(null);\n const collapsedBefore = useRef(collapse);\n const animations = useRef<Animation[]>([]);\n useLayoutEffect(() => {\n const text = textRef.current;\n const bar = text?.parentElement?.parentElement;\n if (text == null || bar == null) {\n return;\n }\n const moving = animations.current.some(animation => animation.playState === 'running');\n if (collapsedBefore.current === collapse) {\n if (!moving) {\n settled.current = geometryOf(bar, text, align);\n }\n return;\n }\n collapsedBefore.current = collapse;\n const last = settled.current;\n const from = moving && last !== null ? drawnAt(bar, text, last) : last;\n for (const animation of animations.current) {\n animation.cancel();\n }\n animations.current = [];\n const to = geometryOf(bar, text, align);\n settled.current = to;\n if (from === null || prefersReducedMotion()) {\n return;\n }\n const timing = {\n duration: motionDurationMs.medium1,\n easing: motionEasing.emphasized\n };\n const heights = [`${from.height}px`, `${to.height}px`];\n animations.current = [bar.animate({\n blockSize: heights,\n clipPath: ['inset(0)', 'inset(0)'],\n minBlockSize: heights\n }, timing)];\n for (const [index, selector] of LINES.entries()) {\n const element = text.querySelector(selector);\n const was = from.lines[index];\n const is = to.lines[index];\n if (element === null || was == null || is == null || is.size === 0) {\n continue;\n }\n const origin = originOf(element, align);\n animations.current.push(element.animate({\n transform: [`translate(${was.x - is.x}px, ${was.y - is.y}px) scale(${was.size / is.size})`, 'none'],\n transformOrigin: [origin, origin]\n }, timing));\n }\n });\n return textRef;\n}\n\n/**\n * The inset as a length CSS arithmetic accepts. A bare `0` is the one length\n * CSS takes without a unit, and the one it rejects inside `max()` and `min()`,\n * where it reads as a number.\n */\nfunction withUnit(contentInset: string) {\n return contentInset.trim() === '0' ? '0px' : contentInset;\n}\nexport type { AppBarProps };\nexport default AppBar;"],"mappings":"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"}
@@ -37,6 +37,50 @@ type AutocompleteProps$1<T extends object = object> = {
37
37
  * visually hidden status after its children, which tells a screen reader
38
38
  * when a search leaves the collection empty.
39
39
  *
40
+ * A command palette is the last of those, and three things make it one
41
+ * rather than a list in a dialog. The input takes `autoFocus`, so the first
42
+ * keystroke searches rather than landing on the dialog. The collection takes
43
+ * `onAction` and no `selectionMode`, so Enter runs a command and closes the
44
+ * palette rather than marking a row. And the dialog keeps a close button in
45
+ * its header: below the medium breakpoint it fills the window, which leaves
46
+ * no scrim to press, and a phone has no Escape key.
47
+ *
48
+ * ```tsx
49
+ * <Dialog>
50
+ * <Button>Commands</Button>
51
+ * <Dialog.Content>
52
+ * {({ close }) => (
53
+ * <>
54
+ * <Dialog.Header>
55
+ * <Dialog.Title>Commands</Dialog.Title>
56
+ * <IconButton aria-label="Close" slot="close">
57
+ * <CloseIcon />
58
+ * </IconButton>
59
+ * </Dialog.Header>
60
+ * <Dialog.Body>
61
+ * <Autocomplete>
62
+ * <SearchField
63
+ * autoFocus
64
+ * label="Search commands"
65
+ * placeholder="Search commands"
66
+ * />
67
+ * <ListBox
68
+ * aria-label="Commands"
69
+ * onAction={(key) => {
70
+ * runCommand(key)
71
+ * close()
72
+ * }}
73
+ * >
74
+ * <ListBox.Item id="open">Open file</ListBox.Item>
75
+ * </ListBox>
76
+ * </Autocomplete>
77
+ * </Dialog.Body>
78
+ * </>
79
+ * )}
80
+ * </Dialog.Content>
81
+ * </Dialog>
82
+ * ```
83
+ *
40
84
  * Keyboard focus stays in the input while the arrow keys move through the
41
85
  * collection, which is React Aria's virtual focus. `disableVirtualFocus`
42
86
  * turns that off and makes the collection tabbable instead.
@@ -25,6 +25,50 @@ import { Autocomplete, useFilter } from "react-aria-components";
25
25
  * visually hidden status after its children, which tells a screen reader
26
26
  * when a search leaves the collection empty.
27
27
  *
28
+ * A command palette is the last of those, and three things make it one
29
+ * rather than a list in a dialog. The input takes `autoFocus`, so the first
30
+ * keystroke searches rather than landing on the dialog. The collection takes
31
+ * `onAction` and no `selectionMode`, so Enter runs a command and closes the
32
+ * palette rather than marking a row. And the dialog keeps a close button in
33
+ * its header: below the medium breakpoint it fills the window, which leaves
34
+ * no scrim to press, and a phone has no Escape key.
35
+ *
36
+ * ```tsx
37
+ * <Dialog>
38
+ * <Button>Commands</Button>
39
+ * <Dialog.Content>
40
+ * {({ close }) => (
41
+ * <>
42
+ * <Dialog.Header>
43
+ * <Dialog.Title>Commands</Dialog.Title>
44
+ * <IconButton aria-label="Close" slot="close">
45
+ * <CloseIcon />
46
+ * </IconButton>
47
+ * </Dialog.Header>
48
+ * <Dialog.Body>
49
+ * <Autocomplete>
50
+ * <SearchField
51
+ * autoFocus
52
+ * label="Search commands"
53
+ * placeholder="Search commands"
54
+ * />
55
+ * <ListBox
56
+ * aria-label="Commands"
57
+ * onAction={(key) => {
58
+ * runCommand(key)
59
+ * close()
60
+ * }}
61
+ * >
62
+ * <ListBox.Item id="open">Open file</ListBox.Item>
63
+ * </ListBox>
64
+ * </Autocomplete>
65
+ * </Dialog.Body>
66
+ * </>
67
+ * )}
68
+ * </Dialog.Content>
69
+ * </Dialog>
70
+ * ```
71
+ *
28
72
  * Keyboard focus stays in the input while the arrow keys move through the
29
73
  * collection, which is React Aria's virtual focus. `disableVirtualFocus`
30
74
  * turns that off and makes the collection tabbable instead.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["c","_c","ReactNode","AutocompleteProps","RACAutocompleteProps","Autocomplete","RACAutocomplete","useFilter","CollectionStatus","AutocompleteFilter","NonNullable","T","children","filter","Omit","t0","$","props","t1","Symbol","for","sensitivity","contains","t2","containsFilter","t3","t4","textValue","inputValue","Autocomplete","_c","RACAutocomplete"],"sources":["../../../src/components/autocomplete/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactNode } from 'react'\nimport type { AutocompleteProps as RACAutocompleteProps } from 'react-aria-components'\n\nimport {\n Autocomplete as RACAutocomplete,\n useFilter,\n} from 'react-aria-components'\n\nimport { CollectionStatus } from '../../collection'\n\n// The search page's search with suggestions, as the wrapper React Aria makes\n// it: a search input over a collection, where typing narrows what the\n// collection shows. It draws nothing of its own — the input is SearchField,\n// the collection is ListBox or Menu, and where the two sit is the page's\n// business, which is what lets the same wrapper be a searchable list, a\n// filtered menu and a command palette inside a Dialog.\n//\n// Every other component here is a shape; this one is a behaviour, so it\n// renders no box and takes no `className` or `style`. There is nothing for\n// them to land on, and a wrapper element added to give them somewhere would\n// be a layout decision this component has no business making — the three\n// shapes above want three different ones.\n//\n// Two things are added to React Aria's. **A search that empties the\n// collection is announced.** A ListBox or Menu left with nothing shows a\n// \"No results\" row, and the status rendered after the children says the\n// same to a screen reader — visually hidden and out of the flow, so it takes\n// no place in whatever the page lays the two out in. See `CollectionStatus`\n// in `src/collection`.\n//\n// **Filtering is on by default.** Their\n// wrapper filters nothing unless it is handed a predicate, on the grounds\n// that a collection fed from a server may already be filtered. A collection\n// written out in the page is the common case here, and a search box that\n// does not search is a puzzle rather than a default, so `filter` falls back\n// to the same locale-aware contains match ComboBox uses. A collection that\n// filters itself passes a predicate that always returns true.\n\n// React Aria's own filter signature. Taken from the prop rather than written\n// out, since its third parameter is a collection node whose type this package\n// does not depend on directly.\ntype AutocompleteFilter<T extends object = object> = NonNullable<\n RACAutocompleteProps<T>['filter']\n>\n\ntype AutocompleteProps<T extends object = object> = {\n /**\n * The search input and the collection it filters, in whatever the page\n * puts around them. React Aria needs both somewhere inside.\n */\n children?: ReactNode\n /**\n * Which options a search keeps. Defaults to a locale-aware contains match\n * on each option's text — React Aria's own default is to filter nothing,\n * which is right for a collection that arrives filtered and wrong for one\n * written out in the page.\n */\n filter?: AutocompleteFilter<T>\n} & Omit<RACAutocompleteProps<T>, 'children' | 'filter'>\n\n/**\n * A search input that filters the collection under it. Its value is React\n * Aria's: pass `inputValue` with `onInputChange` to control what has been\n * typed, or `defaultInputValue` to let it keep its own.\n *\n * ```tsx\n * <Autocomplete>\n * <SearchField label=\"Search\" placeholder=\"Search\" />\n * <ListBox aria-label=\"Results\">\n * <ListBox.Item id=\"first\">First item</ListBox.Item>\n * </ListBox>\n * </Autocomplete>\n * ```\n *\n * It renders no box of its own, so the input and the collection sit wherever\n * the page puts them — side by side in a panel, in a `Menu.Content`, or in a\n * `Dialog` as a command palette. That is also why it takes no `className` or\n * `style`: there is nothing for them to land on. What it does render is a\n * visually hidden status after its children, which tells a screen reader\n * when a search leaves the collection empty.\n *\n * Keyboard focus stays in the input while the arrow keys move through the\n * collection, which is React Aria's virtual focus. `disableVirtualFocus`\n * turns that off and makes the collection tabbable instead.\n */\nfunction Autocomplete<T extends object = object>({\n children,\n filter,\n ...props\n}: AutocompleteProps<T>) {\n const { contains } = useFilter({ sensitivity: 'base' })\n\n return (\n <RACAutocomplete<T> filter={filter ?? containsFilter(contains)} {...props}>\n <CollectionStatus>{children}</CollectionStatus>\n </RACAutocomplete>\n )\n}\n\n// React Aria's filter is handed the node as well as the two strings, which a\n// contains match has no use for. Built by a call rather than written inline\n// at the prop, which is what react-perf's no-new-function-as-prop is after;\n// the React Compiler memoises the result on its input.\nfunction containsFilter(\n contains: (textValue: string, inputValue: string) => boolean,\n) {\n return (textValue: string, inputValue: string) =>\n contains(textValue, inputValue)\n}\n\nexport type { AutocompleteFilter, AutocompleteProps }\n\nexport default Autocomplete\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFA,SAAAK,eAAAU,IAAA;CAAA,MAAAC,IAAAf,EAAA,EAAA;CAAA,IAAAW;CAAA,IAAAC;CAAA,IAAAI;CAAA,IAAAD,EAAA,OAAAD,IAAA;EAAiD,CAAA,CAAAH,UAAAC,QAAA,GAAAI,SAAAF;EAI1BC,EAAA,KAAAD;EAAAC,EAAA,KAAAJ;EAAAI,EAAA,KAAAH;EAAAG,EAAA,KAAAC;CAAA,OAAA;EAAAL,WAAAI,EAAA;EAAAH,SAAAG,EAAA;EAAAC,QAAAD,EAAA;CAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAG,OAAAC,IAAA,2BAAA,GAAA;EACUF,KAAA,EAAAG,aAAe,OAAO;EAACL,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAtD,MAAA,EAAAM,aAAqBf,UAAUW,EAAuB;CAAC,IAAAK;CAAA,IAAAP,EAAA,OAAAM,YAAAN,EAAA,OAAAH,QAAA;EAGzBU,KAAAV,UAAUW,eAAeF,QAAQ;EAACN,EAAA,KAAAM;EAAAN,EAAA,KAAAH;EAAAG,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAA,IAAAS;CAAA,IAAAT,EAAA,OAAAJ,UAAA;EAC5Da,KAAA,oBAAC,kBAAD,EAAmBb,SAAF,CAAA;EAA8BI,EAAA,KAAAJ;EAAAI,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAU;CAAA,IAAAV,EAAA,QAAAC,SAAAD,EAAA,QAAAO,MAAAP,EAAA,QAAAS,IAAA;EADjDC,KAAA,oBAACK,cAAD;GAA4B,QAAAR;GAAkC,GAAMN;GAClEQ,UAAAA;EADc,CAAA;EAEET,EAAA,MAAAC;EAAAD,EAAA,MAAAO;EAAAP,EAAA,MAAAS;EAAAT,EAAA,MAAAU;CAAA,OAAAA,KAAAV,EAAA;CAAA,OAFlBU;AAEkB;AAQtB,SAASF,eACPF,UACA;CACA,QAAQK,WAAmBC,eACzBN,SAASK,WAAWC,UAAU;AAClC"}
1
+ {"version":3,"file":"index.js","names":["c","_c","ReactNode","AutocompleteProps","RACAutocompleteProps","Autocomplete","RACAutocomplete","useFilter","CollectionStatus","AutocompleteFilter","NonNullable","T","children","filter","Omit","t0","$","props","t1","Symbol","for","sensitivity","contains","t2","containsFilter","t3","t4","textValue","inputValue","Autocomplete","_c","RACAutocomplete"],"sources":["../../../src/components/autocomplete/index.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactNode } from 'react'\nimport type { AutocompleteProps as RACAutocompleteProps } from 'react-aria-components'\n\nimport {\n Autocomplete as RACAutocomplete,\n useFilter,\n} from 'react-aria-components'\n\nimport { CollectionStatus } from '../../collection'\n\n// The search page's search with suggestions, as the wrapper React Aria makes\n// it: a search input over a collection, where typing narrows what the\n// collection shows. It draws nothing of its own — the input is SearchField,\n// the collection is ListBox or Menu, and where the two sit is the page's\n// business, which is what lets the same wrapper be a searchable list, a\n// filtered menu and a command palette inside a Dialog.\n//\n// Every other component here is a shape; this one is a behaviour, so it\n// renders no box and takes no `className` or `style`. There is nothing for\n// them to land on, and a wrapper element added to give them somewhere would\n// be a layout decision this component has no business making — the three\n// shapes above want three different ones.\n//\n// Two things are added to React Aria's. **A search that empties the\n// collection is announced.** A ListBox or Menu left with nothing shows a\n// \"No results\" row, and the status rendered after the children says the\n// same to a screen reader — visually hidden and out of the flow, so it takes\n// no place in whatever the page lays the two out in. See `CollectionStatus`\n// in `src/collection`.\n//\n// **Filtering is on by default.** Their\n// wrapper filters nothing unless it is handed a predicate, on the grounds\n// that a collection fed from a server may already be filtered. A collection\n// written out in the page is the common case here, and a search box that\n// does not search is a puzzle rather than a default, so `filter` falls back\n// to the same locale-aware contains match ComboBox uses. A collection that\n// filters itself passes a predicate that always returns true.\n\n// React Aria's own filter signature. Taken from the prop rather than written\n// out, since its third parameter is a collection node whose type this package\n// does not depend on directly.\ntype AutocompleteFilter<T extends object = object> = NonNullable<\n RACAutocompleteProps<T>['filter']\n>\n\ntype AutocompleteProps<T extends object = object> = {\n /**\n * The search input and the collection it filters, in whatever the page\n * puts around them. React Aria needs both somewhere inside.\n */\n children?: ReactNode\n /**\n * Which options a search keeps. Defaults to a locale-aware contains match\n * on each option's text — React Aria's own default is to filter nothing,\n * which is right for a collection that arrives filtered and wrong for one\n * written out in the page.\n */\n filter?: AutocompleteFilter<T>\n} & Omit<RACAutocompleteProps<T>, 'children' | 'filter'>\n\n/**\n * A search input that filters the collection under it. Its value is React\n * Aria's: pass `inputValue` with `onInputChange` to control what has been\n * typed, or `defaultInputValue` to let it keep its own.\n *\n * ```tsx\n * <Autocomplete>\n * <SearchField label=\"Search\" placeholder=\"Search\" />\n * <ListBox aria-label=\"Results\">\n * <ListBox.Item id=\"first\">First item</ListBox.Item>\n * </ListBox>\n * </Autocomplete>\n * ```\n *\n * It renders no box of its own, so the input and the collection sit wherever\n * the page puts them — side by side in a panel, in a `Menu.Content`, or in a\n * `Dialog` as a command palette. That is also why it takes no `className` or\n * `style`: there is nothing for them to land on. What it does render is a\n * visually hidden status after its children, which tells a screen reader\n * when a search leaves the collection empty.\n *\n * A command palette is the last of those, and three things make it one\n * rather than a list in a dialog. The input takes `autoFocus`, so the first\n * keystroke searches rather than landing on the dialog. The collection takes\n * `onAction` and no `selectionMode`, so Enter runs a command and closes the\n * palette rather than marking a row. And the dialog keeps a close button in\n * its header: below the medium breakpoint it fills the window, which leaves\n * no scrim to press, and a phone has no Escape key.\n *\n * ```tsx\n * <Dialog>\n * <Button>Commands</Button>\n * <Dialog.Content>\n * {({ close }) => (\n * <>\n * <Dialog.Header>\n * <Dialog.Title>Commands</Dialog.Title>\n * <IconButton aria-label=\"Close\" slot=\"close\">\n * <CloseIcon />\n * </IconButton>\n * </Dialog.Header>\n * <Dialog.Body>\n * <Autocomplete>\n * <SearchField\n * autoFocus\n * label=\"Search commands\"\n * placeholder=\"Search commands\"\n * />\n * <ListBox\n * aria-label=\"Commands\"\n * onAction={(key) => {\n * runCommand(key)\n * close()\n * }}\n * >\n * <ListBox.Item id=\"open\">Open file</ListBox.Item>\n * </ListBox>\n * </Autocomplete>\n * </Dialog.Body>\n * </>\n * )}\n * </Dialog.Content>\n * </Dialog>\n * ```\n *\n * Keyboard focus stays in the input while the arrow keys move through the\n * collection, which is React Aria's virtual focus. `disableVirtualFocus`\n * turns that off and makes the collection tabbable instead.\n */\nfunction Autocomplete<T extends object = object>({\n children,\n filter,\n ...props\n}: AutocompleteProps<T>) {\n const { contains } = useFilter({ sensitivity: 'base' })\n\n return (\n <RACAutocomplete<T> filter={filter ?? containsFilter(contains)} {...props}>\n <CollectionStatus>{children}</CollectionStatus>\n </RACAutocomplete>\n )\n}\n\n// React Aria's filter is handed the node as well as the two strings, which a\n// contains match has no use for. Built by a call rather than written inline\n// at the prop, which is what react-perf's no-new-function-as-prop is after;\n// the React Compiler memoises the result on its input.\nfunction containsFilter(\n contains: (textValue: string, inputValue: string) => boolean,\n) {\n return (textValue: string, inputValue: string) =>\n contains(textValue, inputValue)\n}\n\nexport type { AutocompleteFilter, AutocompleteProps }\n\nexport default Autocomplete\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmIA,SAAAK,eAAAU,IAAA;CAAA,MAAAC,IAAAf,EAAA,EAAA;CAAA,IAAAW;CAAA,IAAAC;CAAA,IAAAI;CAAA,IAAAD,EAAA,OAAAD,IAAA;EAAiD,CAAA,CAAAH,UAAAC,QAAA,GAAAI,SAAAF;EAI1BC,EAAA,KAAAD;EAAAC,EAAA,KAAAJ;EAAAI,EAAA,KAAAH;EAAAG,EAAA,KAAAC;CAAA,OAAA;EAAAL,WAAAI,EAAA;EAAAH,SAAAG,EAAA;EAAAC,QAAAD,EAAA;CAAA;CAAA,IAAAE;CAAA,IAAAF,EAAA,OAAAG,OAAAC,IAAA,2BAAA,GAAA;EACUF,KAAA,EAAAG,aAAe,OAAO;EAACL,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAtD,MAAA,EAAAM,aAAqBf,UAAUW,EAAuB;CAAC,IAAAK;CAAA,IAAAP,EAAA,OAAAM,YAAAN,EAAA,OAAAH,QAAA;EAGzBU,KAAAV,UAAUW,eAAeF,QAAQ;EAACN,EAAA,KAAAM;EAAAN,EAAA,KAAAH;EAAAG,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAA,IAAAS;CAAA,IAAAT,EAAA,OAAAJ,UAAA;EAC5Da,KAAA,oBAAC,kBAAD,EAAmBb,SAAF,CAAA;EAA8BI,EAAA,KAAAJ;EAAAI,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAU;CAAA,IAAAV,EAAA,QAAAC,SAAAD,EAAA,QAAAO,MAAAP,EAAA,QAAAS,IAAA;EADjDC,KAAA,oBAACK,cAAD;GAA4B,QAAAR;GAAkC,GAAMN;GAClEQ,UAAAA;EADc,CAAA;EAEET,EAAA,MAAAC;EAAAD,EAAA,MAAAO;EAAAP,EAAA,MAAAS;EAAAT,EAAA,MAAAU;CAAA,OAAAA,KAAAV,EAAA;CAAA,OAFlBU;AAEkB;AAQtB,SAASF,eACPF,UACA;CACA,QAAQK,WAAmBC,eACzBN,SAASK,WAAWC,UAAU;AAClC"}
@@ -13,8 +13,9 @@ type ButtonProps$1 = ButtonDOMProps & (ButtonLinkForm | ButtonPressForm | (Butto
13
13
  /** A function may compute the class from the button's render state. */
14
14
  className?: ClassNameOrFunction<ButtonState>;
15
15
  /**
16
- * Disables the press ripple. The hover/pressed background state layer is
17
- * unaffected.
16
+ * Disables the press ripple. A press then draws its layer as a background
17
+ * instead, at the same pressed opacity, so the button reads the same
18
+ * either way. The hover and focus layers are unaffected.
18
19
  * @default false
19
20
  */
20
21
  disableRipple?: boolean;
@@ -8,7 +8,7 @@ import { ButtonGroupItemContext } from "../../button/context.js";
8
8
  import { groupPressHandlers } from "../../button/group.js";
9
9
  import { pressThen } from "../../button/toggle.js";
10
10
  import { c } from "react/compiler-runtime";
11
- import { useContext } from "react";
11
+ import { useContext, useState } from "react";
12
12
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
13
  import { ToggleGroupStateContext } from "react-aria-components";
14
14
  //#region src/components/button/index.tsx
@@ -181,6 +181,7 @@ const styles = {
181
181
  kGOzcv: "xun2zgk",
182
182
  kpsdNU: "x1ecwmwu",
183
183
  kEoFBp: "x1hmns74",
184
+ kOIVth: "xzoy561",
184
185
  kAzted: "xlzjxrf",
185
186
  k8WAf4: "xmqoko8",
186
187
  kg3NbH: "x18fpw6u",
@@ -422,7 +423,6 @@ const focused = {
422
423
  const pressed = {
423
424
  elevated: {
424
425
  kWkggS: "x1d33wxb",
425
- kGVxlE: "x19efjv6",
426
426
  $$css: true
427
427
  },
428
428
  elevatedToggleSelected: {
@@ -431,7 +431,6 @@ const pressed = {
431
431
  },
432
432
  filled: {
433
433
  kWkggS: "x7b25lv",
434
- kGVxlE: "x1gnnqk1",
435
434
  $$css: true
436
435
  },
437
436
  filledToggle: {
@@ -456,7 +455,6 @@ const pressed = {
456
455
  },
457
456
  tonal: {
458
457
  kWkggS: "xzpauq9",
459
- kGVxlE: "x1gnnqk1",
460
458
  $$css: true
461
459
  },
462
460
  tonalToggleSelected: {
@@ -511,14 +509,16 @@ const toggleContainers = {
511
509
  * ```
512
510
  */
513
511
  function Button$1(t0) {
514
- const $ = c(32);
512
+ const $ = c(21);
515
513
  const { children, defaultSelected, href, icon, isPending, isSelected, onChange, pendingLabel, rel, shape: t1, size: ownSize, target, variant: t2, ...props$1 } = t0;
516
514
  const shape = t1 === void 0 ? "round" : t1;
517
515
  const variant = t2 === void 0 ? "filled" : t2;
518
516
  const group = useContext(ButtonGroupItemContext);
519
517
  const size = ownSize ?? group?.size ?? "md";
520
518
  const inSelectingGroup = useContext(ToggleGroupStateContext) !== null;
521
- const press = groupPressHandlers(group, props$1.onPressStart, props$1.onPressEnd);
519
+ const grouped = groupPressHandlers(group, props$1.onPressStart, props$1.onPressEnd);
520
+ const onPressEnd = grouped.onPressEnd ?? props$1.onPressEnd;
521
+ const onPressStart = grouped.onPressStart ?? props$1.onPressStart;
522
522
  let t3;
523
523
  if ($[0] !== defaultSelected || $[1] !== isSelected || $[2] !== onChange) {
524
524
  t3 = {
@@ -532,6 +532,18 @@ function Button$1(t0) {
532
532
  $[3] = t3;
533
533
  } else t3 = $[3];
534
534
  const selection = useSelection(t3);
535
+ const [keyHeld, setKeyHeld] = useState(false);
536
+ const press = {
537
+ onPressEnd: (event) => {
538
+ setKeyHeld(false);
539
+ onPressEnd?.(event);
540
+ },
541
+ onPressStart: (event_0) => {
542
+ setKeyHeld(event_0.pointerType === "keyboard");
543
+ onPressStart?.(event_0);
544
+ }
545
+ };
546
+ const ripples = props$1.disableRipple !== true && !keyHeld;
535
547
  let t4;
536
548
  if ($[4] !== children || $[5] !== icon || $[6] !== size) {
537
549
  t4 = icon === void 0 ? children : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
@@ -546,14 +558,15 @@ function Button$1(t0) {
546
558
  const content = t4;
547
559
  if (inSelectingGroup) {
548
560
  let t5;
549
- if ($[8] !== group || $[9] !== shape || $[10] !== size || $[11] !== variant) {
550
- t5 = variant === "text" ? buttonClasses(shape, size, variant, group) : toggleClasses(shape, size, variant, group);
561
+ if ($[8] !== group || $[9] !== ripples || $[10] !== shape || $[11] !== size || $[12] !== variant) {
562
+ t5 = variant === "text" ? buttonClasses(shape, size, variant, group, ripples) : toggleClasses(shape, size, variant, group, ripples);
551
563
  $[8] = group;
552
- $[9] = shape;
553
- $[10] = size;
554
- $[11] = variant;
555
- $[12] = t5;
556
- } else t5 = $[12];
564
+ $[9] = ripples;
565
+ $[10] = shape;
566
+ $[11] = size;
567
+ $[12] = variant;
568
+ $[13] = t5;
569
+ } else t5 = $[13];
557
570
  return /* @__PURE__ */ jsx(ToggleButtonBase, {
558
571
  ...props$1,
559
572
  ...press,
@@ -563,63 +576,44 @@ function Button$1(t0) {
563
576
  });
564
577
  }
565
578
  const isToggle = variant !== "text" && (defaultSelected !== void 0 || isSelected !== void 0 || onChange !== void 0);
566
- const T0 = ButtonBase;
567
579
  let t5;
568
- if ($[13] !== group || $[14] !== isToggle || $[15] !== shape || $[16] !== size || $[17] !== variant) {
569
- t5 = isToggle ? toggleClasses(shape, size, variant, group) : buttonClasses(shape, size, variant, group);
570
- $[13] = group;
571
- $[14] = isToggle;
572
- $[15] = shape;
573
- $[16] = size;
574
- $[17] = variant;
575
- $[18] = t5;
576
- } else t5 = $[18];
577
- const t6 = isToggle ? selection.selected : void 0;
578
- const t7 = isToggle ? pressThen(props$1.onPress, selection.toggle) : props$1.onPress;
579
- let t8;
580
- if ($[19] !== T0 || $[20] !== content || $[21] !== href || $[22] !== isPending || $[23] !== pendingLabel || $[24] !== press || $[25] !== props$1 || $[26] !== rel || $[27] !== t5 || $[28] !== t6 || $[29] !== t7 || $[30] !== target) {
581
- t8 = /* @__PURE__ */ jsx(T0, {
582
- ...props$1,
583
- ...press,
584
- classes: t5,
585
- href,
586
- isPending,
587
- isSelected: t6,
588
- onPress: t7,
589
- pendingLabel,
590
- rel,
591
- target,
592
- children: content
593
- });
594
- $[19] = T0;
595
- $[20] = content;
596
- $[21] = href;
597
- $[22] = isPending;
598
- $[23] = pendingLabel;
599
- $[24] = press;
600
- $[25] = props$1;
601
- $[26] = rel;
602
- $[27] = t5;
603
- $[28] = t6;
604
- $[29] = t7;
605
- $[30] = target;
606
- $[31] = t8;
607
- } else t8 = $[31];
608
- return t8;
580
+ if ($[14] !== group || $[15] !== isToggle || $[16] !== ripples || $[17] !== shape || $[18] !== size || $[19] !== variant) {
581
+ t5 = isToggle ? toggleClasses(shape, size, variant, group, ripples) : buttonClasses(shape, size, variant, group, ripples);
582
+ $[14] = group;
583
+ $[15] = isToggle;
584
+ $[16] = ripples;
585
+ $[17] = shape;
586
+ $[18] = size;
587
+ $[19] = variant;
588
+ $[20] = t5;
589
+ } else t5 = $[20];
590
+ return /* @__PURE__ */ jsx(ButtonBase, {
591
+ ...props$1,
592
+ ...press,
593
+ classes: t5,
594
+ href,
595
+ isPending,
596
+ isSelected: isToggle ? selection.selected : void 0,
597
+ onPress: isToggle ? pressThen(props$1.onPress, selection.toggle) : props$1.onPress,
598
+ pendingLabel,
599
+ rel,
600
+ target,
601
+ children: content
602
+ });
609
603
  }
610
- function buttonClasses(shape, size, variant, group) {
611
- return (state) => props(styles.base, focus.ring, styles[variant], styles[size], shape === "square" ? squareShapes[size] : roundShapes[size], variant === "outlined" && outlinedSizes[size], state.isHovered && hovered[variant], state.isFocusVisible && focused[variant], state.isPressed && pressed[variant], state.isPressed && pressedShapes[size], groupStyles(group, size, variant, state), state.isPending === true && styles.pending, state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant]);
604
+ function buttonClasses(shape, size, variant, group, ripples) {
605
+ return (state) => props(styles.base, focus.ring, styles[variant], styles[size], shape === "square" ? squareShapes[size] : roundShapes[size], variant === "outlined" && outlinedSizes[size], state.isHovered && !state.isPressed && hovered[variant], state.isFocusVisible && focused[variant], state.isPressed && !ripples && pressed[variant], state.isPressed && pressedShapes[size], groupStyles(group, size, variant, state), state.isPending === true && styles.pending, state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant]);
612
606
  }
613
607
  function groupStyles(group, size, variant, state) {
614
608
  if (group === null) return null;
615
609
  const border = variant === "outlined" ? OUTLINE_WIDTHS[size] : "0px";
616
610
  return [group.styles?.(state), group.shift !== 0 && shifted.padding(`calc(${PADDINGS[size]} - ${border} + ${group.shift / 2}px)`)];
617
611
  }
618
- function toggleClasses(shape, size, variant, group) {
612
+ function toggleClasses(shape, size, variant, group, ripples) {
619
613
  return (state) => {
620
614
  const isSelected = state.isSelected === true;
621
615
  const container = toggleContainers[variant][isSelected ? "selected" : "unselected"];
622
- return props(styles.base, focus.ring, styles[variant], styles[container], styles[size], shape === "square" ? squareShapes[size] : roundShapes[size], isSelected && (shape === "square" ? roundShapes[size] : squareShapes[size]), variant === "outlined" && outlinedSizes[size], state.isHovered && hovered[variant], state.isHovered && hovered[container], state.isFocusVisible && focused[variant], state.isFocusVisible && focused[container], state.isPressed && pressed[variant], state.isPressed && pressed[container], state.isPressed && pressedShapes[size], groupStyles(group, size, variant, state), state.isPending === true && styles.pending, state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant]);
616
+ return props(styles.base, focus.ring, styles[variant], styles[container], styles[size], shape === "square" ? squareShapes[size] : roundShapes[size], isSelected && (shape === "square" ? roundShapes[size] : squareShapes[size]), variant === "outlined" && outlinedSizes[size], state.isHovered && !state.isPressed && hovered[variant], state.isHovered && !state.isPressed && hovered[container], state.isFocusVisible && focused[variant], state.isFocusVisible && focused[container], state.isPressed && !ripples && pressed[variant], state.isPressed && !ripples && pressed[container], state.isPressed && pressedShapes[size], groupStyles(group, size, variant, state), state.isPending === true && styles.pending, state.isDisabled && styles.disabled, state.isDisabled && disabledStyles[variant]);
623
617
  };
624
618
  }
625
619
  //#endregion