neba 1.18.1 → 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 (185) 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/index.d.ts +1 -1
  30. package/dist/components/chip/Chip.d.ts +32 -3
  31. package/dist/components/chip/Chip.js +1 -1
  32. package/dist/components/code-block/CodeBlock.js +1 -1
  33. package/dist/components/collapsible/Collapsible.js +1 -1
  34. package/dist/components/color-picker/ColorPicker.js +1 -1
  35. package/dist/components/combobox/Combobox.d.ts +11 -0
  36. package/dist/components/combobox/Combobox.js +1 -1
  37. package/dist/components/combobox/index.d.ts +1 -1
  38. package/dist/components/command-palette/CommandPalette.d.ts +21 -5
  39. package/dist/components/command-palette/CommandPalette.js +1 -1
  40. package/dist/components/command-palette/CommandPaletteSheet.d.ts +27 -0
  41. package/dist/components/command-palette/CommandPaletteSheet.js +1 -0
  42. package/dist/components/command-palette/index.d.ts +1 -1
  43. package/dist/components/confirm/Confirm.d.ts +7 -5
  44. package/dist/components/confirm/Confirm.js +1 -1
  45. package/dist/components/data-list/DataList.js +1 -1
  46. package/dist/components/data-table/DataTable.js +1 -1
  47. package/dist/components/data-table/RowsPerPage.d.ts +43 -0
  48. package/dist/components/data-table/RowsPerPage.js +1 -0
  49. package/dist/components/date-picker/DatePicker.js +1 -1
  50. package/dist/components/date-range-picker/DateRangePicker.js +1 -1
  51. package/dist/components/date-time-picker/DateTimePicker.js +1 -1
  52. package/dist/components/dialog/Dialog.js +1 -1
  53. package/dist/components/dialog/index.d.ts +1 -1
  54. package/dist/components/drawer/Drawer.d.ts +1 -1
  55. package/dist/components/drawer/Drawer.js +1 -1
  56. package/dist/components/empty/Empty.js +1 -1
  57. package/dist/components/file-picker/FilePicker.js +1 -1
  58. package/dist/components/floating-action-button/FloatingActionButton.js +1 -1
  59. package/dist/components/floating-action-button/index.d.ts +1 -0
  60. package/dist/components/floating-bottom-navigation/FloatingBottomNavigation.js +1 -1
  61. package/dist/components/footer/Footer.js +1 -1
  62. package/dist/components/gallery/Gallery.js +1 -1
  63. package/dist/components/gauge-chart/GaugeChart.js +1 -1
  64. package/dist/components/header/Header.js +1 -1
  65. package/dist/components/heatmap-chart/HeatmapChart.js +1 -1
  66. package/dist/components/highlight/Highlight.js +1 -1
  67. package/dist/components/hover-card/HoverCard.js +1 -1
  68. package/dist/components/how-to-steps/HowToSteps.d.ts +3 -0
  69. package/dist/components/how-to-steps/HowToSteps.js +1 -1
  70. package/dist/components/image/Image.js +1 -1
  71. package/dist/components/inline-citation/InlineCitation.d.ts +24 -0
  72. package/dist/components/inline-citation/InlineCitation.js +1 -1
  73. package/dist/components/list/List.js +1 -1
  74. package/dist/components/menu/Menu.js +1 -1
  75. package/dist/components/menubar/Menubar.js +1 -1
  76. package/dist/components/meter/Meter.js +1 -1
  77. package/dist/components/mockup/Mockup.js +1 -1
  78. package/dist/components/navigation-menu/NavigationMenu.d.ts +2 -1
  79. package/dist/components/navigation-menu/NavigationMenu.js +1 -1
  80. package/dist/components/number-field/NumberField.js +1 -1
  81. package/dist/components/number-field/index.d.ts +1 -1
  82. package/dist/components/overlay/Overlay.js +1 -1
  83. package/dist/components/page-layout/PageLayout.js +1 -1
  84. package/dist/components/pagination/Pagination.js +1 -1
  85. package/dist/components/panes/Panes.js +1 -1
  86. package/dist/components/pie-chart/PieChart.js +1 -1
  87. package/dist/components/pill/Pill.js +1 -1
  88. package/dist/components/popover/Popover.js +1 -1
  89. package/dist/components/progress-box/ProgressBox.js +1 -1
  90. package/dist/components/progress-circular/ProgressCircular.js +1 -1
  91. package/dist/components/progress-linear/ProgressLinear.js +1 -1
  92. package/dist/components/prompt-input/PromptInput.js +1 -1
  93. package/dist/components/provider/NebaProvider.js +1 -1
  94. package/dist/components/radio-group/RadioGroup.js +1 -1
  95. package/dist/components/radio-group/index.d.ts +1 -1
  96. package/dist/components/rating/Rating.js +1 -1
  97. package/dist/components/reasoning/Reasoning.js +1 -1
  98. package/dist/components/scatter-chart/ScatterChart.js +1 -1
  99. package/dist/components/scroll-area/ScrollArea.js +1 -1
  100. package/dist/components/scroll-zone/ScrollZone.js +1 -1
  101. package/dist/components/segmented-button/SegmentedButton.js +1 -1
  102. package/dist/components/select/Select.d.ts +12 -0
  103. package/dist/components/select/Select.js +1 -1
  104. package/dist/components/select/index.d.ts +1 -1
  105. package/dist/components/shortcut/Shortcut.js +1 -1
  106. package/dist/components/sidebar/Sidebar.js +1 -1
  107. package/dist/components/sidebar/SidebarTrigger.js +1 -1
  108. package/dist/components/skeleton/Skeleton.js +1 -1
  109. package/dist/components/slider/Slider.js +1 -1
  110. package/dist/components/slider/index.d.ts +1 -1
  111. package/dist/components/sources/Sources.js +1 -1
  112. package/dist/components/sparkline/Sparkline.d.ts +7 -0
  113. package/dist/components/sparkline/Sparkline.js +1 -1
  114. package/dist/components/spoiler/Spoiler.js +1 -1
  115. package/dist/components/statistic/Statistic.js +1 -1
  116. package/dist/components/streaming-text/StreamingText.d.ts +10 -6
  117. package/dist/components/streaming-text/StreamingText.js +1 -1
  118. package/dist/components/switch/Switch.js +1 -1
  119. package/dist/components/switch/index.d.ts +1 -1
  120. package/dist/components/table/Table.js +1 -1
  121. package/dist/components/table/index.d.ts +1 -1
  122. package/dist/components/tabs/Tabs.js +1 -1
  123. package/dist/components/text-field/TextField.js +1 -1
  124. package/dist/components/text-field/index.d.ts +1 -1
  125. package/dist/components/text-link/TextLink.js +1 -1
  126. package/dist/components/time-picker/TimePicker.js +1 -1
  127. package/dist/components/timeline-chart/TimelineChart.js +1 -1
  128. package/dist/components/toast/Toast.d.ts +38 -5
  129. package/dist/components/toast/Toast.js +1 -1
  130. package/dist/components/toast/index.d.ts +2 -2
  131. package/dist/components/toast/index.js +1 -1
  132. package/dist/components/toggle/Toggle.js +1 -1
  133. package/dist/components/toggle-group/ToggleGroup.js +1 -1
  134. package/dist/components/tool-call/ToolCall.js +1 -1
  135. package/dist/components/toolbar/Toolbar.js +1 -1
  136. package/dist/components/tooltip/Tooltip.js +1 -1
  137. package/dist/components/tour/Tour.js +1 -1
  138. package/dist/components/tour/index.d.ts +1 -1
  139. package/dist/components/transfer/Transfer.d.ts +7 -0
  140. package/dist/components/transfer/Transfer.js +1 -1
  141. package/dist/components/tree-select/TreeSelect.js +1 -1
  142. package/dist/components/tree-view/TreeView.js +1 -1
  143. package/dist/components/window-pane/WindowPane.js +1 -1
  144. package/dist/internal/animate.d.ts +34 -2
  145. package/dist/internal/animate.js +1 -1
  146. package/dist/internal/cache.d.ts +7 -1
  147. package/dist/internal/cache.js +1 -1
  148. package/dist/internal/calendar.d.ts +40 -1
  149. package/dist/internal/calendar.js +1 -1
  150. package/dist/internal/chart-frame.d.ts +86 -8
  151. package/dist/internal/chart-frame.js +1 -1
  152. package/dist/internal/chart-line.js +1 -1
  153. package/dist/internal/chart.d.ts +13 -0
  154. package/dist/internal/chart.js +1 -1
  155. package/dist/internal/data-table.d.ts +7 -1
  156. package/dist/internal/data-table.js +1 -1
  157. package/dist/internal/date.d.ts +10 -0
  158. package/dist/internal/date.js +1 -1
  159. package/dist/internal/idle.d.ts +10 -0
  160. package/dist/internal/idle.js +1 -0
  161. package/dist/internal/link.d.ts +4 -3
  162. package/dist/internal/media.js +1 -1
  163. package/dist/internal/observe.d.ts +4 -0
  164. package/dist/internal/observe.js +1 -1
  165. package/dist/internal/page-layout.d.ts +30 -2
  166. package/dist/internal/page-layout.js +1 -1
  167. package/dist/internal/picker.js +1 -1
  168. package/dist/internal/progress.d.ts +17 -0
  169. package/dist/internal/progress.js +1 -1
  170. package/dist/internal/refs.d.ts +18 -0
  171. package/dist/internal/refs.js +1 -0
  172. package/dist/internal/run.d.ts +34 -19
  173. package/dist/internal/run.js +1 -1
  174. package/dist/internal/sizer.d.ts +9 -4
  175. package/dist/internal/sizer.js +1 -1
  176. package/dist/internal/styles.d.ts +14 -0
  177. package/dist/internal/styles.js +1 -1
  178. package/dist/internal/tile.d.ts +34 -0
  179. package/dist/internal/tile.js +1 -0
  180. package/dist/internal/wheel.d.ts +24 -1
  181. package/dist/internal/wheel.js +1 -1
  182. package/dist/styles.css +1 -1
  183. package/dist/tailwind.css +366 -61
  184. package/dist/types.d.ts +4 -2
  185. package/package.json +1 -1
