neba 0.0.1 → 1.1.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 +177 -2
- package/dist/components/accordion/Accordion.d.ts +97 -0
- package/dist/components/accordion/Accordion.js +1 -0
- package/dist/components/accordion/index.d.ts +2 -0
- package/dist/components/accordion/index.js +1 -0
- package/dist/components/alert/Alert.d.ts +47 -0
- package/dist/components/alert/Alert.js +1 -0
- package/dist/components/alert/index.d.ts +2 -0
- package/dist/components/alert/index.js +1 -0
- package/dist/components/badge/Badge.d.ts +80 -0
- package/dist/components/badge/Badge.js +1 -0
- package/dist/components/badge/index.d.ts +2 -0
- package/dist/components/badge/index.js +1 -0
- package/dist/components/blockquote/Blockquote.d.ts +65 -0
- package/dist/components/blockquote/Blockquote.js +1 -0
- package/dist/components/blockquote/index.d.ts +2 -0
- package/dist/components/blockquote/index.js +1 -0
- package/dist/components/box/Box.d.ts +50 -0
- package/dist/components/box/Box.js +1 -0
- package/dist/components/box/index.d.ts +2 -0
- package/dist/components/box/index.js +1 -0
- package/dist/components/button/Button.d.ts +25 -3
- package/dist/components/button/Button.js +1 -1
- package/dist/components/button/index.d.ts +1 -0
- package/dist/components/button-group/ButtonGroup.d.ts +31 -0
- package/dist/components/button-group/ButtonGroup.js +1 -0
- package/dist/components/button-group/index.d.ts +2 -0
- package/dist/components/button-group/index.js +1 -0
- package/dist/components/card/Card.d.ts +45 -0
- package/dist/components/card/Card.js +1 -0
- package/dist/components/card/index.d.ts +2 -0
- package/dist/components/card/index.js +1 -0
- package/dist/components/carousel/Carousel.d.ts +74 -0
- package/dist/components/carousel/Carousel.js +1 -0
- package/dist/components/carousel/index.d.ts +2 -0
- package/dist/components/carousel/index.js +1 -0
- package/dist/components/checkbox/Checkbox.d.ts +39 -0
- package/dist/components/checkbox/Checkbox.js +1 -0
- package/dist/components/checkbox/index.d.ts +2 -0
- package/dist/components/checkbox/index.js +1 -0
- package/dist/components/chip/Chip.d.ts +50 -0
- package/dist/components/chip/Chip.js +1 -0
- package/dist/components/chip/index.d.ts +2 -0
- package/dist/components/chip/index.js +1 -0
- package/dist/components/combobox/Combobox.d.ts +131 -0
- package/dist/components/combobox/Combobox.js +1 -0
- package/dist/components/combobox/index.d.ts +2 -0
- package/dist/components/combobox/index.js +1 -0
- package/dist/components/container/Container.d.ts +55 -0
- package/dist/components/container/Container.js +1 -0
- package/dist/components/container/index.d.ts +2 -0
- package/dist/components/container/index.js +1 -0
- package/dist/components/date-picker/DatePicker.d.ts +75 -0
- package/dist/components/date-picker/DatePicker.js +1 -0
- package/dist/components/date-picker/index.d.ts +2 -0
- package/dist/components/date-picker/index.js +1 -0
- package/dist/components/date-range-picker/DateRangePicker.d.ts +81 -0
- package/dist/components/date-range-picker/DateRangePicker.js +1 -0
- package/dist/components/date-range-picker/index.d.ts +2 -0
- package/dist/components/date-range-picker/index.js +1 -0
- package/dist/components/date-time-picker/DateTimePicker.d.ts +68 -0
- package/dist/components/date-time-picker/DateTimePicker.js +1 -0
- package/dist/components/date-time-picker/index.d.ts +2 -0
- package/dist/components/date-time-picker/index.js +1 -0
- package/dist/components/dialog/Dialog.d.ts +111 -0
- package/dist/components/dialog/Dialog.js +1 -0
- package/dist/components/dialog/index.d.ts +2 -0
- package/dist/components/dialog/index.js +1 -0
- package/dist/components/divider/Divider.d.ts +67 -0
- package/dist/components/divider/Divider.js +1 -0
- package/dist/components/divider/index.d.ts +2 -0
- package/dist/components/divider/index.js +1 -0
- package/dist/components/file-picker/FilePicker.d.ts +103 -0
- package/dist/components/file-picker/FilePicker.js +1 -0
- package/dist/components/file-picker/index.d.ts +2 -0
- package/dist/components/file-picker/index.js +1 -0
- package/dist/components/grid/Grid.d.ts +50 -0
- package/dist/components/grid/Grid.js +1 -0
- package/dist/components/grid/index.d.ts +2 -0
- package/dist/components/grid/index.js +1 -0
- package/dist/components/grid-container/GridContainer.d.ts +79 -0
- package/dist/components/grid-container/GridContainer.js +1 -0
- package/dist/components/grid-container/index.d.ts +2 -0
- package/dist/components/grid-container/index.js +1 -0
- package/dist/components/highlight/Highlight.d.ts +84 -0
- package/dist/components/highlight/Highlight.js +1 -0
- package/dist/components/highlight/index.d.ts +2 -0
- package/dist/components/highlight/index.js +1 -0
- package/dist/components/icon/Icon.d.ts +58 -0
- package/dist/components/icon/Icon.js +1 -0
- package/dist/components/icon/index.d.ts +2 -0
- package/dist/components/icon/index.js +1 -0
- package/dist/components/icon-button/IconButton.d.ts +39 -0
- package/dist/components/icon-button/IconButton.js +1 -0
- package/dist/components/icon-button/index.d.ts +2 -0
- package/dist/components/icon-button/index.js +1 -0
- package/dist/components/list/List.d.ts +81 -0
- package/dist/components/list/List.js +1 -0
- package/dist/components/list/index.d.ts +2 -0
- package/dist/components/list/index.js +1 -0
- package/dist/components/menu/Menu.d.ts +216 -0
- package/dist/components/menu/Menu.js +1 -0
- package/dist/components/menu/index.d.ts +2 -0
- package/dist/components/menu/index.js +1 -0
- package/dist/components/number-field/NumberField.d.ts +113 -0
- package/dist/components/number-field/NumberField.js +1 -0
- package/dist/components/number-field/index.d.ts +2 -0
- package/dist/components/number-field/index.js +1 -0
- package/dist/components/overlay/Overlay.d.ts +85 -0
- package/dist/components/overlay/Overlay.js +1 -0
- package/dist/components/overlay/index.d.ts +2 -0
- package/dist/components/overlay/index.js +1 -0
- package/dist/components/pagination/Pagination.d.ts +65 -0
- package/dist/components/pagination/Pagination.js +1 -0
- package/dist/components/pagination/index.d.ts +2 -0
- package/dist/components/pagination/index.js +1 -0
- package/dist/components/pill/Pill.d.ts +80 -0
- package/dist/components/pill/Pill.js +1 -0
- package/dist/components/pill/index.d.ts +2 -0
- package/dist/components/pill/index.js +1 -0
- package/dist/components/progress-box/ProgressBox.d.ts +33 -0
- package/dist/components/progress-box/ProgressBox.js +1 -0
- package/dist/components/progress-box/index.d.ts +2 -0
- package/dist/components/progress-box/index.js +1 -0
- package/dist/components/progress-circular/ProgressCircular.d.ts +19 -0
- package/dist/components/progress-circular/ProgressCircular.js +1 -0
- package/dist/components/progress-circular/index.d.ts +2 -0
- package/dist/components/progress-circular/index.js +1 -0
- package/dist/components/progress-linear/ProgressLinear.d.ts +20 -0
- package/dist/components/progress-linear/ProgressLinear.js +1 -0
- package/dist/components/progress-linear/index.d.ts +2 -0
- package/dist/components/progress-linear/index.js +1 -0
- package/dist/components/radio-group/RadioGroup.d.ts +51 -0
- package/dist/components/radio-group/RadioGroup.js +1 -0
- package/dist/components/radio-group/index.d.ts +2 -0
- package/dist/components/radio-group/index.js +1 -0
- package/dist/components/segmented-button/SegmentedButton.d.ts +77 -0
- package/dist/components/segmented-button/SegmentedButton.js +1 -0
- package/dist/components/segmented-button/index.d.ts +2 -0
- package/dist/components/segmented-button/index.js +1 -0
- package/dist/components/select/Select.d.ts +76 -0
- package/dist/components/select/Select.js +1 -0
- package/dist/components/select/index.d.ts +2 -0
- package/dist/components/select/index.js +1 -0
- package/dist/components/shortcut/Shortcut.d.ts +60 -0
- package/dist/components/shortcut/Shortcut.js +1 -0
- package/dist/components/shortcut/index.d.ts +2 -0
- package/dist/components/shortcut/index.js +1 -0
- package/dist/components/slider/Slider.d.ts +38 -0
- package/dist/components/slider/Slider.js +1 -0
- package/dist/components/slider/index.d.ts +2 -0
- package/dist/components/slider/index.js +1 -0
- package/dist/components/statistic/Statistic.d.ts +91 -0
- package/dist/components/statistic/Statistic.js +1 -0
- package/dist/components/statistic/index.d.ts +2 -0
- package/dist/components/statistic/index.js +1 -0
- package/dist/components/switch/Switch.d.ts +39 -0
- package/dist/components/switch/Switch.js +1 -0
- package/dist/components/switch/index.d.ts +2 -0
- package/dist/components/switch/index.js +1 -0
- package/dist/components/table/Table.d.ts +80 -0
- package/dist/components/table/Table.js +1 -0
- package/dist/components/table/index.d.ts +2 -0
- package/dist/components/table/index.js +1 -0
- package/dist/components/tabs/Tabs.d.ts +92 -0
- package/dist/components/tabs/Tabs.js +1 -0
- package/dist/components/tabs/index.d.ts +2 -0
- package/dist/components/tabs/index.js +1 -0
- package/dist/components/text-field/TextField.d.ts +63 -0
- package/dist/components/text-field/TextField.js +1 -0
- package/dist/components/text-field/index.d.ts +2 -0
- package/dist/components/text-field/index.js +1 -0
- package/dist/components/time-picker/TimePicker.d.ts +76 -0
- package/dist/components/time-picker/TimePicker.js +1 -0
- package/dist/components/time-picker/index.d.ts +2 -0
- package/dist/components/time-picker/index.js +1 -0
- package/dist/components/timeline/Timeline.d.ts +98 -0
- package/dist/components/timeline/Timeline.js +1 -0
- package/dist/components/timeline/index.d.ts +2 -0
- package/dist/components/timeline/index.js +1 -0
- package/dist/components/toast/Toast.d.ts +116 -0
- package/dist/components/toast/Toast.js +1 -0
- package/dist/components/toast/index.d.ts +2 -0
- package/dist/components/toast/index.js +1 -0
- package/dist/components/toolbar/Toolbar.d.ts +67 -0
- package/dist/components/toolbar/Toolbar.js +1 -0
- package/dist/components/toolbar/index.d.ts +2 -0
- package/dist/components/toolbar/index.js +1 -0
- package/dist/components/tooltip/Tooltip.d.ts +81 -0
- package/dist/components/tooltip/Tooltip.js +1 -0
- package/dist/components/tooltip/index.d.ts +2 -0
- package/dist/components/tooltip/index.js +1 -0
- package/dist/components/typography/Typography.d.ts +62 -0
- package/dist/components/typography/Typography.js +1 -0
- package/dist/components/typography/index.d.ts +2 -0
- package/dist/components/typography/index.js +1 -0
- package/dist/index.d.ts +50 -1
- package/dist/index.js +1 -1
- package/dist/internal/button-group.d.ts +25 -0
- package/dist/internal/button-group.js +1 -0
- package/dist/internal/calendar.d.ts +149 -0
- package/dist/internal/calendar.js +1 -0
- package/dist/internal/date.d.ts +170 -0
- package/dist/internal/date.js +1 -0
- package/dist/internal/grid.d.ts +69 -0
- package/dist/internal/grid.js +1 -0
- package/dist/internal/icons.d.ts +79 -0
- package/dist/internal/icons.js +1 -0
- package/dist/internal/menu.d.ts +20 -0
- package/dist/internal/menu.js +1 -0
- package/dist/internal/picker.d.ts +111 -0
- package/dist/internal/picker.js +1 -0
- package/dist/internal/progress.d.ts +122 -0
- package/dist/internal/progress.js +1 -0
- package/dist/internal/sizer.d.ts +33 -0
- package/dist/internal/sizer.js +1 -0
- package/dist/internal/styles.d.ts +257 -0
- package/dist/internal/styles.js +1 -0
- package/dist/styles.css +2 -0
- package/dist/tailwind.css +892 -0
- package/dist/types.d.ts +142 -0
- package/dist/types.js +8 -0
- package/package.json +90 -21
- package/pnpm-workspace.yaml +0 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{Statistic}from"./Statistic";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Switch as BaseUISwitch } from '@base-ui/react/switch';
|
|
3
|
+
import type { NebaColor, NebaSize } from '../../types';
|
|
4
|
+
/** Which side of the track the label sits on. */
|
|
5
|
+
export type SwitchLabelPlacement = 'start' | 'end';
|
|
6
|
+
type BaseSwitchProps = Omit<React.ComponentPropsWithoutRef<typeof BaseUISwitch.Root>, 'className' | 'style' | 'render' | 'children'>;
|
|
7
|
+
export interface SwitchProps extends BaseSwitchProps {
|
|
8
|
+
/** @default 'md' */
|
|
9
|
+
size?: NebaSize;
|
|
10
|
+
/** @default 'primary' */
|
|
11
|
+
color?: NebaColor;
|
|
12
|
+
/** The text beside the track. Wired to it by Base UI's Field. */
|
|
13
|
+
label?: React.ReactNode;
|
|
14
|
+
/** Helper text under the label. */
|
|
15
|
+
description?: React.ReactNode;
|
|
16
|
+
/** Error message below. Its presence also turns the switch invalid. */
|
|
17
|
+
error?: React.ReactNode;
|
|
18
|
+
/** Forces the invalid state without a message. Defaults to `!!error`. */
|
|
19
|
+
invalid?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Which side the label sits on. `end` reads as a caption for the control;
|
|
22
|
+
* `start` is for a settings list, where the labels form a column and every
|
|
23
|
+
* switch lines up on the right.
|
|
24
|
+
* @default 'end'
|
|
25
|
+
*/
|
|
26
|
+
labelPlacement?: SwitchLabelPlacement;
|
|
27
|
+
/** Class names for the field wrapper, not for the track. */
|
|
28
|
+
className?: string;
|
|
29
|
+
style?: React.CSSProperties;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* An immediate on/off.
|
|
33
|
+
*
|
|
34
|
+
* The difference from a Checkbox is not visual, it is temporal: a checkbox is a
|
|
35
|
+
* value that gets submitted with a form, a switch takes effect the moment it
|
|
36
|
+
* moves. If there is a Save button underneath, it should have been a checkbox.
|
|
37
|
+
*/
|
|
38
|
+
export declare const Switch: React.ForwardRefExoticComponent<SwitchProps & React.RefAttributes<HTMLElement>>;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as a,Fragment as r}from"react/jsx-runtime";import*as n from"react";import{Switch as l}from"@base-ui/react/switch";import{Field as o}from"@base-ui/react/field";import{controlTextClasses as t,metaTextClasses as i,surfaceClasses as c,tickRowLeadingClasses as s}from"../../internal/styles";const d={xs:"h-3.5 w-6",sm:"h-4 w-7",md:"h-5 w-9",lg:"h-6 w-11",xl:"h-7 w-13"},b={xs:"data-[checked]:left-[calc(100%-0.75rem)]",sm:"data-[checked]:left-[calc(100%-0.875rem)]",md:"data-[checked]:left-[calc(100%-1.125rem)]",lg:"data-[checked]:left-[calc(100%-1.375rem)]",xl:"data-[checked]:left-[calc(100%-1.625rem)]"},h=["relative inline-flex shrink-0 border","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]","rounded-full","[transition-property:background-color,border-color,box-shadow]","[transition-duration:var(--neba-duration-fill),var(--neba-duration),var(--neba-duration)]","[transition-timing-function:var(--neba-ease)]","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2"].join(" "),f=[c,"cursor-pointer bg-(--n-panel) [border-color:var(--n-line)]","hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)]","data-[checked]:bg-(--n-fill) data-[checked]:[border-color:transparent]","data-[checked]:hover:bg-(--n-fill-hover)"].join(" "),m=[c,"cursor-default bg-(--n-panel) [border-color:var(--n-line)]","[filter:saturate(0.55)]","data-[checked]:bg-(--n-fill) data-[checked]:[border-color:transparent]"].join(" "),u=["cursor-not-allowed bg-transparent [border-color:var(--neba-disabled-border)] shadow-none","data-[checked]:bg-(--neba-disabled-bg)"].join(" "),v=["absolute inset-y-0.5 left-0.5 aspect-square rounded-full bg-(--neba-surface)","[box-shadow:var(--neba-shadow-1)]","[transition:left_var(--neba-duration)_var(--neba-ease)]"].join(" ");export const Switch=n.forwardRef(function({size:n="md",color:c="primary",label:p,description:g,error:x,invalid:w,labelPlacement:k="end",disabled:j=!1,readOnly:$=!1,className:N,style:y,..._},R){const B=null!=x&&!1!==x&&""!==x,O=w??B,S=O?"danger":c,q={"--n-fill":`var(--neba-${S}-fill)`,"--n-fill-hover":`var(--neba-${S}-fill-hover)`,"--n-accent":`var(--neba-${S}-accent)`,"--n-panel":"var(--neba-panel)","--n-panel-hover":"var(--neba-panel-hover)","--n-line":`var(--neba-${S}-line)`,"--n-line-hover":`var(--neba-${S}-line-hover)`,"--n-ring":`var(--neba-${S}-ring)`},z=e("span",{className:"flex h-[1lh] shrink-0 items-center",children:e(l.Root,{ref:R,className:[h,d[n],j?u:$?m:f].join(" "),disabled:j,readOnly:$,..._,children:e(l.Thumb,{className:`${v} ${b[n]}`})})}),D=p||g?a("span",{className:["flex min-w-0 flex-col gap-0.5","start"===k?"flex-1":""].filter(Boolean).join(" "),children:[p?e(o.Label,{className:["leading-[1.4]",j?"text-(--neba-disabled-fg)":"cursor-pointer text-(--neba-fg)"].join(" "),children:p}):null,g?e(o.Description,{className:`${i[n]} text-(--neba-muted-fg)`,children:g}):null]}):null;return a(o.Root,{disabled:j,invalid:O,className:["inline-flex flex-col gap-1 align-top",N??""].filter(Boolean).join(" "),style:{...q,...y},children:[e("div",{className:`flex items-start gap-2.5 ${t[n]} ${s}`,children:a(r,"start"===k?{children:[D,z]}:{children:[z,D]})}),B?e(o.Error,{match:!0,className:`${i[n]} text-(--n-accent)`,children:x}):null]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{Switch}from"./Switch";
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type BoxProps } from '../box/Box';
|
|
3
|
+
import type { NebaAlign } from '../../types';
|
|
4
|
+
/** Which edge the text in a column lines up against. */
|
|
5
|
+
export type TableAlign = NebaAlign;
|
|
6
|
+
/**
|
|
7
|
+
* A column: its heading, its default width, and how to get a cell out of a row.
|
|
8
|
+
*
|
|
9
|
+
* This is the whole reason Table takes data rather than markup. A `<td>` written
|
|
10
|
+
* out per row can silently disagree with the `<th>` above it about how many
|
|
11
|
+
* there are or what order they come in; a column list cannot.
|
|
12
|
+
*/
|
|
13
|
+
export interface TableColumn<Row> {
|
|
14
|
+
/**
|
|
15
|
+
* Identifies the column, and — unless `render` says otherwise — names the
|
|
16
|
+
* property to read off each row.
|
|
17
|
+
*/
|
|
18
|
+
key: string;
|
|
19
|
+
/** The heading. Defaults to the `key`, which is usually not what you want. */
|
|
20
|
+
label?: React.ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* The column's default width. A number is pixels; a string is any CSS length
|
|
23
|
+
* (`'30%'`, `'12rem'`, `'minmax(...)'` is not — this is a `<col>`, not a grid).
|
|
24
|
+
*
|
|
25
|
+
* "Default" is meant: the table still balances the columns to fill its width,
|
|
26
|
+
* so this is a starting proportion rather than a guarantee.
|
|
27
|
+
*/
|
|
28
|
+
width?: number | string;
|
|
29
|
+
/**
|
|
30
|
+
* Text alignment. Numbers usually want `end` so their digits line up in a
|
|
31
|
+
* column; everything else wants `start`.
|
|
32
|
+
* @default 'start'
|
|
33
|
+
*/
|
|
34
|
+
align?: TableAlign;
|
|
35
|
+
/**
|
|
36
|
+
* Renders the cell. Without it the cell is `row[key]` rendered as-is, which
|
|
37
|
+
* covers strings and numbers and nothing else.
|
|
38
|
+
*/
|
|
39
|
+
render?: (row: Row, index: number) => React.ReactNode;
|
|
40
|
+
}
|
|
41
|
+
export interface TableProps<Row> extends Omit<BoxProps, 'padded' | 'children' | 'render' | 'title'> {
|
|
42
|
+
/** The columns, in the order they appear. */
|
|
43
|
+
headers: readonly TableColumn<Row>[];
|
|
44
|
+
/** The rows. */
|
|
45
|
+
items: readonly Row[];
|
|
46
|
+
/**
|
|
47
|
+
* A stable key per row. Defaults to the row's index, which is fine for a
|
|
48
|
+
* static table and wrong for one that sorts or filters.
|
|
49
|
+
*/
|
|
50
|
+
getRowKey?: (row: Row, index: number) => React.Key;
|
|
51
|
+
/** Shown above the table, and read out as its accessible name. */
|
|
52
|
+
caption?: React.ReactNode;
|
|
53
|
+
/** What to show instead of rows when `items` is empty. */
|
|
54
|
+
empty?: React.ReactNode;
|
|
55
|
+
/**
|
|
56
|
+
* Tints every other row. Useful for a wide table where the eye has to track
|
|
57
|
+
* across; noise on a narrow one.
|
|
58
|
+
* @default false
|
|
59
|
+
*/
|
|
60
|
+
striped?: boolean;
|
|
61
|
+
/** Lights the row under the pointer. @default false */
|
|
62
|
+
hoverable?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Pins the header while the body scrolls. Only does anything if something
|
|
65
|
+
* around the table actually constrains its height.
|
|
66
|
+
* @default false
|
|
67
|
+
*/
|
|
68
|
+
stickyHeader?: boolean;
|
|
69
|
+
/** Makes rows activatable. Also turns on the hover treatment. */
|
|
70
|
+
onRowClick?: (row: Row, index: number) => void;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A grid of data.
|
|
74
|
+
*
|
|
75
|
+
* The sheet is a Box — `variant`, `size`, `color`, `density` and `elevation` all
|
|
76
|
+
* pass straight through, so a table is styled on the same axes as everything it
|
|
77
|
+
* might sit next to. What Table adds is the part that is genuinely tabular: the
|
|
78
|
+
* columns, the rows, and the fact that the two cannot drift apart.
|
|
79
|
+
*/
|
|
80
|
+
export declare function Table<Row>({ headers, items, getRowKey, caption, empty, striped, hoverable, stickyHeader, onRowClick, size, density, className, ...boxProps }: TableProps<Row>): React.JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import{Box as r}from"../box/Box";import{controlTextLeadingClasses as a,metaTextClasses as l,paddingXValues as n}from"../../internal/styles";const o={default:{xs:"0.25rem",sm:"0.375rem",md:"0.625rem",lg:"0.75rem",xl:"0.875rem"},compact:{xs:"0.125rem",sm:"0.25rem",md:"0.375rem",lg:"0.5rem",xl:"0.625rem"}},s=["[--n-row:transparent]","[transition:background-color_var(--neba-duration)_var(--neba-ease)]"].join(" "),i={borderTop:"1px solid var(--n-line)",backgroundColor:"var(--n-row)"};export function Table({headers:d,items:c,getRowKey:m,caption:p,empty:h,striped:b=!1,hoverable:x=!1,stickyHeader:y=!1,onRowClick:g,size:f="md",density:u="default",className:v,...w}){const k=n[u][f],N=o[u][f],j=Boolean(g),$=x||j,B={padding:`${N} ${k}`},C={...B,backgroundColor:"var(--n-panel-press)"};return e(r,{size:f,density:u,padded:!1,className:["overflow-x-auto",v??""].filter(Boolean).join(" "),...w,children:t("table",{className:`w-full text-start ${a[f]} text-(--neba-fg)`,style:{borderCollapse:"collapse"},children:[p?e("caption",{className:`${l[f]} text-(--neba-muted-fg)`,style:{...B,textAlign:"start"},children:p}):null,e("colgroup",{children:d.map(t=>e("col",{style:void 0===t.width?void 0:{width:"number"==typeof t.width?`${t.width}px`:t.width}},t.key))}),e("thead",{children:e("tr",{children:d.map(t=>e("th",{scope:"col",className:["font-semibold whitespace-nowrap text-(--neba-muted-fg)",y?"sticky top-0 z-10 [backdrop-filter:var(--neba-blur)]":""].filter(Boolean).join(" "),style:{...C,textAlign:t.align??"start"},children:t.label??t.key},t.key))})}),e("tbody",{children:0===c.length?e("tr",{className:s,style:i,children:e("td",{colSpan:d.length,className:"text-(--neba-muted-fg)",style:{padding:`2rem ${k}`,textAlign:"center"},children:h??"No data"})}):c.map((t,r)=>e("tr",{className:[s,b&&r%2==1?"[--n-row:var(--n-panel-hover)]":"",$?"hover:[--n-row:var(--n-soft)]":"",j?"cursor-pointer":""].filter(Boolean).join(" "),style:i,onClick:g?()=>g(t,r):void 0,children:d.map(a=>e("td",{style:{...B,textAlign:a.align??"start"},children:a.render?a.render(t,r):t[a.key]},a.key))},m?m(t,r):r))})]})})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{Table}from"./Table";
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { NebaOrientation, NebaStyleProps, NebaVariant } from '../../types';
|
|
3
|
+
/** A tab's value. The same restraint Select puts on its own — an identifier. */
|
|
4
|
+
export type TabValue = string | number;
|
|
5
|
+
export interface TabsProps extends Omit<NebaStyleProps, 'variant'>, Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'defaultValue' | 'onChange'> {
|
|
6
|
+
/**
|
|
7
|
+
* Weight of the tab *bar*, not of the panels under it.
|
|
8
|
+
*
|
|
9
|
+
* - `solid` — a segmented control: the bar is a frosted trough and the
|
|
10
|
+
* indicator is a filled tile that slides between the tabs.
|
|
11
|
+
* - `outline` — the classic: a rule along the edge of the bar with the
|
|
12
|
+
* indicator riding on it.
|
|
13
|
+
* - `text` — the same bar with the rule taken away, for tabs inside a Card
|
|
14
|
+
* that already has an edge of its own.
|
|
15
|
+
* @default 'outline'
|
|
16
|
+
*/
|
|
17
|
+
variant?: NebaVariant;
|
|
18
|
+
/** The chosen tab. Use with `onValueChange` for a controlled set. */
|
|
19
|
+
value?: TabValue | null;
|
|
20
|
+
/** Which starts chosen, for an uncontrolled set. */
|
|
21
|
+
defaultValue?: TabValue | null;
|
|
22
|
+
onValueChange?: (value: TabValue | null) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Which way the bar runs. `vertical` puts the tabs down the side and the
|
|
25
|
+
* panel beside them, and moves the arrow keys onto the other axis — which is
|
|
26
|
+
* Base UI's doing, and is what makes a vertical tab bar reachable.
|
|
27
|
+
* @default 'horizontal'
|
|
28
|
+
*/
|
|
29
|
+
orientation?: NebaOrientation;
|
|
30
|
+
/**
|
|
31
|
+
* Whether moving the arrow keys also chooses the tab it lands on.
|
|
32
|
+
*
|
|
33
|
+
* `false` by default. Automatic activation is only kind when every panel is
|
|
34
|
+
* already on the page; the moment one of them fetches, walking past four tabs
|
|
35
|
+
* fires four requests.
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
activateOnFocus?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Whether the arrow keys wrap from the last tab back to the first.
|
|
41
|
+
* @default true
|
|
42
|
+
*/
|
|
43
|
+
loopFocus?: boolean;
|
|
44
|
+
/** The tabs share the bar's full width, each taking an equal share of it. */
|
|
45
|
+
fullWidth?: boolean;
|
|
46
|
+
children?: React.ReactNode;
|
|
47
|
+
}
|
|
48
|
+
export interface TabProps extends Omit<React.ComponentPropsWithoutRef<'button'>, 'value' | 'color'> {
|
|
49
|
+
/** Identifies the tab, and picks out the panel with the same value. */
|
|
50
|
+
value: TabValue;
|
|
51
|
+
/** Content before the label. Sized in `em`, so it tracks the label. */
|
|
52
|
+
startIcon?: React.ReactNode;
|
|
53
|
+
/** Content after the label — a count, a Badge, a status dot. */
|
|
54
|
+
endIcon?: React.ReactNode;
|
|
55
|
+
/** Unavailable, but still listed. */
|
|
56
|
+
disabled?: boolean;
|
|
57
|
+
children?: React.ReactNode;
|
|
58
|
+
}
|
|
59
|
+
export interface TabPanelProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
60
|
+
/** Which tab shows this panel. */
|
|
61
|
+
value: TabValue;
|
|
62
|
+
/**
|
|
63
|
+
* Keeps the panel in the DOM while it is hidden. For a panel that is expensive
|
|
64
|
+
* to build, or that holds form state which should survive being switched away
|
|
65
|
+
* from.
|
|
66
|
+
* @default false
|
|
67
|
+
*/
|
|
68
|
+
keepMounted?: boolean;
|
|
69
|
+
children?: React.ReactNode;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* One tab, and one place a tab differs from a Button: `solid` puts the tile
|
|
73
|
+
* *behind* the tab rather than on it, so the tab needs a stacking context of its
|
|
74
|
+
* own or the indicator would cover the label it is meant to be under.
|
|
75
|
+
*/
|
|
76
|
+
export declare const Tab: React.ForwardRefExoticComponent<TabProps & React.RefAttributes<HTMLButtonElement>>;
|
|
77
|
+
/** The content behind one tab. */
|
|
78
|
+
export declare const TabPanel: React.ForwardRefExoticComponent<TabPanelProps & React.RefAttributes<HTMLDivElement>>;
|
|
79
|
+
/**
|
|
80
|
+
* One set of panels, one of which is shown.
|
|
81
|
+
*
|
|
82
|
+
* Base UI owns everything that makes a tab bar a tab bar rather than a row of
|
|
83
|
+
* buttons: roving focus so the whole bar is one tab stop, the arrow keys on
|
|
84
|
+
* whichever axis the bar runs, Home and End, the `tab` / `tabpanel` roles and
|
|
85
|
+
* the `aria-controls` wiring between them, and the measurement that puts the
|
|
86
|
+
* indicator under the chosen tab. What is here is the surface and the ladders.
|
|
87
|
+
*
|
|
88
|
+
* The tabs and the panels are composed rather than passed as data, unlike
|
|
89
|
+
* Select — because a panel is a subtree, and there is no useful shape for
|
|
90
|
+
* "an array of arbitrary React trees" that is not just children.
|
|
91
|
+
*/
|
|
92
|
+
export declare const Tabs: React.ForwardRefExoticComponent<TabsProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as a from"react";import{Tabs as i}from"@base-ui/react/tabs";import{controlHeightClasses as o,controlTextClasses as l,gapClasses as n,hasContent as r,iconClasses as s,paddingXClasses as c,radiusClasses as d,surfaceClasses as f,surfaceSlots as u,transitionClasses as h}from"../../internal/styles";const b=a.createContext({variant:"outline",size:"md",density:"default",orientation:"horizontal",fullWidth:!1}),v={solid:{horizontal:`${f} inline-flex bg-(--n-panel) p-1 [box-shadow:var(--neba-plate-glass)]`,vertical:`${f} inline-flex flex-col bg-(--n-panel) p-1 [box-shadow:var(--neba-plate-glass)]`},outline:{horizontal:"flex border-b [border-color:var(--n-line)]",vertical:"flex flex-col border-e [border-color:var(--n-line)]"},text:{horizontal:"flex",vertical:"flex flex-col"}},p={solid:{horizontal:"absolute left-(--active-tab-left) top-(--active-tab-top) h-(--active-tab-height) w-(--active-tab-width)",vertical:"absolute left-(--active-tab-left) top-(--active-tab-top) h-(--active-tab-height) w-(--active-tab-width)"},outline:{horizontal:"absolute bottom-0 left-(--active-tab-left) h-0.5 w-(--active-tab-width)",vertical:"absolute end-0 top-(--active-tab-top) h-(--active-tab-height) w-0.5"},text:{horizontal:"absolute bottom-0 left-(--active-tab-left) h-0.5 w-(--active-tab-width)",vertical:"absolute end-0 top-(--active-tab-top) h-(--active-tab-height) w-0.5"}},x={solid:`${f} bg-(--n-panel-press) [box-shadow:var(--neba-shadow-1),var(--neba-plate-glass)]`,outline:"bg-(--n-accent)",text:"bg-(--n-accent)"},m={solid:"text-(--neba-muted-fg) hover:text-(--neba-fg) data-[active]:text-(--n-accent)",outline:"text-(--neba-muted-fg) hover:text-(--neba-fg) data-[active]:text-(--n-accent)",text:"text-(--neba-muted-fg) hover:text-(--neba-fg) data-[active]:text-(--n-accent)"};export const Tab=a.forwardRef(function({value:f,startIcon:u,endIcon:v,disabled:p=!1,className:x,children:g,...w},z){const{variant:y,size:N,density:j,fullWidth:k}=a.useContext(b);return t(i.Tab,{ref:z,value:f,disabled:p,className:["relative z-10 inline-flex shrink-0 cursor-pointer items-center justify-center select-none","whitespace-nowrap font-medium","[-webkit-tap-highlight-color:transparent] [touch-action:manipulation]",o[N],l[N],n[N],c[j][N],"solid"===y?d[N]:"",h,s,m[y],"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:[outline-offset:-2px]","data-[disabled]:cursor-not-allowed data-[disabled]:text-(--neba-disabled-fg)",k?"flex-1":"",x??""].filter(Boolean).join(" "),...w,children:[r(u)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:u}):null,g,r(v)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:v}):null]})});export const TabPanel=a.forwardRef(function({value:t,keepMounted:o=!1,className:l,children:n,...r},s){const{size:c}=a.useContext(b);return e(i.Panel,{ref:s,value:t,keepMounted:o,className:["min-w-0 flex-1 text-(--neba-fg)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2",d[c],l??""].filter(Boolean).join(" "),...r,children:n})});export const Tabs=a.forwardRef(function({variant:o="outline",size:l="md",color:n="primary",density:r="default",value:s,defaultValue:c,onValueChange:f,orientation:h="horizontal",activateOnFocus:m=!1,loopFocus:g=!0,fullWidth:w=!1,className:z,style:y,children:N,...j},k){const C=a.useMemo(()=>({variant:o,size:l,density:r,orientation:h,fullWidth:w}),[o,l,r,h,w]),T=[],V=[];return a.Children.forEach(N,e=>{a.isValidElement(e)&&e.type===TabPanel?V.push(e):null!=e&&!1!==e&&T.push(e)}),e(b.Provider,{value:C,children:t(i.Root,{ref:k,value:s,defaultValue:c,onValueChange:e=>f?.(e),orientation:h,className:["flex min-w-0","vertical"===h?"flex-row gap-4":"flex-col gap-4",z??""].filter(Boolean).join(" "),style:{...u(n,0),...y},...j,children:[t(i.List,{activateOnFocus:m,loopFocus:g,className:["relative shrink-0",v[o][h],"solid"===o?d[l]:"",w&&"horizontal"===h?"w-full":"","horizontal"===h?"overflow-x-auto overflow-y-hidden":""].filter(Boolean).join(" "),children:[T,e(i.Indicator,{className:["pointer-events-none",p[o][h],x[o],"solid"===o?d[l]:"rounded-full","[transition-property:left,top,width,height]","[transition-duration:var(--neba-duration)]","[transition-timing-function:var(--neba-ease)]"].join(" ")})]}),V]})})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{Tab,TabPanel,Tabs}from"./Tabs";
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { NebaElevation, NebaStyleProps } from '../../types';
|
|
3
|
+
/** How the multiline control may be resized by the user. Ignored when single line. */
|
|
4
|
+
export type TextFieldResize = 'none' | 'vertical' | 'horizontal' | 'both';
|
|
5
|
+
/**
|
|
6
|
+
* Native `<input>` attributes, minus the three that collide with the shared
|
|
7
|
+
* vocabulary: `color` and `size` are Neba props here, and `onChange` is widened
|
|
8
|
+
* below so the same handler types against a `<textarea>` in multiline mode.
|
|
9
|
+
*/
|
|
10
|
+
type NativeControlProps = Omit<React.ComponentPropsWithoutRef<'input'>, 'color' | 'size' | 'onChange' | 'children'>;
|
|
11
|
+
export interface TextFieldProps extends NebaStyleProps, NativeControlProps {
|
|
12
|
+
/**
|
|
13
|
+
* Drop shadow depth. `0` (the default) is flat — a field is a well, not a
|
|
14
|
+
* surface that floats, so this is raised even less often than on a Button.
|
|
15
|
+
* @default 0
|
|
16
|
+
*/
|
|
17
|
+
elevation?: NebaElevation;
|
|
18
|
+
/**
|
|
19
|
+
* Renders a `<textarea>` instead of an `<input>`. Everything else — sizing,
|
|
20
|
+
* density, variants, states — stays identical, so switching a field to
|
|
21
|
+
* multiline never changes how it sits in a form.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
multiline?: boolean;
|
|
25
|
+
/** Visible rows in multiline mode. One row is exactly the single-line height. */
|
|
26
|
+
rows?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Which way the user may drag the multiline control. Horizontal resizing
|
|
29
|
+
* breaks a form's column, so only the vertical axis is on by default.
|
|
30
|
+
* @default 'vertical'
|
|
31
|
+
*/
|
|
32
|
+
resize?: TextFieldResize;
|
|
33
|
+
/**
|
|
34
|
+
* Label above the control, wired to it by Base UI's Field. There is no
|
|
35
|
+
* floating variant on purpose: floating labels need a `transform`, and
|
|
36
|
+
* controls in this library never transform.
|
|
37
|
+
*/
|
|
38
|
+
label?: React.ReactNode;
|
|
39
|
+
/** Helper text below the control. */
|
|
40
|
+
description?: React.ReactNode;
|
|
41
|
+
/** Error message below the control. Its presence also turns the field invalid. */
|
|
42
|
+
error?: React.ReactNode;
|
|
43
|
+
/**
|
|
44
|
+
* Forces the invalid state without a message — for when an external form
|
|
45
|
+
* library owns the validity. Defaults to whether `error` has content.
|
|
46
|
+
*/
|
|
47
|
+
invalid?: boolean;
|
|
48
|
+
/** Content placed before the control. Sized in `em`, so it tracks the text. */
|
|
49
|
+
startIcon?: React.ReactNode;
|
|
50
|
+
/** Content placed after the control. */
|
|
51
|
+
endIcon?: React.ReactNode;
|
|
52
|
+
/**
|
|
53
|
+
* Shows a spinner in place of `endIcon` and marks the field busy. Typing is
|
|
54
|
+
* deliberately still allowed — a field is usually loading *because of* what
|
|
55
|
+
* was typed into it.
|
|
56
|
+
*/
|
|
57
|
+
loading?: boolean;
|
|
58
|
+
/** Stretches to the width of the container. */
|
|
59
|
+
fullWidth?: boolean;
|
|
60
|
+
onChange?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement>;
|
|
61
|
+
}
|
|
62
|
+
export declare const TextField: React.ForwardRefExoticComponent<TextFieldProps & React.RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
|
|
63
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{Field as r}from"@base-ui/react/field";import{Input as i}from"@base-ui/react/input";import{controlHeightClasses as l,controlTextLeadingClasses as a,disabledClasses as s,fieldReadOnlyClasses as o,fieldRestClasses as c,focusWithinRingClasses as d,gapClasses as m,iconClasses as u,metaTextClasses as f,paddingXClasses as p,radiusClasses as x,stackGapClasses as h,surfaceSlots as g,transitionClasses as b}from"../../internal/styles";const y={xs:`${m.xs} ${x.xs} ${a.xs}`,sm:`${m.sm} ${x.sm} ${a.sm}`,md:`${m.md} ${x.md} ${a.md}`,lg:`${m.lg} ${x.lg} ${a.lg}`,xl:`${m.xl} ${x.xl} ${a.xl}`},$={xs:"min-h-5.5 py-[3px]",sm:"min-h-6.5 py-[4px]",md:"min-h-8 py-[5px]",lg:"min-h-10 py-[8px]",xl:"min-h-12 py-[10px]"},v={none:"resize-none",vertical:"resize-y",horizontal:"resize-x",both:"resize"},w=["group relative flex w-full cursor-text","[-webkit-tap-highlight-color:transparent]",b,"focus-within:[transition-duration:0ms]",d,u].join(" "),N=c,j=o;function k(){return t("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 TextField=n.forwardRef(function({variant:a="outline",size:o="md",color:c="primary",density:d="default",elevation:m=0,multiline:u=!1,rows:x=3,resize:b="vertical",label:z,description:B,error:C,invalid:D,startIcon:O,endIcon:R,loading:W=!1,fullWidth:I=!1,readOnly:L=!1,disabled:T=!1,type:A="text",className:E,style:F,...M},P){const q=null!=C&&!1!==C&&""!==C,G=D??q,H=G?"danger":c,J=n.useRef(null),K=n.useCallback(e=>{J.current=e,"function"==typeof P?P(e):P&&(P.current=e)},[P]),Q=[w,y[o],u?`${$[o]} items-start`:`${l[o]} items-center`,p[d][o],T?s[a]:L?j[a]:N[a]].filter(Boolean).join(" "),S=["min-w-0 flex-1 bg-transparent [font:inherit] text-inherit","[outline:none]","placeholder:text-(--neba-muted-fg)","caret-(--n-accent) selection:bg-(--n-soft-press)","disabled:cursor-not-allowed",u?`block ${v[b]}`:"self-stretch"].join(" "),U="inline-flex h-[1lh] shrink-0 items-center text-(--neba-muted-fg) transition-[color] duration-(--neba-duration) group-focus-within:text-(--n-accent)";return t(r.Root,{disabled:T,invalid:G,className:["flex-col align-top",h[o],I?"flex w-full":"inline-flex",E??""].filter(Boolean).join(" "),style:{...g(H,m),...F},children:[z?e(r.Label,{className:[f[o],"font-medium",T?"text-(--neba-disabled-fg)":"text-(--neba-fg)"].join(" "),children:z}):null,t("span",{className:Q,onPointerDown:e=>{e.target!==e.currentTarget||T||(e.preventDefault(),J.current?.focus())},children:[O?e("span",{className:U,children:O}):null,e(i,{ref:K,className:S,disabled:T,readOnly:L,"aria-busy":W||void 0,"data-loading":W||void 0,...u?{render:e("textarea",{rows:x})}:{type:A},...M}),W?e("span",{className:U,children:e(k,{})}):R?e("span",{className:U,children:R}):null]}),B?e(r.Description,{className:[f[o],"text-(--neba-muted-fg)"].join(" "),children:B}):null,q?e(r.Error,{match:!0,className:[f[o],"text-(--n-accent)"].join(" "),children:C}):null]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{TextField}from"./TextField";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type PickerLabels, type TimeUnit } from '../../internal/calendar';
|
|
3
|
+
import { type PickerShellProps } from '../../internal/picker';
|
|
4
|
+
/**
|
|
5
|
+
* Which column of the clock a row belongs to. Re-exported so a caller writing a
|
|
6
|
+
* `shouldDisableTime` rule can name the argument it is handed.
|
|
7
|
+
*/
|
|
8
|
+
export type { TimeUnit };
|
|
9
|
+
export interface TimePickerProps extends PickerShellProps {
|
|
10
|
+
/** The chosen time. A `Date`, so it carries a day as well — see `referenceDate`. */
|
|
11
|
+
value?: Date | null;
|
|
12
|
+
defaultValue?: Date | null;
|
|
13
|
+
onValueChange?: (value: Date | null) => void;
|
|
14
|
+
open?: boolean;
|
|
15
|
+
defaultOpen?: boolean;
|
|
16
|
+
onOpenChange?: (open: boolean) => void;
|
|
17
|
+
/**
|
|
18
|
+
* The day a chosen time is written onto while there is no value yet.
|
|
19
|
+
* @default today
|
|
20
|
+
*/
|
|
21
|
+
referenceDate?: Date;
|
|
22
|
+
/** The earliest time of day that may be chosen. Only the clock is read. */
|
|
23
|
+
minTime?: Date | null;
|
|
24
|
+
/** The latest time of day that may be chosen. */
|
|
25
|
+
maxTime?: Date | null;
|
|
26
|
+
/**
|
|
27
|
+
* Blocks individual rows. Called once per row per column with the instant that
|
|
28
|
+
* row would produce and the column it is in, so a rule may be as coarse as
|
|
29
|
+
* "no afternoons" or as fine as one minute.
|
|
30
|
+
*/
|
|
31
|
+
shouldDisableTime?: (value: Date, unit: TimeUnit) => boolean;
|
|
32
|
+
/** A 12-hour dial with an AM/PM column. Defaults to whatever the locale does. */
|
|
33
|
+
hour12?: boolean;
|
|
34
|
+
/** Adds the seconds column. @default false */
|
|
35
|
+
showSeconds?: boolean;
|
|
36
|
+
/** How far apart the rows of each column are. @default 1 */
|
|
37
|
+
hourStep?: number;
|
|
38
|
+
minuteStep?: number;
|
|
39
|
+
secondStep?: number;
|
|
40
|
+
locale?: string;
|
|
41
|
+
/**
|
|
42
|
+
* How the trigger writes the chosen time. Passed straight to `Intl`.
|
|
43
|
+
* @default { hour: 'numeric', minute: '2-digit' }, plus seconds when shown
|
|
44
|
+
*/
|
|
45
|
+
format?: Intl.DateTimeFormatOptions;
|
|
46
|
+
placeholder?: React.ReactNode;
|
|
47
|
+
clearable?: boolean;
|
|
48
|
+
/** Offers the shortcut to the current time in the footer. @default true */
|
|
49
|
+
showNowButton?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Closes the popup as soon as any column is touched. `false` by default and
|
|
52
|
+
* unlike DatePicker, because a time is two answers and closing after the first
|
|
53
|
+
* one would make choosing 9:30 a matter of opening the popup twice.
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
closeOnSelect?: boolean;
|
|
57
|
+
labels?: Partial<PickerLabels>;
|
|
58
|
+
/** Identifies the field when a form is submitted, as `HH:MM` (`HH:MM:SS`). */
|
|
59
|
+
name?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A time of day, chosen from columns.
|
|
63
|
+
*
|
|
64
|
+
* The bounds are checked at the granularity of the column being drawn, which is
|
|
65
|
+
* the detail that separates a working time picker from a frustrating one. With a
|
|
66
|
+
* `minTime` of 09:30, the hour `9` stays available — the hour *contains* allowed
|
|
67
|
+
* minutes — and it is the minute column that greys out `00` through `25`. The
|
|
68
|
+
* naive check compares the whole candidate instant and hides the 9 entirely,
|
|
69
|
+
* which makes half past nine unreachable.
|
|
70
|
+
*
|
|
71
|
+
* The value is a `Date` rather than a string or a number of minutes, because
|
|
72
|
+
* everything else in this library that carries a moment is one, and because a
|
|
73
|
+
* time on its own has nowhere to record that it crossed a DST boundary.
|
|
74
|
+
* `referenceDate` is the day a bare time is written onto.
|
|
75
|
+
*/
|
|
76
|
+
export declare const TimePicker: React.ForwardRefExoticComponent<TimePickerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as n}from"react/jsx-runtime";import*as o from"react";import{Button as t}from"../button/Button";import{TimeGrid as l,usePickerLabels as a}from"../../internal/calendar";import{ClockIcon as i}from"../../internal/icons";import{PickerFooter as r,PickerShell as s}from"../../internal/picker";import{displaySamples as c,formatDate as d,isHour12 as u,isValidDate as m,secondsOfDay as p,timeUnitSpan as h,toISOTime as f,withPlaceholder as S,withTime as b}from"../../internal/date";import{cx as g}from"../../internal/styles";export const TimePicker=o.forwardRef(function({value:y,defaultValue:v,onValueChange:x,open:C,defaultOpen:w,onOpenChange:z,referenceDate:k,minTime:D,maxTime:O,shouldDisableTime:T,hour12:j,showSeconds:V=!1,hourStep:B=1,minuteStep:I=1,secondStep:M=1,locale:N,format:R,placeholder:F,clearable:H=!1,showNowButton:P=!0,closeOnSelect:q=!1,labels:A,name:E,size:G="md",color:J="primary",density:K="default",readOnly:L=!1,disabled:Q=!1,startIcon:U,...W},X){const Y=a(A),Z=j??u(N),[$,_]=o.useState(v??null),ee=void 0!==y?y:$,[ne,oe]=o.useState(w??!1),te=C??ne,[le]=o.useState(()=>k??new Date),ae=e=>{e&&(L||Q)||(void 0===C&&oe(e),z?.(e))},ie=e=>{void 0===y&&_(e),x?.(e)},re=o.useCallback((e,n)=>{const[o,t]=h(n,e);return!!(m(D)&&t<p(D))||(!!(m(O)&&o>p(O))||(T?.(e,n)??!1))},[D,O,T]),se=R??{hour:"numeric",minute:"2-digit",...V?{second:"2-digit"}:{}},ce=new Date,de=b(k??le,{hours:ce.getHours(),minutes:ce.getMinutes(),seconds:V?ce.getSeconds():0}),ue=P||H||!q,me=o.useMemo(()=>S(c(N,se),F),[N,se,F]);return e(s,{...W,size:G,color:J,density:K,readOnly:L,disabled:Q,triggerRef:X,startIcon:U??e(i,{}),display:m(ee)?d(ee,N,se):F??"",samples:me,empty:!m(ee),clearable:H,onClear:()=>ie(null),open:te,onOpenChange:ae,labels:Y,hiddenValues:E?[{name:E,value:m(ee)?f(ee,V):""}]:void 0,children:n("div",{className:g("flex flex-col",ue&&"gap-1.5"),children:[e(l,{size:G,density:K,locale:N,value:m(ee)?ee:null,referenceDate:k??le,onChange:e=>{ie(e),q&&ae(!1)},hour12:Z,showSeconds:V,hourStep:B,minuteStep:I,secondStep:M,shouldDisableTime:re,labels:Y,autoFocus:!0}),ue?n(r,{size:G,children:[H?e(t,{variant:"text",size:G,color:J,density:"compact",onClick:()=>{ie(null),ae(!1)},children:Y.clear}):null,P?e(t,{variant:"text",size:G,color:J,density:"compact",disabled:re(de,"second"),onClick:()=>{ie(de),ae(!1)},children:Y.now}):null,q?null:e(t,{variant:"solid",size:G,color:J,density:"compact",onClick:()=>ae(!1),children:Y.done})]}):null]})})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{TimePicker}from"./TimePicker";
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
+
import type { NebaColor, NebaDensity, NebaOrientation, NebaSize } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* How far along one item is.
|
|
6
|
+
*
|
|
7
|
+
* Three states rather than two, because "the one you are on" is not the same
|
|
8
|
+
* claim as "done" and a sequence that cannot say which step is current is a
|
|
9
|
+
* list. Each gets its own axis — a filled bullet, a filled bullet with a halo
|
|
10
|
+
* around it, an empty one — rather than three shades of the same thing.
|
|
11
|
+
*/
|
|
12
|
+
export type TimelineStatus = 'complete' | 'current' | 'upcoming';
|
|
13
|
+
/** How the line between two items is drawn. `none` leaves the gap open. */
|
|
14
|
+
export type TimelineConnector = 'solid' | 'dashed' | 'dotted' | 'none';
|
|
15
|
+
export interface TimelineProps extends Omit<React.ComponentPropsWithoutRef<'ol'>, 'color'> {
|
|
16
|
+
/**
|
|
17
|
+
* How far the sequence has got: the index of the item being worked on now.
|
|
18
|
+
* Everything before it is complete, everything after it is still to come.
|
|
19
|
+
*
|
|
20
|
+
* An index rather than a value, because a timeline has no selection — nothing
|
|
21
|
+
* here is chosen, and the only question is how far down the list reality has
|
|
22
|
+
* reached. Omit it and every item is `upcoming` unless it says otherwise; pass
|
|
23
|
+
* the item count to mark the whole sequence done.
|
|
24
|
+
*/
|
|
25
|
+
active?: number;
|
|
26
|
+
/** @default 'md' */
|
|
27
|
+
size?: NebaSize;
|
|
28
|
+
/** @default 'primary' */
|
|
29
|
+
color?: NebaColor;
|
|
30
|
+
/** Spacing between items. Never the type scale, never the bullet. */
|
|
31
|
+
density?: NebaDensity;
|
|
32
|
+
/**
|
|
33
|
+
* Which way the sequence runs. `vertical` is the default and the one that
|
|
34
|
+
* takes an arbitrary number of steps with an arbitrary amount to say about
|
|
35
|
+
* each; `horizontal` is the stepper across the top of a checkout, and it is
|
|
36
|
+
* only honest while every label is short.
|
|
37
|
+
* @default 'vertical'
|
|
38
|
+
*/
|
|
39
|
+
orientation?: NebaOrientation;
|
|
40
|
+
/** Renders something other than an `<ol>` — Base UI's own escape hatch. */
|
|
41
|
+
render?: useRender.RenderProp;
|
|
42
|
+
children?: React.ReactNode;
|
|
43
|
+
}
|
|
44
|
+
export interface TimelineItemProps extends Omit<React.ComponentPropsWithoutRef<'li'>, 'color' | 'title'> {
|
|
45
|
+
/** The heading of this step. */
|
|
46
|
+
title?: React.ReactNode;
|
|
47
|
+
/**
|
|
48
|
+
* When it happened — a date, a duration, a name. Set beside the title on a
|
|
49
|
+
* wide item and under it on a narrow one.
|
|
50
|
+
*/
|
|
51
|
+
meta?: React.ReactNode;
|
|
52
|
+
/**
|
|
53
|
+
* What goes inside the bullet: a number, an icon, an avatar. Omit it and the
|
|
54
|
+
* bullet is a plain disc, which is what a step with nothing to say about
|
|
55
|
+
* itself should be.
|
|
56
|
+
*/
|
|
57
|
+
bullet?: React.ReactNode;
|
|
58
|
+
/**
|
|
59
|
+
* Overrides what the timeline's `active` would have computed for this item —
|
|
60
|
+
* a step that failed and stopped the sequence, a step that was skipped.
|
|
61
|
+
*/
|
|
62
|
+
status?: TimelineStatus;
|
|
63
|
+
/** Overrides the timeline's colour family for this item alone. */
|
|
64
|
+
color?: NebaColor;
|
|
65
|
+
/**
|
|
66
|
+
* How the line to the next item is drawn.
|
|
67
|
+
* @default 'solid'
|
|
68
|
+
*/
|
|
69
|
+
connector?: TimelineConnector;
|
|
70
|
+
/** The body of the step. */
|
|
71
|
+
children?: React.ReactNode;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* One step.
|
|
75
|
+
*
|
|
76
|
+
* Its index is not a prop and cannot be: an item that had to be told where it
|
|
77
|
+
* was in the list would be an item every caller could put in the wrong place,
|
|
78
|
+
* and `active={2}` would stop meaning anything. The Timeline numbers its
|
|
79
|
+
* children as it walks them, and hands each one its index through a context.
|
|
80
|
+
*/
|
|
81
|
+
export declare const TimelineItem: React.ForwardRefExoticComponent<TimelineItemProps & React.RefAttributes<HTMLLIElement>>;
|
|
82
|
+
/**
|
|
83
|
+
* A sequence of steps, in the order they happen in.
|
|
84
|
+
*
|
|
85
|
+
* There is no Base UI primitive under this and there should not be: a timeline
|
|
86
|
+
* has no selection, no roving focus and no keyboard contract — it is a list, and
|
|
87
|
+
* reaching for a composite primitive to draw one would hand every consumer's
|
|
88
|
+
* record of events the semantics of a widget.
|
|
89
|
+
*
|
|
90
|
+
* It is an `<ol>` for the reason it exists at all: the order *is* the content. A
|
|
91
|
+
* screen reader announcing "list of 5 items" over an unordered list would be
|
|
92
|
+
* describing something else.
|
|
93
|
+
*
|
|
94
|
+
* The children are numbered here rather than by a prop on each item, so `active`
|
|
95
|
+
* has something to count against and inserting a step in the middle does not
|
|
96
|
+
* mean renumbering the ones after it.
|
|
97
|
+
*/
|
|
98
|
+
export declare const Timeline: React.ForwardRefExoticComponent<TimelineProps & React.RefAttributes<HTMLOListElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as l}from"react/jsx-runtime";import*as r from"react";import{useRender as t}from"@base-ui/react/use-render";import{cx as n,hasContent as a,iconClasses as o,metaTextClasses as s,sheetBodyClasses as i,sheetTitleClasses as d,surfaceClasses as c,surfaceSlots as m,transitionClasses as p}from"../../internal/styles";const u=r.createContext(null),b=r.createContext({index:0,last:!1}),x={xs:"0.875rem",sm:"1rem",md:"1.25rem",lg:"1.5rem",xl:"1.875rem"},f={xs:"gap-2",sm:"gap-2.5",md:"gap-3",lg:"gap-3.5",xl:"gap-4"},v={default:{xs:"pb-5",sm:"pb-6",md:"pb-7",lg:"pb-8",xl:"pb-10"},compact:{xs:"pb-3",sm:"pb-3.5",md:"pb-4",lg:"pb-5",xl:"pb-6"}},g={default:{xs:"pe-5",sm:"pe-6",md:"pe-7",lg:"pe-8",xl:"pe-10"},compact:{xs:"pe-3",sm:"pe-3.5",md:"pe-4",lg:"pe-5",xl:"pe-6"}},h={solid:"border-solid",dashed:"border-dashed",dotted:"border-dotted",none:""},y={complete:`${c} bg-(--n-fill) text-(--n-on-solid) [box-shadow:var(--neba-plate-solid)]`,current:`${c} bg-(--n-fill) text-(--n-on-solid) [box-shadow:0_0_0_0.25rem_var(--n-soft),var(--neba-plate-solid)]`,upcoming:`${c} border-2 bg-(--n-panel) text-(--neba-muted-fg) [border-color:var(--n-line)]`},N={complete:"[border-color:var(--n-line-hover)]",current:"[border-color:var(--neba-border)]",upcoming:"[border-color:var(--neba-border)]"},w={complete:"text-(--neba-fg)",current:"text-(--n-accent)",upcoming:"text-(--neba-muted-fg)"};export const TimelineItem=r.forwardRef(function({title:t,meta:c,bullet:_,status:z,color:C,connector:$="solid",className:j,children:P,...R},T){const k=r.useContext(u),{index:A,last:I}=r.useContext(b),M=k?.size??"md",q=k?.density??"default",B=k?.orientation??"vertical",D=C??k?.color??"primary",E=k?.active??null,F=z??(null===E?"upcoming":A<E?"complete":A===E?"current":"upcoming"),G="horizontal"===B,H="none"!==$&&!I,J=e("span",{"aria-hidden":"true",className:n("relative z-10 flex shrink-0 items-center justify-center rounded-full","size-(--n-bullet) text-[calc(var(--n-bullet)*0.5)] leading-none font-semibold tabular-nums",y[F],p,o),children:_}),K=H?e("span",{"aria-hidden":"true",className:n("pointer-events-none absolute",G?"top-[calc(var(--n-bullet)/2_-_1px)] start-(--n-bullet) end-0 border-t-2":"start-[calc(var(--n-bullet)/2_-_1px)] top-(--n-bullet) bottom-0 border-s-2",h[$],N[F],p)}):null,L=l("div",{className:n("flex min-w-0 flex-col gap-0.5",G?"mt-2":""),children:[a(t)||a(c)?l("div",{className:"flex flex-wrap items-baseline gap-x-2",children:[a(t)?e("span",{className:n("font-semibold",d[M],w[F],p),children:t}):null,a(c)?e("span",{className:n("text-(--neba-muted-fg)",s[M]),children:c}):null]}):null,a(P)?e("div",{className:n("text-(--neba-muted-fg)",i[M]),children:P}):null]});return l("li",{ref:T,"aria-current":"current"===F?"step":void 0,"data-status":F,className:n("relative",G?n("flex min-w-0 flex-1 flex-col",I?"":g[q][M]):n("flex",f[M],I?"":v[q][M]),j),style:{"--n-bullet":x[M],...m(D,0),"--n-fill":`var(--neba-${D}-fill)`,"--n-on-solid":`var(--neba-${D}-on-solid)`},...R,children:[K,J,L]})});export const Timeline=r.forwardRef(function({active:l,size:a="md",color:o="primary",density:s="default",orientation:i="vertical",render:d,className:c,style:p,children:x,...f},v){const g=r.Children.toArray(x),h=g.length,y=r.useMemo(()=>({size:a,density:s,orientation:i,color:o,active:l??null}),[a,s,i,o,l]),N=t({render:d??e("ol",{}),ref:v,props:{role:"list",className:n("flex","horizontal"===i?"flex-row":"flex-col",c),style:{...m(o,0),...p},children:g.map((l,r)=>e(b.Provider,{value:{index:r,last:r===h-1},children:l},r)),...f}});return e(u.Provider,{value:y,children:N})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{Timeline,TimelineItem}from"./Timeline";
|