neba 1.18.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/dist/a2ui/adapter-catalog.json +1 -1
  2. package/dist/a2ui/catalog.json +2 -2
  3. package/dist/components/accordion/Accordion.js +1 -1
  4. package/dist/components/agent-steps/AgentSteps.js +1 -1
  5. package/dist/components/alert/Alert.js +1 -1
  6. package/dist/components/anchor/Anchor.js +1 -1
  7. package/dist/components/animate-counter/AnimateCounter.js +1 -1
  8. package/dist/components/animate-headline/AnimateHeadline.js +1 -1
  9. package/dist/components/animate-lighting/AnimateLighting.js +1 -1
  10. package/dist/components/animate-marquee/AnimateMarquee.js +1 -1
  11. package/dist/components/animate-scramble/AnimateScramble.js +1 -1
  12. package/dist/components/animate-typing/AnimateTyping.js +1 -1
  13. package/dist/components/app-logo/AppLogo.js +1 -1
  14. package/dist/components/approval/Approval.js +1 -1
  15. package/dist/components/aspect-ratio/AspectRatio.js +1 -1
  16. package/dist/components/avatar/Avatar.js +1 -1
  17. package/dist/components/badge/Badge.js +1 -1
  18. package/dist/components/bar-chart/BarChart.js +1 -1
  19. package/dist/components/blockquote/Blockquote.js +1 -1
  20. package/dist/components/bottom-navigation/BottomNavigation.js +1 -1
  21. package/dist/components/breadcrumb/Breadcrumb.js +1 -1
  22. package/dist/components/button/Button.js +1 -1
  23. package/dist/components/button-group/ButtonGroup.js +1 -1
  24. package/dist/components/calendar/Calendar.js +1 -1
  25. package/dist/components/carousel/Carousel.js +1 -1
  26. package/dist/components/chat-bubble/ChatBubble.js +1 -1
  27. package/dist/components/checkbox/Checkbox.js +1 -1
  28. package/dist/components/checkbox/index.d.ts +1 -1
  29. package/dist/components/checkbox-group/CheckboxGroup.d.ts +84 -0
  30. package/dist/components/checkbox-group/CheckboxGroup.js +1 -0
  31. package/dist/components/checkbox-group/index.d.ts +2 -0
  32. package/dist/components/checkbox-group/index.js +1 -0
  33. package/dist/components/chip/Chip.d.ts +32 -3
  34. package/dist/components/chip/Chip.js +1 -1
  35. package/dist/components/code-block/CodeBlock.js +1 -1
  36. package/dist/components/collapsible/Collapsible.js +1 -1
  37. package/dist/components/color-picker/ColorPicker.js +1 -1
  38. package/dist/components/combobox/Combobox.d.ts +11 -0
  39. package/dist/components/combobox/Combobox.js +1 -1
  40. package/dist/components/combobox/index.d.ts +1 -1
  41. package/dist/components/command-palette/CommandPalette.d.ts +21 -5
  42. package/dist/components/command-palette/CommandPalette.js +1 -1
  43. package/dist/components/command-palette/CommandPaletteSheet.d.ts +27 -0
  44. package/dist/components/command-palette/CommandPaletteSheet.js +1 -0
  45. package/dist/components/command-palette/index.d.ts +1 -1
  46. package/dist/components/confirm/Confirm.d.ts +7 -5
  47. package/dist/components/confirm/Confirm.js +1 -1
  48. package/dist/components/data-list/DataList.js +1 -1
  49. package/dist/components/data-table/DataTable.js +1 -1
  50. package/dist/components/data-table/RowsPerPage.d.ts +43 -0
  51. package/dist/components/data-table/RowsPerPage.js +1 -0
  52. package/dist/components/date-picker/DatePicker.js +1 -1
  53. package/dist/components/date-range-picker/DateRangePicker.js +1 -1
  54. package/dist/components/date-time-picker/DateTimePicker.js +1 -1
  55. package/dist/components/dialog/Dialog.js +1 -1
  56. package/dist/components/dialog/index.d.ts +1 -1
  57. package/dist/components/drawer/Drawer.d.ts +1 -1
  58. package/dist/components/drawer/Drawer.js +1 -1
  59. package/dist/components/empty/Empty.js +1 -1
  60. package/dist/components/fieldset/Fieldset.d.ts +12 -1
  61. package/dist/components/fieldset/Fieldset.js +1 -1
  62. package/dist/components/file-picker/FilePicker.js +1 -1
  63. package/dist/components/floating-action-button/FloatingActionButton.js +1 -1
  64. package/dist/components/floating-action-button/index.d.ts +1 -0
  65. package/dist/components/floating-bottom-navigation/FloatingBottomNavigation.js +1 -1
  66. package/dist/components/footer/Footer.js +1 -1
  67. package/dist/components/form/Form.d.ts +8 -2
  68. package/dist/components/form/Form.js +1 -1
  69. package/dist/components/gallery/Gallery.js +1 -1
  70. package/dist/components/gauge-chart/GaugeChart.js +1 -1
  71. package/dist/components/header/Header.js +1 -1
  72. package/dist/components/heatmap-chart/HeatmapChart.js +1 -1
  73. package/dist/components/highlight/Highlight.js +1 -1
  74. package/dist/components/hover-card/HoverCard.js +1 -1
  75. package/dist/components/how-to-steps/HowToSteps.d.ts +3 -0
  76. package/dist/components/how-to-steps/HowToSteps.js +1 -1
  77. package/dist/components/image/Image.js +1 -1
  78. package/dist/components/inline-citation/InlineCitation.d.ts +24 -0
  79. package/dist/components/inline-citation/InlineCitation.js +1 -1
  80. package/dist/components/list/List.d.ts +9 -0
  81. package/dist/components/list/List.js +1 -1
  82. package/dist/components/menu/Menu.js +1 -1
  83. package/dist/components/menubar/Menubar.js +1 -1
  84. package/dist/components/meter/Meter.js +1 -1
  85. package/dist/components/mockup/Mockup.js +1 -1
  86. package/dist/components/navigation-menu/NavigationMenu.d.ts +2 -1
  87. package/dist/components/navigation-menu/NavigationMenu.js +1 -1
  88. package/dist/components/number-field/NumberField.js +1 -1
  89. package/dist/components/number-field/index.d.ts +1 -1
  90. package/dist/components/overlay/Overlay.js +1 -1
  91. package/dist/components/page-layout/PageLayout.js +1 -1
  92. package/dist/components/pagination/Pagination.js +1 -1
  93. package/dist/components/panes/Panes.js +1 -1
  94. package/dist/components/pie-chart/PieChart.js +1 -1
  95. package/dist/components/pill/Pill.js +1 -1
  96. package/dist/components/popover/Popover.js +1 -1
  97. package/dist/components/progress-box/ProgressBox.js +1 -1
  98. package/dist/components/progress-circular/ProgressCircular.js +1 -1
  99. package/dist/components/progress-linear/ProgressLinear.js +1 -1
  100. package/dist/components/prompt-input/PromptInput.js +1 -1
  101. package/dist/components/provider/NebaProvider.d.ts +3 -2
  102. package/dist/components/provider/NebaProvider.js +1 -1
  103. package/dist/components/radio-group/RadioGroup.d.ts +13 -0
  104. package/dist/components/radio-group/RadioGroup.js +1 -1
  105. package/dist/components/radio-group/index.d.ts +1 -1
  106. package/dist/components/rating/Rating.js +1 -1
  107. package/dist/components/reasoning/Reasoning.js +1 -1
  108. package/dist/components/scatter-chart/ScatterChart.js +1 -1
  109. package/dist/components/scroll-area/ScrollArea.js +1 -1
  110. package/dist/components/scroll-zone/ScrollZone.js +1 -1
  111. package/dist/components/segmented-button/SegmentedButton.js +1 -1
  112. package/dist/components/select/Select.d.ts +12 -0
  113. package/dist/components/select/Select.js +1 -1
  114. package/dist/components/select/index.d.ts +1 -1
  115. package/dist/components/shortcut/Shortcut.js +1 -1
  116. package/dist/components/sidebar/Sidebar.js +1 -1
  117. package/dist/components/sidebar/SidebarTrigger.js +1 -1
  118. package/dist/components/skeleton/Skeleton.js +1 -1
  119. package/dist/components/slider/Slider.js +1 -1
  120. package/dist/components/slider/index.d.ts +1 -1
  121. package/dist/components/sources/Sources.js +1 -1
  122. package/dist/components/sparkline/Sparkline.d.ts +7 -0
  123. package/dist/components/sparkline/Sparkline.js +1 -1
  124. package/dist/components/spoiler/Spoiler.js +1 -1
  125. package/dist/components/statistic/Statistic.js +1 -1
  126. package/dist/components/streaming-text/StreamingText.d.ts +10 -6
  127. package/dist/components/streaming-text/StreamingText.js +1 -1
  128. package/dist/components/switch/Switch.js +1 -1
  129. package/dist/components/switch/index.d.ts +1 -1
  130. package/dist/components/table/Table.js +1 -1
  131. package/dist/components/table/index.d.ts +1 -1
  132. package/dist/components/tabs/Tabs.js +1 -1
  133. package/dist/components/text-field/TextField.js +1 -1
  134. package/dist/components/text-field/index.d.ts +1 -1
  135. package/dist/components/text-link/TextLink.js +1 -1
  136. package/dist/components/time-picker/TimePicker.js +1 -1
  137. package/dist/components/timeline-chart/TimelineChart.js +1 -1
  138. package/dist/components/toast/Toast.d.ts +38 -5
  139. package/dist/components/toast/Toast.js +1 -1
  140. package/dist/components/toast/index.d.ts +2 -2
  141. package/dist/components/toast/index.js +1 -1
  142. package/dist/components/toggle/Toggle.js +1 -1
  143. package/dist/components/toggle-group/ToggleGroup.js +1 -1
  144. package/dist/components/tool-call/ToolCall.js +1 -1
  145. package/dist/components/toolbar/Toolbar.js +1 -1
  146. package/dist/components/tooltip/Tooltip.js +1 -1
  147. package/dist/components/tour/Tour.js +1 -1
  148. package/dist/components/tour/index.d.ts +1 -1
  149. package/dist/components/transfer/Transfer.d.ts +7 -0
  150. package/dist/components/transfer/Transfer.js +1 -1
  151. package/dist/components/tree-select/TreeSelect.js +1 -1
  152. package/dist/components/tree-view/TreeView.js +1 -1
  153. package/dist/components/window-pane/WindowPane.js +1 -1
  154. package/dist/index.d.ts +1 -0
  155. package/dist/index.js +1 -1
  156. package/dist/internal/animate.d.ts +34 -2
  157. package/dist/internal/animate.js +1 -1
  158. package/dist/internal/cache.d.ts +7 -1
  159. package/dist/internal/cache.js +1 -1
  160. package/dist/internal/calendar.d.ts +40 -1
  161. package/dist/internal/calendar.js +1 -1
  162. package/dist/internal/chart-frame.d.ts +86 -8
  163. package/dist/internal/chart-frame.js +1 -1
  164. package/dist/internal/chart-line.js +1 -1
  165. package/dist/internal/chart.d.ts +13 -0
  166. package/dist/internal/chart.js +1 -1
  167. package/dist/internal/checkbox-group.d.ts +29 -0
  168. package/dist/internal/checkbox-group.js +1 -0
  169. package/dist/internal/data-table.d.ts +7 -1
  170. package/dist/internal/data-table.js +1 -1
  171. package/dist/internal/date.d.ts +10 -0
  172. package/dist/internal/date.js +1 -1
  173. package/dist/internal/defaults.d.ts +14 -2
  174. package/dist/internal/idle.d.ts +10 -0
  175. package/dist/internal/idle.js +1 -0
  176. package/dist/internal/link.d.ts +4 -3
  177. package/dist/internal/media.js +1 -1
  178. package/dist/internal/observe.d.ts +4 -0
  179. package/dist/internal/observe.js +1 -1
  180. package/dist/internal/page-layout.d.ts +30 -2
  181. package/dist/internal/page-layout.js +1 -1
  182. package/dist/internal/picker.js +1 -1
  183. package/dist/internal/progress.d.ts +17 -0
  184. package/dist/internal/progress.js +1 -1
  185. package/dist/internal/refs.d.ts +18 -0
  186. package/dist/internal/refs.js +1 -0
  187. package/dist/internal/run.d.ts +34 -19
  188. package/dist/internal/run.js +1 -1
  189. package/dist/internal/sizer.d.ts +9 -4
  190. package/dist/internal/sizer.js +1 -1
  191. package/dist/internal/styles.d.ts +27 -1
  192. package/dist/internal/styles.js +1 -1
  193. package/dist/internal/tile.d.ts +34 -0
  194. package/dist/internal/tile.js +1 -0
  195. package/dist/internal/wheel.d.ts +24 -1
  196. package/dist/internal/wheel.js +1 -1
  197. package/dist/styles.css +1 -1
  198. package/dist/tailwind.css +369 -62
  199. package/dist/types.d.ts +4 -2
  200. package/package.json +2 -2