@@ -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))})}
@@ -464,6 +464,12 @@ export declare function clampClasses(lines: number): string;
464
464
  export declare function clampSlot(lines: number | undefined): React.CSSProperties | undefined;
465
465
  /** Icons track their label rather than carrying a size of their own. */
466
466
  export declare const iconClasses = "[&_svg]:pointer-events-none [&_svg]:size-[1.2em] [&_svg]:shrink-0";
467
+ /**
468
+ * A Select's trigger: a TextField's shell, to the pixel. Here rather than in
469
+ * `Select.tsx` because a DataTable's rows-per-page control draws the closed
470
+ * Select before the Select's own chunk arrives, and the two must not drift.
471
+ */
472
+ export declare const selectTriggerClasses: string;
467
473
  /**
468
474
  * A Base UI **Collapsible** panel: Collapsible itself, and the three agent
469
475
  * components built on the same primitive.
@@ -683,6 +689,14 @@ export declare function hasContent(node: React.ReactNode): boolean;
683
689
  * length.
684
690
  */
685
691
  export declare function toLength(value: number | string | undefined): string | undefined;
692
+ /**
693
+ * Which of the four units a length is written in, or `undefined` for a string
694
+ * `toPixels` would not read. The same test `toPixels` makes, without converting:
695
+ * converting a `rem` reads the root's font size, which is a style read, and a
696
+ * render that only needs to know *whether* something is a length has no reason
697
+ * to make one.
698
+ */
699
+ export declare function lengthUnit(value: string): 'px' | 'rem' | 'em' | '%' | undefined;
686
700
  /**
687
701
  * The other direction: a CSS length a caller wrote, as the number a drag can do
688
702
  * arithmetic on.
@@ -1 +1 @@
1
- export const radiusClasses={xs:"rounded-(--neba-radius-xs)",sm:"rounded-(--neba-radius-sm)",md:"rounded-(--neba-radius-md)",lg:"rounded-(--neba-radius-lg)",xl:"rounded-(--neba-radius-xl)"};export const controlHeightClasses={xs:"h-5.5",sm:"h-6.5",md:"h-8",lg:"h-10",xl:"h-12"};export const fieldHeightClasses={xs:"min-h-5.5",sm:"min-h-6.5",md:"min-h-8",lg:"min-h-10",xl:"min-h-12"};export const controlHeightValues={xs:"1.375rem",sm:"1.625rem",md:"2rem",lg:"2.5rem",xl:"3rem"};export const measureWidths={xs:"30rem",sm:"40rem",md:"48rem",lg:"64rem",xl:"80rem"};export function measureValue(e){return"number"==typeof e?`${e}px`:measureWidths[e]??e}export const controlSquareClasses={xs:"w-5.5",sm:"w-6.5",md:"w-8",lg:"w-10",xl:"w-12"};export const controlTextClasses={xs:"text-[0.6875rem]",sm:"text-[0.75rem]",md:"text-[0.8125rem]",lg:"text-[0.9375rem]",xl:"text-[1.0625rem]"};export const controlTextLeadingClasses={xs:"text-[0.6875rem]/[0.875rem]",sm:"text-[0.75rem]/[1rem]",md:"text-[0.8125rem]/[1.25rem]",lg:"text-[0.9375rem]/[1.375rem]",xl:"text-[1.0625rem]/[1.625rem]"};export const metaTextClasses={xs:"text-[0.625rem]",sm:"text-[0.6875rem]",md:"text-[0.75rem]",lg:"text-[0.8125rem]",xl:"text-[0.875rem]"};export const metaTextValues={xs:"0.625rem",sm:"0.6875rem",md:"0.75rem",lg:"0.8125rem",xl:"0.875rem"};export const paddingXClasses={default:{xs:"px-2.5",sm:"px-3",md:"px-4",lg:"px-5",xl:"px-6"},compact:{xs:"px-1.5",sm:"px-2",md:"px-2.5",lg:"px-3",xl:"px-4"}};export const iconSizeClasses={xs:"size-3.5",sm:"size-4",md:"size-5",lg:"size-6",xl:"size-7"};export const tickSizeClasses={xs:"size-3.5",sm:"size-4",md:"size-4.5",lg:"size-5",xl:"size-6"};export const tickRadiusClasses={xs:"rounded-[0.25rem]",sm:"rounded-[0.3125rem]",md:"rounded-[0.375rem]",lg:"rounded-[0.4375rem]",xl:"rounded-[0.5rem]"};export const tickDotClasses={xs:"size-1.5",sm:"size-1.5",md:"size-2",lg:"size-2",xl:"size-2.5"};export const tickRowLeadingClasses="leading-[1.4]";export const hitAreaClasses="neba-hit";export const paddingXValues={default:{xs:"0.625rem",sm:"0.75rem",md:"1rem",lg:"1.25rem",xl:"1.5rem"},compact:{xs:"0.375rem",sm:"0.5rem",md:"0.625rem",lg:"0.75rem",xl:"1rem"}};export const gapClasses={xs:"gap-1",sm:"gap-1.5",md:"gap-1.5",lg:"gap-2",xl:"gap-2.5"};export const stackGapClasses={xs:"gap-1",sm:"gap-1",md:"gap-1.5",lg:"gap-1.5",xl:"gap-2"};export const sheetTitleClasses={xs:"text-[0.75rem]/[1rem]",sm:"text-[0.8125rem]/[1.125rem]",md:"text-[0.9375rem]/[1.25rem]",lg:"text-[1.0625rem]/[1.5rem]",xl:"text-[1.25rem]/[1.75rem]"};export const sheetTitleHeadingClasses="neba-title [&.neba-title_:where(h1,h2,h3,h4,h5,h6):not([class])]:[font:inherit] [&.neba-title_:where(h1,h2,h3,h4,h5,h6):not([class])]:m-0 [:where(&)_:where(h1,h2,h3,h4,h5,h6)]:[font:inherit] [:where(&)_:where(h1,h2,h3,h4,h5,h6)]:m-0";export const headingTitleClasses={xs:"[&.neba-heading]:text-[0.75rem]/[1rem]",sm:"[&.neba-heading]:text-[0.8125rem]/[1.125rem]",md:"[&.neba-heading]:text-[0.9375rem]/[1.25rem]",lg:"[&.neba-heading]:text-[1.0625rem]/[1.5rem]",xl:"[&.neba-heading]:text-[1.25rem]/[1.75rem]"};export const sheetBodyClasses={xs:"text-[0.6875rem]/[1rem]",sm:"text-[0.75rem]/[1.125rem]",md:"text-[0.8125rem]/[1.375rem]",lg:"text-[0.9375rem]/[1.5rem]",xl:"text-[1.0625rem]/[1.75rem]"};export const sheetHeaderGapClasses={xs:"gap-0.5",sm:"gap-0.5",md:"gap-1",lg:"gap-1",xl:"gap-1.5"};export const sheetSectionGapClasses={xs:"gap-1.5",sm:"gap-2",md:"gap-3",lg:"gap-3.5",xl:"gap-4"};export const optionGapClasses={vertical:sheetSectionGapClasses,horizontal:{xs:"gap-x-5 gap-y-1.5",sm:"gap-x-5 gap-y-2",md:"gap-x-5 gap-y-3",lg:"gap-x-5 gap-y-3.5",xl:"gap-x-5 gap-y-4"}};export const surfaceClasses="[background-image:var(--neba-grain),var(--neba-sheen)] [background-blend-mode:overlay,normal] [backdrop-filter:var(--neba-blur)]";export const ringRestClasses="[outline:0_solid_transparent]";export const transitionClasses=`${ringRestClasses} [transition-property:background-color,border-color,box-shadow,color,outline-color] [transition-duration:var(--neba-duration-fill),var(--neba-duration),var(--neba-duration),var(--neba-duration),var(--neba-duration)] [transition-timing-function:var(--neba-ease)]`;export const pressTransitionClasses="active:[transition-duration:0ms]";export const popupFadeStateClasses="data-[starting-style]:opacity-0 data-[ending-style]:opacity-0";export const popupFadeClasses="[transition:opacity_var(--neba-duration)_var(--neba-ease)] "+popupFadeStateClasses;export const focusRingClasses=`${ringRestClasses} outline-offset-2 focus-visible:[outline:2px_solid_var(--n-ring)]`;export const insetRingClasses=`${ringRestClasses} outline-offset-[-2px] focus-visible:[outline:2px_solid_var(--n-ring)]`;export const focusWithinRingClasses=`${ringRestClasses} outline-offset-2 has-[:focus-visible]:[outline:2px_solid_var(--n-ring)] supports-[not_selector(:has(*))]:focus-within:[outline:2px_solid_var(--n-ring)]`;export const fieldRingClasses=`${ringRestClasses} outline-offset-0 has-[:focus-visible]:[outline:2px_solid_var(--n-ring)]`;export const fieldFocusTransitionClasses="focus-within:[transition-duration:var(--neba-duration)]";export function clampClasses(e){return e>1?"line-clamp-(--n-lines)":"truncate"}export function clampSlot(e){return void 0!==e&&e>1?{"--n-lines":Math.floor(e)}:void 0}export const iconClasses="[&_svg]:pointer-events-none [&_svg]:size-[1.2em] [&_svg]:shrink-0";const e="[transition:height_var(--neba-duration)_var(--neba-ease)] motion-reduce:[transition-duration:0ms] data-[starting-style]:h-0 data-[ending-style]:h-0";export const collapsiblePanelClasses=`h-(--collapsible-panel-height) overflow-hidden ${e}`;export const accordionPanelClasses=`h-(--accordion-panel-height) overflow-hidden ${e}`;export const disclosureTriggerClasses="group/disclosure";export const disclosureChevronClasses="flex h-[1lh] shrink-0 items-center [transition:rotate_var(--neba-duration)_var(--neba-ease)] group-data-[panel-open]/disclosure:rotate-180";export const preformattedClasses="m-0 overflow-auto rounded-(--neba-radius-sm) bg-(--neba-groove) p-2 font-mono text-[0.9em]/[1.5] whitespace-pre";export const srOnlyClasses="absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]";export function controlSlots(e,s,t){const n="solid"===t;return{"--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)`,"--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-on-tint":`var(--neba-${e}-on-tint)`,"--n-panel":`var(--neba-${e}-panel)`,"--n-panel-hover":`var(--neba-${e}-panel-hover)`,"--n-panel-press":`var(--neba-${e}-panel-press)`,"--n-line":`var(--neba-${e}-line)`,"--n-line-hover":`var(--neba-${e}-line-hover)`,"--n-ring":`var(--neba-${e}-ring)`,"--n-glow":n?"var(--neba-glow-on-fill)":`var(--neba-${e}-soft)`,"--n-flash":n?"var(--neba-flash-on-fill)":`var(--neba-${e}-soft-press)`,"--n-elev":`var(--neba-shadow-${s})`,"--n-elev-hover":`var(--neba-shadow-${Math.min(s+1,4)})`,"--n-elev-press":`var(--neba-shadow-${Math.max(s-1,0)})`}}export function surfaceSlots(e,s){return{"--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-on-tint":`var(--neba-${e}-on-tint)`,"--n-panel":"var(--neba-panel)","--n-panel-hover":"var(--neba-panel-hover)","--n-panel-press":"var(--neba-panel-press)","--n-line":`var(--neba-${e}-line)`,"--n-line-hover":`var(--neba-${e}-line-hover)`,"--n-ring":`var(--neba-${e}-ring)`,"--n-elev":`var(--neba-shadow-${s})`}}export const tintPlateClasses="neba-tint-plate";export const disabledClasses={solid:"cursor-not-allowed bg-(--neba-disabled-bg) text-(--neba-disabled-fg) shadow-none",outline:"cursor-not-allowed border bg-transparent text-(--neba-disabled-fg) [border-color:var(--neba-disabled-border)] shadow-none",text:"cursor-not-allowed bg-transparent text-(--neba-disabled-fg) shadow-none"};export const fieldRestClasses={solid:`${surfaceClasses} text-(--neba-fg) bg-(--n-panel-hover) [box-shadow:var(--n-elev),var(--neba-plate-solid)] hover:bg-(--n-panel-press) focus-within:bg-(--n-panel-press)`,outline:`${surfaceClasses} border text-(--neba-fg) bg-(--n-panel) [border-color:var(--n-line)] [box-shadow:var(--n-elev),var(--neba-plate-glass)] hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)] focus-within:bg-(--n-panel-hover) focus-within:[border-color:var(--n-ring)] focus-within:hover:[border-color:var(--n-ring)]`,text:"text-(--neba-fg) bg-transparent hover:bg-(--n-soft) focus-within:bg-(--n-soft-hover) focus-within:hover:bg-(--n-soft-hover)"};export const fieldReadOnlyClasses={solid:`${surfaceClasses} text-(--neba-fg) bg-(--n-panel-hover) [box-shadow:var(--neba-plate-solid)] [filter:saturate(0.55)]`,outline:`${surfaceClasses} border text-(--neba-fg) bg-(--n-panel) [border-color:var(--n-line)] [box-shadow:var(--neba-plate-glass)] [filter:saturate(0.55)]`,text:"text-(--neba-fg) bg-transparent [filter:saturate(0.55)]"};export const readOnlyFilterClasses="[filter:saturate(0.55)]";export const fieldSheetClasses={solid:`${surfaceClasses} text-(--neba-fg) bg-(--n-panel-hover) [box-shadow:var(--n-elev)] hover:bg-(--n-panel-press) focus-within:bg-(--n-panel-press)`,outline:`${surfaceClasses} border [border-color:transparent] text-(--neba-fg) bg-(--n-panel) [box-shadow:var(--n-elev)] hover:bg-(--n-panel-hover) focus-within:bg-(--n-panel-hover)`,text:fieldRestClasses.text};export const fieldSheetReadOnlyClasses={solid:`${surfaceClasses} text-(--neba-fg) bg-(--n-panel-hover)`,outline:`${surfaceClasses} border [border-color:transparent] text-(--neba-fg) bg-(--n-panel)`,text:"text-(--neba-fg) bg-transparent"};export const fieldSheetDisabledClasses={solid:disabledClasses.solid,outline:"cursor-not-allowed border bg-transparent text-(--neba-disabled-fg) [border-color:transparent] shadow-none",text:disabledClasses.text};export const citationMarkClasses="inline-flex shrink-0 items-center justify-center rounded-[0.3em] min-w-[1.5em] px-[0.35em] py-[0.05em] bg-(--n-soft) text-[0.8em]/[1.6] font-semibold text-(--n-on-tint) tabular-nums";export const chipRemoveClasses="relative ms-0.5 inline-flex shrink-0 items-center justify-center rounded-full size-[1.15em] cursor-pointer opacity-70 neba-hit [transition:opacity_var(--neba-duration)_var(--neba-ease)] hover:opacity-100 focus-visible:opacity-100 focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1 disabled:cursor-not-allowed";export const sheetCloseClasses="relative flex size-[1.6em] shrink-0 cursor-pointer items-center justify-center rounded-full text-(--neba-muted-fg) neba-hit [&_svg]:size-[1.1em] [&_svg]:shrink-0 [transition:background-color_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)] hover:bg-(--n-soft) hover:text-(--neba-fg) focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2";export function hasContent(e){return null!=e&&!1!==e&&""!==e}export function toLength(e){if(null!=e)return"number"==typeof e?`${e}px`:e}const s=/^\s*(-?[\d.]+)\s*(px|rem|em|%)\s*$/;export function toPixels(e,n){const r=s.exec(e);if(!r)return;const a=Number(r[1]);if(!Number.isNaN(a))switch(r[2]){case"px":return a;case"%":return n.percentOf*a/100;case"em":return a*t(n.relativeTo);default:return a*t("undefined"==typeof document?null:document.documentElement)}}function t(e){return e&&"undefined"!=typeof getComputedStyle&&parseFloat(getComputedStyle(e).fontSize)||16}export function cx(...e){return e.filter(Boolean).join(" ")}
1
+ export const radiusClasses={xs:"rounded-(--neba-radius-xs)",sm:"rounded-(--neba-radius-sm)",md:"rounded-(--neba-radius-md)",lg:"rounded-(--neba-radius-lg)",xl:"rounded-(--neba-radius-xl)"};export const controlHeightClasses={xs:"h-5.5",sm:"h-6.5",md:"h-8",lg:"h-10",xl:"h-12"};export const fieldHeightClasses={xs:"min-h-5.5",sm:"min-h-6.5",md:"min-h-8",lg:"min-h-10",xl:"min-h-12"};export const controlHeightValues={xs:"1.375rem",sm:"1.625rem",md:"2rem",lg:"2.5rem",xl:"3rem"};export const measureWidths={xs:"30rem",sm:"40rem",md:"48rem",lg:"64rem",xl:"80rem"};export function measureValue(e){return"number"==typeof e?`${e}px`:measureWidths[e]??e}export const controlSquareClasses={xs:"w-5.5",sm:"w-6.5",md:"w-8",lg:"w-10",xl:"w-12"};export const controlTextClasses={xs:"text-[0.6875rem]",sm:"text-[0.75rem]",md:"text-[0.8125rem]",lg:"text-[0.9375rem]",xl:"text-[1.0625rem]"};export const controlTextLeadingClasses={xs:"text-[0.6875rem]/[0.875rem]",sm:"text-[0.75rem]/[1rem]",md:"text-[0.8125rem]/[1.25rem]",lg:"text-[0.9375rem]/[1.375rem]",xl:"text-[1.0625rem]/[1.625rem]"};export const metaTextClasses={xs:"text-[0.625rem]",sm:"text-[0.6875rem]",md:"text-[0.75rem]",lg:"text-[0.8125rem]",xl:"text-[0.875rem]"};export const metaTextValues={xs:"0.625rem",sm:"0.6875rem",md:"0.75rem",lg:"0.8125rem",xl:"0.875rem"};export const paddingXClasses={default:{xs:"px-2.5",sm:"px-3",md:"px-4",lg:"px-5",xl:"px-6"},compact:{xs:"px-1.5",sm:"px-2",md:"px-2.5",lg:"px-3",xl:"px-4"}};export const iconSizeClasses={xs:"size-3.5",sm:"size-4",md:"size-5",lg:"size-6",xl:"size-7"};export const tickSizeClasses={xs:"size-3.5",sm:"size-4",md:"size-4.5",lg:"size-5",xl:"size-6"};export const tickRadiusClasses={xs:"rounded-[0.25rem]",sm:"rounded-[0.3125rem]",md:"rounded-[0.375rem]",lg:"rounded-[0.4375rem]",xl:"rounded-[0.5rem]"};export const tickDotClasses={xs:"size-1.5",sm:"size-1.5",md:"size-2",lg:"size-2",xl:"size-2.5"};export const tickRowLeadingClasses="leading-[1.4]";export const hitAreaClasses="neba-hit";export const paddingXValues={default:{xs:"0.625rem",sm:"0.75rem",md:"1rem",lg:"1.25rem",xl:"1.5rem"},compact:{xs:"0.375rem",sm:"0.5rem",md:"0.625rem",lg:"0.75rem",xl:"1rem"}};export const gapClasses={xs:"gap-1",sm:"gap-1.5",md:"gap-1.5",lg:"gap-2",xl:"gap-2.5"};export const stackGapClasses={xs:"gap-1",sm:"gap-1",md:"gap-1.5",lg:"gap-1.5",xl:"gap-2"};export const sheetTitleClasses={xs:"text-[0.75rem]/[1rem]",sm:"text-[0.8125rem]/[1.125rem]",md:"text-[0.9375rem]/[1.25rem]",lg:"text-[1.0625rem]/[1.5rem]",xl:"text-[1.25rem]/[1.75rem]"};export const sheetTitleHeadingClasses="neba-title [&.neba-title_:where(h1,h2,h3,h4,h5,h6):not([class])]:[font:inherit] [&.neba-title_:where(h1,h2,h3,h4,h5,h6):not([class])]:m-0 [:where(&)_:where(h1,h2,h3,h4,h5,h6)]:[font:inherit] [:where(&)_:where(h1,h2,h3,h4,h5,h6)]:m-0";export const headingTitleClasses={xs:"[&.neba-heading]:text-[0.75rem]/[1rem]",sm:"[&.neba-heading]:text-[0.8125rem]/[1.125rem]",md:"[&.neba-heading]:text-[0.9375rem]/[1.25rem]",lg:"[&.neba-heading]:text-[1.0625rem]/[1.5rem]",xl:"[&.neba-heading]:text-[1.25rem]/[1.75rem]"};export const sheetBodyClasses={xs:"text-[0.6875rem]/[1rem]",sm:"text-[0.75rem]/[1.125rem]",md:"text-[0.8125rem]/[1.375rem]",lg:"text-[0.9375rem]/[1.5rem]",xl:"text-[1.0625rem]/[1.75rem]"};export const sheetHeaderGapClasses={xs:"gap-0.5",sm:"gap-0.5",md:"gap-1",lg:"gap-1",xl:"gap-1.5"};export const sheetSectionGapClasses={xs:"gap-1.5",sm:"gap-2",md:"gap-3",lg:"gap-3.5",xl:"gap-4"};export const optionGapClasses={vertical:sheetSectionGapClasses,horizontal:{xs:"gap-x-5 gap-y-1.5",sm:"gap-x-5 gap-y-2",md:"gap-x-5 gap-y-3",lg:"gap-x-5 gap-y-3.5",xl:"gap-x-5 gap-y-4"}};export const surfaceClasses="[background-image:var(--neba-grain),var(--neba-sheen)] [background-blend-mode:overlay,normal] [backdrop-filter:var(--neba-blur)]";export const ringRestClasses="[outline:0_solid_transparent]";export const transitionClasses=`${ringRestClasses} [transition-property:background-color,border-color,box-shadow,color,outline-color] [transition-duration:var(--neba-duration-fill),var(--neba-duration),var(--neba-duration),var(--neba-duration),var(--neba-duration)] [transition-timing-function:var(--neba-ease)]`;export const pressTransitionClasses="active:[transition-duration:0ms]";export const popupFadeStateClasses="data-[starting-style]:opacity-0 data-[ending-style]:opacity-0";export const popupFadeClasses="[transition:opacity_var(--neba-duration)_var(--neba-ease)] "+popupFadeStateClasses;export const focusRingClasses=`${ringRestClasses} outline-offset-2 focus-visible:[outline:2px_solid_var(--n-ring)]`;export const insetRingClasses=`${ringRestClasses} outline-offset-[-2px] focus-visible:[outline:2px_solid_var(--n-ring)]`;export const focusWithinRingClasses=`${ringRestClasses} outline-offset-2 has-[:focus-visible]:[outline:2px_solid_var(--n-ring)] supports-[not_selector(:has(*))]:focus-within:[outline:2px_solid_var(--n-ring)]`;export const fieldRingClasses=`${ringRestClasses} outline-offset-0 has-[:focus-visible]:[outline:2px_solid_var(--n-ring)]`;export const fieldFocusTransitionClasses="focus-within:[transition-duration:var(--neba-duration)]";export function clampClasses(e){return e>1?"line-clamp-(--n-lines)":"truncate"}export function clampSlot(e){return void 0!==e&&e>1?{"--n-lines":Math.floor(e)}:void 0}export const iconClasses="[&_svg]:pointer-events-none [&_svg]:size-[1.2em] [&_svg]:shrink-0";export const selectTriggerClasses=`group relative flex w-full cursor-pointer items-center select-none [-webkit-tap-highlight-color:transparent] [touch-action:manipulation] ${transitionClasses} ${fieldFocusTransitionClasses} ${iconClasses}`;const e="[transition:height_var(--neba-duration)_var(--neba-ease)] motion-reduce:[transition-duration:0ms] data-[starting-style]:h-0 data-[ending-style]:h-0";export const collapsiblePanelClasses=`h-(--collapsible-panel-height) overflow-hidden ${e}`;export const accordionPanelClasses=`h-(--accordion-panel-height) overflow-hidden ${e}`;export const disclosureTriggerClasses="group/disclosure";export const disclosureChevronClasses="flex h-[1lh] shrink-0 items-center [transition:rotate_var(--neba-duration)_var(--neba-ease)] group-data-[panel-open]/disclosure:rotate-180";export const preformattedClasses="m-0 overflow-auto rounded-(--neba-radius-sm) bg-(--neba-groove) p-2 font-mono text-[0.9em]/[1.5] whitespace-pre";export const srOnlyClasses="absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]";export function controlSlots(e,s,t){const n="solid"===t;return{"--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)`,"--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-on-tint":`var(--neba-${e}-on-tint)`,"--n-panel":`var(--neba-${e}-panel)`,"--n-panel-hover":`var(--neba-${e}-panel-hover)`,"--n-panel-press":`var(--neba-${e}-panel-press)`,"--n-line":`var(--neba-${e}-line)`,"--n-line-hover":`var(--neba-${e}-line-hover)`,"--n-ring":`var(--neba-${e}-ring)`,"--n-glow":n?"var(--neba-glow-on-fill)":`var(--neba-${e}-soft)`,"--n-flash":n?"var(--neba-flash-on-fill)":`var(--neba-${e}-soft-press)`,"--n-elev":`var(--neba-shadow-${s})`,"--n-elev-hover":`var(--neba-shadow-${Math.min(s+1,4)})`,"--n-elev-press":`var(--neba-shadow-${Math.max(s-1,0)})`}}export function surfaceSlots(e,s){return{"--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-on-tint":`var(--neba-${e}-on-tint)`,"--n-panel":"var(--neba-panel)","--n-panel-hover":"var(--neba-panel-hover)","--n-panel-press":"var(--neba-panel-press)","--n-line":`var(--neba-${e}-line)`,"--n-line-hover":`var(--neba-${e}-line-hover)`,"--n-ring":`var(--neba-${e}-ring)`,"--n-elev":`var(--neba-shadow-${s})`}}export const tintPlateClasses="neba-tint-plate";export const disabledClasses={solid:"cursor-not-allowed bg-(--neba-disabled-bg) text-(--neba-disabled-fg) shadow-none",outline:"cursor-not-allowed border bg-transparent text-(--neba-disabled-fg) [border-color:var(--neba-disabled-border)] shadow-none",text:"cursor-not-allowed bg-transparent text-(--neba-disabled-fg) shadow-none"};export const fieldRestClasses={solid:`${surfaceClasses} text-(--neba-fg) bg-(--n-panel-hover) [box-shadow:var(--n-elev),var(--neba-plate-solid)] hover:bg-(--n-panel-press) focus-within:bg-(--n-panel-press)`,outline:`${surfaceClasses} border text-(--neba-fg) bg-(--n-panel) [border-color:var(--n-line)] [box-shadow:var(--n-elev),var(--neba-plate-glass)] hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)] focus-within:bg-(--n-panel-hover) focus-within:[border-color:var(--n-ring)] focus-within:hover:[border-color:var(--n-ring)]`,text:"text-(--neba-fg) bg-transparent hover:bg-(--n-soft) focus-within:bg-(--n-soft-hover) focus-within:hover:bg-(--n-soft-hover)"};export const fieldReadOnlyClasses={solid:`${surfaceClasses} text-(--neba-fg) bg-(--n-panel-hover) [box-shadow:var(--neba-plate-solid)] [filter:saturate(0.55)]`,outline:`${surfaceClasses} border text-(--neba-fg) bg-(--n-panel) [border-color:var(--n-line)] [box-shadow:var(--neba-plate-glass)] [filter:saturate(0.55)]`,text:"text-(--neba-fg) bg-transparent [filter:saturate(0.55)]"};export const readOnlyFilterClasses="[filter:saturate(0.55)]";export const fieldSheetClasses={solid:`${surfaceClasses} text-(--neba-fg) bg-(--n-panel-hover) [box-shadow:var(--n-elev)] hover:bg-(--n-panel-press) focus-within:bg-(--n-panel-press)`,outline:`${surfaceClasses} border [border-color:transparent] text-(--neba-fg) bg-(--n-panel) [box-shadow:var(--n-elev)] hover:bg-(--n-panel-hover) focus-within:bg-(--n-panel-hover)`,text:fieldRestClasses.text};export const fieldSheetReadOnlyClasses={solid:`${surfaceClasses} text-(--neba-fg) bg-(--n-panel-hover)`,outline:`${surfaceClasses} border [border-color:transparent] text-(--neba-fg) bg-(--n-panel)`,text:"text-(--neba-fg) bg-transparent"};export const fieldSheetDisabledClasses={solid:disabledClasses.solid,outline:"cursor-not-allowed border bg-transparent text-(--neba-disabled-fg) [border-color:transparent] shadow-none",text:disabledClasses.text};export const citationMarkClasses="inline-flex shrink-0 items-center justify-center rounded-[0.3em] min-w-[1.5em] px-[0.35em] py-[0.05em] bg-(--n-soft) text-[0.8em]/[1.6] font-semibold text-(--n-on-tint) tabular-nums";export const chipRemoveClasses="relative ms-0.5 inline-flex shrink-0 items-center justify-center rounded-full size-[1.15em] cursor-pointer opacity-70 neba-hit [transition:opacity_var(--neba-duration)_var(--neba-ease)] hover:opacity-100 focus-visible:opacity-100 focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1 disabled:cursor-not-allowed";export const sheetCloseClasses="relative flex size-[1.6em] shrink-0 cursor-pointer items-center justify-center rounded-full text-(--neba-muted-fg) neba-hit [&_svg]:size-[1.1em] [&_svg]:shrink-0 [transition:background-color_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)] hover:bg-(--n-soft) hover:text-(--neba-fg) focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2";export function hasContent(e){return null!=e&&!1!==e&&""!==e}export function toLength(e){if(null!=e)return"number"==typeof e?`${e}px`:e}const s=/^\s*(-?[\d.]+)\s*(px|rem|em|%)\s*$/;export function lengthUnit(e){const t=s.exec(e);if(t&&!Number.isNaN(Number(t[1])))return t[2]}export function toPixels(e,n){const r=s.exec(e);if(!r)return;const a=Number(r[1]);if(!Number.isNaN(a))switch(r[2]){case"px":return a;case"%":return n.percentOf*a/100;case"em":return a*t(n.relativeTo);default:return a*t("undefined"==typeof document?null:document.documentElement)}}function t(e){return e&&"undefined"!=typeof getComputedStyle&&parseFloat(getComputedStyle(e).fontSize)||16}export function cx(...e){return e.filter(Boolean).join(" ")}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Keeps a sliding tile on the item it marks while the items change under it.
3
+ *
4
+ * A SegmentedButton and a FloatingBottomNavigation draw one tile behind the
5
+ * current item and measure that item to place it. A value change is a render
6
+ * of the component and is measured there. What is not is a change to the items
7
+ * themselves: a label that grew, a font that arrived, the set reordered by its
8
+ * caller. Both components used to catch those by measuring again whenever their
9
+ * `children` changed identity, which is every render of whatever is above them,
10
+ * and every one of those measurements laid the page out to read four offsets
11
+ * that had not moved.
12
+ *
13
+ * So the items are watched instead, and nothing is measured unless something
14
+ * happened to them:
15
+ *
16
+ * - **The root's size**, with no animation. That is the container moving under
17
+ * a tile that was already in the right place, and a tile that slides there
18
+ * lags behind a window being dragged.
19
+ * - **Each item's size**, animated, as a label change always was.
20
+ * - **The set itself**, through a `MutationObserver` on the root: an item added,
21
+ * removed or moved, and the attribute that marks the current one moving to
22
+ * another node, which is what a reorder of unkeyed items looks like.
23
+ *
24
+ * The root is observed before any item, and that order is load-bearing. One
25
+ * `ResizeObserver` delivers its entries in the order its targets were added,
26
+ * so when a resize of the root resizes the items with it, the instant
27
+ * placement lands first and the animated ones that follow find the tile
28
+ * already there. The other way round, the animated one starts a transition and
29
+ * the instant one, asking for the same box, cannot stop it.
30
+ *
31
+ * `items` selects every item and `current` names the attribute on the current
32
+ * one. Returns what stops all three.
33
+ */
34
+ export declare function watchTile(root: HTMLElement, items: string, current: string, measure: (animate: boolean) => void): () => void;
@@ -0,0 +1 @@
1
+ import{observeResize as e}from"./observe.js";export function watchTile(t,o,r,s){const n=e(t,()=>s(!1)),c=new Map,i=()=>{const r=new Set(t.querySelectorAll(o));for(const[e,t]of c)r.has(e)||(t(),c.delete(e));for(const t of r)c.has(t)||c.set(t,e(t,()=>s(!0)))};i();const a=new MutationObserver(()=>{i(),s(!0)});return a.observe(t,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[r]}),()=>{n(),a.disconnect();for(const e of c.values())e();c.clear()}}
@@ -18,7 +18,11 @@
18
18
  * Held only where there is a strip to hold it. A bar that fits in its box takes
