neba 1.9.0 → 1.11.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 (204) hide show
  1. package/README.md +35 -5
  2. package/dist/components/accordion/Accordion.js +1 -1
  3. package/dist/components/alert/Alert.js +1 -1
  4. package/dist/components/anchor/Anchor.js +1 -1
  5. package/dist/components/animate-lighting/AnimateLighting.js +1 -1
  6. package/dist/components/app-logo/AppLogo.js +1 -1
  7. package/dist/components/aspect-ratio/AspectRatio.js +1 -1
  8. package/dist/components/avatar/Avatar.js +1 -1
  9. package/dist/components/avatar-group/AvatarGroup.js +1 -1
  10. package/dist/components/badge/Badge.js +1 -1
  11. package/dist/components/bar-chart/BarChart.d.ts +1 -1
  12. package/dist/components/bar-chart/BarChart.js +1 -1
  13. package/dist/components/blockquote/Blockquote.js +1 -1
  14. package/dist/components/bottom-navigation/BottomNavigation.js +1 -1
  15. package/dist/components/box/Box.js +1 -1
  16. package/dist/components/breadcrumb/Breadcrumb.js +1 -1
  17. package/dist/components/button/Button.js +1 -1
  18. package/dist/components/button-group/ButtonGroup.js +1 -1
  19. package/dist/components/calendar/Calendar.d.ts +72 -0
  20. package/dist/components/calendar/Calendar.js +1 -0
  21. package/dist/components/calendar/index.d.ts +2 -0
  22. package/dist/components/calendar/index.js +1 -0
  23. package/dist/components/card/Card.js +1 -1
  24. package/dist/components/carousel/Carousel.js +1 -1
  25. package/dist/components/chat-bubble/ChatBubble.js +1 -1
  26. package/dist/components/checkbox/Checkbox.d.ts +13 -1
  27. package/dist/components/checkbox/Checkbox.js +1 -1
  28. package/dist/components/chip/Chip.js +1 -1
  29. package/dist/components/code-block/CodeBlock.js +1 -1
  30. package/dist/components/collapsible/Collapsible.js +1 -1
  31. package/dist/components/color-picker/ColorPicker.js +1 -1
  32. package/dist/components/combobox/Combobox.d.ts +29 -2
  33. package/dist/components/combobox/Combobox.js +1 -1
  34. package/dist/components/command-palette/CommandPalette.d.ts +19 -2
  35. package/dist/components/command-palette/CommandPalette.js +1 -1
  36. package/dist/components/confirm/Confirm.d.ts +83 -0
  37. package/dist/components/confirm/Confirm.js +1 -0
  38. package/dist/components/confirm/index.d.ts +2 -0
  39. package/dist/components/confirm/index.js +1 -0
  40. package/dist/components/container/Container.js +1 -1
  41. package/dist/components/data-list/DataList.js +1 -1
  42. package/dist/components/data-table/DataTable.d.ts +104 -1
  43. package/dist/components/data-table/DataTable.js +1 -1
  44. package/dist/components/date-picker/DatePicker.d.ts +40 -8
  45. package/dist/components/date-picker/DatePicker.js +1 -1
  46. package/dist/components/date-range-picker/DateRangePicker.js +1 -1
  47. package/dist/components/date-time-picker/DateTimePicker.js +1 -1
  48. package/dist/components/dialog/Dialog.d.ts +19 -2
  49. package/dist/components/dialog/Dialog.js +1 -1
  50. package/dist/components/divider/Divider.js +1 -1
  51. package/dist/components/drawer/Drawer.d.ts +1 -1
  52. package/dist/components/drawer/Drawer.js +1 -1
  53. package/dist/components/empty/Empty.js +1 -1
  54. package/dist/components/file-picker/FilePicker.js +1 -1
  55. package/dist/components/floating-action-button/FloatingActionButton.js +1 -1
  56. package/dist/components/floating-bottom-navigation/FloatingBottomNavigation.js +1 -1
  57. package/dist/components/footer/Footer.js +1 -1
  58. package/dist/components/gauge-chart/GaugeChart.d.ts +1 -1
  59. package/dist/components/gauge-chart/GaugeChart.js +1 -1
  60. package/dist/components/grid-container/GridContainer.js +1 -1
  61. package/dist/components/header/Header.js +1 -1
  62. package/dist/components/heatmap-chart/HeatmapChart.d.ts +1 -1
  63. package/dist/components/heatmap-chart/HeatmapChart.js +1 -1
  64. package/dist/components/highlight/Highlight.js +1 -1
  65. package/dist/components/hover-card/HoverCard.d.ts +1 -1
  66. package/dist/components/hover-card/HoverCard.js +1 -1
  67. package/dist/components/how-to-steps/HowToSteps.js +1 -1
  68. package/dist/components/image/Image.d.ts +70 -0
  69. package/dist/components/image/Image.js +1 -0
  70. package/dist/components/image/index.d.ts +2 -0
  71. package/dist/components/image/index.js +1 -0
  72. package/dist/components/list/List.js +1 -1
  73. package/dist/components/menubar/Menubar.js +1 -1
  74. package/dist/components/meter/Meter.js +1 -1
  75. package/dist/components/mockup/Mockup.js +1 -1
  76. package/dist/components/number-field/NumberField.d.ts +27 -2
  77. package/dist/components/number-field/NumberField.js +1 -1
  78. package/dist/components/otp-field/OtpField.js +1 -1
  79. package/dist/components/overlay/Overlay.d.ts +1 -1
  80. package/dist/components/overlay/Overlay.js +1 -1
  81. package/dist/components/page-layout/PageLayout.js +1 -1
  82. package/dist/components/pagination/Pagination.js +1 -1
  83. package/dist/components/panes/Panes.js +1 -1
  84. package/dist/components/pie-chart/PieChart.d.ts +1 -1
  85. package/dist/components/pie-chart/PieChart.js +1 -1
  86. package/dist/components/pill/Pill.js +1 -1
  87. package/dist/components/popconfirm/Popconfirm.d.ts +71 -0
  88. package/dist/components/popconfirm/Popconfirm.js +1 -0
  89. package/dist/components/popconfirm/index.d.ts +2 -0
  90. package/dist/components/popconfirm/index.js +1 -0
  91. package/dist/components/popover/Popover.d.ts +1 -1
  92. package/dist/components/popover/Popover.js +1 -1
  93. package/dist/components/portal/Portal.d.ts +48 -0
  94. package/dist/components/portal/Portal.js +1 -0
  95. package/dist/components/portal/index.d.ts +2 -0
  96. package/dist/components/portal/index.js +1 -0
  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/provider/NebaProvider.d.ts +99 -0
  101. package/dist/components/provider/NebaProvider.js +1 -0
  102. package/dist/components/provider/index.d.ts +3 -0
  103. package/dist/components/provider/index.js +1 -0
  104. package/dist/components/radio-group/RadioGroup.d.ts +22 -1
  105. package/dist/components/radio-group/RadioGroup.js +1 -1
  106. package/dist/components/rating/Rating.js +1 -1
  107. package/dist/components/scatter-chart/ScatterChart.d.ts +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/select/Select.d.ts +16 -1
  112. package/dist/components/select/Select.js +1 -1
  113. package/dist/components/shortcut/Shortcut.d.ts +2 -1
  114. package/dist/components/shortcut/Shortcut.js +1 -1
  115. package/dist/components/sidebar/Sidebar.js +1 -1
  116. package/dist/components/sidebar/SidebarTrigger.js +1 -1
  117. package/dist/components/skeleton/Skeleton.js +1 -1
  118. package/dist/components/slider/Slider.js +1 -1
  119. package/dist/components/sparkline/Sparkline.js +1 -1
  120. package/dist/components/spoiler/Spoiler.js +1 -1
  121. package/dist/components/statistic/Statistic.js +1 -1
  122. package/dist/components/switch/Switch.d.ts +13 -1
  123. package/dist/components/switch/Switch.js +1 -1
  124. package/dist/components/table/Table.d.ts +21 -2
  125. package/dist/components/table/Table.js +1 -1
  126. package/dist/components/text-field/TextField.d.ts +27 -1
  127. package/dist/components/text-field/TextField.js +1 -1
  128. package/dist/components/text-link/TextLink.js +1 -1
  129. package/dist/components/time-picker/TimePicker.js +1 -1
  130. package/dist/components/timeline-chart/TimelineChart.d.ts +1 -1
  131. package/dist/components/timeline-chart/TimelineChart.js +1 -1
  132. package/dist/components/toast/Toast.d.ts +17 -2
  133. package/dist/components/toast/Toast.js +1 -1
  134. package/dist/components/toggle/Toggle.js +1 -1
  135. package/dist/components/toggle-group/ToggleGroup.js +1 -1
  136. package/dist/components/toolbar/Toolbar.js +1 -1
  137. package/dist/components/tooltip/Tooltip.d.ts +1 -1
  138. package/dist/components/tooltip/Tooltip.js +1 -1
  139. package/dist/components/tour/Tour.d.ts +17 -2
  140. package/dist/components/tour/Tour.js +1 -1
  141. package/dist/components/transfer/Transfer.js +1 -1
  142. package/dist/components/tree-select/TreeSelect.d.ts +88 -0
  143. package/dist/components/tree-select/TreeSelect.js +1 -0
  144. package/dist/components/tree-select/index.d.ts +2 -0
  145. package/dist/components/tree-select/index.js +1 -0
  146. package/dist/components/tree-view/TreeView.js +1 -1
  147. package/dist/components/visually-hidden/VisuallyHidden.d.ts +37 -0
  148. package/dist/components/visually-hidden/VisuallyHidden.js +1 -0
  149. package/dist/components/visually-hidden/index.d.ts +2 -0
  150. package/dist/components/visually-hidden/index.js +1 -0
  151. package/dist/components/window-pane/WindowPane.js +1 -1
  152. package/dist/hooks/index.d.ts +10 -0
  153. package/dist/hooks/index.js +1 -0
  154. package/dist/hooks/useDisclosure.d.ts +21 -0
  155. package/dist/hooks/useDisclosure.js +1 -0
  156. package/dist/hooks/useElementSize.d.ts +23 -0
  157. package/dist/hooks/useElementSize.js +1 -0
  158. package/dist/hooks/useMediaQuery.d.ts +27 -0
  159. package/dist/hooks/useMediaQuery.js +1 -0
  160. package/dist/hooks/useOnScreen.d.ts +24 -0
  161. package/dist/hooks/useOnScreen.js +1 -0
  162. package/dist/hooks/useShortcut.d.ts +34 -0
  163. package/dist/hooks/useShortcut.js +1 -0
  164. package/dist/index.d.ts +9 -0
  165. package/dist/index.js +1 -1
  166. package/dist/internal/calendar.d.ts +31 -5
  167. package/dist/internal/calendar.js +1 -1
  168. package/dist/internal/csv.d.ts +40 -0
  169. package/dist/internal/csv.js +1 -0
  170. package/dist/internal/date.d.ts +39 -1
  171. package/dist/internal/date.js +1 -1
  172. package/dist/internal/defaults.d.ts +46 -0
  173. package/dist/internal/defaults.js +1 -0
  174. package/dist/internal/i18n.d.ts +23 -0
  175. package/dist/internal/i18n.js +1 -1
  176. package/dist/internal/keys.d.ts +92 -0
  177. package/dist/internal/keys.js +1 -0
  178. package/dist/internal/media.d.ts +27 -0
  179. package/dist/internal/media.js +1 -1
  180. package/dist/internal/page-layout.d.ts +7 -0
  181. package/dist/internal/page-layout.js +1 -1
  182. package/dist/internal/picker.d.ts +7 -1
  183. package/dist/internal/picker.js +1 -1
  184. package/dist/locales/ar.js +1 -1
  185. package/dist/locales/de.js +1 -1
  186. package/dist/locales/es.js +1 -1
  187. package/dist/locales/fr.js +1 -1
  188. package/dist/locales/hi.js +1 -1
  189. package/dist/locales/id.js +1 -1
  190. package/dist/locales/it.js +1 -1
  191. package/dist/locales/ja.js +1 -1
  192. package/dist/locales/ko.js +1 -1
  193. package/dist/locales/nl.js +1 -1
  194. package/dist/locales/pl.js +1 -1
  195. package/dist/locales/pt.js +1 -1
  196. package/dist/locales/ru.js +1 -1
  197. package/dist/locales/th.js +1 -1
  198. package/dist/locales/tr.js +1 -1
  199. package/dist/locales/vi.js +1 -1
  200. package/dist/locales/zh-hans.js +1 -1
  201. package/dist/locales/zh-hant.js +1 -1
  202. package/dist/styles.css +1 -1
  203. package/dist/types.d.ts +73 -0
  204. package/package.json +6 -1