@@ -1 +1 @@
1
- import{parseColor as t,readableInk as e}from"./color.js";import{dateFormatter as n,numberFormatter as r}from"./format.js";export const plotHeights={xs:120,sm:160,md:220,lg:280,xl:360};export const sparklineHeights={xs:16,sm:20,md:28,lg:40,xl:56};export const lineWidths={xs:1.5,sm:1.75,md:2,lg:2.25,xl:2.5};export const markerRadii={xs:3,sm:3.5,md:4,lg:4.5,xl:5};export const chartFontSizes={xs:10,sm:11,md:12,lg:13,xl:14};export const barMaxThickness={xs:14,sm:18,md:24,lg:30,xl:36};export const barBandRatio={default:.62,compact:.82};export const markGap=2;export const barRadius=4;export const chartPalette=["var(--neba-chart-1)","var(--neba-chart-2)","var(--neba-chart-3)","var(--neba-chart-4)","var(--neba-chart-5)","var(--neba-chart-6)","var(--neba-chart-7)","var(--neba-chart-8)"];export function inkOn(n,r){if(!n)return`var(--neba-chart-on-${r%chartPalette.length+1})`;const a=o.has(n)?null:t(n);return a?e(a.hsv):"var(--neba-surface)"}export function labelInk(t){return`color-mix(in oklab, ${t} 85%, var(--neba-fg))`}const o=new Set(["primary","secondary","success","warning","danger","info"]);export function resolveColor(t){return o.has(t)?`var(--neba-${t}-accent)`:t}export function seriesColor(t,e,n=chartPalette){return resolveColor(t?.color?t.color:n[e%n.length]??chartPalette[0])}const a=new Set;export function warnPaletteOverflow(t){"production"===process.env.NODE_ENV||t<=chartPalette.length||a.has(t)||(a.add(t),console.warn(`Neba: a chart was given ${t} series and its palette has ${chartPalette.length} colours, so the colours repeat from the ninth series. Fold the smallest into an "Other" series, or draw a second chart.`))}export function toFullShares(t,e,n){const r=[];return t.forEach((t,n)=>{!1!==e[n]&&t.forEach((t,e)=>{r[e]=(r[e]??0)+Math.abs(t.value??0)})}),t.map(t=>t.map((t,e)=>{if(null===t.value)return t;const o=r[e]??0;return{...t,value:0===o?0:t.value/o*100,label:t.label??n(t.value)}}))}export function toValue(t){return null==t?{value:null}:"number"==typeof t?{value:Number.isFinite(t)?t:null}:(t=>"object"==typeof t&&null!==t)(t)?{value:null!==t.y&&Number.isFinite(t.y)?t.y:null,x:t.x,z:t.z,color:t.color?resolveColor(t.color):void 0,label:t.label}:{value:null}}export function toValues(t){return t.map(t=>t.data.map(toValue))}export function zeroGaps(t){return t.map(t=>({...t,data:t.data.map(t=>null==t?0:"number"==typeof t?Number.isFinite(t)?t:0:null!==t.y&&Number.isFinite(t.y)?t:{...t,y:0})}))}export function toNumber(t){return t instanceof Date?Number.isFinite(t.getTime())?t.getTime():null:"number"==typeof t&&Number.isFinite(t)?t:null}export function pointX(t,e,n){return toNumber(t.x??n?.[e]??e)}export function categoryExtent(t,e){let n=1/0,r=-1/0,o=!1;return t.forEach(t=>{t.forEach((t,a)=>{if(null===t.value)return;const i=pointX(t,a,e);null!==i&&(o=!0,n=Math.min(n,i),r=Math.max(r,i))})}),o?{min:n,max:r}:null}export function bubbleRadius(t,e,n,r){return e>0&&Number.isFinite(t)&&!(t<=0)?Math.max(r,Math.sqrt(Math.min(t,e)/e)*n):0===t?0:r}export function categoryCount(t){return t.reduce((t,e)=>Math.max(t,e.data.length),0)}export function categoryAt(t,e,n){if(e&&t<e.length)return e[t];for(const e of n){const n=e[t]?.x;if(void 0!==n)return n}return t}export function extentOf(t,e){let n=1/0,r=-1/0,o=!1;if(e){const e=t.reduce((t,e)=>Math.max(t,e.length),0);for(let a=0;a<e;a++){let e=0,i=0;for(const n of t){const t=n[a]?.value;null!=t&&(o=!0,t>=0?e+=t:i+=t)}n=Math.min(n,i),r=Math.max(r,e)}}else for(const e of t)for(const{value:t}of e)null!==t&&(o=!0,n=Math.min(n,t),r=Math.max(r,t));return o?{min:n,max:r}:null}function i(t){const e=10**Math.floor(Math.log10(t)),n=t/e;return n<=1?e:n<=2?2*e:n<=5?5*e:10*e}export function valueScale(t,e={}){const{tickCount:n=5}=e,{low:r,high:o}=u(t,e),a=void 0!==e.min&&void 0!==e.max?function(t,e){const n=10**Math.floor(Math.log10(t/Math.max(1,e)));let r=i(t/Math.max(1,e)),o=1/0;for(const a of[.1,1,10])for(const i of[1,2,2.5,5]){const u=i*a*n,s=t/u,c=Math.round(s);if(c<1||Math.abs(s-c)>1e-9)continue;const l=Math.abs(c-e);l<o&&(o=l,r=u)}return r}(o-r,n):i((o-r)/Math.max(1,n)),s=void 0!==e.min?r:Number((Math.floor(r/a+1e-9)*a).toFixed(12)),c=void 0!==e.max?o:Number((Math.ceil(o/a-1e-9)*a).toFixed(12)),l=c-s||1,h=[];for(let t=s;t<=c+1e-9*a;t+=a)h.push(Number(t.toFixed(12)));return{min:s,max:c,ticks:h,fraction:t=>(t-s)/l}}export function alignedScale(t,e,n={}){const r=Math.max(1,Math.round(e)),{low:o,high:a}=u(t,n);let s,c=i((a-o)/r);if(void 0!==n.min&&void 0!==n.max)c=(a-o)/r,s=o;else if(void 0!==n.max)s=a-r*c;else if(void 0!==n.min)s=o;else for(s=Math.floor(o/c+1e-9)*c;s+r*c<a-1e-9*c;)c=i(1.000001*c),s=Math.floor(o/c+1e-9)*c;const l=Array.from({length:r+1},(t,e)=>Number((s+e*c).toFixed(12))),h=l[0],m=l[r]-h||1;return{min:h,max:l[r],ticks:l,fraction:t=>(t-h)/m}}function u(t,e){const{includeZero:n=!0}=e;let r=e.min??(t?t.min:0),o=e.max??(t?t.max:1);n&&void 0===e.min&&(r=Math.min(r,0)),n&&void 0===e.max&&(o=Math.max(o,0));const a=void 0!==e.min&&void 0===e.max,i=void 0!==e.max&&void 0===e.min;if(o<=r&&(a||i)){const t=a?r:o,e=Math.abs(t)>0?Math.abs(t):2;a?o=r+e:r=o-e}else if(o===r){const t=Math.abs(o)>0?.5*Math.abs(o):1;r-=t,o+=t}return{low:r,high:o}}const s=1e3,c=6e4,l=36e5,h=24*l,m=[{unit:"second",count:1,size:s},{unit:"second",count:5,size:5e3},{unit:"second",count:15,size:15e3},{unit:"second",count:30,size:3e4},{unit:"minute",count:1,size:c},{unit:"minute",count:5,size:3e5},{unit:"minute",count:15,size:9e5},{unit:"minute",count:30,size:18e5},{unit:"hour",count:1,size:l},{unit:"hour",count:3,size:3*l},{unit:"hour",count:6,size:6*l},{unit:"hour",count:12,size:12*l},{unit:"day",count:1,size:h},{unit:"day",count:2,size:2*h},{unit:"week",count:1,size:7*h},{unit:"week",count:2,size:14*h},{unit:"month",count:1,size:30*h},{unit:"quarter",count:1,size:91*h},{unit:"month",count:6,size:182*h},{unit:"year",count:1,size:365*h}];function f(t,e,n){const r=new Date(t);if("year"===e)r.setFullYear(r.getFullYear()+n);else if("quarter"===e)r.setMonth(r.getMonth()+3*n);else if("month"===e)r.setMonth(r.getMonth()+n);else if("week"===e)r.setDate(r.getDate()+7*n);else if("day"===e)r.setDate(r.getDate()+n);else{if("hour"!==e)return t+n*("minute"===e?c:s);r.setHours(r.getHours()+n)}return r.getTime()}const $={second:"minute",minute:"hour",hour:"day",day:"month",week:"week",month:"year",quarter:"year",year:"year"};function x(t,e,n){let r=function(t,e){const n=new Date(t);if("year"===e)return new Date(n.getFullYear(),0,1).getTime();if("quarter"===e)return new Date(n.getFullYear(),3*Math.floor(n.getMonth()/3),1).getTime();if("month"===e)return new Date(n.getFullYear(),n.getMonth(),1).getTime();if("week"===e){const t=new Date(n.getFullYear(),n.getMonth(),n.getDate());return t.setDate(t.getDate()-t.getDay()),t.getTime()}return"day"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime():"hour"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours()).getTime():"minute"===e?Math.floor(t/c)*c:Math.floor(t/s)*s}(t,$[e]);if("year"===e&&n>1){const t=new Date(r).getFullYear();r=new Date(t-(t%n+n)%n,0,1).getTime()}for(let o=0;o<500;o++){const o=f(r,e,n);if(o>t)return r;r=o}return r}export function timeScale(t,e={}){const{tickCount:n=6}=e;let r=e.min??t?.min??Date.parse("2000-01-01T00:00:00"),o=e.max??t?.max??r+h;o<=r&&(r-=h/2,o+=h/2);const a=o-r;let u=m[0],s=1/0;for(const t of m){const e=Math.abs(a/t.size-n);e<s&&(s=e,u=t)}const c=u.unit,l="year"===c?Math.max(1,Math.round(i(a/n/(365*h)))):u.count,$=e.min??x(r,c,l),M=[];let p=x(r,c,l);for(let t=0;t<500&&(M.push(p),!(p>o));t++)p=f(p,c,l);const d=e.max??M[M.length-1],g=d-$||1;return{min:$,max:d,ticks:M.filter(t=>t>=$&&t<=d),unit:c,step:l,fraction:t=>(t-$)/g}}function M(t,e){if("second"===t)return{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"};if("minute"===t||"hour"===t)return{hour:"2-digit",minute:"2-digit",hourCycle:"h23"};if("year"===t)return{year:"numeric"};const n="month"===t||"quarter"===t?{month:"short"}:{month:"short",day:"numeric"};return e?{...n,year:"numeric"}:n}export function formatTimeValue(t,e,r,o=!1){const a=M(e,!0);return n(r,o&&void 0===a.hour?{...a,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}:a).format(new Date(t))}export function formatTimeTicks(t,e,r){const o=new Set(t.map(t=>new Date(t).getFullYear())).size>1;return t.map((t,a)=>n(r,M(e,o||0===a)).format(new Date(t)))}export function tickStride(t,e,n){if(t<=1||e<=0)return 1;const r=Math.max(1,Math.floor(e/Math.max(1,n)));return Math.max(1,Math.ceil(t/r))}export function showsTick(t,e,n,r){return t%n===0||r&&t===e-1}export function fitsLast(t,e,n,r){const o=(t-1)%e;return o>0&&o*n>=r+8}export function textWidth(t,e){let n=0;for(const e of t)n+=/[ᄀ-ᇿ⺀-꓏가-퟿豈-﫿︰-﹏]/.test(e)?1:.6;return n*e}export function turnedAxis(t,e){const n=Math.max(-90,Math.min(90,t??0)),r=Math.abs(n)*(Math.PI/180),o=Math.sin(r),a=Math.cos(r);return 0===n?{angle:0,depth:()=>e,room:t=>Math.max(t,1)+12,cut:t=>t,offset:e+6,overhang:t=>t/2,anchor:"middle"}:{angle:n,depth:t=>t*o+e*a,room:()=>e/Math.max(.2,o)+4,cut:t=>Math.max(0,(t-e*a)/Math.max(.05,o)),offset:8+e/2*a,overhang:t=>t*a,anchor:n<0?"end":"start"}}export function truncate(t,e,n){if(e<=0||textWidth(t,n)<=e)return t;const r=e-textWidth("…",n);let o="",a=0;for(const e of t){const t=a+textWidth(e,n);if(t>r)break;a=t,o+=e}return o.length>0?`${o.trimEnd()}…`:"…"}export function bandScale(t,e,n){const r=t>0?e/t:e;return{step:r,band:r*n,centre:t=>r*(t+.5)}}export function linePath(t,e){const n=[];let r=[];const o=()=>{if(0!==r.length){if(1===r.length)n.push(`M${r[0].x} ${r[0].y}h0`);else if("step"===e){n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++){const e=(r[t-1].x+r[t].x)/2;n.push(`H${e}V${r[t].y}H${r[t].x}`)}}else if("smooth"===e)n.push(`M${r[0].x} ${r[0].y}`),n.push(function(t){const e=t.length,n=[];for(let r=0;r<e-1;r++){const e=t[r+1].x-t[r].x;n.push(0===e?0:(t[r+1].y-t[r].y)/e)}const r=[n[0]??0];for(let t=1;t<e-1;t++){const e=n[t-1],o=n[t];r.push(e*o<=0?0:2*e*o/(e+o))}r.push(n[e-2]??0);const o=[];for(let n=0;n<e-1;n++){const e=(t[n+1].x-t[n].x)/3;o.push(`C${t[n].x+e} ${t[n].y+r[n]*e} ${t[n+1].x-e} ${t[n+1].y-r[n+1]*e} ${t[n+1].x} ${t[n+1].y}`)}return o.join("")}(r));else{n.push(`M${r[0].x} ${r[0].y}`);for(let t=1;t<r.length;t++)n.push(`L${r[t].x} ${r[t].y}`)}r=[]}};for(const e of t)null===e?o():r.push(e);return o(),n.join("")}export function areaPath(t,e,n){const r=[];let o=0;const a=a=>{const i=t.slice(o,a).filter(Boolean);if(0===i.length)return;const u="number"==typeof e?i.map(t=>({x:t.x,y:e})).reverse():e.slice(o,a).filter(Boolean).reverse();if(0===u.length)return;const s=linePath(i,n),c=linePath(u,n).replace(/^M/,"L");r.push(`${s}${c}Z`)};for(let e=0;e<t.length;e++)null===t[e]&&(a(e),o=e+1);return a(t.length),r.join("")}export function barPath(t,e,n,r,o,a){const i=Math.max(0,Math.min(o,n/2,r/2));if(0===i||n<=0||r<=0)return`M${t} ${e}h${n}v${r}h${-n}Z`;const u=(t,e)=>`a${i} ${i} 0 0 1 ${t} ${e}`;return"up"===a?`M${t} ${e+r}V${e+i}${u(i,-i)}H${t+n-i}${u(i,i)}V${e+r}Z`:"down"===a?`M${t} ${e}H${t+n}V${e+r-i}${u(-i,i)}H${t+i}${u(-i,-i)}Z`:"right"===a?`M${t} ${e}H${t+n-i}${u(i,i)}V${e+r-i}${u(-i,i)}H${t}Z`:`M${t+n} ${e+r}H${t+i}${u(-i,-i)}V${e+i}${u(i,-i)}H${t+n}Z`}export const markShapes=["circle","square","triangle","diamond","cross"];const p={circle:1,square:.8862,triangle:1.5551,diamond:1.2533,cross:1.189};export function markPath(t,e,n,r){const o=Math.max(0,r)*p[t];if(0===o)return"";if("circle"===t)return`M${e-o} ${n}a${o} ${o} 0 1 0 ${2*o} 0a${o} ${o} 0 1 0 ${2*-o} 0Z`;if("square"===t)return`M${e-o} ${n-o}h${2*o}v${2*o}h${2*-o}Z`;if("diamond"===t)return`M${e} ${n-o}L${e+o} ${n}L${e} ${n+o}L${e-o} ${n}Z`;if("triangle"===t){return`M${[0,120,240].map(t=>{const r=(t-90)*Math.PI/180;return`${e+o*Math.cos(r)} ${n+o*Math.sin(r)}`}).join("L")}Z`}const a=o/3;return`M${e-a} ${n-o}h${2*a}v${o-a}h${o-a}v${2*a}h${-(o-a)}v${o-a}h${2*-a}v${-(o-a)}h${-(o-a)}v${2*-a}h${o-a}Z`}export function ringPath(t,e,n,r,o){const a=r=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(o-r)>=360){const t=r+180;return`M${a(r)}A${n} ${n} 0 1 1 ${a(t)}A${n} ${n} 0 1 1 ${a(r)}`}const i=Math.abs(o-r)>180?1:0;return`M${a(r)}A${n} ${n} 0 ${i} 1 ${a(o)}`}export function arcPath(t,e,n,r,o,a){const i=(n,r)=>{const o=(r-90)*Math.PI/180;return`${t+n*Math.cos(o)} ${e+n*Math.sin(o)}`};if(Math.abs(a-o)>=360){const t=o+180;return r>0?`M${i(n,o)}A${n} ${n} 0 1 1 ${i(n,t)}A${n} ${n} 0 1 1 ${i(n,o)}ZM${i(r,o)}A${r} ${r} 0 1 0 ${i(r,t)}A${r} ${r} 0 1 0 ${i(r,o)}Z`:`M${i(n,o)}A${n} ${n} 0 1 1 ${i(n,t)}A${n} ${n} 0 1 1 ${i(n,o)}Z`}const u=Math.abs(a-o)>180?1:0;return r<=0?`M${t} ${e}L${i(n,o)}A${n} ${n} 0 ${u} 1 ${i(n,a)}Z`:`M${i(n,o)}A${n} ${n} 0 ${u} 1 ${i(n,a)}L${i(r,a)}A${r} ${r} 0 ${u} 0 ${i(r,o)}Z`}export const rampSteps=5;export function rampStep(t,e,n,r,o=0){if("diverging"===r){const r=Math.max(Math.abs(n-o),Math.abs(o-e));if(!(r>0))return 2;const a=(t-o)/r;return Math.min(4,Math.max(0,2+Math.round(2*a)))}const a=n-e;return a>0?Math.min(4,Math.max(0,Math.floor((t-e)/a*5))):t>0?4:0}export function rampFill(t,e){return`var(--neba-chart-${"diverging"===e?"div":"seq"}-${t+1})`}export function rampInk(t,e){return`var(--neba-chart-${"diverging"===e?"div":"seq"}-on-${t+1})`}export function squarify(t,e,n){const r=t.reduce((t,e)=>t+Math.max(0,e),0);if(!(r>0)||e<=0||n<=0)return[];const o=e*n/r,a=t.map((t,e)=>({index:e,area:Math.max(0,t)*o})).filter(t=>t.area>0).sort((t,e)=>e.area-t.area),i=[];let u=0,s=0,c=e,l=n,h=[];const m=t=>{const e=Math.min(c,l),n=t.reduce((t,e)=>t+e.area,0);if(!(n>0&&e>0))return 1/0;const r=t[0].area,o=t[t.length-1].area;return Math.max(e*e*r/(n*n),n*n/(e*e*o))},f=()=>{const t=h.reduce((t,e)=>t+e.area,0),e=Math.min(c,l),n=e>0?t/e:0,r=c>=l;let o=0;for(const t of h){const e=n>0?t.area/n:0;i.push(r?{index:t.index,x:u,y:s+o,width:n,height:e}:{index:t.index,x:u+o,y:s,width:e,height:n}),o+=e}r?(u+=n,c-=n):(s+=n,l-=n),h=[]};for(const t of a)0===h.length||m([...h,t])<=m(h)||f(),h.push(t);return h.length>0&&f(),i}const d={month:"short",day:"numeric"},g={notation:"compact",maximumFractionDigits:1},v={maximumFractionDigits:2};export function labelledPoints(t,e){if("all"===e)return()=>!0;if("last"===e){let e=-1;for(let n=t.length-1;n>=0;n--)if(null!==t[n].value){e=n;break}return t=>t===e}let n=1/0,r=-1/0;for(const e of t)null!==e.value&&(n=Math.min(n,e.value),r=Math.max(r,e.value));return e=>{const o=t[e].value;return null!==o&&(o===n||o===r)}}export function formatCategory(t,e){return t instanceof Date?n(e,d).format(t):String(t)}export function compactNumber(t,e){return Math.abs(t)>=1e4?r(e,g).format(t):r(e,v).format(t)}
1
+ import{parseColor as t,readableInk as e}from"./color.js";import{dateFormatter as n,numberFormatter as r}from"./format.js";export const plotHeights={xs:120,sm:160,md:220,lg:280,xl:360};export const sparklineHeights={xs:16,sm:20,md:28,lg:40,xl:56};export const lineWidths={xs:1.5,sm:1.75,md:2,lg:2.25,xl:2.5};export const markerRadii={xs:3,sm:3.5,md:4,lg:4.5,xl:5};export const chartFontSizes={xs:10,sm:11,md:12,lg:13,xl:14};export const barMaxThickness={xs:14,sm:18,md:24,lg:30,xl:36};export const barBandRatio={default:.62,compact:.82};export const markGap=2;export const barRadius=4;export const chartPalette=["var(--neba-chart-1)","var(--neba-chart-2)","var(--neba-chart-3)","var(--neba-chart-4)","var(--neba-chart-5)","var(--neba-chart-6)","var(--neba-chart-7)","var(--neba-chart-8)"];export function inkOn(n,r){if(!n)return`var(--neba-chart-on-${r%chartPalette.length+1})`;const a=o.has(n)?null:t(n);return a?e(a.hsv):"var(--neba-surface)"}export function labelInk(t){return`color-mix(in oklab, ${t} 85%, var(--neba-fg))`}const o=new Set(["primary","secondary","success","warning","danger","info"]);export function resolveColor(t){return o.has(t)?`var(--neba-${t}-accent)`:t}export function seriesColor(t,e,n=chartPalette){return resolveColor(t?.color?t.color:n[e%n.length]??chartPalette[0])}const a=new Set;export function warnPaletteOverflow(t){"production"===process.env.NODE_ENV||t<=chartPalette.length||a.has(t)||(a.add(t),console.warn(`Neba: a chart was given ${t} series and its palette has ${chartPalette.length} colours, so the colours repeat from the ninth series. Fold the smallest into an "Other" series, or draw a second chart.`))}export function toFullShares(t,e,n){const r=[];return t.forEach((t,n)=>{!1!==e[n]&&t.forEach((t,e)=>{r[e]=(r[e]??0)+Math.abs(t.value??0)})}),t.map(t=>t.map((t,e)=>{if(null===t.value)return t;const o=r[e]??0;return{...t,value:0===o?0:t.value/o*100,label:t.label??n(t.value)}}))}export function toValue(t){return null==t?{value:null}:"number"==typeof t?{value:Number.isFinite(t)?t:null}:(t=>"object"==typeof t&&null!==t)(t)?{value:null!==t.y&&Number.isFinite(t.y)?t.y:null,x:t.x,z:t.z,color:t.color?resolveColor(t.color):void 0,label:t.label}:{value:null}}export function toValues(t){return t.map(t=>t.data.map(toValue))}export function zeroGaps(t){return t.map(t=>({...t,data:t.data.map(t=>null==t?0:"number"==typeof t?Number.isFinite(t)?t:0:null!==t.y&&Number.isFinite(t.y)?t:{...t,y:0})}))}export function toNumber(t){return t instanceof Date?Number.isFinite(t.getTime())?t.getTime():null:"number"==typeof t&&Number.isFinite(t)?t:null}export function pointX(t,e,n){return toNumber(t.x??n?.[e]??e)}export function categoryExtent(t,e){let n=1/0,r=-1/0,o=!1;return t.forEach(t=>{t.forEach((t,a)=>{if(null===t.value)return;const i=pointX(t,a,e);null!==i&&(o=!0,n=Math.min(n,i),r=Math.max(r,i))})}),o?{min:n,max:r}:null}export function bubbleRadius(t,e,n,r){return e>0&&Number.isFinite(t)&&!(t<=0)?Math.max(r,Math.sqrt(Math.min(t,e)/e)*n):0===t?0:r}export function categoryCount(t){return t.reduce((t,e)=>Math.max(t,e.data.length),0)}export function categoryAt(t,e,n){if(e&&t<e.length)return e[t];for(const e of n){const n=e[t]?.x;if(void 0!==n)return n}return t}export function extentOf(t,e){let n=1/0,r=-1/0,o=!1;if(e){const e=t.reduce((t,e)=>Math.max(t,e.length),0);for(let a=0;a<e;a++){let e=0,i=0;for(const n of t){const t=n[a]?.value;null!=t&&(o=!0,t>=0?e+=t:i+=t)}n=Math.min(n,i),r=Math.max(r,e)}}else for(const e of t)for(const{value:t}of e)null!==t&&(o=!0,n=Math.min(n,t),r=Math.max(r,t));return o?{min:n,max:r}:null}function i(t){const e=10**Math.floor(Math.log10(t)),n=t/e;return n<=1?e:n<=2?2*e:n<=5?5*e:10*e}export function valueScale(t,e={}){const{tickCount:n=5}=e,{low:r,high:o}=u(t,e),a=void 0!==e.min&&void 0!==e.max?function(t,e){const n=10**Math.floor(Math.log10(t/Math.max(1,e)));let r=i(t/Math.max(1,e)),o=1/0;for(const a of[.1,1,10])for(const i of[1,2,2.5,5]){const u=i*a*n,s=t/u,c=Math.round(s);if(c<1||Math.abs(s-c)>1e-9)continue;const l=Math.abs(c-e);l<o&&(o=l,r=u)}return r}(o-r,n):i((o-r)/Math.max(1,n)),s=void 0!==e.min?r:Number((Math.floor(r/a+1e-9)*a).toFixed(12)),c=void 0!==e.max?o:Number((Math.ceil(o/a-1e-9)*a).toFixed(12)),l=c-s||1,h=[];for(let t=s;t<=c+1e-9*a;t+=a)h.push(Number(t.toFixed(12)));return{min:s,max:c,ticks:h,fraction:t=>(t-s)/l}}export function alignedScale(t,e,n={}){const r=Math.max(1,Math.round(e)),{low:o,high:a}=u(t,n);let s,c=i((a-o)/r);if(void 0!==n.min&&void 0!==n.max)c=(a-o)/r,s=o;else if(void 0!==n.max)s=a-r*c;else if(void 0!==n.min)s=o;else for(s=Math.floor(o/c+1e-9)*c;s+r*c<a-1e-9*c;)c=i(1.000001*c),s=Math.floor(o/c+1e-9)*c;const l=Array.from({length:r+1},(t,e)=>Number((s+e*c).toFixed(12))),h=l[0],m=l[r]-h||1;return{min:h,max:l[r],ticks:l,fraction:t=>(t-h)/m}}function u(t,e){const{includeZero:n=!0}=e;let r=e.min??(t?t.min:0),o=e.max??(t?t.max:1);n&&void 0===e.min&&(r=Math.min(r,0)),n&&void 0===e.max&&(o=Math.max(o,0));const a=void 0!==e.min&&void 0===e.max,i=void 0!==e.max&&void 0===e.min;if(o<=r&&(a||i)){const t=a?r:o,e=Math.abs(t)>0?Math.abs(t):2;a?o=r+e:r=o-e}else if(o===r){const t=Math.abs(o)>0?.5*Math.abs(o):1;r-=t,o+=t}return{low:r,high:o}}const s=1e3,c=6e4,l=36e5,h=24*l,m=[{unit:"second",count:1,size:s},{unit:"second",count:5,size:5e3},{unit:"second",count:15,size:15e3},{unit:"second",count:30,size:3e4},{unit:"minute",count:1,size:c},{unit:"minute",count:5,size:3e5},{unit:"minute",count:15,size:9e5},{unit:"minute",count:30,size:18e5},{unit:"hour",count:1,size:l},{unit:"hour",count:3,size:3*l},{unit:"hour",count:6,size:6*l},{unit:"hour",count:12,size:12*l},{unit:"day",count:1,size:h},{unit:"day",count:2,size:2*h},{unit:"week",count:1,size:7*h},{unit:"week",count:2,size:14*h},{unit:"month",count:1,size:30*h},{unit:"quarter",count:1,size:91*h},{unit:"month",count:6,size:182*h},{unit:"year",count:1,size:365*h}];function f(t,e,n){const r=new Date(t);if("year"===e)r.setFullYear(r.getFullYear()+n);else if("quarter"===e)r.setMonth(r.getMonth()+3*n);else if("month"===e)r.setMonth(r.getMonth()+n);else if("week"===e)r.setDate(r.getDate()+7*n);else if("day"===e)r.setDate(r.getDate()+n);else{if("hour"!==e)return t+n*("minute"===e?c:s);r.setHours(r.getHours()+n)}return r.getTime()}const $={second:"minute",minute:"hour",hour:"day",day:"month",week:"week",month:"year",quarter:"year",year:"year"};function x(t,e,n){let r=function(t,e){const n=new Date(t);if("year"===e)return new Date(n.getFullYear(),0,1).getTime();if("quarter"===e)return new Date(n.getFullYear(),3*Math.floor(n.getMonth()/3),1).getTime();if("month"===e)return new Date(n.getFullYear(),n.getMonth(),1).getTime();if("week"===e){const t=new Date(n.getFullYear(),n.getMonth(),n.getDate());return t.setDate(t.getDate()-t.getDay()),t.getTime()}return"day"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate()).getTime():"hour"===e?new Date(n.getFullYear(),n.getMonth(),n.getDate(),n.getHours()).getTime():"minute"===e?Math.floor(t/c)*c:Math.floor(t/s)*s}(t,$[e]);if("year"===e&&n>1){const t=new Date(r).getFullYear();r=new Date(t-(t%n+n)%n,0,1).getTime()}for(let o=0;o<500;o++){const o=f(r,e,n);if(o>t)return r;r=o}return r}export function timeScale(t,e={}){const{tickCount:n=6}=e;let r=e.min??t?.min??Date.parse("2000-01-01T00:00:00"),o=e.max??t?.max??r+h;o<=r&&(r-=h/2,o+=h/2);const a=o-r;let u=m[0],s=1/0;for(const t of m){const e=Math.abs(a/t.size-n);e<s&&(s=e,u=t)}const c=u.unit,l="year"===c?Math.max(1,Math.round(i(a/n/(365*h)))):u.count,$=e.min??x(r,c,l),M=[];let p=x(r,c,l);for(let t=0;t<500&&(M.push(p),!(p>o));t++)p=f(p,c,l);const d=e.max??M[M.length-1],g=d-$||1;return{min:$,max:d,ticks:M.filter(t=>t>=$&&t<=d),unit:c,step:l,fraction:t=>(t-$)/g}}function M(t,e){if("second"===t)return{hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"};if("minute"===t||"hour"===t)return{hour:"2-digit",minute:"2-digit",hourCycle:"h23"};if("year"===t)return{year:"numeric"};const n="month"===t||"quarter"===t?{month:"short"}:{month:"short",day:"numeric"};return e?{...n,year:"numeric"}:n}export function formatTimeValue(t,e,r,o=!1){const a=M(e,!0);return n(r,o&&void 0===a.hour?{...a,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}:a).format(new Date(t))}export function formatTimeTicks(t,e,r){const o=new Set(t.map(t=>new Date(t).getFullYear())).size>1;return t.map((t,a)=>n(r,M(e,o||0===a)).format(new Date(t)))}export function tickStride(t,e,n){if(t<=1||e<=0)return 1;const r=Math.max(1,Math.floor(e/Math.max(1,n)));return Math.max(1,Math.ceil(t/r))}export function showsTick(t,e,n,r){return t%n===0||r&&t===e-1}export function fitsLast(t,e,n,r){const o=(t-1)%e;return o>0&&o*n>=r+8}export function textWidth(t,e){let n=0;for(const e of t)n+=/[ᄀ-ᇿ⺀-꓏가-퟿豈-﫿︰-﹏]/.test(e)?1:.6;return n*e}export function turnedAxis(t,e){const n=Math.max(-90,Math.min(90,t??0)),r=Math.abs(n)*(Math.PI/180),o=Math.sin(r),a=Math.cos(r);return 0===n?{angle:0,depth:()=>e,room:t=>Math.max(t,1)+12,cut:t=>t,offset:e+6,overhang:t=>t/2,anchor:"middle"}:{angle:n,depth:t=>t*o+e*a,room:()=>e/Math.max(.2,o)+4,cut:t=>Math.max(0,(t-e*a)/Math.max(.05,o)),offset:8+e/2*a,overhang:t=>t*a,anchor:n<0?"end":"start"}}export function truncate(t,e,n){if(e<=0||textWidth(t,n)<=e)return t;const r=e-textWidth("…",n);let o="",a=0;for(const e of t){const t=a+textWidth(e,n);if(t>r)break;a=t,o+=e}return o.length>0?`${o.trimEnd()}…`:"…"}export function bandScale(t,e,n){const r=t>0?e/t:e;return{step:r,band:r*n,centre:t=>r*(t+.5)}}function p(t){return Math.round(100*t)/100}export function linePath(t,e){const n=[];let r=[];const o=()=>{if(0!==r.length){if(1===r.length)n.push(`M${p(r[0].x)} ${p(r[0].y)}h0`);else if("step"===e){n.push(`M${p(r[0].x)} ${p(r[0].y)}`);for(let t=1;t<r.length;t++){const e=(r[t-1].x+r[t].x)/2;n.push(`H${p(e)}V${p(r[t].y)}H${p(r[t].x)}`)}}else if("smooth"===e)n.push(`M${p(r[0].x)} ${p(r[0].y)}`),n.push(function(t){const e=t.length,n=[];for(let r=0;r<e-1;r++){const e=t[r+1].x-t[r].x;n.push(0===e?0:(t[r+1].y-t[r].y)/e)}const r=[n[0]??0];for(let t=1;t<e-1;t++){const e=n[t-1],o=n[t];r.push(e*o<=0?0:2*e*o/(e+o))}r.push(n[e-2]??0);const o=[];for(let n=0;n<e-1;n++){const e=(t[n+1].x-t[n].x)/3;o.push(`C${p(t[n].x+e)} ${p(t[n].y+r[n]*e)} ${p(t[n+1].x-e)} ${p(t[n+1].y-r[n+1]*e)} ${p(t[n+1].x)} ${p(t[n+1].y)}`)}return o.join("")}(r));else{n.push(`M${p(r[0].x)} ${p(r[0].y)}`);for(let t=1;t<r.length;t++)n.push(`L${p(r[t].x)} ${p(r[t].y)}`)}r=[]}};for(const e of t)null===e?o():r.push(e);return o(),n.join("")}export function areaPath(t,e,n){const r=[];let o=0;const a=a=>{const i=t.slice(o,a).filter(Boolean);if(0===i.length)return;const u="number"==typeof e?i.map(t=>({x:t.x,y:e})).reverse():e.slice(o,a).filter(Boolean).reverse();if(0===u.length)return;const s=linePath(i,n),c=linePath(u,n).replace(/^M/,"L");r.push(`${s}${c}Z`)};for(let e=0;e<t.length;e++)null===t[e]&&(a(e),o=e+1);return a(t.length),r.join("")}export function barPath(t,e,n,r,o,a){const i=p(Math.max(0,Math.min(o,n/2,r/2)));if(0===i||n<=0||r<=0)return`M${p(t)} ${p(e)}h${p(n)}v${p(r)}h${p(-n)}Z`;const u=(t,e)=>`a${i} ${i} 0 0 1 ${t} ${e}`,s=p(t),c=p(e),l=p(t+n),h=p(e+r);return"up"===a?`M${s} ${h}V${p(e+i)}${u(i,-i)}H${p(t+n-i)}${u(i,i)}V${h}Z`:"down"===a?`M${s} ${c}H${l}V${p(e+r-i)}${u(-i,i)}H${p(t+i)}${u(-i,-i)}Z`:"right"===a?`M${s} ${c}H${p(t+n-i)}${u(i,i)}V${p(e+r-i)}${u(-i,i)}H${s}Z`:`M${l} ${h}H${p(t+i)}${u(-i,-i)}V${p(e+i)}${u(i,-i)}H${l}Z`}export const markShapes=["circle","square","triangle","diamond","cross"];const d={circle:1,square:.8862,triangle:1.5551,diamond:1.2533,cross:1.189};export function markPath(t,e,n,r){const o=p(Math.max(0,r)*d[t]);if(0===o)return"";const a=p(e),i=p(n);if("circle"===t)return`M${p(e-o)} ${i}a${o} ${o} 0 1 0 ${p(2*o)} 0a${o} ${o} 0 1 0 ${p(2*-o)} 0Z`;if("square"===t)return`M${p(e-o)} ${p(n-o)}h${p(2*o)}v${p(2*o)}h${p(2*-o)}Z`;if("diamond"===t)return`M${a} ${p(n-o)}L${p(e+o)} ${i}L${a} ${p(n+o)}L${p(e-o)} ${i}Z`;if("triangle"===t){return`M${[0,120,240].map(t=>{const r=(t-90)*Math.PI/180;return`${p(e+o*Math.cos(r))} ${p(n+o*Math.sin(r))}`}).join("L")}Z`}const u=p(o/3),s=p(o-u),c=p(2*u);return`M${p(e-u)} ${p(n-o)}h${c}v${s}h${s}v${c}h${-s}v${s}h${-c}v${-s}h${-s}v${-c}h${s}Z`}export function markOrigin(t){return"triangle"===t?"50% 66.6667%":void 0}export function ringPath(t,e,n,r,o){const a=r=>{const o=(r-90)*Math.PI/180;return`${p(t+n*Math.cos(o))} ${p(e+n*Math.sin(o))}`},i=p(n);if(Math.abs(o-r)>=360){const t=r+180;return`M${a(r)}A${i} ${i} 0 1 1 ${a(t)}A${i} ${i} 0 1 1 ${a(r)}`}const u=Math.abs(o-r)>180?1:0;return`M${a(r)}A${i} ${i} 0 ${u} 1 ${a(o)}`}export function arcPath(t,e,n,r,o,a){const i=(n,r)=>{const o=(r-90)*Math.PI/180;return`${p(t+n*Math.cos(o))} ${p(e+n*Math.sin(o))}`},u=p(n),s=p(r);if(Math.abs(a-o)>=360){const t=o+180;return r>0?`M${i(n,o)}A${u} ${u} 0 1 1 ${i(n,t)}A${u} ${u} 0 1 1 ${i(n,o)}ZM${i(r,o)}A${s} ${s} 0 1 0 ${i(r,t)}A${s} ${s} 0 1 0 ${i(r,o)}Z`:`M${i(n,o)}A${u} ${u} 0 1 1 ${i(n,t)}A${u} ${u} 0 1 1 ${i(n,o)}Z`}const c=Math.abs(a-o)>180?1:0;return r<=0?`M${p(t)} ${p(e)}L${i(n,o)}A${u} ${u} 0 ${c} 1 ${i(n,a)}Z`:`M${i(n,o)}A${u} ${u} 0 ${c} 1 ${i(n,a)}L${i(r,a)}A${s} ${s} 0 ${c} 0 ${i(r,o)}Z`}export const rampSteps=5;export function rampStep(t,e,n,r,o=0){if("diverging"===r){const r=Math.max(Math.abs(n-o),Math.abs(o-e));if(!(r>0))return 2;const a=(t-o)/r;return Math.min(4,Math.max(0,2+Math.round(2*a)))}const a=n-e;return a>0?Math.min(4,Math.max(0,Math.floor((t-e)/a*5))):t>0?4:0}export function rampFill(t,e){return`var(--neba-chart-${"diverging"===e?"div":"seq"}-${t+1})`}export function rampInk(t,e){return`var(--neba-chart-${"diverging"===e?"div":"seq"}-on-${t+1})`}export function squarify(t,e,n){const r=t.reduce((t,e)=>t+Math.max(0,e),0);if(!(r>0)||e<=0||n<=0)return[];const o=e*n/r,a=t.map((t,e)=>({index:e,area:Math.max(0,t)*o})).filter(t=>t.area>0).sort((t,e)=>e.area-t.area),i=[];let u=0,s=0,c=e,l=n,h=[];const m=t=>{const e=Math.min(c,l),n=t.reduce((t,e)=>t+e.area,0);if(!(n>0&&e>0))return 1/0;const r=t[0].area,o=t[t.length-1].area;return Math.max(e*e*r/(n*n),n*n/(e*e*o))},f=()=>{const t=h.reduce((t,e)=>t+e.area,0),e=Math.min(c,l),n=e>0?t/e:0,r=c>=l;let o=0;for(const t of h){const e=n>0?t.area/n:0;i.push(r?{index:t.index,x:u,y:s+o,width:n,height:e}:{index:t.index,x:u+o,y:s,width:e,height:n}),o+=e}r?(u+=n,c-=n):(s+=n,l-=n),h=[]};for(const t of a)0===h.length||m([...h,t])<=m(h)||f(),h.push(t);return h.length>0&&f(),i}const g={month:"short",day:"numeric"},v={notation:"compact",maximumFractionDigits:1},b={maximumFractionDigits:2};export function labelledPoints(t,e){if("all"===e)return()=>!0;if("last"===e){let e=-1;for(let n=t.length-1;n>=0;n--)if(null!==t[n].value){e=n;break}return t=>t===e}let n=1/0,r=-1/0;for(const e of t)null!==e.value&&(n=Math.min(n,e.value),r=Math.max(r,e.value));return e=>{const o=t[e].value;return null!==o&&(o===n||o===r)}}export function formatCategory(t,e){return t instanceof Date?n(e,g).format(t):String(t)}export function compactNumber(t,e){return Math.abs(t)>=1e4?r(e,v).format(t):r(e,b).format(t)}
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import type { NebaColor, NebaSize } from '../types.js';
3
+ /**
4
+ * What a Checkbox inherits from the CheckboxGroup around it.
5
+ *
6
+ * A Checkbox is a component in its own right and a group of them is a second
7
+ * one, so the context lives here rather than in either folder: Checkbox reads
8
+ * it without importing the group, which is the arrangement `button-group.ts`
9
+ * makes for a Button and the ButtonGroup around it.
10
+ *
11
+ * Unlike that context every field here is filled in, because the group has
12
+ * already settled each of them. A Checkbox's own prop still wins over `size`,
13
+ * `color`, `readOnly` and `name`. `invalid` and `disabled` win over the
14
+ * Checkbox instead: a question that was answered wrongly is wrong in every
15
+ * option, and a disabled group cannot hold an option that answers.
16
+ *
17
+ * `name` is the half Base UI does not carry. Its group takes the name from the
18
+ * Field around it, and each Neba Checkbox draws a Field of its own, so without
19
+ * this the inputs would reach a native submit with no name at all.
20
+ */
21
+ export interface CheckboxGroupContextValue {
22
+ size: NebaSize;
23
+ color: NebaColor;
24
+ invalid: boolean;
25
+ disabled: boolean;
26
+ readOnly: boolean;
27
+ name: string | undefined;
28
+ }
29
+ export declare const CheckboxGroupContext: React.Context<CheckboxGroupContextValue | null>;
@@ -0,0 +1 @@
1
+ "use client";import*as t from"react";export const CheckboxGroupContext=/*@__PURE__*/t.createContext(null);
@@ -170,5 +170,11 @@ export declare function virtualWindow(scrollTop: number, viewport: number, rowHe
170
170
  * A key that is no longer in the list (a row the current filter hides) yields
171
171
  * an empty range rather than a range from one end, which is what an index of
172
172
  * `-1` would silently produce.
173
+ *
174
+ * `positions` is where each key sits in `order`, for a caller that already
175
+ * holds it. A drag asks this once for every row it reaches, and finding the two
176
+ * ends by walking the list was two passes over every key in the table per row:
177
+ * on a hundred thousand rows, most of the frame went on finding where the run
178
+ * starts rather than on the run.
173
179
  */
174
- export declare function keysBetween(order: readonly string[], from: string, to: string): string[];
180
+ export declare function keysBetween(order: readonly string[], from: string, to: string, positions?: ReadonlyMap<string, number>): string[];
@@ -1 +1 @@
1
- export const dataRowHeights={default:{xs:24,sm:28,md:32,lg:38,xl:44},compact:{xs:20,sm:24,md:28,lg:32,xl:38}};export const dataHeaderHeights={default:{xs:28,sm:32,md:36,lg:42,xl:48},compact:{xs:24,sm:28,md:32,lg:36,xl:42}};export const dataTickWidths={xs:30,sm:34,md:38,lg:42,xl:50};export const defaultColumnWidth=160;export const minColumnWidth=48;export function compareValues(t,e,n){const o=isEmptyValue(t),r=isEmptyValue(e);return o||r?o&&r?0:o?1:-1:"number"==typeof t&&"number"==typeof e?t-e:"boolean"==typeof t&&"boolean"==typeof e?Number(t)-Number(e):t instanceof Date&&e instanceof Date?t.getTime()-e.getTime():n.compare(String(t),String(e))}export function isEmptyValue(t){return null==t||""===t||"number"==typeof t&&Number.isNaN(t)}export function sortRows(t,e,n){if(0===e.length)return t;const o=e.map(t=>{const e=n(t.key);if(!e)return null;const o="desc"===t.direction?-1:1;return"function"==typeof e?{compare:e,isEmpty:null,sign:o}:{compare:e.compare,isEmpty:e.isEmpty,sign:o}}).filter(t=>null!==t);return 0===o.length?t:[...t].sort((t,e)=>{for(const n of o){if(n.isEmpty){const o=n.isEmpty(t);if(o!==n.isEmpty(e))return o?1:-1;if(o)continue}const o=n.compare(t,e);if(0!==o)return o*n.sign}return 0})}export function nextSort(t,e,n){const o=t.find(t=>t.key===e),r=void 0===o?"asc":"asc"===o.direction?"desc":null;return n?null===r?t.filter(t=>t.key!==e):void 0===o?[...t,{key:e,direction:r}]:t.map(t=>t.key===e?{key:e,direction:r}:t):null===r?[]:[{key:e,direction:r}]}export function pageBounds(t,e,n){const o=Math.max(1,Math.floor(n)),r=Math.max(1,Math.ceil(t/o)),i=Math.min(Math.max(Math.floor(e),1),r),a=(i-1)*o;return{pages:r,page:i,start:a,end:Math.min(a+o,t)}}export function virtualWindow(t,e,n,o,r){const i=e>0?Math.ceil(e/n):3*r,a=Math.min(Math.floor(t/n),Math.max(0,o-i)),s=Math.max(0,a-r),m=Math.min(o,s+i+2*r);return{start:s,end:m,before:s*n,after:Math.max(0,(o-m)*n)}}export function keysBetween(t,e,n){const o=t.indexOf(e),r=t.indexOf(n);return-1===o||-1===r?[]:t.slice(Math.min(o,r),Math.max(o,r)+1)}
1
+ export const dataRowHeights={default:{xs:24,sm:28,md:32,lg:38,xl:44},compact:{xs:20,sm:24,md:28,lg:32,xl:38}};export const dataHeaderHeights={default:{xs:28,sm:32,md:36,lg:42,xl:48},compact:{xs:24,sm:28,md:32,lg:36,xl:42}};export const dataTickWidths={xs:30,sm:34,md:38,lg:42,xl:50};export const defaultColumnWidth=160;export const minColumnWidth=48;export function compareValues(t,e,n){const o=isEmptyValue(t),r=isEmptyValue(e);return o||r?o&&r?0:o?1:-1:"number"==typeof t&&"number"==typeof e?t-e:"boolean"==typeof t&&"boolean"==typeof e?Number(t)-Number(e):t instanceof Date&&e instanceof Date?t.getTime()-e.getTime():n.compare(String(t),String(e))}export function isEmptyValue(t){return null==t||""===t||"number"==typeof t&&Number.isNaN(t)}export function sortRows(t,e,n){if(0===e.length)return t;const o=e.map(t=>{const e=n(t.key);if(!e)return null;const o="desc"===t.direction?-1:1;return"function"==typeof e?{compare:e,isEmpty:null,sign:o}:{compare:e.compare,isEmpty:e.isEmpty,sign:o}}).filter(t=>null!==t);return 0===o.length?t:[...t].sort((t,e)=>{for(const n of o){if(n.isEmpty){const o=n.isEmpty(t);if(o!==n.isEmpty(e))return o?1:-1;if(o)continue}const o=n.compare(t,e);if(0!==o)return o*n.sign}return 0})}export function nextSort(t,e,n){const o=t.find(t=>t.key===e),r=void 0===o?"asc":"asc"===o.direction?"desc":null;return n?null===r?t.filter(t=>t.key!==e):void 0===o?[...t,{key:e,direction:r}]:t.map(t=>t.key===e?{key:e,direction:r}:t):null===r?[]:[{key:e,direction:r}]}export function pageBounds(t,e,n){const o=Math.max(1,Math.floor(n)),r=Math.max(1,Math.ceil(t/o)),i=Math.min(Math.max(Math.floor(e),1),r),a=(i-1)*o;return{pages:r,page:i,start:a,end:Math.min(a+o,t)}}export function virtualWindow(t,e,n,o,r){const i=e>0?Math.ceil(e/n):3*r,a=Math.min(Math.floor(t/n),Math.max(0,o-i)),s=Math.max(0,a-r),m=Math.min(o,s+i+2*r);return{start:s,end:m,before:s*n,after:Math.max(0,(o-m)*n)}}export function keysBetween(t,e,n,o){const r=o?o.get(e)??-1:t.indexOf(e),i=o?o.get(n)??-1:t.indexOf(n);return-1===r||-1===i?[]:t.slice(Math.min(r,i),Math.max(r,i)+1)}
@@ -72,6 +72,16 @@ export declare function addYears(date: Date, amount: number): Date;
72
72
  export declare function compareDay(a: Date, b: Date): number;
73
73
  export declare function isSameDay(a: Date | null | undefined, b: Date | null | undefined): boolean;
74
74
  export declare function isSameMonth(a: Date | null | undefined, b: Date | null | undefined): boolean;
75
+ /**
76
+ * A state updater that moves a held month to the one `date` is in, and keeps
77
+ * the object it already holds when that is the same month.
78
+ *
79
+ * Every picker puts its calendar back on the chosen month when the popup
80
+ * opens, from an effect on `open`. Handed a fresh `Date` there, React saw a
81
+ * new state on every open and drew the trigger, its sizer and the field
82
+ * around it a second time to arrive at the month it was already holding.
83
+ */
84
+ export declare function toMonthOf(date: Date): (current: Date) => Date;
75
85
  /** Holds a date inside `[min, max]`, at whatever precision the bounds carry. */
76
86
  export declare function clampDate(date: Date, min?: Date | null, max?: Date | null): Date;
77
87
  /**
@@ -1 +1 @@
1
- import{memoise as t}from"./cache.js";import{dateFormatter as e}from"./format.js";export const YEAR_PAGE_SIZE=12;export function makeDate(t,e,r){const n=new Date(0);return n.setFullYear(t,e,r),n.setHours(0,0,0,0),n}export function isValidDate(t){return t instanceof Date&&!Number.isNaN(t.getTime())}export function startOfDay(t){const e=new Date(t.getTime());return e.setHours(0,0,0,0),e}export function startOfMonth(t){return makeDate(t.getFullYear(),t.getMonth(),1)}export function startOfYear(t){return makeDate(t.getFullYear(),0,1)}export function startOfUnit(t,e){return"year"===e?startOfYear(t):"month"===e?startOfMonth(t):startOfDay(t)}export function endOfUnit(t,e){const r=t.getFullYear();return"year"===e?makeDate(r,11,31):"month"===e?makeDate(r,t.getMonth(),daysInMonth(r,t.getMonth())):startOfDay(t)}export function daysInMonth(t,e){return makeDate(t,e+1,0).getDate()}export function today(){return startOfDay(new Date)}export function addDays(t,e){const r=new Date(t.getTime());return r.setDate(r.getDate()+e),r}export function addMonths(t,e){const r=t.getFullYear(),n=t.getMonth()+e,o=new Date(t.getTime()),a=makeDate(r,n,1);return o.setFullYear(a.getFullYear(),a.getMonth(),Math.min(t.getDate(),daysInMonth(a.getFullYear(),a.getMonth()))),o}export function addYears(t,e){return addMonths(t,12*e)}export function compareDay(t,e){return startOfDay(t).getTime()-startOfDay(e).getTime()}export function isSameDay(t,e){return isValidDate(t)&&isValidDate(e)&&0===compareDay(t,e)}export function isSameMonth(t,e){return isValidDate(t)&&isValidDate(e)&&t.getFullYear()===e.getFullYear()&&t.getMonth()===e.getMonth()}export function clampDate(t,e,r){return isValidDate(e)&&t.getTime()<e.getTime()?new Date(e.getTime()):isValidDate(r)&&t.getTime()>r.getTime()?new Date(r.getTime()):t}export function isDayOutside(t,e,r){return!!(isValidDate(e)&&compareDay(t,e)<0)||isValidDate(r)&&compareDay(t,r)>0}export function isUnitOutside(t,e,r,n){return!!(isValidDate(r)&&compareDay(endOfUnit(t,e),r)<0)||isValidDate(n)&&compareDay(startOfUnit(t,e),n)>0}export function secondsOfDay(t){return 3600*t.getHours()+60*t.getMinutes()+t.getSeconds()}export function timeUnitSpan(t,e){const r=secondsOfDay(e);if("hour"===t){const t=3600*Math.floor(r/3600);return[t,t+3599]}if("minute"===t){const t=60*Math.floor(r/60);return[t,t+59]}if("second"===t)return[r,r];const n=e.getHours()<12?0:43200;return[n,n+43200-1]}export function timeUnitRange(t,e){const[r,n]=timeUnitSpan(t,e),o=t=>withTime(e,{hours:Math.floor(t/3600),minutes:Math.floor(t%3600/60),seconds:t%60});return[o(r),o(n)]}export function withTime(t,e){const r=new Date(t.getTime());return r.setHours(e.hours??r.getHours(),e.minutes??r.getMinutes(),e.seconds??r.getSeconds(),0),r}export function mergeDateAndTime(t,e){return withTime(startOfDay(t),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()})}export function calendarWeeks(t,e){const r=startOfMonth(t),n=(r.getDay()-e+7)%7,o=addDays(r,-n);return Array.from({length:6},(t,e)=>Array.from({length:7},(t,r)=>addDays(o,7*e+r)))}export function yearPageStart(t){return t-(t%12+12)%12}export function formatDate(t,r,n){return isValidDate(t)?e(r,n).format(t):""}const r=Array.from({length:24},(t,e)=>new Date(2027,e%12,21+e%7,e,58,58)),n=Array.from({length:84},(t,e)=>{const r=Math.floor(e/7),n=new Date(2027,r,21).getDay();return new Date(2027,r,21+(e-n+7)%7,e%24,58,58)}),o=new WeakMap;export function displaySamples(t,a){const i=e(t,a),u=o.get(i);if(u)return u;const s=i.formatToParts(r[0]).some(t=>"weekday"===t.type),c=[...new Set((s?n:r).map(t=>i.format(t)))];return o.set(i,c),c}export function withPlaceholder(t,e){return"string"==typeof e&&""!==e?[...t,e]:t}export function toISODate(t){const e=t=>String(t).padStart(2,"0");return`${String(t.getFullYear()).padStart(4,"0")}-${e(t.getMonth()+1)}-${e(t.getDate())}`}export function toISOMonth(t){return`${String(t.getFullYear()).padStart(4,"0")}-${String(t.getMonth()+1).padStart(2,"0")}`}export function toISOYear(t){return String(t.getFullYear()).padStart(4,"0")}export function toISOTime(t,e=!1){const r=t=>String(t).padStart(2,"0"),n=`${r(t.getHours())}:${r(t.getMinutes())}`;return e?`${n}:${r(t.getSeconds())}`:n}export function toISODateTime(t,e=!1){return`${toISODate(t)}T${toISOTime(t,e)}`}const a=makeDate(2021,7,1);export function weekdayLabels(t,r,n="short"){const o=e(t,{weekday:n});return Array.from({length:7},(t,e)=>o.format(addDays(a,(r+e)%7)))}export function monthLabels(t,r="short"){const n=e(t,{month:r});return Array.from({length:12},(t,e)=>n.format(makeDate(2021,e,1)))}export function isMonthBeforeYear(t){const r=e(t,{year:"numeric",month:"long"}).formatToParts(a);return r.findIndex(t=>"month"===t.type)<r.findIndex(t=>"year"===t.type)}export function isHour12(t){const r=e(t,{hour:"numeric"}).resolvedOptions();return r.hourCycle?"h11"===r.hourCycle||"h12"===r.hourCycle:!0===r.hour12}export function meridiemLabels(t){const r=e(t,{hour:"numeric",hour12:!0}),n=t=>{const e=r.formatToParts(withTime(a,{hours:t})).find(t=>"dayPeriod"===t.type);return e?.value??(t<12?"AM":"PM")};return[n(9),n(21)]}const i=new Map;export function localeWeekStart(e){return t(i,e??"",()=>function(t){try{const e=t??(new Intl.DateTimeFormat).resolvedOptions().locale,r=new Intl.Locale(e),n="function"==typeof r.getWeekInfo?r.getWeekInfo():r.weekInfo;if("number"==typeof n?.firstDay)return n.firstDay%7}catch{}return 0}(e))}
1
+ import{memoise as t}from"./cache.js";import{dateFormatter as e}from"./format.js";export const YEAR_PAGE_SIZE=12;export function makeDate(t,e,n){const r=new Date(0);return r.setFullYear(t,e,n),r.setHours(0,0,0,0),r}export function isValidDate(t){return t instanceof Date&&!Number.isNaN(t.getTime())}export function startOfDay(t){const e=new Date(t.getTime());return e.setHours(0,0,0,0),e}export function startOfMonth(t){return makeDate(t.getFullYear(),t.getMonth(),1)}export function startOfYear(t){return makeDate(t.getFullYear(),0,1)}export function startOfUnit(t,e){return"year"===e?startOfYear(t):"month"===e?startOfMonth(t):startOfDay(t)}export function endOfUnit(t,e){const n=t.getFullYear();return"year"===e?makeDate(n,11,31):"month"===e?makeDate(n,t.getMonth(),daysInMonth(n,t.getMonth())):startOfDay(t)}export function daysInMonth(t,e){return makeDate(t,e+1,0).getDate()}export function today(){return startOfDay(new Date)}export function addDays(t,e){const n=new Date(t.getTime());return n.setDate(n.getDate()+e),n}export function addMonths(t,e){const n=t.getFullYear(),r=t.getMonth()+e,o=new Date(t.getTime()),a=makeDate(n,r,1);return o.setFullYear(a.getFullYear(),a.getMonth(),Math.min(t.getDate(),daysInMonth(a.getFullYear(),a.getMonth()))),o}export function addYears(t,e){return addMonths(t,12*e)}export function compareDay(t,e){return startOfDay(t).getTime()-startOfDay(e).getTime()}export function isSameDay(t,e){return isValidDate(t)&&isValidDate(e)&&0===compareDay(t,e)}export function isSameMonth(t,e){return isValidDate(t)&&isValidDate(e)&&t.getFullYear()===e.getFullYear()&&t.getMonth()===e.getMonth()}export function toMonthOf(t){return e=>isSameMonth(e,t)?e:startOfMonth(t)}export function clampDate(t,e,n){return isValidDate(e)&&t.getTime()<e.getTime()?new Date(e.getTime()):isValidDate(n)&&t.getTime()>n.getTime()?new Date(n.getTime()):t}export function isDayOutside(t,e,n){return!!(isValidDate(e)&&compareDay(t,e)<0)||isValidDate(n)&&compareDay(t,n)>0}export function isUnitOutside(t,e,n,r){return!!(isValidDate(n)&&compareDay(endOfUnit(t,e),n)<0)||isValidDate(r)&&compareDay(startOfUnit(t,e),r)>0}export function secondsOfDay(t){return 3600*t.getHours()+60*t.getMinutes()+t.getSeconds()}export function timeUnitSpan(t,e){const n=secondsOfDay(e);if("hour"===t){const t=3600*Math.floor(n/3600);return[t,t+3599]}if("minute"===t){const t=60*Math.floor(n/60);return[t,t+59]}if("second"===t)return[n,n];const r=e.getHours()<12?0:43200;return[r,r+43200-1]}export function timeUnitRange(t,e){const[n,r]=timeUnitSpan(t,e),o=t=>withTime(e,{hours:Math.floor(t/3600),minutes:Math.floor(t%3600/60),seconds:t%60});return[o(n),o(r)]}export function withTime(t,e){const n=new Date(t.getTime());return n.setHours(e.hours??n.getHours(),e.minutes??n.getMinutes(),e.seconds??n.getSeconds(),0),n}export function mergeDateAndTime(t,e){return withTime(startOfDay(t),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()})}export function calendarWeeks(t,e){const n=startOfMonth(t),r=(n.getDay()-e+7)%7,o=addDays(n,-r);return Array.from({length:6},(t,e)=>Array.from({length:7},(t,n)=>addDays(o,7*e+n)))}export function yearPageStart(t){return t-(t%12+12)%12}export function formatDate(t,n,r){return isValidDate(t)?e(n,r).format(t):""}const n=Array.from({length:24},(t,e)=>new Date(2027,e%12,21+e%7,e,58,58)),r=Array.from({length:84},(t,e)=>{const n=Math.floor(e/7),r=new Date(2027,n,21).getDay();return new Date(2027,n,21+(e-r+7)%7,e%24,58,58)}),o=new WeakMap;export function displaySamples(t,a){const i=e(t,a),u=o.get(i);if(u)return u;const s=i.formatToParts(n[0]).some(t=>"weekday"===t.type),c=[...new Set((s?r:n).map(t=>i.format(t)))];return o.set(i,c),c}export function withPlaceholder(t,e){return"string"==typeof e&&""!==e?[...t,e]:t}export function toISODate(t){const e=t=>String(t).padStart(2,"0");return`${String(t.getFullYear()).padStart(4,"0")}-${e(t.getMonth()+1)}-${e(t.getDate())}`}export function toISOMonth(t){return`${String(t.getFullYear()).padStart(4,"0")}-${String(t.getMonth()+1).padStart(2,"0")}`}export function toISOYear(t){return String(t.getFullYear()).padStart(4,"0")}export function toISOTime(t,e=!1){const n=t=>String(t).padStart(2,"0"),r=`${n(t.getHours())}:${n(t.getMinutes())}`;return e?`${r}:${n(t.getSeconds())}`:r}export function toISODateTime(t,e=!1){return`${toISODate(t)}T${toISOTime(t,e)}`}const a=makeDate(2021,7,1);export function weekdayLabels(t,n,r="short"){const o=e(t,{weekday:r});return Array.from({length:7},(t,e)=>o.format(addDays(a,(n+e)%7)))}export function monthLabels(t,n="short"){const r=e(t,{month:n});return Array.from({length:12},(t,e)=>r.format(makeDate(2021,e,1)))}export function isMonthBeforeYear(t){const n=e(t,{year:"numeric",month:"long"}).formatToParts(a);return n.findIndex(t=>"month"===t.type)<n.findIndex(t=>"year"===t.type)}export function isHour12(t){const n=e(t,{hour:"numeric"}).resolvedOptions();return n.hourCycle?"h11"===n.hourCycle||"h12"===n.hourCycle:!0===n.hour12}export function meridiemLabels(t){const n=e(t,{hour:"numeric",hour12:!0}),r=t=>{const e=n.formatToParts(withTime(a,{hours:t})).find(t=>"dayPeriod"===t.type);return e?.value??(t<12?"AM":"PM")};return[r(9),r(21)]}const i=new Map;export function localeWeekStart(e){return t(i,e??"",()=>function(t){try{const e=t??(new Intl.DateTimeFormat).resolvedOptions().locale,n=new Intl.Locale(e),r="function"==typeof n.getWeekInfo?n.getWeekInfo():n.weekInfo;if("number"==typeof r?.firstDay)return r.firstDay%7}catch{}return 0}(e))}
@@ -3,7 +3,7 @@ import type { NebaDensity, NebaLabelPlacement, NebaSize, NebaVariant } from '../
3
3
  /**
4
4
  * The prop values an application can set once instead of at every call site.
5
5
  *
6
- * Five, and the list is closed on purpose. These are the axes whose right value
6
+ * Six, and the list is closed on purpose. These are the axes whose right value
7
7
  * is a property of the *product* rather than of the control — a dense
8
8
  * application is dense everywhere, a Korean one is Korean everywhere, and a
9
9
  * form whose fields put their labels in two different places looks assembled
@@ -24,8 +24,20 @@ export interface NebaDefaults {
24
24
  locale?: string;
25
25
  /** Where every field-shaped component draws its label. */
26
26
  labelPlacement?: NebaLabelPlacement;
27
+ /**
28
+ * The gap a Form and a Fieldset stand their fields at, on Tailwind's spacing
29
+ * scale: `4` is `1rem`.
30
+ *
31
+ * Only those two read it. The options of a RadioGroup or a CheckboxGroup and
32
+ * the rows of a List take a `spacing` of their own: they start on the same
33
+ * step at `md`, but a product that spreads its fields apart should not spread
34
+ * every set of options with them, until the options stop reading as a set.
35
+ * Flex and GridContainer are layout, and a page-wide gutter would move every
36
+ * layout in the product.
37
+ */
38
+ spacing?: number;
27
39
  }
28
- /** Which of the five a given component actually accepts. */
40
+ /** Which of the six a given component actually accepts. */
29
41
  export type DefaultableKey = keyof NebaDefaults;
30
42
  /**
31
43
  * `null` when there is no provider, which is the common case and the one worth
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Runs `task` when the browser next has nothing else to do, and returns what
3
+ * cancels it.
4
+ *
5
+ * `timeout` is how long a page that is never idle may hold the task back, and
6
+ * it is the caller's: a chart's hidden table wants its next slice within half a
7
+ * second, a palette fetching its sheet can wait two. Where there is no idle
8
+ * callback, which is Safari, a timer of `fallbackDelay` stands in.
9
+ */
10
+ export declare function whenIdle(task: (deadline?: IdleDeadline) => void, timeout: number, fallbackDelay?: number): () => void;
@@ -0,0 +1 @@
1
+ export function whenIdle(e,t,l=16){if("function"==typeof requestIdleCallback&&"function"==typeof cancelIdleCallback){const l=requestIdleCallback(e,{timeout:t});return()=>cancelIdleCallback(l)}const c=setTimeout(e,l);return()=>clearTimeout(c)}
@@ -32,9 +32,10 @@ export declare function opensElsewhere(target: string | undefined): boolean;
32
32
  * and neither is implied for a named target. So the two tokens are added
33
33
  * wherever a component lets a caller choose where a link opens — TextLink, a
34
34
  * Menu row, a NavigationMenu link, a ChatBubble's link, an AppLogo, a
35
- * BottomNavigation destination, a Breadcrumb item, a Sources row and an
36
- * InlineCitation — and they are added the same way in all of them, because a
37
- * library where only some are safe is a library whose users cannot tell which.
35
+ * BottomNavigation destination, a Breadcrumb item, a Sources row, an
36
+ * InlineCitation and a Chip — and they are added the same way in all of them,
37
+ * because a library where only some are safe is a library whose users cannot
38
+ * tell which.
38
39
  *
39
40
  * It is a *merge* and not an override, and that is the whole reason this is a
40
41
  * function rather than a string. The common reason to write a `rel` by hand is
@@ -1 +1 @@
1
- "use client";import*as e from"react";import{memoise as t}from"./cache.js";const r=new Map;function n(e){return t(r,e,()=>"undefined"!=typeof window&&window.matchMedia?window.matchMedia(e):null)}export function subscribeToQuery(e,t){const r=n(e);return r?(r.addEventListener("change",t),()=>r.removeEventListener("change",t)):()=>{}}export function queryMatches(e){return n(e)?.matches??!1}export function noMatchOnServer(){return!1}export const breakpointWidths={xs:"0rem",sm:"40rem",md:"48rem",lg:"64rem",xl:"80rem"};let o=null;function u(){if(o)return o;if("undefined"==typeof window||!window.getComputedStyle)return breakpointWidths;const e=getComputedStyle(document.documentElement),t={...breakpointWidths};for(const r of["sm","md","lg","xl"]){const n=e.getPropertyValue(`--neba-breakpoint-${r}`).trim();n&&(t[r]=n)}return o=t,t}export function widthBelow(e){return"xs"===e?null:`(width < ${u()[e]})`}export function widthAtLeast(e){return`(width >= ${u()[e]})`}export function useMediaQuery(t){const r=e.useCallback(e=>t?subscribeToQuery(t,e):()=>{},[t]),n=e.useCallback(()=>!!t&&queryMatches(t),[t]);return e.useSyncExternalStore(r,n,noMatchOnServer)}export const reducedMotionQuery="(prefers-reduced-motion: reduce)";const c=e=>subscribeToQuery(reducedMotionQuery,e),i=()=>queryMatches(reducedMotionQuery),s=()=>()=>{},d=()=>!0,a=()=>!1;export function useHydrated(){return e.useSyncExternalStore(s,d,a)}export const HYDRATION_LOCALE="en-US";export function useIntlLocale(e){const t=useHydrated();return e??(t?void 0:"en-US")}export function usePrefersReducedMotion(){return e.useSyncExternalStore(c,i,noMatchOnServer)}
1
+ "use client";import*as e from"react";import{memoise as t}from"./cache.js";const n=new Map;function r(e){return t(n,e,()=>"undefined"!=typeof window&&window.matchMedia?window.matchMedia(e):null)}export function subscribeToQuery(e,t){const n=r(e);return n?(n.addEventListener("change",t),()=>n.removeEventListener("change",t)):()=>{}}export function queryMatches(e){return r(e)?.matches??!1}export function noMatchOnServer(){return!1}export const breakpointWidths={xs:"0rem",sm:"40rem",md:"48rem",lg:"64rem",xl:"80rem"};let o=null;function u(){if(o)return o;if("undefined"==typeof window||!window.getComputedStyle)return breakpointWidths;const e=getComputedStyle(document.documentElement),t={...breakpointWidths};let n=!1;for(const r of["sm","md","lg","xl"]){const o=e.getPropertyValue(`--neba-breakpoint-${r}`).trim();o&&(t[r]=o,n=!0)}return n&&(o=t),t}export function widthBelow(e){return"xs"===e?null:`(width < ${u()[e]})`}export function widthAtLeast(e){return`(width >= ${u()[e]})`}export function useMediaQuery(t){const n=e.useCallback(e=>t?subscribeToQuery(t,e):()=>{},[t]),r=e.useCallback(()=>!!t&&queryMatches(t),[t]);return e.useSyncExternalStore(n,r,noMatchOnServer)}export const reducedMotionQuery="(prefers-reduced-motion: reduce)";const c=e=>subscribeToQuery(reducedMotionQuery,e),i=()=>queryMatches(reducedMotionQuery),s=()=>()=>{},d=()=>!0,a=()=>!1;export function useHydrated(){return e.useSyncExternalStore(s,d,a)}export const HYDRATION_LOCALE="en-US";export function useIntlLocale(t){const n=e.useSyncExternalStore(s,d,void 0===t?a:d);return t??(n?void 0:"en-US")}export function usePrefersReducedMotion(){return e.useSyncExternalStore(c,i,noMatchOnServer)}
@@ -32,6 +32,10 @@ type VisibilityCallback = (visible: boolean) => void;
32
32
  /**
33
33
  * Watches whether one element is on screen. Returns the function that stops.
34
34
  *
35
+ * On screen means at least `threshold` of it is showing; `0` is any of it. A
36
+ * watcher is told when that answer changes, and one that arrives after the
37
+ * element was first reported is told the answer as it stands.
38
+ *
35
39
  * `rootMargin` grows the screen it is measured against, for work that should
36
40
  * start before the element arrives rather than as it does.
37
41
  *
@@ -1 +1 @@
1
- const e=new Map;let t=null;export function observeResize(r,n){const s="undefined"==typeof ResizeObserver?null:(t??=new ResizeObserver(t=>{for(const r of t){const t=e.get(r.target);if(t)for(const e of[...t])e(r)}}),t);if(!s)return()=>{};let o=e.get(r);return o||(o=new Set,e.set(r,o),s.observe(r)),o.add(n),()=>{const t=e.get(r);t&&(t.delete(n),0===t.size&&(e.delete(r),s.unobserve(r)))}}const r=new Map;export function observeVisibility(e,t,n,s="0px"){const o=Number.isNaN(t)?0:Math.min(1,Math.max(0,t)),c=function(e,t){if("undefined"==typeof IntersectionObserver)return null;const n=`${e} ${t}`;let s=r.get(n);if(!s){const o=new Map;s={watchers:o,observer:new IntersectionObserver(e=>{for(const t of e){const e=o.get(t.target);if(e)for(const r of[...e])r(t.isIntersecting)}},{threshold:e,rootMargin:t})},r.set(n,s)}return s}(o,s);if(!c)return null;let i=c.watchers.get(e);return i||(i=new Set,c.watchers.set(e,i),c.observer.observe(e)),i.add(n),()=>{const t=c.watchers.get(e);t&&(t.delete(n),0===t.size&&(c.watchers.delete(e),c.observer.unobserve(e),0===c.watchers.size&&(c.observer.disconnect(),r.delete(`${o} ${s}`))))}}export function attachedRef(e){let t=null;return{get current(){return t},set current(r){t=r,e(r)}}}
1
+ const e=new Map;let t=null;export function observeResize(r,n){const s="undefined"==typeof ResizeObserver?null:(t??=new ResizeObserver(t=>{for(const r of t){const t=e.get(r.target);if(t)for(const e of[...t])e(r)}}),t);if(!s)return()=>{};let o=e.get(r);return o||(o=new Set,e.set(r,o),s.observe(r)),o.add(n),()=>{const t=e.get(r);t&&(t.delete(n),0===t.size&&(e.delete(r),s.unobserve(r)))}}const r=new Map;export function observeVisibility(e,t,n,s="0px"){const o=Number.isNaN(t)?0:Math.min(1,Math.max(0,t)),c=function(e,t){if("undefined"==typeof IntersectionObserver)return null;const n=`${e} ${t}`;let s=r.get(n);if(!s){const o=new Map,c=new Map;s={watchers:o,last:c,observer:new IntersectionObserver(e=>{for(const t of e){const e=o.get(t.target);if(e){c.set(t.target,t.isIntersecting);for(const r of[...e])r(t.isIntersecting)}}},{threshold:e,rootMargin:t})},r.set(n,s)}return s}(o,s);if(!c)return null;let i=c.watchers.get(e);return i?c.last.has(e)&&queueMicrotask(()=>{const t=c.last.get(e);void 0!==t&&c.watchers.get(e)?.has(n)&&n(t)}):(i=new Set,c.watchers.set(e,i),c.observer.observe(e)),i.add(n),()=>{const t=c.watchers.get(e);t&&(t.delete(n),0===t.size&&(c.watchers.delete(e),c.last.delete(e),c.observer.unobserve(e),0===c.watchers.size&&(c.observer.disconnect(),r.delete(`${o} ${s}`))))}}export function attachedRef(e){let t=null;return{get current(){return t},set current(r){t=r,e(r)}}}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type { NebaBreakpoint, NebaSide, NebaSize } from '../types.js';
2
+ import type { NebaBreakpoint, NebaPosition, NebaSide, NebaSize } from '../types.js';
3
3
  /**
4
4
  * The vocabulary a page's structure is written in, and the context the four
5
5
  * components that build one share.
@@ -105,6 +105,27 @@ export declare const PageLayoutSlotContext: React.Context<PageLayoutSlot | null>
105
105
  * "nobody said", which a standalone sidebar reads as `start`.
106
106
  */
107
107
  export declare const SidebarSideContext: React.Context<SidebarSide | null>;
108
+ /**
109
+ * The ref a Header or a Footer puts on its bar: it hands the bar to the layout
110
+ * when the bar fills that slot, and forwards it to the caller's own ref.
111
+ *
112
+ * Stable for as long as the slot and `position` are, which is the point of it.
113
+ * A callback ref that changes is detached and attached again on every commit,
114
+ * and each of those registered the bar anew — restarting both of the layout's
115
+ * `ResizeObserver`s and writing the bar's height as `0px` and back onto the
116
+ * layout's root, which invalidates the style of the whole page. A caller who
117
+ * writes `ref={(node) => …}` inline hands the bar a new ref on every render, so
118
+ * every render of a page with a Header in it did all of that. `position` is
119
+ * kept in the dependencies on purpose: a bar switched to `fixed` has the same
120
+ * height and fires no resize, and the room reserved for it is what changed.
121
+ *
122
+ * The caller's ref is therefore read from a ref of its own rather than closed
123
+ * over. When it changes, the old one lets go of the bar and the new one is
124
+ * handed it, which is what React does for a ref that changes, one phase later.
125
+ * Letting go is whatever `attachRef` returned when the bar was handed over: a
126
+ * React 19 ref's own cleanup, or a call with `null` for one that returned none.
127
+ */
128
+ export declare function useBarRef(slot: PageLayoutSlot, ref: React.ForwardedRef<HTMLElement>, position: NebaPosition): (node: HTMLElement | null) => void;
108
129
  /**
109
130
  * A Header's floor at each size, in steps of Tailwind's spacing scale.
110
131
  *
@@ -161,6 +182,11 @@ export declare const expandedOnlyClasses: Record<PageLayoutCollapse, string>;
161
182
  * keeps that column off a narrow screen until this hook can say otherwise.
162
183
  */
163
184
  export declare function useCollapsed(breakpoint: PageLayoutCollapse): boolean;
185
+ export declare const drawerChunk: {
186
+ load(): Promise<{
187
+ default: React.ForwardRefExoticComponent<import("../index.js").DrawerProps & React.RefAttributes<HTMLDivElement>>;
188
+ }>;
189
+ };
164
190
  /**
165
191
  * `start` and `end` as the two sides a Drawer speaks.
166
192
  *
@@ -174,6 +200,8 @@ export declare function useCollapsed(breakpoint: PageLayoutCollapse): boolean;
174
200
  * Read during render rather than in an effect, which is safe here for a
175
201
  * narrower reason than it looks: the only caller is a sidebar that has already
176
202
  * collapsed, and collapsing is a client-side answer. There is no server render
177
- * of this to disagree with.
203
+ * of this to disagree with. It is a style read, so the caller asks once per
204
+ * collapse and once each time the drawer opens or closes, rather than on every
205
+ * render.
178
206
  */
179
207
  export declare function drawerSide(side: SidebarSide): NebaSide;
@@ -1 +1 @@
1
- "use client";import*as e from"react";import{useMediaQuery as t,widthBelow as o}from"./media.js";import{hiddenBelowClasses as n,hiddenFromClasses as r}from"./responsive.js";export const PageLayoutContext=/*@__PURE__*/e.createContext({present:!1,register:()=>{},collapseBelow:"none",open:{start:!1,end:!1},setOpen:()=>{},scroll:"page"});export const PageLayoutSlotContext=/*@__PURE__*/e.createContext(null);export const SidebarSideContext=/*@__PURE__*/e.createContext(null);export const headerFloorSteps={xs:10,sm:12,md:14,lg:16,xl:20};export function headerFloor(t,o){if(!e.isValidElement(t)||"fixed"!==t.props.position)return;const n=headerFloorSteps[t.props.size??o??"md"]??headerFloorSteps.md;return!1===t.props.divider?`calc(var(--spacing) * ${n})`:`calc(var(--spacing) * ${n} + 1px)`}export const collapsedOnlyClasses={none:"hidden",...r};export const expandedOnlyClasses={none:"",...n};export function useCollapsed(e){return t("none"===e?null:o(e))}export function drawerSide(e){const t="undefined"!=typeof document&&"rtl"===getComputedStyle(document.documentElement).direction;return"start"===e?t?"right":"left":t?"left":"right"}
1
+ "use client";import*as e from"react";import{useLayoutEffectOnClient as t}from"./layout-effect.js";import{useMediaQuery as r,widthBelow as o}from"./media.js";import{attachRef as n}from"./refs.js";import{hiddenBelowClasses as s,hiddenFromClasses as l}from"./responsive.js";export const PageLayoutContext=/*@__PURE__*/e.createContext({present:!1,register:()=>{},collapseBelow:"none",open:{start:!1,end:!1},setOpen:()=>{},scroll:"page"});export const PageLayoutSlotContext=/*@__PURE__*/e.createContext(null);export const SidebarSideContext=/*@__PURE__*/e.createContext(null);export function useBarRef(r,o,s){const{register:l}=e.useContext(PageLayoutContext),a=e.useContext(PageLayoutSlotContext)===r,c=e.useRef(null),u=e.useRef(o),p=e.useRef(null);return t(()=>{u.current!==o&&(u.current=o,p.current?.(),p.current=c.current?n(o,c.current):null)},[o]),e.useCallback(e=>{c.current=e,a&&l(r,e),p.current?.(),p.current=e?n(u.current,e):null},[l,r,a,s])}export const headerFloorSteps={xs:10,sm:12,md:14,lg:16,xl:20};export function headerFloor(t,r){if(!e.isValidElement(t)||"fixed"!==t.props.position)return;const o=headerFloorSteps[t.props.size??r??"md"]??headerFloorSteps.md;return!1===t.props.divider?`calc(var(--spacing) * ${o})`:`calc(var(--spacing) * ${o} + 1px)`}export const collapsedOnlyClasses={none:"hidden",...l};export const expandedOnlyClasses={none:"",...s};export function useCollapsed(e){return r("none"===e?null:o(e))}let a;export const drawerChunk={load:()=>(a??=import("../components/drawer/Drawer.js").then(e=>({default:e.Drawer})).catch(e=>{throw a=void 0,e}),a)};export function drawerSide(e){const t="undefined"!=typeof document&&"rtl"===getComputedStyle(document.documentElement).direction;return"start"===e?t?"right":"left":t?"left":"right"}
@@ -1 +1 @@
1
- import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as l from"react";import{Field as n}from"@base-ui/react/field";import{Popover as t}from"@base-ui/react/popover";import{CloseIcon as i}from"./icons.js";import{WidthSizer as r}from"./sizer.js";import{chipRemoveClasses as o,controlTextLeadingClasses as s,cx as d,disabledClasses as c,fieldFocusTransitionClasses as p,fieldHeightClasses as u,fieldReadOnlyClasses as m,fieldRestClasses as f,fieldRingClasses as b,fieldSheetClasses as h,fieldSheetDisabledClasses as v,fieldSheetReadOnlyClasses as x,gapClasses as g,hasContent as y,iconClasses as N,metaTextClasses as $,paddingXClasses as P,popupFadeClasses as j,radiusClasses as w,readOnlyFilterClasses as C,stackGapClasses as k,surfaceClasses as z,surfaceSlots as O,transitionClasses as F}from"./styles.js";import{fieldSpotlightSlot as I,glowClasses as q,trackPointer as R}from"./glow.js";import{useFieldsetDisabled as S}from"./fieldset.js";import{FieldNotch as D,NotchFrame as E}from"./notch.js";export function popupSlots(e,a){return{...O(e,a),"--n-fill":`var(--neba-${e}-fill)`,"--n-fill-hover":`var(--neba-${e}-fill-hover)`,"--n-fill-active":`var(--neba-${e}-fill-active)`,"--n-on-solid":`var(--neba-${e}-on-solid)`}}const L=["group relative flex w-full items-center select-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",F,p,N].join(" ");export const pickerPopupClasses=[z,"border bg-(--n-panel-press)","[border-color:var(--n-line)]","[box-shadow:var(--neba-shadow-3),var(--neba-plate-glass)]","[outline:none]",j].join(" ");export const popupPaddingClasses={xs:"p-1.5",sm:"p-2",md:"p-2.5",lg:"p-3",xl:"p-3.5"};export function PickerShell({variant:p="outline",size:N="md",color:j="primary",density:z="default",elevation:F=0,label:B,labelPlacement:M="top",description:T,error:V,invalid:W,startIcon:A,fullWidth:G=!1,disabled:H,readOnly:J=!1,required:K=!1,id:Q,className:U,style:X,display:Y,samples:Z,empty:_,clearable:ee=!1,onClear:ae,open:le,onOpenChange:ne,clearLabel:te,hiddenValues:ie,repeats:re=!1,sideOffset:oe=6,popupClassName:se,initialFocus:de=!1,children:ce,triggerRef:pe,...ue}){const me=S(H),fe=l.useId(),be=Q??`${fe}-trigger`,he=`${fe}-label`,ve=`${fe}-description`,xe=`${fe}-error`,ge=null!=V&&!1!==V&&""!==V,ye=W??ge,Ne=ye?"danger":j,$e=me||J,Pe=d(T?ve:null,ge?xe:null)||void 0,[je,...we]=ie??[],Ce="top"!==M&&y(B),ke=Ce&&"float"===M&&!y(A),ze=a("span",{onPointerMove:R(void 0,!$e),className:d(L,u[N],s[N],w[N],g[N],P[z][N],Ce?"":b,me?(Ce?v:c)[p]:J?Ce?`${x[p]} ${C}`:m[p]:`${(Ce?h:f)[p]} ${q}`),children:[a(t.Trigger,{id:be,ref:pe,disabled:me,"aria-labelledby":B?`${he} ${be}`:void 0,"aria-describedby":Pe,"aria-required":K||void 0,"aria-invalid":ye||void 0,"data-placeholder":_||void 0,className:d("flex min-w-0 flex-1 items-center bg-transparent text-start [font:inherit] text-inherit",g[N],"[outline:none]",$e?"cursor-default":"cursor-pointer",ke?"neba-float-control":""),children:[A?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--neba-muted-fg) transition-[color] duration-(--neba-duration) group-focus-within:text-(--n-accent)",children:A}):null,a("span",{className:"flex min-w-0 flex-1 flex-col",children:[e("span",{"data-placeholder":_||void 0,className:d("w-full truncate",_?"text-(--neba-muted-fg)":"text-(--neba-fg)"),children:Y}),e(r,{samples:ke?[...Z??[],B]:Z??[]})]})]}),!ee||_||$e?null:e("button",{type:"button","aria-label":te,className:d(o,"text-(--neba-muted-fg)"),onClick:e=>{e.stopPropagation(),ae()},children:e(i,{})}),Ce?e(D,{label:B,variant:p,disabled:me,readOnly:J,rests:ke,labelId:he,htmlFor:be}):null]});return a(n.Root,{disabled:me,invalid:ye,className:d("relative flex-col align-top",k[N],G?"flex w-full":"inline-flex",U),style:{...O(Ne,F),...$e?void 0:I,...X},...ue,children:[B&&!Ce?e(n.Label,{id:he,htmlFor:be,className:d($[N],"font-medium",me?"text-(--neba-disabled-fg)":"text-(--neba-fg)"),children:B}):null,a(t.Root,{open:le,onOpenChange:e=>ne(e),children:[Ce?e(E,{label:B,size:N,density:z,variant:p,children:ze}):ze,e(t.Portal,{children:e(t.Positioner,{className:"neba-portal z-(--neba-z-portal) [outline:none]",sideOffset:oe,align:"start",children:e(t.Popup,{initialFocus:de,className:d(pickerPopupClasses,w[N],popupPaddingClasses[N],s[N],se),style:popupSlots(Ne,3),children:ce})})})]}),T?e(n.Description,{id:ve,className:d($[N],"text-(--neba-muted-fg)"),children:T}):null,e(n.Error,ge?{id:xe,match:!0,className:d($[N],"text-(--n-accent)"),children:V}:{className:d($[N],"text-(--n-accent)")}),je||K&&!$e?e(n.Control,{"aria-hidden":"true",tabIndex:-1,name:je?.name,value:je?je.value:_?"":"chosen",required:K&&!$e,readOnly:J,"data-neba-repeats":re&&je?"":void 0,onFocus:()=>document.getElementById(be)?.focus(),className:"pointer-events-none absolute start-0 bottom-0 size-px overflow-hidden opacity-0 [clip-path:inset(50%)]"}):null,we.map((a,l)=>e("input",{type:"hidden",name:a.name,value:a.value,disabled:me},l))]})}export function PickerFooter({size:a,children:l}){return e("div",{className:d("flex items-center justify-end border-t pt-1.5","[border-color:var(--n-line)]",g[a]),children:l})}export function PickerDivider(){return e("div",{"aria-hidden":"true",className:"w-px self-stretch bg-(--n-line)"})}
1
+ import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as l from"react";import{Field as t}from"@base-ui/react/field";import{Popover as n}from"@base-ui/react/popover";import{CloseIcon as r}from"./icons.js";import{WidthSizer as i}from"./sizer.js";import{chipRemoveClasses as o,controlTextLeadingClasses as s,cx as d,disabledClasses as c,fieldFocusTransitionClasses as p,fieldHeightClasses as u,fieldReadOnlyClasses as m,fieldRestClasses as f,fieldRingClasses as b,fieldSheetClasses as h,fieldSheetDisabledClasses as v,fieldSheetReadOnlyClasses as x,gapClasses as g,hasContent as y,iconClasses as N,metaTextClasses as $,paddingXClasses as P,popupFadeClasses as w,radiusClasses as j,readOnlyFilterClasses as C,stackGapClasses as k,surfaceClasses as z,surfaceSlots as O,transitionClasses as F}from"./styles.js";import{fieldSpotlightSlot as I,glowClasses as q,trackPointer as R}from"./glow.js";import{useFieldsetDisabled as S}from"./fieldset.js";import{FieldNotch as D,NotchFrame as E}from"./notch.js";export function popupSlots(e,a){return{...O(e,a),"--n-fill":`var(--neba-${e}-fill)`,"--n-fill-hover":`var(--neba-${e}-fill-hover)`,"--n-fill-active":`var(--neba-${e}-fill-active)`,"--n-on-solid":`var(--neba-${e}-on-solid)`}}const L=`group relative flex w-full items-center select-none [-webkit-tap-highlight-color:transparent] [touch-action:manipulation] ${F} ${p} ${N}`;export const pickerPopupClasses=`${z} border bg-(--n-panel-press) [border-color:var(--n-line)] [box-shadow:var(--neba-shadow-3),var(--neba-plate-glass)] [outline:none] `+w;export const popupPaddingClasses={xs:"p-1.5",sm:"p-2",md:"p-2.5",lg:"p-3",xl:"p-3.5"};export function PickerShell({variant:p="outline",size:N="md",color:w="primary",density:z="default",elevation:F=0,label:B,labelPlacement:M="top",description:T,error:V,invalid:W,startIcon:A,fullWidth:G=!1,disabled:H,readOnly:J=!1,required:K=!1,id:Q,className:U,style:X,display:Y,samples:Z,empty:_,clearable:ee=!1,onClear:ae,open:le,onOpenChange:te,clearLabel:ne,hiddenValues:re,repeats:ie=!1,sideOffset:oe=6,popupClassName:se,initialFocus:de=!1,children:ce,triggerRef:pe,...ue}){const me=S(H),fe=l.useId(),be=Q??`${fe}-trigger`,he=`${fe}-label`,ve=`${fe}-description`,xe=`${fe}-error`,ge=null!=V&&!1!==V&&""!==V,ye=W??ge,Ne=ye?"danger":w,$e=me||J,Pe=d(T?ve:null,ge?xe:null)||void 0,[we,...je]=re??[],Ce="top"!==M&&y(B),ke=Ce&&"float"===M&&!y(A),ze=a("span",{onPointerMove:R(void 0,!$e),className:d(L,u[N],s[N],j[N],g[N],P[z][N],Ce?"":b,me?(Ce?v:c)[p]:J?Ce?`${x[p]} ${C}`:m[p]:`${(Ce?h:f)[p]} ${q}`),children:[a(n.Trigger,{id:be,ref:pe,disabled:me,"aria-labelledby":B?`${he} ${be}`:void 0,"aria-describedby":Pe,"aria-required":K||void 0,"aria-invalid":ye||void 0,"data-placeholder":_||void 0,className:d("flex min-w-0 flex-1 items-center bg-transparent text-start [font:inherit] text-inherit",g[N],"[outline:none]",$e?"cursor-default":"cursor-pointer",ke?"neba-float-control":""),children:[A?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--neba-muted-fg) transition-[color] duration-(--neba-duration) group-focus-within:text-(--n-accent)",children:A}):null,a("span",{className:"flex min-w-0 flex-1 flex-col",children:[e("span",{"data-placeholder":_||void 0,className:d("w-full truncate",_?"text-(--neba-muted-fg)":"text-(--neba-fg)"),children:Y}),e(i,{samples:ke?[...Z??[],B]:Z??[]})]})]}),!ee||_||$e?null:e("button",{type:"button","aria-label":ne,className:d(o,"text-(--neba-muted-fg)"),onClick:e=>{e.stopPropagation(),ae()},children:e(r,{})}),Ce?e(D,{label:B,variant:p,disabled:me,readOnly:J,rests:ke,labelId:he,htmlFor:be}):null]});return a(t.Root,{disabled:me,invalid:ye,className:d("relative flex-col align-top",k[N],G?"flex w-full":"inline-flex",U),style:{...O(Ne,F),...$e?void 0:I,...X},...ue,children:[B&&!Ce?e(t.Label,{id:he,htmlFor:be,className:d($[N],"font-medium",me?"text-(--neba-disabled-fg)":"text-(--neba-fg)"),children:B}):null,a(n.Root,{open:le,onOpenChange:e=>te(e),children:[Ce?e(E,{label:B,size:N,density:z,variant:p,children:ze}):ze,e(n.Portal,{children:e(n.Positioner,{className:"neba-portal z-(--neba-z-portal) [outline:none]",sideOffset:oe,align:"start",children:e(n.Popup,{initialFocus:de,className:d(pickerPopupClasses,j[N],popupPaddingClasses[N],s[N],se),style:popupSlots(Ne,3),children:ce})})})]}),T?e(t.Description,{id:ve,className:d($[N],"text-(--neba-muted-fg)"),children:T}):null,e(t.Error,ge?{id:xe,match:!0,className:d($[N],"text-(--n-accent)"),children:V}:{className:d($[N],"text-(--n-accent)")}),we||K&&!$e?e(t.Control,{"aria-hidden":"true",tabIndex:-1,name:we?.name,value:we?we.value:_?"":"chosen",required:K&&!$e,readOnly:J,"data-neba-repeats":ie&&we?"":void 0,onFocus:()=>document.getElementById(be)?.focus(),className:"pointer-events-none absolute start-0 bottom-0 size-px overflow-hidden opacity-0 [clip-path:inset(50%)]"}):null,je.map((a,l)=>e("input",{type:"hidden",name:a.name,value:a.value,disabled:me},l))]})}export function PickerFooter({size:a,children:l}){return e("div",{className:d("flex items-center justify-end border-t pt-1.5","[border-color:var(--n-line)]",g[a]),children:l})}export function PickerDivider(){return e("div",{"aria-hidden":"true",className:"w-px self-stretch bg-(--n-line)"})}
@@ -134,6 +134,23 @@ export declare const plateGapClasses: Record<NebaSize, string>;
134
134
  * one request finished twice is a worse bug than a bar that sits full.
135
135
  */
136
136
  export declare function progressFraction(value: number | null | undefined, min: number, max: number): number | null;
137
+ /**
138
+ * The class a progress indicator's or a meter's label is drawn with.
139
+ *
140
+ * Each of the four draws its label itself rather than through Base UI's
141
+ * `Label` part. That part draws the same `<span role="presentation">`, and
142
+ * then tells the root its id from a layout effect, so the root only wrote
143
+ * `aria-labelledby` in a second commit after every mount and every hydration,
144
+ * and a server render named nothing. The id is known while rendering, from
145
+ * `useId`, so the component writes it on both elements in the first one.
146
+ */
147
+ export declare const progressLabelClasses = "min-w-0 truncate text-(--neba-fg)";
148
+ /**
149
+ * The status attribute Base UI's progress parts carry, for the label a
150
+ * progress indicator draws itself: `data-indeterminate` without a fraction,
151
+ * `data-complete` at the top of the range, and `data-progressing` below it.
152
+ */
153
+ export declare function progressStatusAttribute(fraction: number | null, value: number | null | undefined, max: number): Record<string, ''>;
137
154
  /**
138
155
  * What the value reads as, both on screen and to a screen reader.
139
156
  *
@@ -1 +1 @@
1
- export function thresholdColor(e,r,s){if(!s||0===s.length)return r;let n=r;for(const r of s)e>=r.from&&(n=r.color);return n}export function progressSlots(e){return{"--n-fill":`var(--neba-${e}-fill)`,"--n-accent":`var(--neba-${e}-accent)`,"--n-soft":`var(--neba-${e}-soft)`,"--n-soft-hover":`var(--neba-${e}-soft-hover)`,"--n-soft-press":`var(--neba-${e}-soft-press)`,"--n-line":`var(--neba-${e}-line)`}}export const barThicknessClasses={xs:"h-0.5",sm:"h-[3px]",md:"h-1",lg:"h-1.5",xl:"h-2"};export const ringDiameters={xs:14,sm:16,md:20,lg:26,xl:32};export const ringStrokes={xs:1.5,sm:1.75,md:2,lg:2.5,xl:3};export const plateSizeClasses={xs:"size-2",sm:"size-2.5",md:"size-3",lg:"size-4",xl:"size-5"};export const plateRadiusClasses={xs:"rounded-[0.1875rem]",sm:"rounded-[0.25rem]",md:"rounded-[0.28125rem]",lg:"rounded-[0.375rem]",xl:"rounded-[0.4375rem]"};export const plateGapClasses={xs:"gap-1",sm:"gap-1",md:"gap-1.5",lg:"gap-1.5",xl:"gap-2"};export function progressFraction(e,r,s){return null!=e&&Number.isFinite(e)?s<=r?null:Math.min(1,Math.max(0,(e-r)/(s-r))):null}export function progressText(e,r,s){return null===e?null:s?r:`${Math.round(100*e)}%`}export function progressAriaText(e,r){if(null!==e)return s=>progressText(e,s,r)??""}
1
+ export function thresholdColor(e,r,s){if(!s||0===s.length)return r;let t=r;for(const r of s)e>=r.from&&(t=r.color);return t}export function progressSlots(e){return{"--n-fill":`var(--neba-${e}-fill)`,"--n-accent":`var(--neba-${e}-accent)`,"--n-soft":`var(--neba-${e}-soft)`,"--n-soft-hover":`var(--neba-${e}-soft-hover)`,"--n-soft-press":`var(--neba-${e}-soft-press)`,"--n-line":`var(--neba-${e}-line)`}}export const barThicknessClasses={xs:"h-0.5",sm:"h-[3px]",md:"h-1",lg:"h-1.5",xl:"h-2"};export const ringDiameters={xs:14,sm:16,md:20,lg:26,xl:32};export const ringStrokes={xs:1.5,sm:1.75,md:2,lg:2.5,xl:3};export const plateSizeClasses={xs:"size-2",sm:"size-2.5",md:"size-3",lg:"size-4",xl:"size-5"};export const plateRadiusClasses={xs:"rounded-[0.1875rem]",sm:"rounded-[0.25rem]",md:"rounded-[0.28125rem]",lg:"rounded-[0.375rem]",xl:"rounded-[0.4375rem]"};export const plateGapClasses={xs:"gap-1",sm:"gap-1",md:"gap-1.5",lg:"gap-1.5",xl:"gap-2"};export function progressFraction(e,r,s){return null!=e&&Number.isFinite(e)?s<=r?null:Math.min(1,Math.max(0,(e-r)/(s-r))):null}export const progressLabelClasses="min-w-0 truncate text-(--neba-fg)";export function progressStatusAttribute(e,r,s){return null===e||null==r?{"data-indeterminate":""}:r>=s?{"data-complete":""}:{"data-progressing":""}}export function progressText(e,r,s){return null===e?null:s?r:`${Math.round(100*e)}%`}export function progressAriaText(e,r){if(null!==e)return s=>progressText(e,s,r)??""}
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * Hands `node` to a ref of either kind, and returns what takes it back.
4
+ *
5
+ * For a callback ref that is the cleanup it returned, or a call with `null`
6
+ * when it returned none. An object ref is cleared only while it still holds
7
+ * this node, so one that has since been handed another node keeps that one.
8
+ */
9
+ export declare function attachRef<T>(ref: React.Ref<T> | undefined, node: T): () => void;
10
+ /**
11
+ * The ref a component puts on its element when a caller may have forwarded one:
12
+ * `mergeRefs` over the component's own and the caller's.
13
+ *
14
+ * Its identity changes only when one of the two refs does, as a `useCallback`
15
+ * listing both would. An `own` written inline is a new ref on every render, and
16
+ * React then lets go of the node and takes it again each time.
17
+ */
18
+ export declare function useMergedRef<T>(own: React.Ref<T> | undefined, ref: React.Ref<T> | undefined): (node: T | null) => void;
@@ -0,0 +1 @@
1
+ import*as t from"react";const e=()=>{};export function attachRef(t,n){if("function"==typeof t){const e=t(n);return"function"==typeof e?e:()=>{t(null)}}return t?(t.current=n,()=>{t.current===n&&(t.current=null)}):e}export function useMergedRef(n,r){return t.useMemo(()=>function(t,n){let r=e,u=e;return c=>{r(),u(),r=e,u=e,null!==c&&(r=attachRef(t,c),u=attachRef(n,c))}}(n,r),[n,r])}
@@ -13,8 +13,9 @@
13
13
  * something runs re-renders on every tick, so how often it ticks is a decision
14
14
  * about a whole transcript rather than about one row: a page holding twenty
15
15
  * running tool calls at ten frames a second is two hundred renders a second for
16
- * a number nobody is reading that closely. It ticks once a second, and says
17
- * nothing at all until the first one has passed.
16
+ * a number nobody is reading that closely. It ticks once a second, on one timer
17
+ * for the whole page, says nothing at all until the first second has passed,
18
+ * and redraws only the number.
18
19
  */
19
20
  import * as React from 'react';
20
21
  import type { NebaColor, NebaRunStatus } from '../types.js';
@@ -54,25 +55,39 @@ export declare function runColor(status: NebaRunStatus, color: NebaColor): NebaC
54
55
  * browser can never disagree about it.
55
56
  */
56
57
  export declare function formatDuration(ms: number, locale?: string): string;
58
+ /** A run's clock, as the component around the run keeps it. */
59
+ export interface RunClock {
60
+ /** When the run that is going now started, by `Date.now()`, or `null`. */
61
+ since: number | null;
62
+ /** How long it took: a `duration` the caller knows, or the run measured as it ended. */
63
+ total: number | null;
64
+ }
57
65
  /**
58
- * How long a run has been going, in milliseconds, or `null`.
66
+ * When a run started and how long it took, without counting in between.
59
67
  *
60
- * A `duration` the caller knows wins outright; without one the clock counts,
61
- * and what it counts is *whole seconds*, because a component that re-renders
62
- * ten times a second is a decision about a whole transcript rather than about
63
- * one row.
68
+ * A `duration` the caller knows wins outright. Without one, the start is taken
69
+ * when the run starts and the run is **measured once more** when it ends,
70
+ * which is what turns a live count into a total: left at the last tick, a run
71
+ * of 4.9 seconds would say 4, and one under a second would say nothing at all,
72
+ * where a `duration` of the same length says "4.9s" or "900ms". It is cleared
73
+ * when a new run starts, so a retried call counts its own attempt rather than
74
+ * carrying the first one's number forward.
64
75
  *
65
- * `null` is "there is nothing to say", and the first second of every run
66
- * returns it: a counter that starts at "0s" claims a precision the tick rate
67
- * does not have, and a tool that answers in 300ms would have spent its whole
68
- * life saying zero.
76
+ * This hook does not tick, so the component that holds it renders when a run
77
+ * starts and when it ends and at no point in between. The count belongs to
78
+ * `RunTime`, a component of its own, so a second going by redraws a number
79
+ * rather than the row, the panel and everything in them; and a Reasoning, which
80
+ * says "Thinking" until it is done, has nothing to redraw at all.
81
+ */
82
+ export declare function useRunClock(running: boolean, duration: number | undefined): RunClock;
83
+ /**
84
+ * The time a run has taken, as text: the total once there is one, and the
85
+ * running count until then. Nothing at all while there is neither.
69
86
  *
70
- * Once the run ends the figure is **measured once more** and kept, which is
71
- * what turns a live count into a total. Measured rather than left at the last
72
- * tick: a run of 4.9 seconds would otherwise say 4, and one under a second
73
- * would say nothing at all, where a `duration` of the same length says "4.9s"
74
- * or "900ms".
75
- * It is cleared when a new run starts, so a retried call counts its own attempt
76
- * rather than carrying the first one's number forward.
87
+ * A component rather than a hook, so that the one thing that changes every
88
+ * second is the only thing that renders every second.
77
89
  */
78
- export declare function useElapsed(running: boolean, duration: number | undefined): number | null;
90
+ export declare function RunTime({ since, total, locale, className }: RunClock & {
91
+ locale?: string;
92
+ className?: string;
93
+ }): React.ReactElement | null;
@@ -1 +1 @@
1
- "use client";import{jsx as r}from"react/jsx-runtime";import*as t from"react";import{useLayoutEffectOnClient as e}from"./layout-effect.js";import{CircleIcon as n,DangerIcon as u,SpinnerIcon as o,SuccessIcon as s}from"./icons.js";import{numberFormatter as i}from"./format.js";export function runIcon(t){switch(t){case"running":return r(o,{});case"success":return r(s,{});case"error":return r(u,{});default:return r(n,{})}}export function runColor(r,t){switch(r){case"success":return"success";case"error":return"danger";case"pending":return"secondary";default:return t}}export function formatDuration(r,t){if(!Number.isFinite(r)||r<0)return"";const e=t??"en";if(r<1e3)return i(e,{style:"unit",unit:"millisecond",unitDisplay:"narrow",maximumFractionDigits:0}).format(Math.round(r));const n=r/1e3;return i(e,{style:"unit",unit:"second",unitDisplay:"narrow",maximumFractionDigits:n<10?1:0}).format(n)}export function useElapsed(r,n){const u=r&&void 0===n,[o,s]=t.useState(null),[i,c]=t.useState(u);i!==u&&(c(u),u&&s(null));const a=t.useRef(null);return e(()=>{if(!u)return;const r=Date.now(),t=setInterval(()=>s(Date.now()-r),1e3);return()=>{clearInterval(t),a.current=Date.now()-r}},[u]),e(()=>{u||null===a.current||(s(a.current),a.current=null)},[u]),n??o}
1
+ "use client";import{jsx as t}from"react/jsx-runtime";import*as n from"react";import{useLayoutEffectOnClient as e}from"./layout-effect.js";import{CircleIcon as r,DangerIcon as u,SpinnerIcon as o,SuccessIcon as s}from"./icons.js";import{numberFormatter as l}from"./format.js";export function runIcon(n){switch(n){case"running":return t(o,{});case"success":return t(s,{});case"error":return t(u,{});default:return t(r,{})}}export function runColor(t,n){switch(t){case"success":return"success";case"error":return"danger";case"pending":return"secondary";default:return n}}export function formatDuration(t,n){if(!Number.isFinite(t)||t<0)return"";const e=n??"en";if(t<1e3)return l(e,{style:"unit",unit:"millisecond",unitDisplay:"narrow",maximumFractionDigits:0}).format(Math.round(t));const r=t/1e3;return l(e,{style:"unit",unit:"second",unitDisplay:"narrow",maximumFractionDigits:r<10?1:0}).format(r)}const c=new Set;let a;export function useRunClock(t,r){const u=t&&void 0===r,[o,s]=n.useState(null),[l,c]=n.useState(null),[a,i]=n.useState(u);a!==u&&(i(u),u&&(s(null),c(null)));const f=n.useRef(null);return e(()=>{if(!u)return;const t=Date.now();return s(t),()=>{f.current=Date.now()-t}},[u]),e(()=>{u||null===f.current||(c(f.current),f.current=null)},[u]),{since:u?o:null,total:r??l}}function i(t){const[e,r]=n.useState(null),[u,o]=n.useState(t);return u!==t&&(o(t),r(null)),n.useEffect(()=>{var n;if(null!==t)return n=()=>{const n=Date.now()-t;n>=1e3&&r(1e3*Math.floor(n/1e3))},c.add(n),a??=setInterval(()=>{for(const t of[...c])t()},1e3),()=>{c.delete(n),0===c.size&&(clearInterval(a),a=void 0)}},[t]),null===t?null:e}export function RunTime({since:n,total:e,locale:r,className:u}){const o=i(null===e?n:null),s=e??o;return null===s?null:t("span",{className:u,children:formatDuration(s,r)})}
@@ -1,12 +1,17 @@
1
- import type * as React from 'react';
1
+ import * as React from 'react';
2
2
  /**
3
3
  * The samples a `WidthSizer` needs, out of all of them.
4
4
  *
5
5
  * Only the widest sample decides the width, so a Select with two hundred and
6
6
  * fifty countries was two hundred and fifty boxes laid out for the sake of one.
7
- * A string is kept when it is long enough to be the widest and dropped
8
- * otherwise. Anything that is not a string is kept whatever it is, since
9
- * nothing short of laying it out says how wide a node is.
7
+ * A sample is kept when the text it draws is long enough to be the widest and
8
+ * dropped otherwise, and that holds for a node as much as for a string: a
9
+ * country list whose labels each carry a flag `<img>` laid out, and fetched,
10
+ * every flag on the page before the list was ever opened.
11
+ *
12
+ * A node whose children hold no text at all is kept whatever its neighbours
13
+ * say. It may be a picture, or a component that draws words of its own, and
14
+ * nothing short of laying it out says how wide either is.
10
15
  */
11
16
  export declare function widestSamples(samples: readonly React.ReactNode[]): React.ReactNode[];
12
17
  /**
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";const t=/[\u1100-\u115f\u2e80-\ua4cf\uac00-\ud7a3\uf900-\ufaff\ufe30-\ufe4f\uff00-\uff60\uffe0-\uffe6]/g;function a(e){return e.length+(e.match(t)?.length??0)}export function widestSamples(e){let t=0;for(const n of e)"string"==typeof n&&(t=Math.max(t,a(n)));return e.filter(e=>"string"!=typeof e||a(e)>=.4*t)}export function WidthSizer({samples:t}){return 0===t.length?null:e("span",{"aria-hidden":"true",className:"invisible h-0 min-h-0 overflow-hidden",children:t.map((t,a)=>"string"==typeof t?e("span",{"data-sample":t,className:"block whitespace-nowrap before:content-[attr(data-sample)]"},`${a}:${t}`):e("span",{className:"block whitespace-nowrap",children:t},a))})}
1
+ import{jsx as e}from"react/jsx-runtime";import*as t from"react";const r=/[\u1100-\u115f\u2e80-\ua4cf\uac00-\ud7a3\uf900-\ufaff\ufe30-\ufe4f\uff00-\uff60\uffe0-\uffe6]/g;function n(e){if("string"==typeof e)return e;if("number"==typeof e||"bigint"==typeof e)return String(e);if(Array.isArray(e)){let t="";for(const r of e)t+=n(r);return t}return t.isValidElement(e)?n(e.props.children):""}export function widestSamples(e){const t=e.map(e=>{const t=n(e);return"string"!=typeof e&&""===t.trim()?-1:function(e){return e.length+(e.match(r)?.length??0)}(t)});let a=0;for(const e of t)a=Math.max(a,e);return e.filter((e,r)=>-1===t[r]||t[r]>=.4*a)}export function WidthSizer({samples:t}){return 0===t.length?null:e("span",{"aria-hidden":"true",className:"invisible h-0 min-h-0 overflow-hidden",children:t.map((t,r)=>"string"==typeof t?e("span",{"data-sample":t,className:"block whitespace-nowrap before:content-[attr(data-sample)]"},`${r}:${t}`):e("span",{className:"block whitespace-nowrap",children:t},r))})}