19
19
  * nothing at all, which is what makes it safe to leave on: three tabs in a row
20
20
  * are not a scroll container as far as the reader is concerned, and must not
21
- * behave like one.
21
+ * behave like one. And it takes no listener either, which is what
22
+ * `bindAxisWheelWhileOverflowing` is for: a wheel listener that can cancel the
23
+ * scroll makes the browser ask the page's main thread before it scrolls
24
+ * anything under it, so every tab bar on a page held up the page's own scroll
25
+ * while the pointer crossed it, whether the bar could scroll or not.
22
26
  *
23
27
  * Two gestures are deliberately left alone. A wheel held with Ctrl is a zoom. A
24
28
  * trackpad swiping sideways is already travel along the strip, and the browser
@@ -36,3 +40,22 @@
36
40
  * if the page does not answer it as well.
37
41
  */
38
42
  export declare function bindAxisWheel(el: HTMLElement): () => void;
43
+ /** What `bindAxisWheelWhileOverflowing` hands back. */
44
+ export interface AxisWheelBinding {
45
+ /** Measures the strip again, and takes or drops the wheel to match. */
46
+ check: () => void;
47
+ /** The teardown. */
48
+ stop: () => void;
49
+ }
50
+ /**
51
+ * `bindAxisWheel`, attached only while the strip overflows along its width —
52
+ * the one case its handler acts on, measured the same way.
53
+ *
54
+ * `check` is for the caller to run whenever it measures the strip anyway: on a
55
+ * scroll, a resize, a change in what it holds. The strip also checks when a
56
+ * pointer arrives over it, because a label can grow without resizing anything
57
+ * an observer is watching, and a wheel can only reach the strip through a
58
+ * pointer that is over it. The reads come first and nothing is written, so a
59
+ * caller can run it ahead of its own writes without forcing a layout.
60
+ */
61
+ export declare function bindAxisWheelWhileOverflowing(el: HTMLElement): AxisWheelBinding;
@@ -1 +1 @@
1
- export function bindAxisWheel(e){const t=t=>{if(t.defaultPrevented)return;if(t.ctrlKey||Math.abs(t.deltaX)>Math.abs(t.deltaY))return;if(e.scrollWidth-e.clientWidth<=1)return;const r=1===t.deltaMode?16:2===t.deltaMode?e.clientWidth:1,l=t.deltaY*r;if(!l)return;t.preventDefault();const n="rtl"===getComputedStyle(e).direction;e.scrollBy({left:n?-l:l,behavior:"auto"})};return e.addEventListener("wheel",t,{passive:!1}),()=>e.removeEventListener("wheel",t)}
1
+ export function bindAxisWheel(e){const t=t=>{if(t.defaultPrevented)return;if(t.ctrlKey||Math.abs(t.deltaX)>Math.abs(t.deltaY))return;if(e.scrollWidth-e.clientWidth<=1)return;const n=1===t.deltaMode?16:2===t.deltaMode?e.clientWidth:1,l=t.deltaY*n;if(!l)return;t.preventDefault();const r="rtl"===getComputedStyle(e).direction;e.scrollBy({left:r?-l:l,behavior:"auto"})};return e.addEventListener("wheel",t,{passive:!1}),()=>e.removeEventListener("wheel",t)}export function bindAxisWheelWhileOverflowing(e){let t=null;const n=()=>{const n=e.scrollWidth-e.clientWidth>1;n&&!t?t=bindAxisWheel(e):!n&&t&&(t(),t=null)};return e.addEventListener("pointerenter",n),n(),{check:n,stop(){e.removeEventListener("pointerenter",n),t?.(),t=null}}}