@@ -0,0 +1,37 @@
1
+ import * as React from 'react';
2
+ import { useRender } from '@base-ui/react/use-render';
3
+ export interface VisuallyHiddenProps extends React.ComponentPropsWithoutRef<'span'> {
4
+ /**
5
+ * Take the hiding off, so the content is drawn like anything else.
6
+ *
7
+ * This is what a skip link needs: hidden until it has the focus, and then a
8
+ * real control the reader can see themselves press. `focus-visible:` cannot
9
+ * express it, because the element has to *leave* the 1px box entirely.
10
+ * @default false
11
+ */
12
+ visible?: boolean;
13
+ /** Render as something else — a `<div>`, a `<label>`, an element of your own. */
14
+ render?: useRender.RenderProp;
15
+ }
16
+ /**
17
+ * Content that is in the accessibility tree and not on the screen.
18
+ *
19
+ * The library has needed this everywhere from the beginning and kept it to
20
+ * itself: the word "Remove" behind a Chip's ×, the count behind a Badge's dot,
21
+ * the page number under a Pagination chevron, the table a chart draws for a
22
+ * screen reader instead of a picture. This is the same 1px clipped box, offered
23
+ * so an application's own markup can say the same things.
24
+ *
25
+ * The form matters and there is only one that works. `hidden` and
26
+ * `display: none` take the text off the accessibility tree along with the
27
+ * screen, which is the opposite of the job. `opacity: 0` leaves a clickable
28
+ * ghost the size of the words, and a pointer finds it. `text-indent: -9999px`
29
+ * makes a box that wide and a horizontal scrollbar with it. A 1px box with its
30
+ * contents clipped is invisible to a sighted reader and present to every other
31
+ * kind, and it is what every serious implementation converged on.
32
+ *
33
+ * There is no `aria-hidden` here, deliberately: that is the *other* half of the
34
+ * pair — visible and not announced — and it is an attribute rather than a
35
+ * component because it belongs on the element that is already being drawn.
36
+ */
37
+ export declare const VisuallyHidden: React.ForwardRefExoticComponent<VisuallyHiddenProps & React.RefAttributes<HTMLSpanElement>>;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as r}from"react/jsx-runtime";import*as e from"react";import{useRender as s}from"@base-ui/react/use-render";import{cx as t,srOnlyClasses as a}from"../../internal/styles.js";export const VisuallyHidden=/*@__PURE__*/e.forwardRef(function({visible:e=!1,render:i,className:o,...n},m){return s({render:i??r("span",{}),ref:m,props:{...n,className:t(e?void 0:a,o)}})});
@@ -0,0 +1,2 @@
1
+ export { VisuallyHidden } from './VisuallyHidden.js';
2
+ export type { VisuallyHiddenProps } from './VisuallyHidden.js';
@@ -0,0 +1 @@
1
+ export{VisuallyHidden}from"./VisuallyHidden.js";
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import*as i from"react";import{useRender as o}from"@base-ui/react/use-render";import{beginPointerDrag as r}from"../../internal/drag.js";import{actionMessages as a,useMessages as s,windowMessages as l}from"../../internal/i18n.js";import{cx as d,hasContent as c,iconClasses as u,surfaceClasses as m}from"../../internal/styles.js";import{WindowControls as h,orderControls as f,windowChrome as w,windowMetrics as g,windowSlots as p}from"../../internal/window.js";function b(e,t,n){const[o,r]=i.useState(t),a=void 0!==e;return[a?e:o,i.useCallback(e=>{a||r(e),n?.(e)},[a,n])]}const v=[{edge:"n",className:"inset-x-3 top-0 h-1.5 cursor-ns-resize"},{edge:"s",className:"inset-x-3 bottom-0 h-1.5 cursor-ns-resize"},{edge:"w",className:"inset-y-3 left-0 w-1.5 cursor-ew-resize"},{edge:"e",className:"inset-y-3 right-0 w-1.5 cursor-ew-resize"},{edge:"nw",className:"top-0 left-0 size-3 cursor-nwse-resize"},{edge:"ne",className:"top-0 right-0 size-3 cursor-nesw-resize"},{edge:"sw",className:"bottom-0 left-0 size-3 cursor-nesw-resize"},{edge:"se",className:"right-0 bottom-0 size-3 cursor-nwse-resize"}];export const WindowPane=/*@__PURE__*/i.forwardRef(function({os:x="macos",title:z,icon:y,actions:N,controls:M=!0,size:C="md",color:E="primary",accent:S=!1,transparency:k=0,active:L,elevation:I=2,position:R="static",draggable:j=!1,resizable:B=!1,width:D,height:A,minWidth:T=180,minHeight:H,offset:P,defaultOffset:W,onOffsetChange:O,onResize:X,open:$,defaultOpen:F=!0,onOpenChange:Y,minimized:_,defaultMinimized:q=!1,onMinimizedChange:K,maximized:U,defaultMaximized:G=!1,onMaximizedChange:J,scroll:Q=!0,locale:V,minimizeLabel:Z,maximizeLabel:ee,restoreLabel:te,closeLabel:ne,resizeLabel:ie,render:oe,className:re,style:ae,children:se,...le},de){const ce=s(l,V),ue=s(a,V),me=w(x),he=g(x,C),fe=i.useId(),[we,ge]=b($,F,Y),[pe,be]=b(_,q,K),[ve,xe]=b(U,G,J),[ze,ye]=b(P,W??{x:0,y:0},O),[Ne,Me]=i.useState(null),[Ce,Ee]=i.useState(!0),Se=L??Ce,[ke,Le]=i.useState(null),[Ie,Re]=i.useState(null),[je,Be]=i.useState(!1),[De,Ae]=i.useState(!1),[Te,He]=i.useState(we);Te!==we&&(He(we),Ae(!we)),i.useEffect(()=>{if(!De)return;const e=window.setTimeout(()=>Ae(!1),260);return()=>window.clearTimeout(e)},[De]);const Pe=i.useRef(null),We=i.useCallback(e=>{Pe.current=e,"function"==typeof de?de(e):de&&(de.current=e)},[de]);i.useEffect(()=>{if(void 0!==L)return;const e=Pe.current;if(!e)return;const t=t=>{const n=t.target;if(!(n instanceof Node))return;if(e.contains(n))return void Ee(!0);const i=n instanceof Element?n:n.parentElement;i?.closest(".neba-window")&&Ee(!1)};return document.addEventListener("pointerdown",t,!0),document.addEventListener("focusin",t,!0),()=>{document.removeEventListener("pointerdown",t,!0),document.removeEventListener("focusin",t,!0)}},[L]);const Oe=i.useRef(null);function Xe(e,t){if(0!==e.button)return;Oe.current?.();const n=e.currentTarget,i=e.clientX,o=e.clientY;Be(!0);const a=()=>{Oe.current=null,Be(!1)},s=r({target:n,pointerId:e.pointerId,onMove:e=>t(e.clientX-i,e.clientY-o),onEnd:a});Oe.current=()=>{s(),a()}}i.useEffect(()=>()=>Oe.current?.(),[]);const $e={width:Math.max(0,T),height:Math.max(he.bar,H??he.bar)};function Fe(e){Me(e),X?.(e)}const Ye=f(x,!0===M?["minimize","maximize","close"]:!1===M?[]:M),_e=Ye.includes("maximize");i.useEffect(()=>{if(pe||null===Ie)return;const e=window.setTimeout(()=>Re(null),400);return()=>window.clearTimeout(e)},[pe,Ie]);const qe={minimize:Z??ce.minimize,maximize:ee??ce.maximize,restore:te??ce.restore,close:ne??ue.close},Ke=e(h,{os:x,metrics:he,controls:Ye,maximized:ve,active:Se,labels:qe,onCommand:function(e){"close"===e?ge(!1):"minimize"===e?function(e){const t=Pe.current,n=t?.firstElementChild;if(t&&n instanceof HTMLElement&&Le(n.offsetHeight+(t.offsetHeight-t.clientHeight)),e&&void 0===(Ne?.height??A)&&t)return Re(t.getBoundingClientRect().height),void requestAnimationFrame(()=>be(!0));be(e)}(!pe):xe(!ve)}}),Ue=c(z)?e("span",{id:fe,className:"min-w-0 truncate",children:z}):null,Ge=c(y)?e("span",{className:"flex shrink-0 items-center",children:y}):null,Je=t("div",{className:d("relative flex shrink-0 items-center select-none",u,j&&!ve?"cursor-grab active:cursor-grabbing":""),style:{height:he.bar,textShadow:"var(--n-window-bar-shadow)",fontWeight:he.weight,paddingInlineStart:he.padX,paddingInlineEnd:he.padEnd,gap:Math.round(.7*he.title),fontSize:he.title,backgroundColor:"var(--n-window-bar)",backgroundImage:"var(--n-window-bar-image)",color:"var(--n-window-bar-fg)",borderBlockEnd:me.rule?"1px solid var(--n-window-line)":void 0},onPointerDown:function(e){if(!j||ve)return;const t={...ze};Xe(e,(e,n)=>ye({x:t.x+e,y:t.y+n}))},onDoubleClick:_e?()=>xe(!ve):void 0,children:["start"===me.controlsSide?Ke:null,"center"===me.titleAlign?e("span",{"aria-hidden":"true",className:"pointer-events-none absolute inset-x-0 flex items-center justify-center",style:{paddingInline:he.controlsWidth(Ye.length)+2*he.padX},children:t("span",{className:"flex min-w-0 items-center",style:{gap:Math.round(.5*he.title)},children:[Ge,Ue]})}):t(n,{children:[Ge,Ue]}),e("span",{className:"flex-1"}),c(N)?e("span",{className:"flex shrink-0 items-center",style:{gap:Math.round(.5*he.title)},onPointerDown:e=>e.stopPropagation(),children:N}):null,"end"===me.controlsSide?Ke:null]}),Qe=ve?{left:0,top:0,width:"100%",height:"100%"}:{left:ze.x,top:ze.y,width:Ne?.width??D,height:pe?ke??he.bar:Ne?.height??A??Ie??void 0},Ve=o({render:oe,ref:We,props:{role:"group","aria-labelledby":Ue?fe:void 0,className:d("neba-window relative flex min-w-0 flex-col overflow-hidden",k>0?m:"",me.glass&&0===k?"[backdrop-filter:var(--neba-blur)]":"","[transition-property:left,top,width,height,opacity,box-shadow,background-color,border-color,border-radius]","[transition-duration:var(--neba-duration-window)]","[transition-timing-function:var(--neba-ease)]","motion-reduce:[transition-duration:0ms]","data-[gesture]:[transition-property:none]",re),"data-gesture":je?"":void 0,inert:!we||void 0,style:{opacity:we?void 0:0,...p({os:x,color:E,accent:S,transparency:k,active:Se,elevation:I}),position:"static"===R?"relative":R,...Qe,borderRadius:ve?0:`${he.radius}px ${he.radius}px ${he.radiusBottom}px ${he.radiusBottom}px`,borderStyle:"solid",borderWidth:he.frame,borderColor:"var(--n-window-line)",backgroundColor:"var(--n-window-band)",boxShadow:"var(--n-window-shadow), var(--neba-plate-glass)",...ae},children:t(n,{children:[Je,e("div",{className:d("min-h-0 flex-1",Q?"overflow-auto":"overflow-hidden"),style:{backgroundColor:"var(--n-window-body)",marginInline:he.band.side,marginBottom:he.band.bottom,boxShadow:he.band.side>0?"inset 0 0 0 1px rgb(0 0 0 / 0.12)":void 0},inert:pe,children:se}),!B||ve||pe?null:v.map(t=>{const n="se"===t.edge;return e("div",{role:n?"button":void 0,tabIndex:n?0:void 0,"aria-label":n?ie??ce.resize:void 0,"aria-hidden":n?void 0:"true",className:d("absolute z-10 touch-none",t.className,n?"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:[outline-offset:-2px]":""),onPointerDown:e=>function(e,t){const n=Pe.current;if(!n||ve)return;const i=n.getBoundingClientRect(),o={width:i.width,height:i.height,x:ze.x,y:ze.y},r=e.includes("e"),a=e.includes("w"),s=e.includes("n"),l=e.includes("s");Xe(t,(e,t)=>{let{width:n,height:i}=o,{x:d,y:c}=o;r&&(n=Math.max($e.width,o.width+e)),l&&(i=Math.max($e.height,o.height+t)),a&&(n=Math.max($e.width,o.width-e),d=o.x+(o.width-n)),s&&(i=Math.max($e.height,o.height-t),c=o.y+(o.height-i)),Fe({width:n,height:i}),(a||s)&&ye({x:d,y:c})})}(t.edge,e),onKeyDown:n?e=>{const t={ArrowRight:[16,0],ArrowLeft:[-16,0],ArrowDown:[0,16],ArrowUp:[0,-16]}[e.key];t&&(e.preventDefault(),function(e,t){const n=Pe.current;if(!n)return;const i=n.getBoundingClientRect();Fe({width:Math.max($e.width,i.width+e),height:Math.max($e.height,i.height+t)})}(t[0],t[1]))}:void 0},t.edge)})]}),...le}});return we||De?Ve:null});
1
+ "use client";import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import*as i from"react";import{useRender as o}from"@base-ui/react/use-render";import{beginPointerDrag as r}from"../../internal/drag.js";import{actionMessages as a,useMessages as s,windowMessages as l}from"../../internal/i18n.js";import{cx as d,hasContent as c,iconClasses as u,surfaceClasses as m}from"../../internal/styles.js";import{WindowControls as h,orderControls as f,windowChrome as w,windowMetrics as g,windowSlots as p}from"../../internal/window.js";import{useStyleDefaults as b}from"../../internal/defaults.js";function v(e,t,n){const[o,r]=i.useState(t),a=void 0!==e;return[a?e:o,i.useCallback(e=>{a||r(e),n?.(e)},[a,n])]}const x=[{edge:"n",className:"inset-x-3 top-0 h-1.5 cursor-ns-resize"},{edge:"s",className:"inset-x-3 bottom-0 h-1.5 cursor-ns-resize"},{edge:"w",className:"inset-y-3 left-0 w-1.5 cursor-ew-resize"},{edge:"e",className:"inset-y-3 right-0 w-1.5 cursor-ew-resize"},{edge:"nw",className:"top-0 left-0 size-3 cursor-nwse-resize"},{edge:"ne",className:"top-0 right-0 size-3 cursor-nesw-resize"},{edge:"sw",className:"bottom-0 left-0 size-3 cursor-nesw-resize"},{edge:"se",className:"right-0 bottom-0 size-3 cursor-nwse-resize"}];export const WindowPane=/*@__PURE__*/i.forwardRef(function(z,y){const{os:N="macos",title:M,icon:C,actions:E,controls:S=!0,size:k="md",color:L="primary",accent:j=!1,transparency:I=0,active:R,elevation:B=2,position:D="static",draggable:A=!1,resizable:T=!1,width:H,height:P,minWidth:W=180,minHeight:O,offset:X,defaultOffset:$,onOffsetChange:F,onResize:Y,open:_,defaultOpen:q=!0,onOpenChange:K,minimized:U,defaultMinimized:G=!1,onMinimizedChange:J,maximized:Q,defaultMaximized:V=!1,onMaximizedChange:Z,scroll:ee=!0,locale:te,minimizeLabel:ne,maximizeLabel:ie,restoreLabel:oe,closeLabel:re,resizeLabel:ae,render:se,className:le,style:de,children:ce,...ue}=b(z,["size","locale"]),me=s(l,te),he=s(a,te),fe=w(N),we=g(N,k),ge=i.useId(),[pe,be]=v(_,q,K),[ve,xe]=v(U,G,J),[ze,ye]=v(Q,V,Z),[Ne,Me]=v(X,$??{x:0,y:0},F),[Ce,Ee]=i.useState(null),[Se,ke]=i.useState(!0),Le=R??Se,[je,Ie]=i.useState(null),[Re,Be]=i.useState(null),[De,Ae]=i.useState(!1),[Te,He]=i.useState(!1),[Pe,We]=i.useState(pe);Pe!==pe&&(We(pe),He(!pe)),i.useEffect(()=>{if(!Te)return;const e=window.setTimeout(()=>He(!1),260);return()=>window.clearTimeout(e)},[Te]);const Oe=i.useRef(null),Xe=i.useCallback(e=>{Oe.current=e,"function"==typeof y?y(e):y&&(y.current=e)},[y]);i.useEffect(()=>{if(void 0!==R)return;const e=Oe.current;if(!e)return;const t=t=>{const n=t.target;if(!(n instanceof Node))return;if(e.contains(n))return void ke(!0);const i=n instanceof Element?n:n.parentElement;i?.closest(".neba-window")&&ke(!1)};return document.addEventListener("pointerdown",t,!0),document.addEventListener("focusin",t,!0),()=>{document.removeEventListener("pointerdown",t,!0),document.removeEventListener("focusin",t,!0)}},[R]);const $e=i.useRef(null);function Fe(e,t){if(0!==e.button)return;$e.current?.();const n=e.currentTarget,i=e.clientX,o=e.clientY;Ae(!0);const a=()=>{$e.current=null,Ae(!1)},s=r({target:n,pointerId:e.pointerId,onMove:e=>t(e.clientX-i,e.clientY-o),onEnd:a});$e.current=()=>{s(),a()}}i.useEffect(()=>()=>$e.current?.(),[]);const Ye={width:Math.max(0,W),height:Math.max(we.bar,O??we.bar)};function _e(e){Ee(e),Y?.(e)}const qe=f(N,!0===S?["minimize","maximize","close"]:!1===S?[]:S),Ke=qe.includes("maximize");i.useEffect(()=>{if(ve||null===Re)return;const e=window.setTimeout(()=>Be(null),400);return()=>window.clearTimeout(e)},[ve,Re]);const Ue={minimize:ne??me.minimize,maximize:ie??me.maximize,restore:oe??me.restore,close:re??he.close},Ge=e(h,{os:N,metrics:we,controls:qe,maximized:ze,active:Le,labels:Ue,onCommand:function(e){"close"===e?be(!1):"minimize"===e?function(e){const t=Oe.current,n=t?.firstElementChild;if(t&&n instanceof HTMLElement&&Ie(n.offsetHeight+(t.offsetHeight-t.clientHeight)),e&&void 0===(Ce?.height??P)&&t)return Be(t.getBoundingClientRect().height),void requestAnimationFrame(()=>xe(!0));xe(e)}(!ve):ye(!ze)}}),Je=c(M)?e("span",{id:ge,className:"min-w-0 truncate",children:M}):null,Qe=c(C)?e("span",{className:"flex shrink-0 items-center",children:C}):null,Ve=t("div",{className:d("relative flex shrink-0 items-center select-none",u,A&&!ze?"cursor-grab active:cursor-grabbing":""),style:{height:we.bar,textShadow:"var(--n-window-bar-shadow)",fontWeight:we.weight,paddingInlineStart:we.padX,paddingInlineEnd:we.padEnd,gap:Math.round(.7*we.title),fontSize:we.title,backgroundColor:"var(--n-window-bar)",backgroundImage:"var(--n-window-bar-image)",color:"var(--n-window-bar-fg)",borderBlockEnd:fe.rule?"1px solid var(--n-window-line)":void 0},onPointerDown:function(e){if(!A||ze)return;const t={...Ne};Fe(e,(e,n)=>Me({x:t.x+e,y:t.y+n}))},onDoubleClick:Ke?()=>ye(!ze):void 0,children:["start"===fe.controlsSide?Ge:null,"center"===fe.titleAlign?e("span",{"aria-hidden":"true",className:"pointer-events-none absolute inset-x-0 flex items-center justify-center",style:{paddingInline:we.controlsWidth(qe.length)+2*we.padX},children:t("span",{className:"flex min-w-0 items-center",style:{gap:Math.round(.5*we.title)},children:[Qe,Je]})}):t(n,{children:[Qe,Je]}),e("span",{className:"flex-1"}),c(E)?e("span",{className:"flex shrink-0 items-center",style:{gap:Math.round(.5*we.title)},onPointerDown:e=>e.stopPropagation(),children:E}):null,"end"===fe.controlsSide?Ge:null]}),Ze=ze?{left:0,top:0,width:"100%",height:"100%"}:{left:Ne.x,top:Ne.y,width:Ce?.width??H,height:ve?je??we.bar:Ce?.height??P??Re??void 0},et=o({render:se,ref:Xe,props:{role:"group","aria-labelledby":Je?ge:void 0,className:d("neba-window relative flex min-w-0 flex-col overflow-hidden",I>0?m:"",fe.glass&&0===I?"[backdrop-filter:var(--neba-blur)]":"","[transition-property:left,top,width,height,opacity,box-shadow,background-color,border-color,border-radius]","[transition-duration:var(--neba-duration-window)]","[transition-timing-function:var(--neba-ease)]","motion-reduce:[transition-duration:0ms]","data-[gesture]:[transition-property:none]",le),"data-gesture":De?"":void 0,inert:!pe||void 0,style:{opacity:pe?void 0:0,...p({os:N,color:L,accent:j,transparency:I,active:Le,elevation:B}),position:"static"===D?"relative":D,...Ze,borderRadius:ze?0:`${we.radius}px ${we.radius}px ${we.radiusBottom}px ${we.radiusBottom}px`,borderStyle:"solid",borderWidth:we.frame,borderColor:"var(--n-window-line)",backgroundColor:"var(--n-window-band)",boxShadow:"var(--n-window-shadow), var(--neba-plate-glass)",...de},children:t(n,{children:[Ve,e("div",{className:d("min-h-0 flex-1",ee?"overflow-auto":"overflow-hidden"),style:{backgroundColor:"var(--n-window-body)",marginInline:we.band.side,marginBottom:we.band.bottom,boxShadow:we.band.side>0?"inset 0 0 0 1px rgb(0 0 0 / 0.12)":void 0},inert:ve,children:ce}),!T||ze||ve?null:x.map(t=>{const n="se"===t.edge;return e("div",{role:n?"button":void 0,tabIndex:n?0:void 0,"aria-label":n?ae??me.resize:void 0,"aria-hidden":n?void 0:"true",className:d("absolute z-10 touch-none",t.className,n?"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:[outline-offset:-2px]":""),onPointerDown:e=>function(e,t){const n=Oe.current;if(!n||ze)return;const i=n.getBoundingClientRect(),o={width:i.width,height:i.height,x:Ne.x,y:Ne.y},r=e.includes("e"),a=e.includes("w"),s=e.includes("n"),l=e.includes("s");Fe(t,(e,t)=>{let{width:n,height:i}=o,{x:d,y:c}=o;r&&(n=Math.max(Ye.width,o.width+e)),l&&(i=Math.max(Ye.height,o.height+t)),a&&(n=Math.max(Ye.width,o.width-e),d=o.x+(o.width-n)),s&&(i=Math.max(Ye.height,o.height-t),c=o.y+(o.height-i)),_e({width:n,height:i}),(a||s)&&Me({x:d,y:c})})}(t.edge,e),onKeyDown:n?e=>{const t={ArrowRight:[16,0],ArrowLeft:[-16,0],ArrowDown:[0,16],ArrowUp:[0,-16]}[e.key];t&&(e.preventDefault(),function(e,t){const n=Oe.current;if(!n)return;const i=n.getBoundingClientRect();_e({width:Math.max(Ye.width,i.width+e),height:Math.max(Ye.height,i.height+t)})}(t[0],t[1]))}:void 0},t.edge)})]}),...ue}});return pe||Te?et:null});
@@ -0,0 +1,10 @@
1
+ export { useDisclosure } from './useDisclosure.js';
2
+ export type { Disclosure } from './useDisclosure.js';
3
+ export { useElementSize } from './useElementSize.js';
4
+ export type { ElementSize } from './useElementSize.js';
5
+ export { useBreakpoint, useMediaQuery } from './useMediaQuery.js';
6
+ export { useOnScreen } from './useOnScreen.js';
7
+ export type { OnScreenOptions } from './useOnScreen.js';
8
+ export { useShortcut } from './useShortcut.js';
9
+ export type { ShortcutOptions } from './useShortcut.js';
10
+ export { usePrefersReducedMotion } from '../internal/media.js';
@@ -0,0 +1 @@
1
+ export{useDisclosure}from"./useDisclosure.js";export{useElementSize}from"./useElementSize.js";export{useBreakpoint,useMediaQuery}from"./useMediaQuery.js";export{useOnScreen}from"./useOnScreen.js";export{useShortcut}from"./useShortcut.js";export{usePrefersReducedMotion}from"../internal/media.js";
@@ -0,0 +1,21 @@
1
+ /** What `useDisclosure` hands back: the state, and the three ways to change it. */
2
+ export interface Disclosure {
3
+ open: boolean;
4
+ setOpen: (open: boolean) => void;
5
+ onOpen: () => void;
6
+ onClose: () => void;
7
+ onToggle: () => void;
8
+ }
9
+ /**
10
+ * The caller's half of the `open` / `onOpenChange` pair every overlay in the
11
+ * library offers.
12
+ *
13
+ * A Dialog, a Drawer, a Popover, a Tour, a Menu, a CommandPalette and all four
14
+ * pickers take the same three props, so the state beside them is the same six
15
+ * lines every time — and the sixth is the one that gets written wrong: a
16
+ * `setOpen(!open)` closed over a stale render rather than an updater.
17
+ *
18
+ * Every function it returns is stable for the life of the component, so passing
19
+ * `onClose` straight to a memoised child does not re-render it on every open.
20
+ */
21
+ export declare function useDisclosure(defaultOpen?: boolean): Disclosure;
@@ -0,0 +1 @@
1
+ "use client";import*as e from"react";export function useDisclosure(o=!1){const[s,n]=e.useState(o),l=e.useCallback(()=>n(!0),[]),t=e.useCallback(()=>n(!1),[]),u=e.useCallback(()=>n(e=>!e),[]);return e.useMemo(()=>({open:s,setOpen:n,onOpen:l,onClose:t,onToggle:u}),[s,l,t,u])}
@@ -0,0 +1,23 @@
1
+ import * as React from 'react';
2
+ /** A box, in CSS pixels. `0` × `0` before the first measurement and on a server. */
3
+ export interface ElementSize {
4
+ width: number;
5
+ height: number;
6
+ }
7
+ /**
8
+ * One element's size, kept up to date.
9
+ *
10
+ * The same shared `ResizeObserver` eleven components in the library measure
11
+ * themselves with — one observer for the whole page rather than one per
12
+ * subscriber, because a dashboard of eight charts inside a PageLayout with a
13
+ * Panes in it was a dozen registrations the browser walked on every layout.
14
+ *
15
+ * The ref goes on the element to watch. It measures once as soon as that
16
+ * element is there rather than waiting to be told, because a `ResizeObserver`
17
+ * that is missing — an old browser, a server — never says anything at all, and
18
+ * a component sized `0 × 0` forever is worse than one measured once.
19
+ */
20
+ export declare function useElementSize<E extends Element = HTMLElement>(): [
21
+ React.RefObject<E | null>,
22
+ ElementSize
23
+ ];
@@ -0,0 +1 @@
1
+ "use client";import*as t from"react";import{observeResize as e}from"../internal/observe.js";export function useElementSize(){const i=t.useRef(null),[n,r]=t.useState({width:0,height:0});return t.useLayoutEffect(()=>{const t=i.current;if(!t)return;const n=()=>{const e=t.getBoundingClientRect();r(t=>t.width===e.width&&t.height===e.height?t:{width:e.width,height:e.height})};return n(),e(t,n)},[]),[i,n]}
@@ -0,0 +1,27 @@
1
+ import type { NebaBreakpoint } from '../types.js';
2
+ /**
3
+ * One media query, as a boolean this component re-renders on.
4
+ *
5
+ * The same store the library's own layout runs on, which is the reason it is
6
+ * offered rather than left to be written again: a `MediaQueryList` is live, so
7
+ * there is exactly one per query string for the whole page no matter how many
8
+ * components ask. Written the obvious way — `window.matchMedia` inside a
9
+ * `getSnapshot` — every subscriber builds a fresh one on every render *and*
10
+ * every commit, and a PageLayout with a Header, a Footer and two Sidebars in it
11
+ * asks the same question five times per render.
12
+ *
13
+ * It answers `false` on a server, where there is no window and no honest answer.
14
+ * A layout that must not flash is a layout stated in CSS; this is for the
15
+ * decisions CSS cannot make — which component to render at all.
16
+ */
17
+ export declare function useMediaQuery(query: string): boolean;
18
+ /**
19
+ * The same question in the units the rest of the library uses: is the window at
20
+ * least this wide?
21
+ *
22
+ * `useBreakpoint('md')` is `md:` in a class name, in JavaScript — the widths are
23
+ * one table, so a component that branches here and a utility that branches in
24
+ * CSS change at the same pixel. `xs` is `0rem` and therefore always true, which
25
+ * is the value with no media query around it.
26
+ */
27
+ export declare function useBreakpoint(breakpoint: NebaBreakpoint): boolean;
@@ -0,0 +1 @@
1
+ "use client";import{useMediaQuery as e,widthAtLeast as r}from"../internal/media.js";export function useMediaQuery(r){return e(r)}export function useBreakpoint(n){return e(r(n))}
@@ -0,0 +1,24 @@
1
+ import * as React from 'react';
2
+ export interface OnScreenOptions {
3
+ /** How much of the element has to be showing. @default 0 */
4
+ threshold?: number;
5
+ /**
6
+ * Stop watching once it has been seen. The right default for the thing this
7
+ * is usually for — mounting something, starting something, loading
8
+ * something — where the answer only has to arrive once.
9
+ * @default true
10
+ */
11
+ once?: boolean;
12
+ }
13
+ /**
14
+ * Whether an element is on screen.
15
+ *
16
+ * The same shared `IntersectionObserver` the eleven `Animate*` wrappers watch
17
+ * for their own element with — one per threshold for the whole page, because a
18
+ * page of them was one registration each.
19
+ *
20
+ * It answers `true` where there is no `IntersectionObserver` rather than
21
+ * `false`, and that is the load-bearing part: a caller cannot know without one,
22
+ * and the right fallback is to show the thing rather than to hide it forever.
23
+ */
24
+ export declare function useOnScreen<E extends Element = HTMLElement>(options?: OnScreenOptions): [React.RefObject<E | null>, boolean];
@@ -0,0 +1 @@
1
+ "use client";import*as e from"react";import{observeVisibility as r}from"../internal/observe.js";export function useOnScreen(t={}){const{threshold:n=0,once:o=!0}=t,s=e.useRef(null),[u,c]=e.useState(!1);return e.useEffect(()=>{const e=s.current;if(!e)return;const t=r(e,n,e=>{c(e),e&&o&&t?.()});if(t)return t;c(!0)},[n,o]),[s,u]}
@@ -0,0 +1,34 @@
1
+ export interface ShortcutOptions {
2
+ /** Stop listening without unmounting — a modal is open, a field has focus. @default true */
3
+ enabled?: boolean;
4
+ /**
5
+ * Ignore the key while the reader is typing into an input, a textarea or
6
+ * anything `contenteditable`.
7
+ *
8
+ * On by default, and it is the reason a bare `/` or `?` can be bound at all:
9
+ * a page-wide single-letter shortcut that fires inside a search box is a
10
+ * shortcut that eats what somebody was writing. A combination with a modifier
11
+ * is usually meant to work everywhere, so turn this off for those.
12
+ * @default true
13
+ */
14
+ ignoreWhileTyping?: boolean;
15
+ /**
16
+ * Call `preventDefault` when it matches — for a key the browser also has an
17
+ * opinion about, like `Mod+K` or `Mod+S`. @default true
18
+ */
19
+ preventDefault?: boolean;
20
+ }
21
+ /**
22
+ * A key combination bound on the window, spelled the way
23
+ * [Shortcut](../components/shortcut) draws it — `'Mod+K'`, `'Mod+Shift+P'`,
24
+ * `'?'`.
25
+ *
26
+ * This is what `CommandPalette` binds its own opener with, offered because an
27
+ * application has more shortcuts than the library does and every one of them
28
+ * should be spelled the way its key cap is. `Mod` is Command on a Mac and
29
+ * Control everywhere else; the modifiers are matched exactly.
30
+ *
31
+ * The handler is held in a ref, so a listener is bound once per combination
32
+ * rather than re-bound on every render that closes over new state.
33
+ */
34
+ export declare function useShortcut(shortcut: string | false, handler: (event: KeyboardEvent) => void, options?: ShortcutOptions): void;
@@ -0,0 +1 @@
1
+ "use client";import*as e from"react";import{matchesShortcut as t}from"../internal/keys.js";export function useShortcut(n,r,a={}){const{enabled:o=!0,ignoreWhileTyping:i=!0,preventDefault:s=!0}=a,u=e.useRef(r);e.useEffect(()=>{u.current=r}),e.useEffect(()=>{if(!1===n||!o)return;const e=e=>{var r;i&&(r=e.target,r instanceof HTMLElement&&(r.isContentEditable||"INPUT"===r.tagName||"TEXTAREA"===r.tagName||"SELECT"===r.tagName))||t(e,n)&&(s&&e.preventDefault(),u.current(e))};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[n,o,i,s])}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './types.js';
2
+ export * from './hooks/index.js';
2
3
  export * from './components/accordion/index.js';
3
4
  export * from './components/alert/index.js';
4
5
  export * from './components/anchor/index.js';
@@ -26,6 +27,7 @@ export * from './components/box/index.js';
26
27
  export * from './components/breadcrumb/index.js';
27
28
  export * from './components/button/index.js';
28
29
  export * from './components/button-group/index.js';
30
+ export * from './components/calendar/index.js';
29
31
  export * from './components/card/index.js';
30
32
  export * from './components/carousel/index.js';
31
33
  export * from './components/chat-bubble/index.js';
@@ -36,6 +38,7 @@ export * from './components/collapsible/index.js';
36
38
  export * from './components/color-picker/index.js';
37
39
  export * from './components/combobox/index.js';
38
40
  export * from './components/command-palette/index.js';
41
+ export * from './components/confirm/index.js';
39
42
  export * from './components/container/index.js';
40
43
  export * from './components/data-list/index.js';
41
44
  export * from './components/data-table/index.js';
@@ -62,6 +65,7 @@ export * from './components/hover-card/index.js';
62
65
  export * from './components/how-to-steps/index.js';
63
66
  export * from './components/icon/index.js';
64
67
  export * from './components/icon-button/index.js';
68
+ export * from './components/image/index.js';
65
69
  export * from './components/line-chart/index.js';
66
70
  export * from './components/list/index.js';
67
71
  export * from './components/menu/index.js';
@@ -77,10 +81,13 @@ export * from './components/pagination/index.js';
77
81
  export * from './components/panes/index.js';
78
82
  export * from './components/pie-chart/index.js';
79
83
  export * from './components/pill/index.js';
84
+ export * from './components/popconfirm/index.js';
80
85
  export * from './components/popover/index.js';
86
+ export * from './components/portal/index.js';
81
87
  export * from './components/progress-box/index.js';
82
88
  export * from './components/progress-circular/index.js';
83
89
  export * from './components/progress-linear/index.js';
90
+ export * from './components/provider/index.js';
84
91
  export * from './components/radio-group/index.js';
85
92
  export * from './components/rating/index.js';
86
93
  export * from './components/scatter-chart/index.js';
@@ -110,6 +117,8 @@ export * from './components/toolbar/index.js';
110
117
  export * from './components/tooltip/index.js';
111
118
  export * from './components/tour/index.js';
112
119
  export * from './components/transfer/index.js';
120
+ export * from './components/tree-select/index.js';
113
121
  export * from './components/tree-view/index.js';
114
122
  export * from './components/typography/index.js';
123
+ export * from './components/visually-hidden/index.js';
115
124
  export * from './components/window-pane/index.js';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export*from"./types.js";export*from"./components/accordion/index.js";export*from"./components/alert/index.js";export*from"./components/anchor/index.js";export*from"./components/animate-appear/index.js";export*from"./components/app-logo/index.js";export*from"./components/animate-blink/index.js";export*from"./components/animate-fade/index.js";export*from"./components/animate-grow/index.js";export*from"./components/animate-headline/index.js";export*from"./components/animate-lighting/index.js";export*from"./components/animate-marquee/index.js";export*from"./components/animate-rotate/index.js";export*from"./components/animate-slide/index.js";export*from"./components/animate-typing/index.js";export*from"./components/animate-zoom/index.js";export*from"./components/area-chart/index.js";export*from"./components/aspect-ratio/index.js";export*from"./components/avatar/index.js";export*from"./components/avatar-group/index.js";export*from"./components/badge/index.js";export*from"./components/bar-chart/index.js";export*from"./components/blockquote/index.js";export*from"./components/bottom-navigation/index.js";export*from"./components/box/index.js";export*from"./components/breadcrumb/index.js";export*from"./components/button/index.js";export*from"./components/button-group/index.js";export*from"./components/card/index.js";export*from"./components/carousel/index.js";export*from"./components/chat-bubble/index.js";export*from"./components/checkbox/index.js";export*from"./components/chip/index.js";export*from"./components/code-block/index.js";export*from"./components/collapsible/index.js";export*from"./components/color-picker/index.js";export*from"./components/combobox/index.js";export*from"./components/command-palette/index.js";export*from"./components/container/index.js";export*from"./components/data-list/index.js";export*from"./components/data-table/index.js";export*from"./components/date-picker/index.js";export*from"./components/date-range-picker/index.js";export*from"./components/date-time-picker/index.js";export*from"./components/dialog/index.js";export*from"./components/divider/index.js";export*from"./components/drawer/index.js";export*from"./components/empty/index.js";export*from"./components/fieldset/index.js";export*from"./components/file-picker/index.js";export*from"./components/form/index.js";export*from"./components/gauge-chart/index.js";export*from"./components/grid/index.js";export*from"./components/floating-action-button/index.js";export*from"./components/floating-bottom-navigation/index.js";export*from"./components/footer/index.js";export*from"./components/grid-container/index.js";export*from"./components/header/index.js";export*from"./components/heatmap-chart/index.js";export*from"./components/highlight/index.js";export*from"./components/hover-card/index.js";export*from"./components/how-to-steps/index.js";export*from"./components/icon/index.js";export*from"./components/icon-button/index.js";export*from"./components/line-chart/index.js";export*from"./components/list/index.js";export*from"./components/menu/index.js";export*from"./components/menubar/index.js";export*from"./components/meter/index.js";export*from"./components/mockup/index.js";export*from"./components/navigation-menu/index.js";export*from"./components/number-field/index.js";export*from"./components/otp-field/index.js";export*from"./components/overlay/index.js";export*from"./components/page-layout/index.js";export*from"./components/pagination/index.js";export*from"./components/panes/index.js";export*from"./components/pie-chart/index.js";export*from"./components/pill/index.js";export*from"./components/popover/index.js";export*from"./components/progress-box/index.js";export*from"./components/progress-circular/index.js";export*from"./components/progress-linear/index.js";export*from"./components/radio-group/index.js";export*from"./components/rating/index.js";export*from"./components/scatter-chart/index.js";export*from"./components/scroll-area/index.js";export*from"./components/scroll-zone/index.js";export*from"./components/segmented-button/index.js";export*from"./components/select/index.js";export*from"./components/shortcut/index.js";export*from"./components/sidebar/index.js";export*from"./components/skeleton/index.js";export*from"./components/slider/index.js";export*from"./components/sparkline/index.js";export*from"./components/spoiler/index.js";export*from"./components/statistic/index.js";export*from"./components/switch/index.js";export*from"./components/table/index.js";export*from"./components/tabs/index.js";export*from"./components/text-field/index.js";export*from"./components/text-link/index.js";export*from"./components/time-picker/index.js";export*from"./components/timeline/index.js";export*from"./components/timeline-chart/index.js";export*from"./components/toast/index.js";export*from"./components/toggle/index.js";export*from"./components/toggle-group/index.js";export*from"./components/toolbar/index.js";export*from"./components/tooltip/index.js";export*from"./components/tour/index.js";export*from"./components/transfer/index.js";export*from"./components/tree-view/index.js";export*from"./components/typography/index.js";export*from"./components/window-pane/index.js";
1
+ export*from"./types.js";export*from"./hooks/index.js";export*from"./components/accordion/index.js";export*from"./components/alert/index.js";export*from"./components/anchor/index.js";export*from"./components/animate-appear/index.js";export*from"./components/app-logo/index.js";export*from"./components/animate-blink/index.js";export*from"./components/animate-fade/index.js";export*from"./components/animate-grow/index.js";export*from"./components/animate-headline/index.js";export*from"./components/animate-lighting/index.js";export*from"./components/animate-marquee/index.js";export*from"./components/animate-rotate/index.js";export*from"./components/animate-slide/index.js";export*from"./components/animate-typing/index.js";export*from"./components/animate-zoom/index.js";export*from"./components/area-chart/index.js";export*from"./components/aspect-ratio/index.js";export*from"./components/avatar/index.js";export*from"./components/avatar-group/index.js";export*from"./components/badge/index.js";export*from"./components/bar-chart/index.js";export*from"./components/blockquote/index.js";export*from"./components/bottom-navigation/index.js";export*from"./components/box/index.js";export*from"./components/breadcrumb/index.js";export*from"./components/button/index.js";export*from"./components/button-group/index.js";export*from"./components/calendar/index.js";export*from"./components/card/index.js";export*from"./components/carousel/index.js";export*from"./components/chat-bubble/index.js";export*from"./components/checkbox/index.js";export*from"./components/chip/index.js";export*from"./components/code-block/index.js";export*from"./components/collapsible/index.js";export*from"./components/color-picker/index.js";export*from"./components/combobox/index.js";export*from"./components/command-palette/index.js";export*from"./components/confirm/index.js";export*from"./components/container/index.js";export*from"./components/data-list/index.js";export*from"./components/data-table/index.js";export*from"./components/date-picker/index.js";export*from"./components/date-range-picker/index.js";export*from"./components/date-time-picker/index.js";export*from"./components/dialog/index.js";export*from"./components/divider/index.js";export*from"./components/drawer/index.js";export*from"./components/empty/index.js";export*from"./components/fieldset/index.js";export*from"./components/file-picker/index.js";export*from"./components/form/index.js";export*from"./components/gauge-chart/index.js";export*from"./components/grid/index.js";export*from"./components/floating-action-button/index.js";export*from"./components/floating-bottom-navigation/index.js";export*from"./components/footer/index.js";export*from"./components/grid-container/index.js";export*from"./components/header/index.js";export*from"./components/heatmap-chart/index.js";export*from"./components/highlight/index.js";export*from"./components/hover-card/index.js";export*from"./components/how-to-steps/index.js";export*from"./components/icon/index.js";export*from"./components/icon-button/index.js";export*from"./components/image/index.js";export*from"./components/line-chart/index.js";export*from"./components/list/index.js";export*from"./components/menu/index.js";export*from"./components/menubar/index.js";export*from"./components/meter/index.js";export*from"./components/mockup/index.js";export*from"./components/navigation-menu/index.js";export*from"./components/number-field/index.js";export*from"./components/otp-field/index.js";export*from"./components/overlay/index.js";export*from"./components/page-layout/index.js";export*from"./components/pagination/index.js";export*from"./components/panes/index.js";export*from"./components/pie-chart/index.js";export*from"./components/pill/index.js";export*from"./components/popconfirm/index.js";export*from"./components/popover/index.js";export*from"./components/portal/index.js";export*from"./components/progress-box/index.js";export*from"./components/progress-circular/index.js";export*from"./components/progress-linear/index.js";export*from"./components/provider/index.js";export*from"./components/radio-group/index.js";export*from"./components/rating/index.js";export*from"./components/scatter-chart/index.js";export*from"./components/scroll-area/index.js";export*from"./components/scroll-zone/index.js";export*from"./components/segmented-button/index.js";export*from"./components/select/index.js";export*from"./components/shortcut/index.js";export*from"./components/sidebar/index.js";export*from"./components/skeleton/index.js";export*from"./components/slider/index.js";export*from"./components/sparkline/index.js";export*from"./components/spoiler/index.js";export*from"./components/statistic/index.js";export*from"./components/switch/index.js";export*from"./components/table/index.js";export*from"./components/tabs/index.js";export*from"./components/text-field/index.js";export*from"./components/text-link/index.js";export*from"./components/time-picker/index.js";export*from"./components/timeline/index.js";export*from"./components/timeline-chart/index.js";export*from"./components/toast/index.js";export*from"./components/toggle/index.js";export*from"./components/toggle-group/index.js";export*from"./components/toolbar/index.js";export*from"./components/tooltip/index.js";export*from"./components/tour/index.js";export*from"./components/transfer/index.js";export*from"./components/tree-select/index.js";export*from"./components/tree-view/index.js";export*from"./components/typography/index.js";export*from"./components/visually-hidden/index.js";export*from"./components/window-pane/index.js";
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { type TimeUnit } from './date.js';
3
- import type { NebaColor, NebaDensity, NebaSize, NebaWeekday } from '../types.js';
3
+ import type { NebaColor, NebaDateGranularity, NebaDensity, NebaSize, NebaWeekday } from '../types.js';
4
4
  /**
5
5
  * The calendar grid and the clock columns, written once for the four pickers.
6
6
  *
@@ -20,9 +20,9 @@ import type { NebaColor, NebaDensity, NebaSize, NebaWeekday } from '../types.js'
20
20
  /**
21
21
  * Every string a picker says that is not a date.
22
22
  *
23
- * One object rather than eighteen props. These are a set: a caller who has to
23
+ * One object rather than twenty props. These are a set: a caller who has to
24
24
  * translate "Previous month" has to translate "Next month" in the same breath,
25
- * and a component with eighteen `*Label` props is a component whose signature is
25
+ * and a component with twenty `*Label` props is a component whose signature is
26
26
  * mostly apology. The dates themselves are never in here — those come from
27
27
  * `Intl`, which already knows what July is called in more languages than this
28
28
  * file ever will.
@@ -40,8 +40,14 @@ export interface PickerLabels {
40
40
  /** The two header buttons that open the month grid and the year grid. */
41
41
  chooseMonth: string;
42
42
  chooseYear: string;
43
- /** The footer's actions. */
43
+ /**
44
+ * The footer's actions. Three shortcuts rather than one because the button
45
+ * jumps to the current *unit*, and a month picker whose footer says "Today"
46
+ * is offering a day it has no way to accept.
47
+ */
44
48
  today: string;
49
+ thisMonth: string;
50
+ thisYear: string;
45
51
  now: string;
46
52
  clear: string;
47
53
  done: string;
@@ -71,6 +77,12 @@ export interface CalendarProps {
71
77
  rangeStart?: Date | null;
72
78
  rangeEnd?: Date | null;
73
79
  onSelect: (date: Date) => void;
80
+ /**
81
+ * Which grid the reader is allowed to stop on, and therefore what `onSelect`
82
+ * hands back: a day, the 1st of a month, or the 1st of January.
83
+ * @default 'day'
84
+ */
85
+ granularity?: NebaDateGranularity;
74
86
  /** The day under the pointer, for a range that is only half chosen. */
75
87
  onPreviewChange?: (date: Date | null) => void;
76
88
  minDate?: Date | null;
@@ -88,6 +100,14 @@ export interface CalendarProps {
88
100
  * @default true
89
101
  */
90
102
  showOutsideDays?: boolean;
103
+ /**
104
+ * What a day cell draws under its number — a dot, a count, a bar.
105
+ *
106
+ * A hook rather than a slot: the caller is the only one who knows what a day
107
+ * *has* on it, and the alternative is an `events` prop that would make this
108
+ * file responsible for a data shape it has no opinion about.
109
+ */
110
+ renderDay?: (date: Date) => React.ReactNode;
91
111
  /** Takes the focus on mount — the popup has just opened. */
92
112
  autoFocus?: boolean;
93
113
  showPreviousButton?: boolean;
@@ -104,13 +124,19 @@ export interface CalendarProps {
104
124
  * two stretch four rows and three rows across that same height — so switching
105
125
  * view never resizes the popup under the pointer that opened it.
106
126
  *
127
+ * `granularity` says which of the three the reader may stop on. At `day` the
128
+ * other two are only a way of reaching it; at `month` or `year` the grid that
129
+ * names that unit is where the calendar opens and where a click becomes an
130
+ * answer. Climbing is unaffected — a month picker still reaches 2019 through
131
+ * the year grid — so the coarser settings take a view away and add none.
132
+ *
107
133
  * Arrow keys move by one cell, `PageUp`/`PageDown` by a month (a year with
108
134
  * Shift), `Home`/`End` to the ends of the week, and running off an edge steps
109
135
  * the calendar rather than stopping. One roving tab stop, so `Tab` leaves the
110
136
  * grid instead of walking forty-two cells — the pattern the ARIA date-picker
111
137
  * practice describes, and the reason none of the cells is a `disabled` button.
112
138
  */
113
- export declare function Calendar({ size, color, locale, weekStartsOn, month, onMonthChange, selected, rangeStart, rangeEnd, onSelect, onPreviewChange, minDate, maxDate, shouldDisableDate, showOutsideDays, autoFocus, showPreviousButton, showNextButton, labels, className }: CalendarProps): React.JSX.Element;
139
+ export declare function Calendar({ size, color, locale, weekStartsOn, month, onMonthChange, selected, rangeStart, rangeEnd, onSelect, granularity, renderDay, onPreviewChange, minDate, maxDate, shouldDisableDate, showOutsideDays, autoFocus, showPreviousButton, showNextButton, labels, className }: CalendarProps): React.JSX.Element;
114
140
  export type { TimeUnit };
115
141
  export interface TimeGridProps {
116
142
  size: NebaSize;
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import*as o from"react";import{Button as r}from"../components/button/Button.js";import{ChevronIcon as a}from"./icons.js";import{controlHeightClasses as l,controlTextClasses as s,cx as i,gapClasses as c,metaTextClasses as u,pressTransitionClasses as d,srOnlyClasses as m,transitionClasses as h}from"./styles.js";import{addDays as g,addMonths as f,addYears as b,calendarWeeks as p,compareDay as v,daysInMonth as x,isDayOutside as w,isMonthBeforeYear as y,isSameDay as D,isSameMonth as N,isValidDate as S,makeDate as M,meridiemLabels as P,monthLabels as C,startOfDay as k,startOfMonth as Y,today as z,weekdayLabels as A,withTime as F,YEAR_PAGE_SIZE as j,yearPageStart as E}from"./date.js";import{dateFormatter as T}from"./format.js";export const defaultPickerLabels={previousMonth:"Previous month",nextMonth:"Next month",previousYear:"Previous year",nextYear:"Next year",previousYears:"Previous years",nextYears:"Next years",chooseMonth:"Choose a month",chooseYear:"Choose a year",today:"Today",now:"Now",clear:"Clear",done:"Done",hour:"Hour",minute:"Minute",second:"Second",meridiem:"AM/PM",start:"Start",end:"End"};export function usePickerLabels(e){return o.useMemo(()=>e?{...defaultPickerLabels,...e}:defaultPickerLabels,[e])}const R={xs:"1.375rem",sm:"1.625rem",md:"2rem",lg:"2.5rem",xl:"3rem"},B={xs:"rounded-(--neba-radius-xs)",sm:"rounded-(--neba-radius-xs)",md:"rounded-(--neba-radius-sm)",lg:"rounded-(--neba-radius-md)",xl:"rounded-(--neba-radius-lg)"},H={xs:"rounded-s-(--neba-radius-xs)",sm:"rounded-s-(--neba-radius-xs)",md:"rounded-s-(--neba-radius-sm)",lg:"rounded-s-(--neba-radius-md)",xl:"rounded-s-(--neba-radius-lg)"},L={xs:"rounded-e-(--neba-radius-xs)",sm:"rounded-e-(--neba-radius-xs)",md:"rounded-e-(--neba-radius-sm)",lg:"rounded-e-(--neba-radius-md)",xl:"rounded-e-(--neba-radius-lg)"},K=["relative flex select-none items-center justify-center tabular-nums","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",h,d,"focus-visible:z-10 focus-visible:[outline:2px_solid_var(--n-ring)]","focus-visible:[outline-offset:-2px]"].join(" ");function O({children:n,label:o,selected:r,inRange:a=!1,rangeEdge:l=null,current:s=!1,muted:c=!1,disabled:u=!1,focused:d=!1,size:m,className:h,onClick:g,onPointerEnter:f,onKeyDown:b}){return t("button",{type:"button",role:"gridcell","aria-label":o,"aria-selected":r,"aria-current":s?"date":void 0,"aria-disabled":u||void 0,tabIndex:d?0:-1,"data-focus-target":d?"true":void 0,className:i(K,"start"===l?H[m]:"end"===l?L[m]:"middle"===l?"rounded-none":B[m],u?"cursor-not-allowed text-(--neba-disabled-fg)":r?"cursor-pointer bg-(--n-fill) font-semibold text-(--n-on-solid) hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)":a?"cursor-pointer bg-(--n-soft) text-(--neba-fg) hover:bg-(--n-soft-hover) active:bg-(--n-soft-press)":s?"cursor-pointer font-semibold text-(--n-accent) hover:bg-(--n-soft) active:bg-(--n-soft-press)":c?"cursor-pointer text-(--neba-muted-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)":"cursor-pointer text-(--neba-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)",h),onClick:()=>{u||g()},onPointerEnter:f,onKeyDown:b,children:[n,s?e("span",{"aria-hidden":"true",className:"absolute bottom-[0.18em] size-[0.22em] rounded-full bg-current"}):null]})}function U({size:o,color:u,view:d,month:m,locale:h,labels:g,showPreviousButton:f,showNextButton:b,onStep:p,onViewChange:v}){const x=C(h,"long")[m.getMonth()],w=String(m.getFullYear()),D=y(h),N="day"===d?[g.previousMonth,g.nextMonth]:"month"===d?[g.previousYear,g.nextYear]:[g.previousYears,g.nextYears],S=(t,n)=>n?e(r,{variant:"text",size:o,color:u,density:"compact","aria-label":N[-1===t?0:1],onClick:()=>p(t),startIcon:e("span",{className:i("flex items-center",-1===t?"rotate-90 rtl:-rotate-90":"-rotate-90 rtl:rotate-90"),children:e(a,{})})}):e("span",{"aria-hidden":"true",className:i(l[o],"w-(--n-cell)")}),M=t=>e("span",{className:i("flex items-center text-(--neba-muted-fg)","[transition:rotate_var(--neba-duration)_var(--neba-ease)]",t&&"rotate-180"),children:e(a,{})}),P=e(r,{variant:"text",size:o,color:u,density:"compact","aria-label":g.chooseMonth,"aria-expanded":"month"===d,onClick:()=>v("month"===d?"day":"month"),endIcon:M("month"===d),children:x},"month"),k=e(r,{variant:"text",size:o,color:u,density:"compact",className:"tabular-nums","aria-label":g.chooseYear,"aria-expanded":"year"===d,onClick:()=>v("year"===d?"day":"year"),endIcon:M("year"===d),children:w},"year"),Y=E(m.getFullYear());return t("div",{className:"flex items-center justify-between gap-1",children:[S(-1,f),e("div",{className:i("flex min-w-0 flex-1 items-center justify-center",c[o]),children:"year"===d?e("span",{className:i("flex items-center font-medium tabular-nums text-(--neba-fg)",l[o],s[o]),children:`${Y}–${Y+j-1}`}):"month"===d?k:t(n,D?{children:[P,k]}:{children:[k,P]})}),S(1,b)]})}export function Calendar({size:n,color:r,locale:a,weekStartsOn:l,month:s,onMonthChange:u,selected:d,rangeStart:m=null,rangeEnd:h=null,onSelect:g,onPreviewChange:p,minDate:v,maxDate:x,shouldDisableDate:y,showOutsideDays:D=!0,autoFocus:P=!1,showPreviousButton:C=!0,showNextButton:A=!0,labels:F,className:E}){const[T,B]=o.useState("day"),H=o.useMemo(()=>d.filter(S),[d]),[L,K]=o.useState(()=>{const e=H.find(e=>N(e,s));return e?k(e):N(z(),s)?z():Y(s)}),O=o.useRef(P),_=o.useRef(null);o.useEffect(()=>{K(e=>N(e,s)?e:Y(s))},[s]),o.useLayoutEffect(()=>{O.current&&(O.current=!1,_.current?.querySelector('[data-focus-target="true"]')?.focus({preventScroll:!0}))});const V=o.useCallback(e=>w(e,v,x)||(y?.(e)??!1),[v,x,y]),G=e=>{O.current=!0,B(e)},J=e=>{O.current=!0,u(e)};return t("div",{ref:_,className:i("flex flex-col",c[n],E),style:{"--n-cell":R[n]},onPointerLeave:()=>p?.(null),children:[e(U,{size:n,color:r,view:T,month:s,locale:a,labels:F,showPreviousButton:C,showNextButton:A,onStep:e=>{u("day"===T?f(s,e):b(s,"month"===T?e:e*j))},onViewChange:G}),e("div",{className:"h-[calc(var(--n-cell)*7)] w-[calc(var(--n-cell)*7)]",children:"day"===T?e(q,{size:n,locale:a,weekStartsOn:l,month:s,chosen:H,rangeStart:m,rangeEnd:h,focusedDate:L,showOutsideDays:D,isDisabled:V,onSelect:e=>{K(e),g(e)},onPreviewChange:p,onMoveFocus:e=>{O.current=!0,K(e),N(e,s)||u(Y(e))}}):"month"===T?e(I,{size:n,locale:a,month:s,chosen:H,minDate:v,maxDate:x,onMoveCursor:J,onPick:e=>{u(M(s.getFullYear(),e,1)),G("day")}}):e($,{size:n,month:s,chosen:H,minDate:v,maxDate:x,onMoveCursor:J,onPick:e=>{u(M(e,s.getMonth(),1)),G("month")}})})]})}function q({size:n,locale:o,weekStartsOn:r,month:a,chosen:l,rangeStart:c,rangeEnd:d,focusedDate:m,showOutsideDays:h,isDisabled:b,onSelect:x,onPreviewChange:w,onMoveFocus:y}){const M=p(a,r),P=A(o,r,"short"),C=A(o,r,"long"),k=T(o,{dateStyle:"full"}),Y=(j=d,S(F=c)&&S(j)?v(F,j)<=0?[F,j]:[j,F]:null);var F,j;const E=z();return t("div",{role:"grid",className:"flex h-full flex-col",children:[e("div",{role:"row",className:"grid grid-cols-7",children:P.map((t,o)=>e("span",{role:"columnheader","aria-label":C[o],className:i("flex h-(--n-cell) items-center justify-center font-medium text-(--neba-muted-fg) select-none",u[n]),children:t},o))}),M.map((t,o)=>e("div",{role:"row",className:"grid grid-cols-7",children:t.map(t=>{const o=!N(t,a);if(o&&!h)return e("span",{role:"gridcell","aria-hidden":"true",className:"size-(--n-cell)"},t.getTime());const c=l.some(e=>D(e,t)),u=null!==Y&&v(t,Y[0])>=0&&v(t,Y[1])<=0,d=null!==Y&&u&&D(t,Y[0]),p=null!==Y&&u&&D(t,Y[1]);return e(O,{size:n,label:k.format(t),selected:c,inRange:u&&!c,rangeEdge:u?d&&p?"both":d?"start":p?"end":"middle":null,current:D(t,E)&&!c,muted:o,disabled:b(t),focused:D(t,m),className:i("size-(--n-cell)",s[n]),onClick:()=>x(t),onPointerEnter:()=>w?.(t),onKeyDown:e=>((e,t)=>{const n=(t.getDay()-r+7)%7,o={ArrowLeft:()=>g(t,-1),ArrowRight:()=>g(t,1),ArrowUp:()=>g(t,-7),ArrowDown:()=>g(t,7),Home:()=>g(t,-n),End:()=>g(t,6-n),PageUp:()=>f(t,e.shiftKey?-12:-1),PageDown:()=>f(t,e.shiftKey?12:1)}[e.key];o&&(e.preventDefault(),y(o()))})(e,t),children:t.getDate()},t.getTime())})},o))]})}function I({size:t,locale:n,month:o,chosen:r,minDate:a,maxDate:l,onMoveCursor:c,onPick:u}){const d=C(n,"short"),m=C(n,"long"),h=o.getFullYear(),g=new Date,b=e=>{const t={ArrowLeft:-1,ArrowRight:1,ArrowUp:-3,ArrowDown:3,PageUp:-12,PageDown:12}[e.key];void 0!==t&&(e.preventDefault(),c(f(Y(o),t)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2,3].map(n=>e("div",{role:"row",className:"grid grid-cols-3 gap-1",children:[0,1,2].map(c=>{const f=3*n+c,p=M(h,f,1),w=M(h,f,x(h,f));return e(O,{size:t,label:`${m[f]} ${h}`,selected:r.some(e=>e.getFullYear()===h&&e.getMonth()===f),current:g.getFullYear()===h&&g.getMonth()===f,disabled:S(a)&&v(w,a)<0||S(l)&&v(p,l)>0,focused:f===o.getMonth(),className:i("h-(--n-cell) w-full",s[t]),onClick:()=>u(f),onKeyDown:b,children:d[f]},f)})},n))})}function $({size:t,month:n,chosen:o,minDate:r,maxDate:a,onMoveCursor:l,onPick:c}){const u=E(n.getFullYear()),d=(new Date).getFullYear(),m=e=>{const t={ArrowLeft:-1,ArrowRight:1,ArrowUp:-4,ArrowDown:4,PageUp:-j,PageDown:j}[e.key];void 0!==t&&(e.preventDefault(),l(b(Y(n),t)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2].map(l=>e("div",{role:"row",className:"grid grid-cols-4 gap-1",children:[0,1,2,3].map(h=>{const g=u+4*l+h;return e(O,{size:t,label:String(g),selected:o.some(e=>e.getFullYear()===g),current:g===d,disabled:S(r)&&g<r.getFullYear()||S(a)&&g>a.getFullYear(),focused:g===n.getFullYear(),className:i("h-(--n-cell) w-full",s[t]),onClick:()=>c(g),onKeyDown:m,children:g},g)})},l))})}function _(e){const t=e.parentElement;if(!t)return;const n=e.getBoundingClientRect(),o=t.getBoundingClientRect(),r=n.top-o.top-t.clientTop+t.scrollTop,a=r+n.height;r<t.scrollTop?t.scrollTop=r:a>t.scrollTop+t.clientHeight&&(t.scrollTop=a-t.clientHeight)}export function TimeGrid({size:n,density:r,locale:a,value:c,referenceDate:u,onChange:d,hour12:h,showSeconds:g,hourStep:f,minuteStep:b,secondStep:p,shouldDisableTime:v,autoFocus:x=!1,labels:w,className:y}){const D=c??u,N=o.useRef(null),[S,M]=o.useMemo(()=>P(a),[a]);o.useEffect(()=>{const e=N.current;if(e?.querySelectorAll('[data-chosen="true"]').forEach(_),x){const t=e?.querySelector('[role="listbox"]');(t?.querySelector('[data-chosen="true"]')??t?.querySelector('[role="option"]'))?.focus({preventScroll:!0})}},[x]);const C=o.useMemo(()=>{const e=Math.ceil((h?12:24)/f),t=Array.from({length:e},(e,t)=>t*f);return h?t.map(e=>0===e?12:e):t},[h,f]),k=o.useMemo(()=>Array.from({length:Math.ceil(60/b)},(e,t)=>t*b),[b]),Y=o.useMemo(()=>Array.from({length:Math.ceil(60/p)},(e,t)=>t*p),[p]),z=e=>String(e).padStart(2,"0"),A=h?D.getHours()%12||12:D.getHours(),j=(t,o,r,a,u)=>e("div",{role:"listbox","aria-label":o,className:i("flex flex-col gap-0.5 overflow-y-auto overscroll-contain","h-[calc(var(--n-cell)*7)] w-[calc(var(--n-cell)*2)]","scroll-py-0.5 [scrollbar-width:thin]"),children:r.map(o=>{const r=((e,t)=>F(D,"hour"===e?{hours:h?t%12+(D.getHours()>=12?12:0):t}:"minute"===e?{minutes:t}:"second"===e?{seconds:t}:{hours:D.getHours()%12+12*t}))(t,o),m=null!==c&&a(o),g=v?.(r,t)??!1;return e("button",{type:"button",role:"option","aria-selected":m,"aria-disabled":g||void 0,"data-chosen":m?"true":void 0,className:i(K,B[n],l[n],s[n],"w-full shrink-0",g?"cursor-not-allowed text-(--neba-disabled-fg)":m?"cursor-pointer bg-(--n-fill) font-semibold text-(--n-on-solid) hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)":"cursor-pointer text-(--neba-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)"),onClick:()=>{g||d(r)},children:u(o)},o)})},t);return t("div",{ref:N,className:i("flex","compact"===r?"gap-0.5":"gap-1",y),style:{"--n-cell":R[n]},children:[j("hour",w.hour,C,e=>e===A,e=>h?String(e):z(e)),j("minute",w.minute,k,e=>e===D.getMinutes(),z),g?j("second",w.second,Y,e=>e===D.getSeconds(),z):null,h?j("meridiem",w.meridiem,[0,1],e=>(D.getHours()>=12?1:0)===e,e=>0===e?S:M):null,e("span",{className:m,"aria-live":"polite",children:null===c?"":T(a,{hour:"numeric",minute:"2-digit",...g?{second:"2-digit"}:{}}).format(c)})]})}
1
+ "use client";import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import*as o from"react";import{Button as r}from"../components/button/Button.js";import{ChevronIcon as a}from"./icons.js";import{controlHeightClasses as l,controlTextClasses as s,cx as i,gapClasses as c,metaTextClasses as u,pressTransitionClasses as d,srOnlyClasses as m,transitionClasses as h}from"./styles.js";import{addDays as g,addMonths as f,addYears as b,calendarWeeks as p,compareDay as v,isDayOutside as x,isMonthBeforeYear as y,isSameDay as w,isSameMonth as D,isUnitOutside as N,isValidDate as S,makeDate as M,meridiemLabels as P,monthLabels as C,startOfDay as k,startOfMonth as z,today as Y,weekdayLabels as A,withTime as j,YEAR_PAGE_SIZE as E,yearPageStart as F}from"./date.js";import{dateFormatter as T}from"./format.js";export const defaultPickerLabels={previousMonth:"Previous month",nextMonth:"Next month",previousYear:"Previous year",nextYear:"Next year",previousYears:"Previous years",nextYears:"Next years",chooseMonth:"Choose a month",chooseYear:"Choose a year",today:"Today",thisMonth:"This month",thisYear:"This year",now:"Now",clear:"Clear",done:"Done",hour:"Hour",minute:"Minute",second:"Second",meridiem:"AM/PM",start:"Start",end:"End"};export function usePickerLabels(e){return o.useMemo(()=>e?{...defaultPickerLabels,...e}:defaultPickerLabels,[e])}const R={xs:"1.375rem",sm:"1.625rem",md:"2rem",lg:"2.5rem",xl:"3rem"},B={xs:"rounded-(--neba-radius-xs)",sm:"rounded-(--neba-radius-xs)",md:"rounded-(--neba-radius-sm)",lg:"rounded-(--neba-radius-md)",xl:"rounded-(--neba-radius-lg)"},H={xs:"rounded-s-(--neba-radius-xs)",sm:"rounded-s-(--neba-radius-xs)",md:"rounded-s-(--neba-radius-sm)",lg:"rounded-s-(--neba-radius-md)",xl:"rounded-s-(--neba-radius-lg)"},L={xs:"rounded-e-(--neba-radius-xs)",sm:"rounded-e-(--neba-radius-xs)",md:"rounded-e-(--neba-radius-sm)",lg:"rounded-e-(--neba-radius-md)",xl:"rounded-e-(--neba-radius-lg)"},K=["relative flex select-none items-center justify-center tabular-nums","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",h,d,"focus-visible:z-10 focus-visible:[outline:2px_solid_var(--n-ring)]","focus-visible:[outline-offset:-2px]"].join(" ");function O({children:n,label:o,selected:r,inRange:a=!1,rangeEdge:l=null,current:s=!1,muted:c=!1,disabled:u=!1,focused:d=!1,size:m,className:h,onClick:g,onPointerEnter:f,onKeyDown:b}){return t("button",{type:"button",role:"gridcell","aria-label":o,"aria-selected":r,"aria-current":s?"date":void 0,"aria-disabled":u||void 0,tabIndex:d?0:-1,"data-focus-target":d?"true":void 0,className:i(K,"start"===l?H[m]:"end"===l?L[m]:"middle"===l?"rounded-none":B[m],u?"cursor-not-allowed text-(--neba-disabled-fg)":r?"cursor-pointer bg-(--n-fill) font-semibold text-(--n-on-solid) hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)":a?"cursor-pointer bg-(--n-soft) text-(--neba-fg) hover:bg-(--n-soft-hover) active:bg-(--n-soft-press)":s?"cursor-pointer font-semibold text-(--n-accent) hover:bg-(--n-soft) active:bg-(--n-soft-press)":c?"cursor-pointer text-(--neba-muted-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)":"cursor-pointer text-(--neba-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)",h),onClick:()=>{u||g()},onPointerEnter:f,onKeyDown:b,children:[n,s?e("span",{"aria-hidden":"true",className:"absolute bottom-[0.18em] size-[0.22em] rounded-full bg-current"}):null]})}function U({size:o,color:u,view:d,month:m,locale:h,labels:g,showPreviousButton:f,showNextButton:b,onStep:p,onViewChange:v}){const x=C(h,"long")[m.getMonth()],w=String(m.getFullYear()),D=y(h),N="day"===d?[g.previousMonth,g.nextMonth]:"month"===d?[g.previousYear,g.nextYear]:[g.previousYears,g.nextYears],S=(t,n)=>n?e(r,{variant:"text",size:o,color:u,density:"compact","aria-label":N[-1===t?0:1],onClick:()=>p(t),startIcon:e("span",{className:i("flex items-center",-1===t?"rotate-90 rtl:-rotate-90":"-rotate-90 rtl:rotate-90"),children:e(a,{})})}):e("span",{"aria-hidden":"true",className:i(l[o],"w-(--n-cell)")}),M=t=>e("span",{className:i("flex items-center text-(--neba-muted-fg)","[transition:rotate_var(--neba-duration)_var(--neba-ease)]",t&&"rotate-180"),children:e(a,{})}),P=e(r,{variant:"text",size:o,color:u,density:"compact","aria-label":g.chooseMonth,"aria-expanded":"month"===d,onClick:()=>v("month"===d?"day":"month"),endIcon:M("month"===d),children:x},"month"),k=e(r,{variant:"text",size:o,color:u,density:"compact",className:"tabular-nums","aria-label":g.chooseYear,"aria-expanded":"year"===d,onClick:()=>v("year"===d?"day":"year"),endIcon:M("year"===d),children:w},"year"),z=F(m.getFullYear());return t("div",{className:"flex items-center justify-between gap-1",children:[S(-1,f),e("div",{className:i("flex min-w-0 flex-1 items-center justify-center",c[o]),children:"year"===d?e("span",{className:i("flex items-center font-medium tabular-nums text-(--neba-fg)",l[o],s[o]),children:`${z}–${z+E-1}`}):"month"===d?k:t(n,D?{children:[P,k]}:{children:[k,P]})}),S(1,b)]})}const q={day:0,month:1,year:2};export function Calendar({size:n,color:r,locale:a,weekStartsOn:l,month:s,onMonthChange:u,selected:d,rangeStart:m=null,rangeEnd:h=null,onSelect:g,granularity:p="day",renderDay:v,onPreviewChange:y,minDate:w,maxDate:N,shouldDisableDate:P,showOutsideDays:C=!0,autoFocus:A=!1,showPreviousButton:j=!0,showNextButton:F=!0,labels:T,className:B}){const[H,L]=o.useState(p),K=q[H]<q[p]?p:H,O=o.useMemo(()=>d.filter(S),[d]),[V,G]=o.useState(()=>{const e=O.find(e=>D(e,s));return e?k(e):D(Y(),s)?Y():z(s)}),J=o.useRef(A),Q=o.useRef(null);o.useEffect(()=>{G(e=>D(e,s)?e:z(s))},[s]),o.useLayoutEffect(()=>{J.current&&(J.current=!1,Q.current?.querySelector('[data-focus-target="true"]')?.focus({preventScroll:!0}))});const W=o.useCallback(e=>x(e,w,N)||(P?.(e)??!1),[w,N,P]),X=e=>{J.current=!0,L(e)},Z=e=>{J.current=!0,u(e)};return t("div",{ref:Q,className:i("flex flex-col",c[n],B),style:{"--n-cell":R[n]},onPointerLeave:()=>y?.(null),children:[e(U,{size:n,color:r,view:K,month:s,locale:a,labels:T,showPreviousButton:j,showNextButton:F,onStep:e=>{u("day"===K?f(s,e):b(s,"month"===K?e:e*E))},onViewChange:X}),e("div",{className:"h-[calc(var(--n-cell)*7)] w-[calc(var(--n-cell)*7)]",children:"day"===K?e(I,{size:n,locale:a,weekStartsOn:l,month:s,chosen:O,rangeStart:m,rangeEnd:h,focusedDate:V,renderDay:v,showOutsideDays:C,isDisabled:W,onSelect:e=>{G(e),g(e)},onPreviewChange:y,onMoveFocus:e=>{J.current=!0,G(e),D(e,s)||u(z(e))}}):"month"===K?e($,{size:n,locale:a,month:s,chosen:O,minDate:w,maxDate:N,shouldDisable:"month"===p?P:void 0,onMoveCursor:Z,onPick:e=>{const t=M(s.getFullYear(),e,1);u(t),"month"===p?g(t):X("day")}}):e(_,{size:n,month:s,chosen:O,minDate:w,maxDate:N,shouldDisable:"year"===p?P:void 0,onMoveCursor:Z,onPick:e=>{if("year"===p){const t=M(e,0,1);return u(t),void g(t)}u(M(e,s.getMonth(),1)),X("month")}})})]})}function I({size:n,locale:o,weekStartsOn:r,month:a,chosen:l,rangeStart:c,rangeEnd:d,focusedDate:m,renderDay:h,showOutsideDays:b,isDisabled:x,onSelect:y,onPreviewChange:N,onMoveFocus:M}){const P=p(a,r),C=A(o,r,"short"),k=A(o,r,"long"),z=T(o,{dateStyle:"full"}),j=(F=d,S(E=c)&&S(F)?v(E,F)<=0?[E,F]:[F,E]:null);var E,F;const R=Y();return t("div",{role:"grid",className:"flex h-full flex-col",children:[e("div",{role:"row",className:"grid grid-cols-7",children:C.map((t,o)=>e("span",{role:"columnheader","aria-label":k[o],className:i("flex h-(--n-cell) items-center justify-center font-medium text-(--neba-muted-fg) select-none",u[n]),children:t},o))}),P.map((o,c)=>e("div",{role:"row",className:"grid grid-cols-7",children:o.map(o=>{const c=!D(o,a);if(c&&!b)return e("span",{role:"gridcell","aria-hidden":"true",className:"size-(--n-cell)"},o.getTime());const u=l.some(e=>w(e,o)),d=null!==j&&v(o,j[0])>=0&&v(o,j[1])<=0,p=null!==j&&d&&w(o,j[0]),S=null!==j&&d&&w(o,j[1]);return t(O,{size:n,label:z.format(o),selected:u,inRange:d&&!u,rangeEdge:d?p&&S?"both":p?"start":S?"end":"middle":null,current:w(o,R)&&!u,muted:c,disabled:x(o),focused:w(o,m),className:i("size-(--n-cell)",s[n]),onClick:()=>y(o),onPointerEnter:()=>N?.(o),onKeyDown:e=>((e,t)=>{const n=(t.getDay()-r+7)%7,o={ArrowLeft:()=>g(t,-1),ArrowRight:()=>g(t,1),ArrowUp:()=>g(t,-7),ArrowDown:()=>g(t,7),Home:()=>g(t,-n),End:()=>g(t,6-n),PageUp:()=>f(t,e.shiftKey?-12:-1),PageDown:()=>f(t,e.shiftKey?12:1)}[e.key];o&&(e.preventDefault(),M(o()))})(e,o),children:[o.getDate(),h?h(o):null]},o.getTime())})},c))]})}function $({size:t,locale:n,month:o,chosen:r,minDate:a,maxDate:l,shouldDisable:c,onMoveCursor:u,onPick:d}){const m=C(n,"short"),h=C(n,"long"),g=o.getFullYear(),b=new Date,p=e=>{const t={ArrowLeft:-1,ArrowRight:1,ArrowUp:-3,ArrowDown:3,PageUp:-12,PageDown:12}[e.key];void 0!==t&&(e.preventDefault(),u(f(z(o),t)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2,3].map(n=>e("div",{role:"row",className:"grid grid-cols-3 gap-1",children:[0,1,2].map(u=>{const f=3*n+u,v=M(g,f,1);return e(O,{size:t,label:`${h[f]} ${g}`,selected:r.some(e=>e.getFullYear()===g&&e.getMonth()===f),current:b.getFullYear()===g&&b.getMonth()===f,disabled:N(v,"month",a,l)||(c?.(v)??!1),focused:f===o.getMonth(),className:i("h-(--n-cell) w-full",s[t]),onClick:()=>d(f),onKeyDown:p,children:m[f]},f)})},n))})}function _({size:t,month:n,chosen:o,minDate:r,maxDate:a,shouldDisable:l,onMoveCursor:c,onPick:u}){const d=F(n.getFullYear()),m=(new Date).getFullYear(),h=e=>{const t={ArrowLeft:-1,ArrowRight:1,ArrowUp:-4,ArrowDown:4,PageUp:-E,PageDown:E}[e.key];void 0!==t&&(e.preventDefault(),c(b(z(n),t)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2].map(c=>e("div",{role:"row",className:"grid grid-cols-4 gap-1",children:[0,1,2,3].map(g=>{const f=d+4*c+g,b=M(f,0,1);return e(O,{size:t,label:String(f),selected:o.some(e=>e.getFullYear()===f),current:f===m,disabled:N(b,"year",r,a)||(l?.(b)??!1),focused:f===n.getFullYear(),className:i("h-(--n-cell) w-full",s[t]),onClick:()=>u(f),onKeyDown:h,children:f},f)})},c))})}function V(e){const t=e.parentElement;if(!t)return;const n=e.getBoundingClientRect(),o=t.getBoundingClientRect(),r=n.top-o.top-t.clientTop+t.scrollTop,a=r+n.height;r<t.scrollTop?t.scrollTop=r:a>t.scrollTop+t.clientHeight&&(t.scrollTop=a-t.clientHeight)}export function TimeGrid({size:n,density:r,locale:a,value:c,referenceDate:u,onChange:d,hour12:h,showSeconds:g,hourStep:f,minuteStep:b,secondStep:p,shouldDisableTime:v,autoFocus:x=!1,labels:y,className:w}){const D=c??u,N=o.useRef(null),[S,M]=o.useMemo(()=>P(a),[a]);o.useEffect(()=>{const e=N.current;if(e?.querySelectorAll('[data-chosen="true"]').forEach(V),x){const t=e?.querySelector('[role="listbox"]');(t?.querySelector('[data-chosen="true"]')??t?.querySelector('[role="option"]'))?.focus({preventScroll:!0})}},[x]);const C=o.useMemo(()=>{const e=Math.ceil((h?12:24)/f),t=Array.from({length:e},(e,t)=>t*f);return h?t.map(e=>0===e?12:e):t},[h,f]),k=o.useMemo(()=>Array.from({length:Math.ceil(60/b)},(e,t)=>t*b),[b]),z=o.useMemo(()=>Array.from({length:Math.ceil(60/p)},(e,t)=>t*p),[p]),Y=e=>String(e).padStart(2,"0"),A=h?D.getHours()%12||12:D.getHours(),E=(t,o,r,a,u)=>e("div",{role:"listbox","aria-label":o,className:i("flex flex-col gap-0.5 overflow-y-auto overscroll-contain","h-[calc(var(--n-cell)*7)] w-[calc(var(--n-cell)*2)]","scroll-py-0.5 [scrollbar-width:thin]"),children:r.map(o=>{const r=((e,t)=>j(D,"hour"===e?{hours:h?t%12+(D.getHours()>=12?12:0):t}:"minute"===e?{minutes:t}:"second"===e?{seconds:t}:{hours:D.getHours()%12+12*t}))(t,o),m=null!==c&&a(o),g=v?.(r,t)??!1;return e("button",{type:"button",role:"option","aria-selected":m,"aria-disabled":g||void 0,"data-chosen":m?"true":void 0,className:i(K,B[n],l[n],s[n],"w-full shrink-0",g?"cursor-not-allowed text-(--neba-disabled-fg)":m?"cursor-pointer bg-(--n-fill) font-semibold text-(--n-on-solid) hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)":"cursor-pointer text-(--neba-fg) hover:bg-(--n-soft) active:bg-(--n-soft-press)"),onClick:()=>{g||d(r)},children:u(o)},o)})},t);return t("div",{ref:N,className:i("flex","compact"===r?"gap-0.5":"gap-1",w),style:{"--n-cell":R[n]},children:[E("hour",y.hour,C,e=>e===A,e=>h?String(e):Y(e)),E("minute",y.minute,k,e=>e===D.getMinutes(),Y),g?E("second",y.second,z,e=>e===D.getSeconds(),Y):null,h?E("meridiem",y.meridiem,[0,1],e=>(D.getHours()>=12?1:0)===e,e=>0===e?S:M):null,e("span",{className:m,"aria-live":"polite",children:null===c?"":T(a,{hour:"numeric",minute:"2-digit",...g?{second:"2-digit"}:{}}).format(c)})]})}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * A table as CSV.
3
+ *
4
+ * It is here rather than in DataTable because the escaping is the whole job and
5
+ * getting it wrong is silent: a comma inside a cell shifts every column after
6
+ * it by one, and nobody notices until a spreadsheet somewhere is off by a
7
+ * column. RFC 4180 is four rules, and all four are below.
8
+ */
9
+ /**
10
+ * One field, quoted only when it has to be.
11
+ *
12
+ * A field is quoted if it holds the separator, a quote, or a line break, and a
13
+ * quote inside a quoted field is written twice. `null` and `undefined` are
14
+ * empty rather than the words "null" and "undefined", which is what `String()`
15
+ * would put in a spreadsheet cell.
16
+ */
17
+ export declare function csvField(value: unknown, separator?: string): string;
18
+ export interface CsvOptions {
19
+ /** What goes between fields. `;` for the locales whose spreadsheets expect it. */
20
+ separator?: string;
21
+ /**
22
+ * Writes a byte-order mark in front.
23
+ *
24
+ * On by default, and not as a nicety: Excel reads a UTF-8 CSV without one as
25
+ * the local code page, so every non-ASCII name in the file arrives as
26
+ * mojibake. Every other reader ignores the mark.
27
+ */
28
+ bom?: boolean;
29
+ }
30
+ /** Rows of already-stringable values, as one CSV document. */
31
+ export declare function toCsv(rows: readonly (readonly unknown[])[], options?: CsvOptions): string;
32
+ /**
33
+ * Hands the file to the browser.
34
+ *
35
+ * A `blob:` URL and a synthesised click, which is the only way a page can
36
+ * produce a file the reader keeps. The URL is revoked on the next frame rather
37
+ * than immediately: some browsers have not finished reading it when the click
38
+ * returns, and revoking too early is a download that silently produces nothing.
39
+ */
40
+ export declare function downloadText(text: string, fileName: string, type: string): void;
@@ -0,0 +1 @@
1
+ export function csvField(e,n=","){if(null==e)return"";const t=e instanceof Date?e.toISOString():"object"==typeof e?JSON.stringify(e):String(e);return/["\r\n]/.test(t)||t.includes(n)?`"${t.replaceAll('"','""')}"`:t}export function toCsv(e,n={}){const{separator:t=",",bom:o=!0}=n,r=e.map(e=>e.map(e=>csvField(e,t)).join(t)).join("\r\n");return o?`\ufeff${r}`:r}export function downloadText(e,n,t){const o=URL.createObjectURL(new Blob([e],{type:t})),r=document.createElement("a");r.href=o,r.download=n,r.rel="noopener",r.style.display="none",document.body.append(r),r.click(),r.remove(),requestAnimationFrame(()=>URL.revokeObjectURL(o))}