neba 1.3.0 → 1.5.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 (135) hide show
  1. package/README.md +7 -7
  2. package/dist/components/alert/Alert.d.ts +9 -1
  3. package/dist/components/alert/Alert.js +1 -1
  4. package/dist/components/area-chart/AreaChart.d.ts +54 -0
  5. package/dist/components/area-chart/AreaChart.js +1 -0
  6. package/dist/components/area-chart/index.d.ts +2 -0
  7. package/dist/components/area-chart/index.js +1 -0
  8. package/dist/components/bar-chart/BarChart.d.ts +63 -0
  9. package/dist/components/bar-chart/BarChart.js +1 -0
  10. package/dist/components/bar-chart/index.d.ts +2 -0
  11. package/dist/components/bar-chart/index.js +1 -0
  12. package/dist/components/bottom-navigation/BottomNavigation.d.ts +111 -0
  13. package/dist/components/bottom-navigation/BottomNavigation.js +1 -0
  14. package/dist/components/bottom-navigation/index.d.ts +1 -0
  15. package/dist/components/bottom-navigation/index.js +1 -0
  16. package/dist/components/breadcrumb/Breadcrumb.d.ts +35 -2
  17. package/dist/components/breadcrumb/Breadcrumb.js +1 -1
  18. package/dist/components/button/Button.d.ts +16 -0
  19. package/dist/components/button/Button.js +1 -1
  20. package/dist/components/carousel/Carousel.d.ts +10 -4
  21. package/dist/components/carousel/Carousel.js +1 -1
  22. package/dist/components/chip/Chip.d.ts +9 -1
  23. package/dist/components/chip/Chip.js +1 -1
  24. package/dist/components/collapsible/Collapsible.d.ts +88 -0
  25. package/dist/components/collapsible/Collapsible.js +1 -0
  26. package/dist/components/collapsible/index.d.ts +1 -0
  27. package/dist/components/collapsible/index.js +1 -0
  28. package/dist/components/combobox/Combobox.d.ts +19 -7
  29. package/dist/components/combobox/Combobox.js +1 -1
  30. package/dist/components/data-table/DataTable.d.ts +323 -0
  31. package/dist/components/data-table/DataTable.js +1 -0
  32. package/dist/components/data-table/index.d.ts +2 -0
  33. package/dist/components/data-table/index.js +1 -0
  34. package/dist/components/dialog/Dialog.d.ts +11 -5
  35. package/dist/components/dialog/Dialog.js +1 -1
  36. package/dist/components/drawer/Drawer.d.ts +11 -5
  37. package/dist/components/drawer/Drawer.js +1 -1
  38. package/dist/components/empty/Empty.d.ts +69 -0
  39. package/dist/components/empty/Empty.js +1 -0
  40. package/dist/components/empty/index.d.ts +2 -0
  41. package/dist/components/empty/index.js +1 -0
  42. package/dist/components/file-picker/FilePicker.d.ts +1 -3
  43. package/dist/components/file-picker/FilePicker.js +1 -1
  44. package/dist/components/floating-action-button/FloatingActionButton.d.ts +146 -0
  45. package/dist/components/floating-action-button/FloatingActionButton.js +1 -0
  46. package/dist/components/floating-action-button/index.d.ts +1 -0
  47. package/dist/components/floating-action-button/index.js +1 -0
  48. package/dist/components/heatmap-chart/HeatmapChart.d.ts +69 -0
  49. package/dist/components/heatmap-chart/HeatmapChart.js +1 -0
  50. package/dist/components/heatmap-chart/index.d.ts +2 -0
  51. package/dist/components/heatmap-chart/index.js +1 -0
  52. package/dist/components/highlight/Highlight.js +1 -1
  53. package/dist/components/line-chart/LineChart.d.ts +74 -0
  54. package/dist/components/line-chart/LineChart.js +1 -0
  55. package/dist/components/line-chart/index.d.ts +2 -0
  56. package/dist/components/line-chart/index.js +1 -0
  57. package/dist/components/mockup/Mockup.d.ts +151 -0
  58. package/dist/components/mockup/Mockup.js +1 -0
  59. package/dist/components/mockup/index.d.ts +2 -0
  60. package/dist/components/mockup/index.js +1 -0
  61. package/dist/components/number-field/NumberField.d.ts +10 -6
  62. package/dist/components/number-field/NumberField.js +1 -1
  63. package/dist/components/overlay/Overlay.d.ts +11 -6
  64. package/dist/components/overlay/Overlay.js +1 -1
  65. package/dist/components/pagination/Pagination.d.ts +28 -6
  66. package/dist/components/pagination/Pagination.js +1 -1
  67. package/dist/components/panes/Panes.js +1 -1
  68. package/dist/components/pie-chart/PieChart.d.ts +58 -0
  69. package/dist/components/pie-chart/PieChart.js +1 -0
  70. package/dist/components/pie-chart/index.d.ts +2 -0
  71. package/dist/components/pie-chart/index.js +1 -0
  72. package/dist/components/popover/Popover.d.ts +11 -5
  73. package/dist/components/popover/Popover.js +1 -1
  74. package/dist/components/progress-box/ProgressBox.js +1 -1
  75. package/dist/components/progress-circular/ProgressCircular.js +1 -1
  76. package/dist/components/progress-linear/ProgressLinear.js +1 -1
  77. package/dist/components/rating/Rating.d.ts +100 -0
  78. package/dist/components/rating/Rating.js +1 -0
  79. package/dist/components/rating/index.d.ts +1 -0
  80. package/dist/components/rating/index.js +1 -0
  81. package/dist/components/scatter-chart/ScatterChart.d.ts +45 -0
  82. package/dist/components/scatter-chart/ScatterChart.js +1 -0
  83. package/dist/components/scatter-chart/index.d.ts +2 -0
  84. package/dist/components/scatter-chart/index.js +1 -0
  85. package/dist/components/select/Select.d.ts +1 -3
  86. package/dist/components/select/Select.js +1 -1
  87. package/dist/components/sparkline/Sparkline.d.ts +67 -0
  88. package/dist/components/sparkline/Sparkline.js +1 -0
  89. package/dist/components/sparkline/index.d.ts +2 -0
  90. package/dist/components/sparkline/index.js +1 -0
  91. package/dist/components/statistic/Statistic.d.ts +7 -0
  92. package/dist/components/statistic/Statistic.js +1 -1
  93. package/dist/components/table/Table.d.ts +13 -2
  94. package/dist/components/table/Table.js +1 -1
  95. package/dist/components/text-link/TextLink.js +1 -1
  96. package/dist/components/time-picker/TimePicker.js +1 -1
  97. package/dist/components/timeline-chart/TimelineChart.d.ts +44 -0
  98. package/dist/components/timeline-chart/TimelineChart.js +1 -0
  99. package/dist/components/timeline-chart/index.d.ts +2 -0
  100. package/dist/components/timeline-chart/index.js +1 -0
  101. package/dist/components/toast/Toast.d.ts +10 -2
  102. package/dist/components/toast/Toast.js +1 -1
  103. package/dist/components/tooltip/Tooltip.d.ts +2 -4
  104. package/dist/components/tooltip/Tooltip.js +1 -1
  105. package/dist/components/tree-view/TreeView.js +1 -1
  106. package/dist/index.d.ts +15 -0
  107. package/dist/index.js +1 -1
  108. package/dist/internal/animate.d.ts +0 -9
  109. package/dist/internal/animate.js +1 -1
  110. package/dist/internal/calendar.js +1 -1
  111. package/dist/internal/chart-frame.d.ts +409 -0
  112. package/dist/internal/chart-frame.js +1 -0
  113. package/dist/internal/chart-line.d.ts +44 -0
  114. package/dist/internal/chart-line.js +1 -0
  115. package/dist/internal/chart.d.ts +456 -0
  116. package/dist/internal/chart.js +1 -0
  117. package/dist/internal/data-table.d.ts +170 -0
  118. package/dist/internal/data-table.js +1 -0
  119. package/dist/internal/date.d.ts +0 -2
  120. package/dist/internal/date.js +1 -1
  121. package/dist/internal/format.d.ts +29 -0
  122. package/dist/internal/format.js +1 -0
  123. package/dist/internal/i18n.d.ts +166 -0
  124. package/dist/internal/i18n.js +1 -1
  125. package/dist/internal/icons.d.ts +2 -0
  126. package/dist/internal/icons.js +1 -1
  127. package/dist/internal/mockup.d.ts +193 -0
  128. package/dist/internal/mockup.js +1 -0
  129. package/dist/internal/picker.d.ts +2 -4
  130. package/dist/internal/picker.js +1 -1
  131. package/dist/internal/progress.d.ts +1 -3
  132. package/dist/styles.css +1 -1
  133. package/dist/tailwind.css +231 -11
  134. package/dist/types.d.ts +214 -0
  135. package/package.json +19 -15
