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.
- package/README.md +7 -7
- package/dist/components/alert/Alert.d.ts +9 -1
- package/dist/components/alert/Alert.js +1 -1
- package/dist/components/area-chart/AreaChart.d.ts +54 -0
- package/dist/components/area-chart/AreaChart.js +1 -0
- package/dist/components/area-chart/index.d.ts +2 -0
- package/dist/components/area-chart/index.js +1 -0
- package/dist/components/bar-chart/BarChart.d.ts +63 -0
- package/dist/components/bar-chart/BarChart.js +1 -0
- package/dist/components/bar-chart/index.d.ts +2 -0
- package/dist/components/bar-chart/index.js +1 -0
- package/dist/components/bottom-navigation/BottomNavigation.d.ts +111 -0
- package/dist/components/bottom-navigation/BottomNavigation.js +1 -0
- package/dist/components/bottom-navigation/index.d.ts +1 -0
- package/dist/components/bottom-navigation/index.js +1 -0
- package/dist/components/breadcrumb/Breadcrumb.d.ts +35 -2
- package/dist/components/breadcrumb/Breadcrumb.js +1 -1
- package/dist/components/button/Button.d.ts +16 -0
- package/dist/components/button/Button.js +1 -1
- package/dist/components/carousel/Carousel.d.ts +10 -4
- package/dist/components/carousel/Carousel.js +1 -1
- package/dist/components/chip/Chip.d.ts +9 -1
- package/dist/components/chip/Chip.js +1 -1
- package/dist/components/collapsible/Collapsible.d.ts +88 -0
- package/dist/components/collapsible/Collapsible.js +1 -0
- package/dist/components/collapsible/index.d.ts +1 -0
- package/dist/components/collapsible/index.js +1 -0
- package/dist/components/combobox/Combobox.d.ts +19 -7
- package/dist/components/combobox/Combobox.js +1 -1
- package/dist/components/data-table/DataTable.d.ts +323 -0
- package/dist/components/data-table/DataTable.js +1 -0
- package/dist/components/data-table/index.d.ts +2 -0
- package/dist/components/data-table/index.js +1 -0
- package/dist/components/dialog/Dialog.d.ts +11 -5
- package/dist/components/dialog/Dialog.js +1 -1
- package/dist/components/drawer/Drawer.d.ts +11 -5
- package/dist/components/drawer/Drawer.js +1 -1
- package/dist/components/empty/Empty.d.ts +69 -0
- package/dist/components/empty/Empty.js +1 -0
- package/dist/components/empty/index.d.ts +2 -0
- package/dist/components/empty/index.js +1 -0
- package/dist/components/file-picker/FilePicker.d.ts +1 -3
- package/dist/components/file-picker/FilePicker.js +1 -1
- package/dist/components/floating-action-button/FloatingActionButton.d.ts +146 -0
- package/dist/components/floating-action-button/FloatingActionButton.js +1 -0
- package/dist/components/floating-action-button/index.d.ts +1 -0
- package/dist/components/floating-action-button/index.js +1 -0
- package/dist/components/heatmap-chart/HeatmapChart.d.ts +69 -0
- package/dist/components/heatmap-chart/HeatmapChart.js +1 -0
- package/dist/components/heatmap-chart/index.d.ts +2 -0
- package/dist/components/heatmap-chart/index.js +1 -0
- package/dist/components/highlight/Highlight.js +1 -1
- package/dist/components/line-chart/LineChart.d.ts +74 -0
- package/dist/components/line-chart/LineChart.js +1 -0
- package/dist/components/line-chart/index.d.ts +2 -0
- package/dist/components/line-chart/index.js +1 -0
- package/dist/components/mockup/Mockup.d.ts +151 -0
- package/dist/components/mockup/Mockup.js +1 -0
- package/dist/components/mockup/index.d.ts +2 -0
- package/dist/components/mockup/index.js +1 -0
- package/dist/components/number-field/NumberField.d.ts +10 -6
- package/dist/components/number-field/NumberField.js +1 -1
- package/dist/components/overlay/Overlay.d.ts +11 -6
- package/dist/components/overlay/Overlay.js +1 -1
- package/dist/components/pagination/Pagination.d.ts +28 -6
- package/dist/components/pagination/Pagination.js +1 -1
- package/dist/components/panes/Panes.js +1 -1
- package/dist/components/pie-chart/PieChart.d.ts +58 -0
- package/dist/components/pie-chart/PieChart.js +1 -0
- package/dist/components/pie-chart/index.d.ts +2 -0
- package/dist/components/pie-chart/index.js +1 -0
- package/dist/components/popover/Popover.d.ts +11 -5
- package/dist/components/popover/Popover.js +1 -1
- package/dist/components/progress-box/ProgressBox.js +1 -1
- package/dist/components/progress-circular/ProgressCircular.js +1 -1
- package/dist/components/progress-linear/ProgressLinear.js +1 -1
- package/dist/components/rating/Rating.d.ts +100 -0
- package/dist/components/rating/Rating.js +1 -0
- package/dist/components/rating/index.d.ts +1 -0
- package/dist/components/rating/index.js +1 -0
- package/dist/components/scatter-chart/ScatterChart.d.ts +45 -0
- package/dist/components/scatter-chart/ScatterChart.js +1 -0
- package/dist/components/scatter-chart/index.d.ts +2 -0
- package/dist/components/scatter-chart/index.js +1 -0
- package/dist/components/select/Select.d.ts +1 -3
- package/dist/components/select/Select.js +1 -1
- package/dist/components/sparkline/Sparkline.d.ts +67 -0
- package/dist/components/sparkline/Sparkline.js +1 -0
- package/dist/components/sparkline/index.d.ts +2 -0
- package/dist/components/sparkline/index.js +1 -0
- package/dist/components/statistic/Statistic.d.ts +7 -0
- package/dist/components/statistic/Statistic.js +1 -1
- package/dist/components/table/Table.d.ts +13 -2
- package/dist/components/table/Table.js +1 -1
- package/dist/components/text-link/TextLink.js +1 -1
- package/dist/components/time-picker/TimePicker.js +1 -1
- package/dist/components/timeline-chart/TimelineChart.d.ts +44 -0
- package/dist/components/timeline-chart/TimelineChart.js +1 -0
- package/dist/components/timeline-chart/index.d.ts +2 -0
- package/dist/components/timeline-chart/index.js +1 -0
- package/dist/components/toast/Toast.d.ts +10 -2
- package/dist/components/toast/Toast.js +1 -1
- package/dist/components/tooltip/Tooltip.d.ts +2 -4
- package/dist/components/tooltip/Tooltip.js +1 -1
- package/dist/components/tree-view/TreeView.js +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1 -1
- package/dist/internal/animate.d.ts +0 -9
- package/dist/internal/animate.js +1 -1
- package/dist/internal/calendar.js +1 -1
- package/dist/internal/chart-frame.d.ts +409 -0
- package/dist/internal/chart-frame.js +1 -0
- package/dist/internal/chart-line.d.ts +44 -0
- package/dist/internal/chart-line.js +1 -0
- package/dist/internal/chart.d.ts +456 -0
- package/dist/internal/chart.js +1 -0
- package/dist/internal/data-table.d.ts +170 -0
- package/dist/internal/data-table.js +1 -0
- package/dist/internal/date.d.ts +0 -2
- package/dist/internal/date.js +1 -1
- package/dist/internal/format.d.ts +29 -0
- package/dist/internal/format.js +1 -0
- package/dist/internal/i18n.d.ts +166 -0
- package/dist/internal/i18n.js +1 -1
- package/dist/internal/icons.d.ts +2 -0
- package/dist/internal/icons.js +1 -1
- package/dist/internal/mockup.d.ts +193 -0
- package/dist/internal/mockup.js +1 -0
- package/dist/internal/picker.d.ts +2 -4
- package/dist/internal/picker.js +1 -1
- package/dist/internal/progress.d.ts +1 -3
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +231 -11
- package/dist/types.d.ts +214 -0
- 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
|
-
**
|
|
116
|
+
**Display** — Typography, TextLink, Blockquote, Highlight, Divider, Chip, Badge, Avatar, Icon, Shortcut, List, Table, DataTable, Timeline, Breadcrumb, TreeView
|
|
117
117
|
|
|
118
|
-
**
|
|
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
|
-
|
|
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
|
-
/**
|
|
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
|
|
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 @@
|
|
|
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 @@
|
|
|
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
|
-
/**
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
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{
|
|
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
|
-
/**
|
|
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{
|
|
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]})});
|