package/README.md CHANGED
@@ -38,8 +38,6 @@ Everything is documented at **[neba.cdget.com](https://neba.cdget.com)**, where
38
38
  | [**Color**](https://neba.cdget.com/design/color) | The token families, and how to theme them. |
39
39
  | [**Changelog**](https://neba.cdget.com/changelog) | What changed in each release, and the setup changes worth acting on. |
40
40
 
41
- Also available in Korean / 한국어 문서: **[neba.cdget.com/ko/](https://neba.cdget.com/ko/)**
42
-
43
41
  ## Installation
44
42
 
45
43
  ```bash
@@ -111,19 +109,21 @@ Placement props are logical, not physical — `start`/`end` rather than `left`/`
111
109
 
112
110
  ### Components
113
111
 
114
- **Inputs** — Button, IconButton, ButtonGroup, SegmentedButton, TextField, NumberField, OtpField, Select, Combobox, Checkbox, RadioGroup, Switch, Slider, Menu (with submenus, checkbox and radio items), ContextMenu, FilePicker, Pagination, ColorPicker, DatePicker, TimePicker, DateTimePicker, DateRangePicker
112
+ **Inputs** — Button, IconButton, ButtonGroup, SegmentedButton, FloatingActionButton (with FloatingAction), TextField, NumberField, OtpField, Select, Combobox, Checkbox, RadioGroup, Switch, Slider, Rating, Menu (with submenus, checkbox and radio items), ContextMenu, FilePicker, Pagination, BottomNavigation, ColorPicker, DatePicker, TimePicker, DateTimePicker, DateRangePicker
113
+
114
+ **Surfaces** — Box, Card, Accordion, Collapsible, Tabs, Carousel, Toolbar, Pill, Spoiler, ChatBubble, Drawer, Popover, Mockup
115
115
 
116
- **Surfaces** — Box, Card, Accordion, Tabs, Carousel, Toolbar, Pill, Spoiler, ChatBubble, Drawer, Popover
116
+ **Display** — Typography, TextLink, Blockquote, Highlight, Divider, Chip, Badge, Avatar, Icon, Shortcut, List, Table, DataTable, Timeline, Breadcrumb, TreeView
117
117
 
118
- **Display** — Typography, TextLink, Blockquote, Highlight, Divider, Chip, Badge, Avatar, Icon, Shortcut, Statistic, List, Table, Timeline, Breadcrumb, TreeView
118
+ **Charts** — Statistic, Sparkline, LineChart, AreaChart, BarChart, PieChart, ScatterChart, TimelineChart, HeatmapChart
119
119
 
120
- **Feedback** — Alert, Dialog, Toast, Tooltip, Overlay, Skeleton, ProgressLinear, ProgressCircular, ProgressBox
120
+ **Feedback** — Alert, Dialog, Toast, Tooltip, Overlay, Skeleton, Empty, ProgressLinear, ProgressCircular, ProgressBox
121
121
 
122
122
  **Layout** — Container, Grid (with GridContainer), Panes, AspectRatio
123
123
 
124
124
  **Transitions** — AnimateFade, AnimateGrow, AnimateZoom, AnimateSlide, AnimateRotate, AnimateBlink, AnimateAppear, AnimateTyping, AnimateLighting, AnimateMarquee, AnimateHeadline
125
125
 
126
- Recent additions: the **Animate** family — eleven wrappers that make anything move (**AnimateFade**, **AnimateGrow**, **AnimateZoom**, **AnimateSlide**, **AnimateRotate**, **AnimateBlink**, plus **AnimateAppear**, **AnimateTyping**, **AnimateLighting**, **AnimateMarquee** and **AnimateHeadline** for the effects that have to know what their children are), each taking the same settings for duration, delay, repeat and what triggers it; the six named effects are also a `transition` prop on the components that display something, and every one of them is switched off entirely by a reduced-motion preference. Alongside them, **ColorPicker** a saturation square, a hue rail, an optional opacity rail and a grid of swatches, reading and writing hex, `rgb()` and `hsl()` with no colour library underneath. Before those, **Drawer** (a panel on one edge of the window, either floating over the page or fixed in the layout — one component, one `mode` prop apart), **Popover** (a sheet anchored to the control that opened it, holding content that can actually be clicked and typed into), **Skeleton** (the shape of something that has not loaded yet, so the page does not reflow when it arrives) and **AspectRatio** (a box that keeps a proportion whatever width it is given); before those, **ChatBubble** (one message in a conversation, where the avatar, the time, the delivery mark, the media and the link card are each drawn only when given something), **Spoiler** (content covered by a blur rather than hidden, so a reader can see there is something there without reading it by accident), **TextLink** (a link with no surface of its own, and a mark for the ones that take over the window), **Avatar** (falls back to initials, a glyph or a silhouette, so it is never an empty box), **TreeView**, **Breadcrumb**, **Panes** (regions with a draggable bar between each pair) and **OtpField**; before those, **Blockquote**, **Shortcut**, **Highlight**, **SegmentedButton** and **Timeline**, and the four pickers — **DatePicker**, **TimePicker**, **DateTimePicker** and **DateRangePicker** — which take and return a plain `Date` and add no date library to your bundle.
126
+ **Recently added** — Collapsible, Rating, BottomNavigation, FloatingActionButton, the charts (Sparkline, LineChart, AreaChart, BarChart, PieChart, ScatterChart, TimelineChart, HeatmapChart), DataTable, Empty, Mockup, the eleven `Animate*` wrappers, ColorPicker, Drawer, Popover, Skeleton, AspectRatio
127
127
 
128
128
  Each one has its own page — live previews, every prop, and the variations worth seeing — under [**All components**](https://neba.cdget.com/components/).
129
129
 
@@ -31,7 +31,15 @@ export interface AlertProps extends NebaStyleProps, Omit<React.ComponentPropsWit
31
31
  action?: React.ReactNode;
32
32
  /** Passing it is what makes the dismiss button appear. */
33
33
  onClose?: (event: React.MouseEvent<HTMLButtonElement>) => void;
34
- /** Accessible name of the dismiss button. */
34
+ /**
35
+ * Which language the dismiss button is named in — a BCP 47 tag such as `ko`, `pt-BR` or
36
+ * `zh-Hant`. Unsupported tags fall back to English.
37
+ *
38
+ * `closeLabel` writes the word out instead; this is for the far more common
39
+ * case where the page already knows its own language.
40
+ */
41
+ locale?: string;
42
+ /** Accessible name of the dismiss button. Defaults to the `locale`'s word. */
35
43
  closeLabel?: string;
36
44
  /** The message. */
37
45
  children?: React.ReactNode;
@@ -1 +1 @@
1
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{boxPaddingClasses as l}from"../box/Box";import{CloseIcon as i,severityIcons as s}from"../../internal/icons";import{transitionProps as a}from"../../internal/animate";import{controlSlots as o,hasContent as r,iconClasses as c,radiusClasses as d,sheetBodyClasses as f,sheetHeaderGapClasses as m,sheetSectionGapClasses as u,sheetTitleClasses as x,surfaceClasses as b,transitionClasses as v}from"../../internal/styles";const h={solid:[b,"text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[b,"border text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--neba-fg) bg-(--n-soft)"},p={solid:"",outline:"text-(--n-accent)",text:"text-(--n-accent)"},y={solid:"",outline:"text-(--neba-muted-fg)",text:"text-(--neba-muted-fg)"},g={primary:"status",secondary:"status",info:"status",success:"status",warning:"alert",danger:"alert"};export const Alert=n.forwardRef(function({variant:n="outline",size:b="md",color:N="info",density:j="default",elevation:w=0,title:k,icon:$,action:_,onClose:z,closeLabel:B="Dismiss",transition:C,className:A,style:D,children:L,...R},q){const E=void 0===$?s[N]:$,F=p[n],G=r(k),H=a(C);return t("div",{ref:q,role:g[N],className:["flex w-full items-start",l[j][b],d[b],u[b],f[b],v,h[n],c,H.className,A??""].filter(Boolean).join(" "),style:{...o(N,w,n),...H.style,...D},...R,children:[r(E)?e("span",{className:`flex h-[1lh] shrink-0 items-center ${F}`,children:E}):null,t("div",{className:`flex min-w-0 flex-1 flex-col ${m[b]}`,children:[G?e("div",{className:`neba-title font-semibold ${x[b]} ${F}`,children:k}):null,r(L)?e("div",{className:G?y[n]:void 0,children:L}):null]}),r(_)?e("div",{className:"flex h-[1lh] shrink-0 items-center",children:_}):null,z?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:e("button",{type:"button","aria-label":B,onClick:z,className:["inline-flex size-[1.15em] cursor-pointer items-center justify-center rounded-full","opacity-70 [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-2"].join(" "),children:e(i,{})})}):null]})});
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{boxPaddingClasses as i}from"../box/Box";import{useMessages as l}from"../../internal/i18n";import{CloseIcon as s,severityIcons as a}from"../../internal/icons";import{transitionProps as o}from"../../internal/animate";import{controlSlots as r,hasContent as c,iconClasses as d,radiusClasses as m,sheetBodyClasses as f,sheetHeaderGapClasses as u,sheetSectionGapClasses as x,sheetTitleClasses as b,surfaceClasses as v,transitionClasses as h}from"../../internal/styles";const p={solid:[v,"text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[v,"border text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--neba-fg) bg-(--n-soft)"},y={solid:"",outline:"text-(--n-accent)",text:"text-(--n-accent)"},g={solid:"",outline:"text-(--neba-muted-fg)",text:"text-(--neba-muted-fg)"},N={primary:"status",secondary:"status",info:"status",success:"status",warning:"alert",danger:"alert"};export const Alert=n.forwardRef(function({variant:n="outline",size:v="md",color:j="info",density:w="default",elevation:k=0,title:$,icon:_,action:z,onClose:B,locale:C,closeLabel:A,transition:L,className:R,style:q,children:D,...E},F){const G=l(C),H=void 0===_?a[j]:_,I=y[n],J=c($),K=o(L);return t("div",{ref:F,role:N[j],className:["flex w-full items-start",i[w][v],m[v],x[v],f[v],h,p[n],d,K.className,R??""].filter(Boolean).join(" "),style:{...r(j,k,n),...K.style,...q},...E,children:[c(H)?e("span",{className:`flex h-[1lh] shrink-0 items-center ${I}`,children:H}):null,t("div",{className:`flex min-w-0 flex-1 flex-col ${u[v]}`,children:[J?e("div",{className:`neba-title font-semibold ${b[v]} ${I}`,children:$}):null,c(D)?e("div",{className:J?g[n]:void 0,children:D}):null]}),c(z)?e("div",{className:"flex h-[1lh] shrink-0 items-center",children:z}):null,B?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:e("button",{type:"button","aria-label":A??G.action.dismiss,onClick:B,className:["inline-flex size-[1.15em] cursor-pointer items-center justify-center rounded-full","opacity-70 [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-2"].join(" "),children:e(s,{})})}):null]})});
@@ -0,0 +1,54 @@
1
+ import * as React from 'react';
2
+ import { type CartesianChartProps } from '../../internal/chart-frame';
3
+ import { type ChartMarkers } from '../../internal/chart-line';
4
+ import type { NebaChartCurve, NebaChartValueLabels } from '../../types';
5
+ export interface AreaChartProps extends CartesianChartProps {
6
+ /**
7
+ * How the edge of the band gets from one point to the next. The same three
8
+ * shapes a [LineChart](./line-chart) offers, and they mean the same things.
9
+ * @default 'linear'
10
+ */
11
+ curve?: NebaChartCurve;
12
+ /**
13
+ * Stacks the bands, each one riding on the total of those below it.
14
+ *
15
+ * - `true` — absolute totals. The top edge is the sum, which is the thing a
16
+ * stacked area is usually drawn to show.
17
+ * - `'full'` — every category normalised to 100%, so the chart is about
18
+ * *share* and stops being about size. The value axis becomes a percentage
19
+ * and says so.
20
+ * @default false
21
+ */
22
+ stacked?: boolean | 'full';
23
+ /**
24
+ * Dots on the points. `none` by default rather than `auto`: a filled band
25
+ * already has a visible edge, and a row of dots on it is ink that says
26
+ * nothing the fill did not.
27
+ * @default 'none'
28
+ */
29
+ markers?: ChartMarkers;
30
+ /** @default 'none' */
31
+ valueLabels?: NebaChartValueLabels;
32
+ /**
33
+ * Draws the band straight through a `null` instead of breaking at it. Off,
34
+ * and on an area it matters more than on a line: a fill that closes across a
35
+ * missing month paints a made-up number over a larger part of the chart.
36
+ * @default false
37
+ */
38
+ connectNulls?: boolean;
39
+ }
40
+ /**
41
+ * A line with the space under it filled — which changes what the chart is
42
+ * about.
43
+ *
44
+ * A line says where a value went. An area says how much of something there was,
45
+ * and stacked it says how that amount was made up. That is the whole test for
46
+ * reaching for this instead of a [LineChart](./line-chart): if the quantity
47
+ * does not add up to anything — a temperature, a rate, a score — the fill under
48
+ * it is decoration, and a chart with two of them is two washes fighting.
49
+ *
50
+ * Unstacked bands are a wash at about a quarter opacity, fading out downward,
51
+ * so two of them overlapping stay readable. Stacked bands are opaquer, because
52
+ * there the fill *is* the mark rather than a hint at the line above it.
53
+ */
54
+ export declare function AreaChart({ curve, stacked, markers, valueLabels, connectNulls, series, yAxis, format, ...props }: AreaChartProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ import{jsx as e}from"react/jsx-runtime";import*as r from"react";import{CartesianChart as a}from"../../internal/chart-frame";import{LineSeries as t}from"../../internal/chart-line";import{toValues as n}from"../../internal/chart";export function AreaChart({curve:o="linear",stacked:l=!1,markers:i="none",valueLabels:c="none",connectNulls:s=!1,series:m,yAxis:u,format:f,...d}){const x=r.useId().replace(/:/g,""),p="full"===l,h=r.useMemo(()=>{if(!p)return m;const e=n(m),r=[];for(const a of e)a.forEach((e,a)=>{r[a]=(r[a]??0)+Math.abs(e.value??0)});return m.map((a,t)=>({...a,data:e[t].map((e,a)=>{if(null===e.value)return null;const t=r[a];return{x:e.x,y:0===t?0:e.value/t*100,color:e.color,label:e.label??String(e.value)}})}))},[m,p]);return e(a,{...d,series:h,format:f,yAxis:p?{min:0,max:100,tickFormat:e=>`${e}%`,...u}:u,stacked:!1!==l,inset:!0,includeZero:!0,headroom:"none"===c?0:10,children:r=>e(t,{context:r,curve:o,filled:!0,stacked:!1!==l,markers:i,valueLabels:c,connectNulls:s,gradient:!1,idPrefix:x})})}
@@ -0,0 +1,2 @@
1
+ export { AreaChart } from './AreaChart';
2
+ export type { AreaChartProps } from './AreaChart';
@@ -0,0 +1 @@
1
+ export{AreaChart}from"./AreaChart";
@@ -0,0 +1,63 @@
1
+ import * as React from 'react';
2
+ import { type CartesianChartProps } from '../../internal/chart-frame';
3
+ import type { NebaChartValueLabels, NebaOrientation } from '../../types';
4
+ export interface BarChartProps extends CartesianChartProps {
5
+ /**
6
+ * Which way the bars run.
7
+ *
8
+ * `vertical` — the default — grows them up from the bottom, which is what
9
+ * most people mean by a bar chart. `horizontal` grows them out from the left,
10
+ * and it is the right answer whenever the category names are words: a
11
+ * horizontal chart has a whole column for them, and a vertical one has the
12
+ * width of one bar.
13
+ * @default 'vertical'
14
+ */
15
+ orientation?: NebaOrientation;
16
+ /**
17
+ * Puts the series on top of each other instead of beside each other.
18
+ *
19
+ * - `false` — grouped. Comparing series within a category.
20
+ * - `true` — stacked. The bar's whole length is the total, and the segments
21
+ * are what it is made of.
22
+ * - `'full'` — every bar the same length, so the chart is about share rather
23
+ * than size. The value axis becomes a percentage.
24
+ * @default false
25
+ */
26
+ stacked?: boolean | 'full';
27
+ /**
28
+ * Cuts the corners off the data end of each bar. The baseline end stays
29
+ * square — that is where the value starts from, and a rounded foot makes the
30
+ * axis look scalloped.
31
+ * @default true
32
+ */
33
+ rounded?: boolean;
34
+ /**
35
+ * How thick a bar may get, in pixels. Below the cap the bars fill their share
36
+ * of the band; above it the leftover stays as air.
37
+ * @default the `size` ladder — 24 at `md`
38
+ */
39
+ barSize?: number;
40
+ /**
41
+ * Which values are written on the bars.
42
+ *
43
+ * `all` is defensible here in a way it is not on a line chart: eight bars
44
+ * with their numbers on them is a chart and a table at once. Past about a
45
+ * dozen it stops being either.
46
+ * @default 'none'
47
+ */
48
+ valueLabels?: NebaChartValueLabels;
49
+ }
50
+ /**
51
+ * Lengths, compared.
52
+ *
53
+ * A bar says *how much*, and it says it by being longer — which is the whole
54
+ * reason its axis starts at zero and cannot be talked out of it. Crop the scale
55
+ * and a bar twice as long stops meaning twice as much, and the reader has no
56
+ * way to know it happened. Reach for a [LineChart](./line-chart) when what
57
+ * matters is the shape of a change rather than the size of each value.
58
+ *
59
+ * Grouped bars answer "which series is bigger here"; stacked bars answer "what
60
+ * is this total made of". They are different questions and the chart should be
61
+ * asked only one of them at a time.
62
+ */
63
+ export declare function BarChart({ orientation, stacked, rounded, barSize, valueLabels, series, yAxis, size, density, ...props }: BarChartProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as a from"react";import{CartesianChart as n}from"../../internal/chart-frame";import{barBandRatio as l,barMaxThickness as r,barPath as o,barRadius as i,chartFontSizes as u,markGap as s,toValues as c}from"../../internal/chart";export function BarChart({orientation:t="vertical",stacked:o=!1,rounded:i=!0,barSize:u,valueLabels:s="none",series:h,yAxis:m,size:v="md",density:f="default",...x}){const b="horizontal"===t,p="full"===o,y=a.useMemo(()=>{if(!p)return h;const e=c(h),t=[];for(const a of e)a.forEach((e,a)=>{t[a]=(t[a]??0)+Math.abs(e.value??0)});return h.map((a,n)=>({...a,data:e[n].map((e,a)=>{if(null===e.value)return null;const n=t[a];return{x:e.x,y:0===n?0:e.value/n*100,color:e.color,label:e.label??String(e.value)}})}))},[h,p]);return e(n,{...x,series:y,size:v,density:f,horizontal:b,stacked:!1!==o,yAxis:p?{min:0,max:100,tickFormat:e=>`${e}%`,...m}:m,includeZero:!0,bandRatio:l[f],headroom:"none"===s?0:12,children:t=>e(d,{context:t,stacked:!1!==o,rounded:i,barSize:u??r[v],valueLabels:s,size:v})})}function d({context:a,stacked:n,rounded:l,barSize:r,valueLabels:c,size:d}){const{values:m,visible:v,colors:f,hovered:x,activeIndex:b,plot:p,band:y,horizontal:z,valuePx:g,categoryPx:M,zeroPx:k,format:S}=a,j=m.map((e,t)=>({one:e,index:t})).filter(e=>v[e.index]),A=n?1:Math.max(1,j.length),L=Math.min(r,Math.max(1,(y.band-s*(A-1))/A)),P=L*A+s*(A-1),W=[],w=[],B=u[d];return t("g",{children:[j.map(({one:a,index:r},u)=>{const d=f[r];return e("g",{opacity:null!==x&&x!==r?.28:1,children:a.map((r,m)=>{if(null===r.value)return null;const v=M(m),f=n?0:u*(L+s)-P/2+L/2,x=n?r.value>=0?W[m]??0:w[m]??0:0,y=g(x),k=g(x+r.value);n&&(r.value>=0?W[m]=x+r.value:w[m]=x+r.value);const j=n&&0!==x?s:0,A=Math.abs(k-y)-j;if(A<=0)return null;const C=k<y,E=m===b,F=z?o(Math.min(y,k)+(C?0:j),p.top+v+f-L/2,A,L,l&&!n?i:l?i/2:0,r.value>=0?"right":"left"):o(p.left+v+f-L/2,Math.min(y,k)+(C?0:j),L,A,l&&!n?i:l?i/2:0,r.value>=0?"up":"down");return t("g",{children:[e("path",{d:F,fill:r.color??d,opacity:E?1:.92}),"none"===c||"extremes"===c&&!h(a,m)||"last"===c&&m!==a.length-1?null:e("text",{x:z?k+(r.value>=0?5:-5):p.left+v+f,y:z?p.top+v+f:r.value>=0?k-5:k+B+2,textAnchor:z?r.value>=0?"start":"end":"middle",dominantBaseline:z?"central":void 0,fontSize:B,fontWeight:500,fill:"var(--neba-fg)",className:"tabular-nums",children:r.label??S(r.value)})]},m)})},r)}),e("line",z?{x1:k,x2:k,y1:p.top,y2:p.top+p.height,stroke:"var(--neba-chart-baseline)",strokeWidth:1}:{x1:p.left,x2:p.left+p.width,y1:k,y2:k,stroke:"var(--neba-chart-baseline)",strokeWidth:1})]})}function h(e,t){const a=e[t].value;if(null===a)return!1;let n=1/0,l=-1/0;for(const t of e)null!==t.value&&(n=Math.min(n,t.value),l=Math.max(l,t.value));return a===n||a===l}
@@ -0,0 +1,2 @@
1
+ export { BarChart } from './BarChart';
2
+ export type { BarChartProps } from './BarChart';
@@ -0,0 +1 @@
1
+ export{BarChart}from"./BarChart";
@@ -0,0 +1,111 @@
1
+ import * as React from 'react';
2
+ import { useRender } from '@base-ui/react/use-render';
3
+ import type { NebaElevation, NebaPosition, NebaStyleProps } from '../../types';
4
+ /** A destination's value. The same restraint Tabs and SegmentedButton put on theirs. */
5
+ export type BottomNavigationValue = string | number;
6
+ /**
7
+ * Which labels are drawn.
8
+ *
9
+ * - `all` — every destination is named. The default, and the only one that
10
+ * works for a reader who has not used the app before.
11
+ * - `selected` — only the destination that is current. The bar keeps its height
12
+ * either way, because the named one is always the tallest; what changes is
13
+ * how much of the row is words. The names the other items lose are still in
14
+ * the document for a screen reader.
15
+ * - `none` — glyphs only, with every name read out but never drawn.
16
+ */
17
+ export type BottomNavigationLabels = 'all' | 'selected' | 'none';
18
+ export interface BottomNavigationProps extends NebaStyleProps, Omit<React.ComponentPropsWithoutRef<'nav'>, 'color' | 'defaultValue' | 'onChange'> {
19
+ /** The destination the reader is on. Use with `onValueChange` for a controlled bar. */
20
+ value?: BottomNavigationValue | null;
21
+ /** Which starts current, for an uncontrolled bar. */
22
+ defaultValue?: BottomNavigationValue | null;
23
+ onValueChange?: (value: BottomNavigationValue) => void;
24
+ /**
25
+ * How the bar sits in the page's scroll. `fixed` — the default here, against
26
+ * the `static` everything else defaults to — is what a bottom navigation is:
27
+ * it is held against the bottom edge of the window whatever the page does,
28
+ * and the page pads itself out of the way.
29
+ * @default 'fixed'
30
+ */
31
+ position?: NebaPosition;
32
+ /** Which names are drawn. @default 'all' */
33
+ labels?: BottomNavigationLabels;
34
+ /**
35
+ * Draws a hairline along the top edge, against the content the bar is over.
36
+ *
37
+ * On by default, which is the other way round from Toolbar: a bar pinned over
38
+ * a scrolling page has content passing underneath it at every moment, and a
39
+ * translucent sheet with nothing marking its edge reads as part of that.
40
+ * @default true
41
+ */
42
+ divider?: boolean;
43
+ /**
44
+ * Keeps the bar clear of the home indicator on a phone, by adding
45
+ * `env(safe-area-inset-bottom)` under it. The sheet still reaches the bottom
46
+ * of the screen; only the items move up.
47
+ * @default true
48
+ */
49
+ safeArea?: boolean;
50
+ /**
51
+ * Drop shadow depth. `0` (the default) is flat: the bar is attached to the
52
+ * edge of the window rather than floating over the middle of it, and
53
+ * `divider` is what separates it from the content.
54
+ * @default 0
55
+ */
56
+ elevation?: NebaElevation;
57
+ /** Every destination stops answering. */
58
+ disabled?: boolean;
59
+ /** The name the bar is announced by — "Main", "Sections". */
60
+ label?: string;
61
+ /**
62
+ * Renders something other than a `<nav>`. Base UI's own escape hatch, and
63
+ * rarely what you want here: a row of destinations is navigation.
64
+ */
65
+ render?: useRender.RenderProp;
66
+ /** The BottomNavigationItems. */
67
+ children?: React.ReactNode;
68
+ }
69
+ export interface BottomNavigationItemProps extends Omit<React.ComponentPropsWithoutRef<'button'>, 'value' | 'color'> {
70
+ /** Identifies the destination. What `onValueChange` reports. */
71
+ value: BottomNavigationValue;
72
+ /** The glyph above the name. Sized on the standalone-glyph ladder. */
73
+ icon?: React.ReactNode;
74
+ /** Renders the item as a link rather than as a button. */
75
+ href?: string;
76
+ /** Unavailable, but still part of the set. */
77
+ disabled?: boolean;
78
+ /** The destination's name. Read out even when `labels` keeps it undrawn. */
79
+ children?: React.ReactNode;
80
+ }
81
+ /**
82
+ * A row of destinations held against the bottom edge of the window.
83
+ *
84
+ * It is a `<nav>` rather than a `role="tablist"`, and its items are ordinary
85
+ * links or buttons rather than tabs, which is a deliberate choice about what is
86
+ * being promised. A tab list owes a keyboard reader one tab stop for the whole
87
+ * set and arrow keys within it, and it owes a screen reader a panel per tab; a
88
+ * bottom navigation switches what the *page* is, not which panel of one is
89
+ * showing. Claiming the role without the behaviour is worse for a keyboard
90
+ * reader than never claiming it. What is claimed instead is `aria-current`,
91
+ * which is the honest statement: this is the destination you are on.
92
+ *
93
+ * The sheet reaches the bottom of the screen and the items are held clear of the
94
+ * home indicator by `safeArea`, so the acrylic runs under it rather than
95
+ * stopping in a stripe above it.
96
+ */
97
+ export declare const BottomNavigation: React.ForwardRefExoticComponent<BottomNavigationProps & React.RefAttributes<HTMLElement>>;
98
+ /**
99
+ * One destination.
100
+ *
101
+ * It has no `size`, no `color` and no `variant` of its own: all three belong to
102
+ * the bar, which is the only place they can be set once and mean the same thing
103
+ * for every item.
104
+ *
105
+ * With an `href` it is a real `<a>`, which is what makes a long press offer
106
+ * "open in a new tab" and what puts the destination in the status bar — neither
107
+ * of which a `<button>` that calls `router.push` can do. Without one it is a
108
+ * `<button>`, because a `<div>` carrying a click handler is invisible to a
109
+ * keyboard.
110
+ */
111
+ export declare const BottomNavigationItem: React.ForwardRefExoticComponent<BottomNavigationItemProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,Fragment as a,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{useRender as n}from"@base-ui/react/use-render";import{cx as i,hasContent as s,iconSizeClasses as r,metaTextClasses as o,radiusClasses as d,srOnlyClasses as c,surfaceClasses as u,surfaceSlots as m,transitionClasses as f}from"../../internal/styles";const p=l.createContext({value:null,change:()=>{},size:"md",density:"default",labels:"all",disabled:!1}),b={solid:[u,"text-(--neba-fg) bg-(--n-panel-hover)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[u,"text-(--neba-fg) bg-(--n-panel)","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--neba-fg) bg-transparent"},v={static:"",sticky:"sticky bottom-0 z-20",fixed:"fixed inset-x-0 bottom-0 z-30"},x={xs:"min-h-10",sm:"min-h-12",md:"min-h-14",lg:"min-h-16",xl:"min-h-18"},g={default:{xs:"p-1",sm:"p-1",md:"p-1.5",lg:"p-2",xl:"p-2.5"},compact:{xs:"p-0.5",sm:"p-0.5",md:"p-1",lg:"p-1",xl:"p-1.5"}},h={xs:"gap-0.5",sm:"gap-0.5",md:"gap-1",lg:"gap-1",xl:"gap-1.5"};export const BottomNavigation=l.forwardRef(function({variant:a="outline",size:t="md",color:s="primary",density:r="default",elevation:o=0,value:c,defaultValue:u=null,onValueChange:h,position:y="fixed",labels:w="all",divider:N=!0,safeArea:z=!0,disabled:k=!1,label:j,render:C,className:B,style:R,children:V,..._},A){const[D,F]=l.useState(u),I=void 0!==c,M=I?c:D,P=l.useCallback(e=>{I||F(e),h?.(e)},[I,h]),S=l.useMemo(()=>({value:M??null,change:P,size:t,density:r,labels:w,disabled:k}),[M,P,t,r,w,k]),q=i("w-full min-w-0","static"===y?d[t]:"",b[a],"outline"===a&&"static"===y?"border [border-color:var(--n-line)]":"",N?"border-t [border-color:var(--n-line)]":"",v[y],z?"pb-[env(safe-area-inset-bottom)]":"",f,B);return n({render:C??e("nav",{}),ref:A,props:{"aria-label":j,className:q,style:{...m(s,o),...R},children:e(p.Provider,{value:S,children:e("div",{className:i("flex w-full items-stretch",x[t],g[r][t]),children:V})}),..._}})});export const BottomNavigationItem=l.forwardRef(function({value:n,icon:u,href:m,disabled:b=!1,className:v,children:x,onClick:g,...y},w){const N=l.useContext(p),z=b||N.disabled,k=null!==N.value&&N.value===n,j="all"===N.labels||"selected"===N.labels&&k,C=i("flex min-w-0 flex-1 flex-col items-center justify-center px-1 py-1.5",h[N.size],d[N.size],"[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",f,"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:[outline-offset:-2px]",z?"cursor-not-allowed text-(--neba-disabled-fg)":k?"cursor-pointer font-medium text-(--n-accent) bg-(--n-soft) hover:bg-(--n-soft-hover)":"cursor-pointer text-(--neba-muted-fg) hover:text-(--neba-fg) hover:bg-(--n-panel-hover)",v),B=t(a,{children:[s(u)?e("span",{className:i("flex shrink-0 items-center justify-center",r[N.size]),children:u}):null,s(x)?e("span",{className:j?i("max-w-full truncate leading-tight",o[N.size]):c,children:x}):null]}),R=e=>{z?e.preventDefault():(N.change(n),g?.(e))};return m?e("a",{ref:w,href:z?void 0:m,"aria-current":k?"page":void 0,"aria-disabled":z||void 0,className:C,onClick:R,...y,children:B}):e("button",{ref:w,type:"button",disabled:z,"aria-current":k?"page":void 0,className:C,onClick:R,...y,children:B})});
@@ -0,0 +1 @@
1
+ export * from './BottomNavigation';
@@ -0,0 +1 @@
1
+ export*from"./BottomNavigation";
@@ -37,10 +37,43 @@ export interface BreadcrumbProps extends Omit<React.ComponentPropsWithoutRef<'na
37
37
  * @default true
38
38
  */
39
39
  expandable?: boolean;
40
- /** The name the trail is announced by. @default 'Breadcrumb' */
40
+ /**
41
+ * Which language the trail names itself in — a BCP 47 tag such as `ko`,
42
+ * `pt-BR` or `zh-Hant`. Unsupported tags fall back to English.
43
+ *
44
+ * Both strings below write the words out instead; this is for the far more
45
+ * common case where the page already knows its own language.
46
+ */
47
+ locale?: string;
48
+ /** The name the trail is announced by. Defaults to the `locale`'s word. */
41
49
  label?: string;
42
- /** What the `…` is announced as. @default 'Show hidden steps' */
50
+ /** What the `…` is announced as. Defaults to the `locale`'s wording. */
43
51
  expandLabel?: string;
52
+ /**
53
+ * Emits the trail a second time as a `BreadcrumbList`, in a
54
+ * `<script type="application/ld+json">` beside the markup.
55
+ *
56
+ * Off by default, because a page can only have one of these and a great many
57
+ * apps already emit theirs from an SEO layer of their own — two would be a
58
+ * page describing itself twice. Turn it on where this component *is* the
59
+ * trail: correct markup alone is not what puts a path under a search result,
60
+ * and the structured data is.
61
+ *
62
+ * Every step goes in, including the ones a `maxItems` fold is hiding — what is
63
+ * collapsed is a matter of how much room the row has, and the path is the
64
+ * path either way.
65
+ * @default false
66
+ */
67
+ structuredData?: boolean;
68
+ /**
69
+ * What relative `href`s are resolved against for `structuredData` — the
70
+ * site's origin, as `https://example.com`.
71
+ *
72
+ * Search engines want an absolute URL there. Without this the `href`s are
73
+ * emitted exactly as written, which is right when they are already absolute
74
+ * and not much use when they are not.
75
+ */
76
+ baseUrl?: string;
44
77
  /** The BreadcrumbItems. */
45
78
  children?: React.ReactNode;
46
79
  }
@@ -1 +1 @@
1
- import{jsx as e,jsxs as a,Fragment as n}from"react/jsx-runtime";import*as t from"react";import{ArrowRightIcon as s,ChevronIcon as r,EllipsisIcon as l}from"../../internal/icons";import{controlTextClasses as i,cx as c,gapClasses as o,hasContent as m,iconClasses as d,radiusClasses as f,transitionClasses as u}from"../../internal/styles";const h=t.createContext({size:"md",last:!1}),p={default:{xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-2.5",xl:"gap-3"},compact:{xs:"gap-0.5",sm:"gap-1",md:"gap-1",lg:"gap-1.5",xl:"gap-2"}},x={xs:f.xs,sm:f.xs,md:f.xs,lg:f.sm,xl:f.sm};const b=["chevron","arrow","slash","dot"];export const Breadcrumb=t.forwardRef(function({size:n="md",color:o="primary",density:m="default",separator:f="chevron",maxItems:x,itemsBeforeCollapse:g=1,itemsAfterCollapse:v=1,expandable:N=!0,label:y="Breadcrumb",expandLabel:w="Show hidden steps",className:k,style:C,children:B,...z},I){const[_,j]=t.useState(!1),M=t.Children.toArray(B).filter(t.isValidElement),$=M.length,A=M.some(e=>!0===e.props.current),F=!_&&void 0!==x&&$>Math.max(x,1)&&$-g-v>1?[...M.slice(0,Math.max(0,g)),null,...M.slice($-Math.max(0,v))]:M,R="string"==typeof(S=f)&&b.includes(S)?function(a){switch(a){case"chevron":return e("span",{className:"flex -rotate-90 items-center rtl:rotate-90",children:e(r,{})});case"arrow":return e("span",{className:"flex items-center rtl:rotate-180",children:e(s,{})});case"slash":return e("span",{className:"opacity-70",children:"/"});case"dot":return e("span",{className:"opacity-70",children:"·"});default:return null}}(f):f;var S;const E=c("inline-flex items-center rounded-(--neba-radius-xs) px-0.5","text-(--neba-muted-fg)",u,d,N?c("cursor-pointer hover:bg-(--n-soft) hover:text-(--n-accent)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1"):"");return e("nav",{ref:I,"aria-label":y,className:c("flex",i[n],d,k),style:{"--n-accent":`var(--neba-${o}-accent)`,"--n-soft":`var(--neba-${o}-soft)`,"--n-ring":`var(--neba-${o}-ring)`,...C},...z,children:e("ol",{role:"list",className:c("flex list-none flex-wrap items-center p-0",p[m][n]),children:F.map((s,r)=>a(t.Fragment,{children:[r>0?e("li",{"aria-hidden":"true",className:"flex shrink-0 items-center text-(--neba-muted-fg) select-none",children:R}):null,s?e(h.Provider,{value:{size:n,last:!A&&r===F.length-1},children:s}):e("li",{className:"flex shrink-0 items-center",children:N?e("button",{type:"button",className:E,"aria-label":w,onClick:()=>j(!0),children:e(l,{})}):e("span",{className:E,"aria-hidden":"true",children:e(l,{})})})]},s?s.key??r:"fold"))})})});export const BreadcrumbItem=t.forwardRef(function({href:s,onClick:r,startIcon:l,endIcon:i,current:d,disabled:f=!1,className:p,children:b,...g},v){const{size:N,last:y}=t.useContext(h),w=d??y,k=Boolean(s||r)&&!w&&!f,C=c("inline-flex min-w-0 items-center px-1",o[N],x[N],u,f?"cursor-not-allowed text-(--neba-disabled-fg)":w?"font-medium text-(--neba-fg)":k?c("cursor-pointer text-(--neba-muted-fg)","hover:bg-(--n-soft) hover:text-(--n-accent)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1"):"text-(--neba-muted-fg)"),B=a(n,{children:[m(l)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:l}):null,e("span",{className:"truncate",children:b}),m(i)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:i}):null]});return e("li",{ref:v,className:c("flex min-w-0 items-center",p),...g,children:k&&s?e("a",{href:s,className:C,onClick:r,children:B}):k?e("button",{type:"button",className:C,onClick:r,children:B}):e("span",{className:C,"aria-current":w?"page":void 0,"aria-disabled":f||void 0,children:B})})});
1
+ import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import*as r from"react";import{useMessages as a}from"../../internal/i18n";import{ArrowRightIcon as s,ChevronIcon as l,EllipsisIcon as i}from"../../internal/icons";import{controlTextClasses as c,cx as o,gapClasses as m,hasContent as d,iconClasses as u,radiusClasses as p,transitionClasses as f}from"../../internal/styles";const h=r.createContext({size:"md",last:!1}),x={default:{xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-2.5",xl:"gap-3"},compact:{xs:"gap-0.5",sm:"gap-1",md:"gap-1",lg:"gap-1.5",xl:"gap-2"}},b={xs:p.xs,sm:p.xs,md:p.xs,lg:p.sm,xl:p.sm};const g=["chevron","arrow","slash","dot"];function v(e){return"string"==typeof e||"number"==typeof e?String(e):Array.isArray(e)?e.map(v).join(""):r.isValidElement(e)?v(e.props.children):""}function y(e,t){if(!t)return e;try{return new URL(e,t).href}catch{return e}}function N(e,t){const n=e.map((e,n)=>{const{href:r,children:a}=e.props;return{"@type":"ListItem",position:n+1,name:v(a),...r?{item:y(r,t)}:null}});return JSON.stringify({"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:n}).replace(/</g,"\\u003c")}export const Breadcrumb=r.forwardRef(function({size:n="md",color:m="primary",density:d="default",separator:p="chevron",maxItems:b,itemsBeforeCollapse:v=1,itemsAfterCollapse:y=1,expandable:w=!0,locale:k,label:C,expandLabel:I,structuredData:L=!1,baseUrl:_,className:j,style:B,children:z,...A},M){const S=a(k),[E,R]=r.useState(!1),$=r.Children.toArray(z).filter(r.isValidElement),F=$.length,U=$.some(e=>!0===e.props.current),V=!E&&void 0!==b&&F>Math.max(b,1)&&F-v-y>1?[...$.slice(0,Math.max(0,v)),null,...$.slice(F-Math.max(0,y))]:$,D="string"==typeof(H=p)&&g.includes(H)?function(t){switch(t){case"chevron":return e("span",{className:"flex -rotate-90 items-center rtl:rotate-90",children:e(l,{})});case"arrow":return e("span",{className:"flex items-center rtl:rotate-180",children:e(s,{})});case"slash":return e("span",{className:"opacity-70",children:"/"});case"dot":return e("span",{className:"opacity-70",children:"·"});default:return null}}(p):p;var H;const J=o("inline-flex items-center rounded-(--neba-radius-xs) px-0.5","text-(--neba-muted-fg)",f,u,w?o("cursor-pointer hover:bg-(--n-soft) hover:text-(--n-accent)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1"):"");return t("nav",{ref:M,"aria-label":C??S.breadcrumb.label,className:o("flex",c[n],u,j),style:{"--n-accent":`var(--neba-${m}-accent)`,"--n-soft":`var(--neba-${m}-soft)`,"--n-ring":`var(--neba-${m}-ring)`,...B},...A,children:[L&&F>0?e("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:N($,_)}}):null,e("ol",{role:"list",className:o("flex list-none flex-wrap items-center p-0",x[d][n]),children:V.map((a,s)=>t(r.Fragment,{children:[s>0?e("li",{"aria-hidden":"true",className:"flex shrink-0 items-center text-(--neba-muted-fg) select-none",children:D}):null,a?e(h.Provider,{value:{size:n,last:!U&&s===V.length-1},children:a}):e("li",{className:"flex shrink-0 items-center",children:w?e("button",{type:"button",className:J,"aria-label":I??S.breadcrumb.expand,onClick:()=>R(!0),children:e(i,{})}):e("span",{className:J,"aria-hidden":"true",children:e(i,{})})})]},a?a.key??s:"fold"))})]})});export const BreadcrumbItem=r.forwardRef(function({href:a,onClick:s,startIcon:l,endIcon:i,current:c,disabled:u=!1,className:p,children:x,...g},v){const{size:y,last:N}=r.useContext(h),w=c??N,k=Boolean(a||s)&&!w&&!u,C=o("inline-flex min-w-0 items-center px-1",m[y],b[y],f,u?"cursor-not-allowed text-(--neba-disabled-fg)":w?"font-medium text-(--neba-fg)":k?o("cursor-pointer text-(--neba-muted-fg)","hover:bg-(--n-soft) hover:text-(--n-accent)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1"):"text-(--neba-muted-fg)"),I=t(n,{children:[d(l)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:l}):null,e("span",{className:"truncate",children:x}),d(i)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:i}):null]});return e("li",{ref:v,className:o("flex min-w-0 items-center",p),...g,children:k&&a?e("a",{href:a,className:C,onClick:s,children:I}):k?e("button",{type:"button",className:C,onClick:s,children:I}):e("span",{className:C,"aria-current":w?"page":void 0,"aria-disabled":u||void 0,children:I})})});
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { useRender } from '@base-ui/react/use-render';
2
3
  import type { NebaElevation, NebaStyleProps } from '../../types';
3
4
  export interface ButtonProps extends NebaStyleProps, Omit<React.ComponentPropsWithoutRef<'button'>, 'color'> {
4
5
  /**
@@ -20,6 +21,21 @@ export interface ButtonProps extends NebaStyleProps, Omit<React.ComponentPropsWi
20
21
  readOnly?: boolean;
21
22
  /** Stretches to the width of the container. */
22
23
  fullWidth?: boolean;
24
+ /**
25
+ * Renders something other than a `<button>` — an `<a href>` for an action that
26
+ * is really a navigation, or the `Link` a router brings. Base UI's own escape
27
+ * hatch, so it behaves here as it does on [TextLink](../display/text-link) and
28
+ * [Typography](../display/typography).
29
+ *
30
+ * The surface, the sizes and the press signature are unchanged; what changes
31
+ * is the element they are drawn on, and what it *is* to everything reading the
32
+ * page. A link stays a link: it is announced as one, it is in the list a
33
+ * screen reader can pull up, and a crawler follows it.
34
+ *
35
+ * An `<a>` has no `disabled`, so a button that has to be unavailable stays a
36
+ * `<button>`.
37
+ */
38
+ render?: useRender.RenderProp;
23
39
  children?: React.ReactNode;
24
40
  }
25
41
  export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
@@ -1 +1 @@
1
- import{jsx as e,jsxs as o}from"react/jsx-runtime";import*as t from"react";import{Button as n}from"@base-ui/react/button";import{ButtonGroupContext as r}from"../../internal/button-group";import{controlHeightClasses as a,controlSlots as l,controlSquareClasses as s,controlTextClasses as i,disabledClasses as d,focusRingClasses as v,gapClasses as c,iconClasses as p,paddingXClasses as x,pressTransitionClasses as b,radiusClasses as u,readOnlyFilterClasses as m,surfaceClasses as g,transitionClasses as h}from"../../internal/styles";const f={xs:`${a.xs} ${c.xs} ${u.xs} ${i.xs}`,sm:`${a.sm} ${c.sm} ${u.sm} ${i.sm}`,md:`${a.md} ${c.md} ${u.md} ${i.md}`,lg:`${a.lg} ${c.lg} ${u.lg} ${i.lg}`,xl:`${a.xl} ${c.xl} ${u.xl} ${i.xl}`},$={xs:`${s.xs} px-0`,sm:`${s.sm} px-0`,md:`${s.md} px-0`,lg:`${s.lg} px-0`,xl:`${s.xl} px-0`},y=["relative inline-flex shrink-0 select-none items-center justify-center","whitespace-nowrap align-middle font-medium leading-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",h,b,v,p].join(" "),w={solid:[g,"text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[g,"border text-(--n-accent) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--n-accent) bg-transparent"},j={solid:["hover:bg-(--n-fill-hover)","hover:[box-shadow:var(--n-elev-hover),var(--neba-plate-solid)]","active:bg-(--n-fill-active)","active:[box-shadow:var(--n-elev-press),var(--neba-plate-solid)]"].join(" "),outline:["hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)]","hover:[box-shadow:var(--n-elev-hover),var(--neba-plate-glass)]","active:bg-(--n-panel-press)","active:[box-shadow:var(--n-elev-press),var(--neba-plate-glass)]"].join(" "),text:"hover:bg-(--n-soft) active:bg-(--n-soft-hover)"},k={solid:[g,m,"cursor-default text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--neba-plate-solid)]"].join(" "),outline:[g,m,"cursor-default border text-(--n-accent) bg-(--n-panel)","[border-color:var(--n-line)] [box-shadow:var(--neba-plate-glass)]"].join(" "),text:`${m} cursor-default text-(--n-accent) bg-transparent`};function C(){return o("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"animate-spin",children:[e("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeOpacity:"0.25",strokeWidth:"2"}),e("path",{d:"M14.5 8A6.5 6.5 0 0 0 8 1.5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}export const Button=t.forwardRef(function({variant:a,size:s,color:i,density:v,elevation:c,startIcon:p,endIcon:b,loading:u=!1,readOnly:m=!1,fullWidth:g=!1,disabled:h,className:P,style:B,children:M,onClick:N,onPointerMove:W,...z},E){const I=t.useContext(r),O=a??I?.variant??"solid",A=s??I?.size??"md",D=i??I?.color??"primary",L=v??I?.density??"default",R=c??I?.elevation??0,T=h??I?.disabled??!1,X=null==M||!1===M,Y=u||m,q=[y,f[A],X?$[A]:x[L][A],T?d[O]:m?k[O]:w[O],T||Y?"":[j[O],"neba-glow","cursor-pointer"].join(" "),u?"cursor-progress":"",g?"w-full":"",P??""].filter(Boolean).join(" ");return o(n,{ref:E,disabled:T,className:q,style:{...l(D,R,O),...B},"aria-disabled":Y||void 0,"aria-busy":u||void 0,"data-loading":u||void 0,"data-readonly":m||void 0,onClick:e=>{if(Y)return e.preventDefault(),void e.stopPropagation();N?.(e)},onPointerMove:e=>{const o=e.currentTarget;o.style.setProperty("--n-mx",`${e.nativeEvent.offsetX}px`),o.style.setProperty("--n-my",`${e.nativeEvent.offsetY}px`),W?.(e)},...z,children:[u?e(C,{}):p,M,b]})});
1
+ import{jsx as e,jsxs as o,Fragment as r}from"react/jsx-runtime";import*as n from"react";import{Button as t}from"@base-ui/react/button";import{useRender as a}from"@base-ui/react/use-render";import{ButtonGroupContext as l}from"../../internal/button-group";import{controlHeightClasses as s,controlSlots as i,controlSquareClasses as d,controlTextClasses as c,disabledClasses as v,focusRingClasses as p,gapClasses as x,iconClasses as b,paddingXClasses as m,pressTransitionClasses as u,radiusClasses as g,readOnlyFilterClasses as h,surfaceClasses as f,transitionClasses as $}from"../../internal/styles";const y={xs:`${s.xs} ${x.xs} ${g.xs} ${c.xs}`,sm:`${s.sm} ${x.sm} ${g.sm} ${c.sm}`,md:`${s.md} ${x.md} ${g.md} ${c.md}`,lg:`${s.lg} ${x.lg} ${g.lg} ${c.lg}`,xl:`${s.xl} ${x.xl} ${g.xl} ${c.xl}`},w={xs:`${d.xs} px-0`,sm:`${d.sm} px-0`,md:`${d.md} px-0`,lg:`${d.lg} px-0`,xl:`${d.xl} px-0`},j=["relative inline-flex shrink-0 select-none items-center justify-center","whitespace-nowrap align-middle font-medium leading-none","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",$,u,p,b].join(" "),k={solid:[f,"text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[f,"border text-(--n-accent) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--n-accent) bg-transparent"},C={solid:["hover:bg-(--n-fill-hover)","hover:[box-shadow:var(--n-elev-hover),var(--neba-plate-solid)]","active:bg-(--n-fill-active)","active:[box-shadow:var(--n-elev-press),var(--neba-plate-solid)]"].join(" "),outline:["hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)]","hover:[box-shadow:var(--n-elev-hover),var(--neba-plate-glass)]","active:bg-(--n-panel-press)","active:[box-shadow:var(--n-elev-press),var(--neba-plate-glass)]"].join(" "),text:"hover:bg-(--n-soft) active:bg-(--n-soft-hover)"},P={solid:[f,h,"cursor-default text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--neba-plate-solid)]"].join(" "),outline:[f,h,"cursor-default border text-(--n-accent) bg-(--n-panel)","[border-color:var(--n-line)] [box-shadow:var(--neba-plate-glass)]"].join(" "),text:`${h} cursor-default text-(--n-accent) bg-transparent`};function B(){return o("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"animate-spin",children:[e("circle",{cx:"8",cy:"8",r:"6.5",stroke:"currentColor",strokeOpacity:"0.25",strokeWidth:"2"}),e("path",{d:"M14.5 8A6.5 6.5 0 0 0 8 1.5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})}export const Button=n.forwardRef(function({variant:s,size:d,color:c,density:p,elevation:x,startIcon:b,endIcon:u,loading:g=!1,readOnly:h=!1,fullWidth:f=!1,disabled:$,render:M,className:N,style:W,children:z,onClick:E,onPointerMove:I,...O},A){const D=n.useContext(l),F=s??D?.variant??"solid",L=d??D?.size??"md",R=c??D?.color??"primary",T=p??D?.density??"default",X=x??D?.elevation??0,Y=$??D?.disabled??!1,q=null==z||!1===z,G=g||h,H=[j,y[L],q?w[L]:m[T][L],Y?v[F]:h?P[F]:k[F],Y||G?"":[C[F],"neba-glow","cursor-pointer"].join(" "),g?"cursor-progress":"",f?"w-full":"",N??""].filter(Boolean).join(" ");return a({render:M??e(t,{disabled:Y}),ref:A,props:{className:H,style:{...i(R,X,F),...W},"aria-disabled":G||void 0,"aria-busy":g||void 0,"data-loading":g||void 0,"data-readonly":h||void 0,onClick:e=>{if(G)return e.preventDefault(),void e.stopPropagation();E?.(e)},onPointerMove:e=>{const o=e.currentTarget;o.style.setProperty("--n-mx",`${e.nativeEvent.offsetX}px`),o.style.setProperty("--n-my",`${e.nativeEvent.offsetY}px`),I?.(e)},...O,children:o(r,{children:[g?e(B,{}):b,z,u]})}})});
@@ -35,15 +35,21 @@ export interface CarouselProps extends NebaStyleProps, Omit<React.ComponentProps
35
35
  arrows?: boolean;
36
36
  /** The row of position dots under the frame. @default true */
37
37
  indicators?: boolean;
38
- /** The carousel's accessible name. @default 'Carousel' */
38
+ /**
39
+ * Which language the carousel names itself in — a BCP 47 tag such as `ko`, `pt-BR` or
40
+ * `zh-Hant`. Unsupported tags fall back to English.
41
+ *
42
+ * The strings below write the words out instead; this is for the far more
43
+ * common case where the page already knows its own language.
44
+ */
45
+ locale?: string;
46
+ /** The carousel's accessible name. Defaults to the `locale`'s word for it. */
39
47
  label?: string;
40
- /** @default 'Previous slide' */
41
48
  previousLabel?: string;
42
- /** @default 'Next slide' */
43
49
  nextLabel?: string;
44
50
  /**
45
51
  * How one slide is named to a screen reader, and how its dot is labelled.
46
- * @default (index, count) => `Slide ${index} of ${count}`
52
+ * Defaults to the `locale`'s wording.
47
53
  */
48
54
  slideLabel?: (index: number, count: number) => string;
49
55
  /** The slides. Every top-level child becomes one. */
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as t from"react";import{IconButton as n}from"../icon-button/IconButton";import{ChevronIcon as a}from"../../internal/icons";import{radiusClasses as o,srOnlyClasses as i,surfaceClasses as l,surfaceSlots as s,transitionClasses as c}from"../../internal/styles";const u={solid:[l,"text-(--neba-fg) bg-(--n-panel-hover)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[l,"border text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--neba-fg) bg-transparent"},d={xs:"start-1 end-1",sm:"start-1.5 end-1.5",md:"start-2 end-2",lg:"start-3 end-3",xl:"start-4 end-4"},f={xs:{rest:"h-1 w-1",current:"h-1 w-3",gap:"gap-1"},sm:{rest:"h-1 w-1",current:"h-1 w-3.5",gap:"gap-1"},md:{rest:"h-1.5 w-1.5",current:"h-1.5 w-4",gap:"gap-1.5"},lg:{rest:"h-1.5 w-1.5",current:"h-1.5 w-5",gap:"gap-2"},xl:{rest:"h-2 w-2",current:"h-2 w-6",gap:"gap-2"}},m=(e,r)=>`Slide ${e} of ${r}`;export const Carousel=t.forwardRef(function({variant:l="outline",size:p="md",color:v="primary",density:h="default",elevation:b=0,value:w,defaultValue:g=0,onValueChange:x,loop:N=!0,autoPlay:y=!1,interval:j=5e3,arrows:k=!0,indicators:C=!0,label:M="Carousel",previousLabel:R="Previous slide",nextLabel:$="Next slide",slideLabel:I=m,className:L,style:P,children:S,..._},z){const B=t.Children.toArray(S),E=B.length,[V,T]=t.useState(g),W=Math.min(Math.max(w??V,0),Math.max(E-1,0)),A=t.useRef(null),F=t.useRef([]),q=t.useRef(!1),D=t.useRef(!1),G=t.useRef(!1),[H,J]=t.useState(!1),K=t.useCallback((e,r=!1)=>{if(0===E)return;const t=N?(e%E+E)%E:Math.min(Math.max(e,0),E-1);q.current=r,void 0===w&&T(t),t!==W&&x?.(t)},[E,N,w,W,x]);t.useEffect(()=>{if(q.current)return void(q.current=!1);if(!D.current)return void(D.current=!0);F.current[W]?.scrollIntoView({block:"nearest",inline:"start"}),G.current=!0;const e=window.setTimeout(()=>{G.current=!1},700);return()=>window.clearTimeout(e)},[W]);t.useEffect(()=>{if(!y||H||E<2)return;if(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches)return;const e=window.setInterval(()=>{document.hidden||K(W+1)},j);return()=>window.clearInterval(e)},[y,H,E,j,W,K]);const O=W<=0,Q=W>=E-1;return r("div",{ref:z,role:"region","aria-roledescription":"carousel","aria-label":M,className:["flex flex-col",L??""].filter(Boolean).join(" "),style:{...s(v,b),...P},onPointerEnter:()=>J(!0),onPointerLeave:()=>J(!1),onFocus:()=>J(!0),onBlur:()=>J(!1),..._,children:[r("div",{className:["relative min-w-0 overflow-hidden",o[p],u[l],c].join(" "),children:[e("div",{ref:A,tabIndex:0,role:"group","aria-label":M,className:["flex min-w-0 snap-x snap-mandatory overflow-x-auto scroll-smooth","motion-reduce:scroll-auto","[scrollbar-width:none] [&::-webkit-scrollbar]:hidden","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:[outline-offset:-2px]"].join(" "),onScroll:()=>{const e=A.current;if(!e||0===e.clientWidth||G.current)return;const r=Math.round(Math.abs(e.scrollLeft)/e.clientWidth);r!==W&&r>=0&&r<E&&K(r,!0)},children:B.map((r,t)=>e("div",{ref:e=>{F.current[t]=e},role:"group","aria-roledescription":"slide","aria-label":I(t+1,E),className:"w-full shrink-0 grow-0 basis-full snap-start",children:r},t))}),k&&E>1?r("div",{className:`pointer-events-none absolute inset-y-0 flex items-center ${d[p]}`,children:[e(n,{variant:"solid",size:p,color:v,density:h,elevation:1,label:R,disabled:!N&&O,className:"pointer-events-auto",icon:e("span",{className:"flex items-center rotate-90 rtl:-rotate-90",children:e(a,{})}),onClick:()=>K(W-1)}),e("span",{className:"flex-1"}),e(n,{variant:"solid",size:p,color:v,density:h,elevation:1,label:$,disabled:!N&&Q,className:"pointer-events-auto",icon:e("span",{className:"flex items-center -rotate-90 rtl:rotate-90",children:e(a,{})}),onClick:()=>K(W+1)})]}):null]}),C&&E>1?e("div",{className:`flex shrink-0 items-center justify-center pt-2 ${f[p].gap}`,children:B.map((r,t)=>e("button",{type:"button","aria-label":I(t+1,E),"aria-current":t===W?"true":void 0,className:["cursor-pointer rounded-full","[transition-property:width,background-color]","[transition-duration:var(--neba-duration)]","[transition-timing-function:var(--neba-ease)]","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2",t===W?`${f[p].current} bg-(--n-accent)`:`${f[p].rest} bg-(--n-line-hover) hover:bg-(--n-accent)`].join(" "),onClick:()=>K(t)},t))}):null,e("span",{className:i,"aria-live":y?"off":"polite",children:E>0?I(W+1,E):""})]})});
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as t from"react";import{IconButton as n}from"../icon-button/IconButton";import{fillMessage as a,useMessages as o}from"../../internal/i18n";import{ChevronIcon as l}from"../../internal/icons";import{radiusClasses as i,srOnlyClasses as s,surfaceClasses as c,surfaceSlots as u,transitionClasses as d}from"../../internal/styles";const f={solid:[c,"text-(--neba-fg) bg-(--n-panel-hover)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[c,"border text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--neba-fg) bg-transparent"},m={xs:"start-1 end-1",sm:"start-1.5 end-1.5",md:"start-2 end-2",lg:"start-3 end-3",xl:"start-4 end-4"},p={xs:{rest:"h-1 w-1",current:"h-1 w-3",gap:"gap-1"},sm:{rest:"h-1 w-1",current:"h-1 w-3.5",gap:"gap-1"},md:{rest:"h-1.5 w-1.5",current:"h-1.5 w-4",gap:"gap-1.5"},lg:{rest:"h-1.5 w-1.5",current:"h-1.5 w-5",gap:"gap-2"},xl:{rest:"h-2 w-2",current:"h-2 w-6",gap:"gap-2"}};export const Carousel=t.forwardRef(function({variant:c="outline",size:b="md",color:v="primary",density:h="default",elevation:g=0,value:w,defaultValue:x=0,onValueChange:y,loop:N=!0,autoPlay:j=!1,interval:k=5e3,arrows:M=!0,indicators:C=!0,locale:R,label:I,previousLabel:L,nextLabel:S,slideLabel:$,className:_,style:z,children:B,...E},P){const V=o(R),T=$??((e,r)=>a(V.carousel.slide,{index:String(e),total:String(r)})),W=t.Children.toArray(B),A=W.length,[F,q]=t.useState(x),D=Math.min(Math.max(w??F,0),Math.max(A-1,0)),G=t.useRef(null),H=t.useRef([]),J=t.useRef(!1),K=t.useRef(!1),O=t.useRef(!1),[Q,U]=t.useState(!1),X=t.useCallback((e,r=!1)=>{if(0===A)return;const t=N?(e%A+A)%A:Math.min(Math.max(e,0),A-1);J.current=r,void 0===w&&q(t),t!==D&&y?.(t)},[A,N,w,D,y]);t.useEffect(()=>{if(J.current)return void(J.current=!1);if(!K.current)return void(K.current=!0);H.current[D]?.scrollIntoView({block:"nearest",inline:"start"}),O.current=!0;const e=window.setTimeout(()=>{O.current=!1},700);return()=>window.clearTimeout(e)},[D]);t.useEffect(()=>{if(!j||Q||A<2)return;if(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches)return;const e=window.setInterval(()=>{document.hidden||X(D+1)},k);return()=>window.clearInterval(e)},[j,Q,A,k,D,X]);const Y=D<=0,Z=D>=A-1;return r("div",{ref:P,role:"region","aria-roledescription":"carousel","aria-label":I??V.carousel.label,className:["flex flex-col",_??""].filter(Boolean).join(" "),style:{...u(v,g),...z},onPointerEnter:()=>U(!0),onPointerLeave:()=>U(!1),onFocus:()=>U(!0),onBlur:()=>U(!1),...E,children:[r("div",{className:["relative min-w-0 overflow-hidden",i[b],f[c],d].join(" "),children:[e("div",{ref:G,tabIndex:0,role:"group","aria-label":I??V.carousel.label,className:["flex min-w-0 snap-x snap-mandatory overflow-x-auto scroll-smooth","motion-reduce:scroll-auto","[scrollbar-width:none] [&::-webkit-scrollbar]:hidden","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:[outline-offset:-2px]"].join(" "),onScroll:()=>{const e=G.current;if(O.current||!e||0===e.clientWidth)return;const r=Math.round(Math.abs(e.scrollLeft)/e.clientWidth);r!==D&&r>=0&&r<A&&X(r,!0)},children:W.map((r,t)=>e("div",{ref:e=>{H.current[t]=e},role:"group","aria-roledescription":"slide","aria-label":T(t+1,A),className:"w-full shrink-0 grow-0 basis-full snap-start",children:r},t))}),M&&A>1?r("div",{className:`pointer-events-none absolute inset-y-0 flex items-center ${m[b]}`,children:[e(n,{variant:"solid",size:b,color:v,density:h,elevation:1,label:L??V.carousel.previous,disabled:!N&&Y,className:"pointer-events-auto",icon:e("span",{className:"flex items-center rotate-90 rtl:-rotate-90",children:e(l,{})}),onClick:()=>X(D-1)}),e("span",{className:"flex-1"}),e(n,{variant:"solid",size:b,color:v,density:h,elevation:1,label:S??V.carousel.next,disabled:!N&&Z,className:"pointer-events-auto",icon:e("span",{className:"flex items-center -rotate-90 rtl:rotate-90",children:e(l,{})}),onClick:()=>X(D+1)})]}):null]}),C&&A>1?e("div",{className:`flex shrink-0 items-center justify-center pt-2 ${p[b].gap}`,children:W.map((r,t)=>e("button",{type:"button","aria-label":T(t+1,A),"aria-current":t===D?"true":void 0,className:["cursor-pointer rounded-full","[transition-property:width,background-color]","[transition-duration:var(--neba-duration)]","[transition-timing-function:var(--neba-ease)]","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2",t===D?`${p[b].current} bg-(--n-accent)`:`${p[b].rest} bg-(--n-line-hover) hover:bg-(--n-accent)`].join(" "),onClick:()=>X(t)},t))}):null,e("span",{className:s,"aria-live":j?"off":"polite",children:A>0?T(D+1,A):""})]})});
@@ -27,7 +27,15 @@ export interface ChipProps extends NebaStyleProps, Omit<React.ComponentPropsWith
27
27
  * makes the affordance appear.
28
28
  */
29
29
  onDelete?: (event: React.MouseEvent<HTMLButtonElement>) => void;
30
- /** Accessible name of the delete button. */
30
+ /**
31
+ * Which language the delete button is named in — a BCP 47 tag such as `ko`, `pt-BR` or
32
+ * `zh-Hant`. Unsupported tags fall back to English.
33
+ *
34
+ * `deleteLabel` writes the word out instead; this is for the far more common
35
+ * case where the page already knows its own language.
36
+ */
37
+ locale?: string;
38
+ /** Accessible name of the delete button. Defaults to the `locale`'s word. */
31
39
  deleteLabel?: string;
32
40
  /**
33
41
  * Marks the chip as chosen — a filter that is on. `selected` deepens the
@@ -1 +1 @@
1
- import{jsx as e,Fragment as n,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{CloseIcon as o}from"../../internal/icons";import{transitionProps as i}from"../../internal/animate";import{chipRemoveClasses as r,controlHeightClasses as a,controlSlots as s,controlTextClasses as c,disabledClasses as d,focusRingClasses as m,gapClasses as p,iconClasses as b,paddingXClasses as f,pressTransitionClasses as u,radiusClasses as h,surfaceClasses as v,transitionClasses as x}from"../../internal/styles";const g={xs:"xs",sm:"xs",md:"sm",lg:"md",xl:"lg"},j={solid:[v,"text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[v,"border text-(--n-accent) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--n-accent) bg-(--n-soft)"},y={solid:"bg-(--n-fill-active)",outline:"bg-(--n-panel-press) [border-color:var(--n-line-hover)]",text:"bg-(--n-soft-press)"},w={solid:"hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)",outline:"hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)] active:bg-(--n-panel-press)",text:"hover:bg-(--n-soft-hover) active:bg-(--n-soft-press)"},N=["relative inline-flex max-w-full shrink-0 select-none items-center","align-middle font-medium leading-none whitespace-nowrap","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",x,u,b].join(" "),k=["flex min-w-0 flex-1 cursor-pointer items-center justify-center self-stretch rounded-[inherit]",m].join(" ");export const Chip=l.forwardRef(function({variant:l="outline",size:m="md",color:b="primary",density:u="default",elevation:v=0,startIcon:x,endIcon:C,count:$,onDelete:B,deleteLabel:I="Remove",transition:R,selected:z=!1,disabled:D=!1,className:F,style:L,children:q,onClick:A,...E},G){const H=Boolean(A)&&!D,J=g[m],K=i(R),M=f[u][J],O=[N,a[J],c[J],p[J],h[J],D?d[l]:j[l],!D&&z?y[l]:"",H?w[l]:"",H?"ps-0":M,B?"pe-1":H?"pe-0":"",K.className,F??""].filter(Boolean).join(" "),P=t(n,{children:[x,null!=q&&!1!==q?e("span",{className:"min-w-0 truncate",children:q}):null,C,null!=$&&!1!==$?e("span",{className:["ms-0.5 inline-flex shrink-0 items-center justify-center rounded-full px-1.5 py-px","text-[0.85em] leading-none font-semibold tabular-nums","solid"===l?"bg-(--neba-glow-on-fill) text-(--n-on-solid)":"bg-(--n-soft-press) text-(--n-accent)"].join(" "),children:$}):null]});return t("span",{ref:G,className:O,style:{...s(b,v,l),...K.style,...L},"aria-disabled":!(!D||H)||void 0,...E,children:[H?e("button",{type:"button","aria-pressed":z,className:`${k} ${p[J]} ${M}`,onClick:A,children:P}):P,B?e("button",{type:"button","aria-label":I,disabled:D,className:r,onClick:B,children:e(o,{})}):null]})});
1
+ import{jsx as e,Fragment as n,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{useMessages as o}from"../../internal/i18n";import{CloseIcon as i}from"../../internal/icons";import{transitionProps as r}from"../../internal/animate";import{chipRemoveClasses as a,controlHeightClasses as s,controlSlots as c,controlTextClasses as d,disabledClasses as m,focusRingClasses as p,gapClasses as b,iconClasses as f,paddingXClasses as u,pressTransitionClasses as h,radiusClasses as v,surfaceClasses as x,transitionClasses as g}from"../../internal/styles";const j={xs:"xs",sm:"xs",md:"sm",lg:"md",xl:"lg"},y={solid:[x,"text-(--n-on-solid) bg-(--n-fill)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[x,"border text-(--n-accent) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--n-accent) bg-(--n-soft)"},w={solid:"bg-(--n-fill-active)",outline:"bg-(--n-panel-press) [border-color:var(--n-line-hover)]",text:"bg-(--n-soft-press)"},N={solid:"hover:bg-(--n-fill-hover) active:bg-(--n-fill-active)",outline:"hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)] active:bg-(--n-panel-press)",text:"hover:bg-(--n-soft-hover) active:bg-(--n-soft-press)"},k=["relative inline-flex max-w-full shrink-0 select-none items-center","align-middle font-medium leading-none whitespace-nowrap","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",g,h,f].join(" "),C=["flex min-w-0 flex-1 cursor-pointer items-center justify-center self-stretch rounded-[inherit]",p].join(" ");export const Chip=l.forwardRef(function({variant:l="outline",size:p="md",color:f="primary",density:h="default",elevation:x=0,startIcon:g,endIcon:$,count:B,onDelete:I,locale:z,deleteLabel:D,transition:F,selected:L=!1,disabled:R=!1,className:q,style:A,children:E,onClick:G,...H},J){const K=o(z),M=Boolean(G)&&!R,O=j[p],P=r(F),Q=u[h][O],S=[k,s[O],d[O],b[O],v[O],R?m[l]:y[l],!R&&L?w[l]:"",M?N[l]:"",M?"ps-0":Q,I?"pe-1":M?"pe-0":"",P.className,q??""].filter(Boolean).join(" "),T=t(n,{children:[g,null!=E&&!1!==E?e("span",{className:"min-w-0 truncate",children:E}):null,$,null!=B&&!1!==B?e("span",{className:["ms-0.5 inline-flex shrink-0 items-center justify-center rounded-full px-1.5 py-px","text-[0.85em] leading-none font-semibold tabular-nums","solid"===l?"bg-(--neba-glow-on-fill) text-(--n-on-solid)":"bg-(--n-soft-press) text-(--n-accent)"].join(" "),children:B}):null]});return t("span",{ref:J,className:S,style:{...c(f,x,l),...P.style,...A},"aria-disabled":!(!R||M)||void 0,...H,children:[M?e("button",{type:"button","aria-pressed":L,className:`${C} ${b[O]} ${Q}`,onClick:G,children:T}):T,I?e("button",{type:"button","aria-label":D??K.action.remove,disabled:R,className:a,onClick:I,children:e(i,{})}):null]})});