neba 0.0.1 → 1.0.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 +169 -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/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/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/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 +48 -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/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/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/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/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/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/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/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 +32 -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/icons.d.ts +48 -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/progress.d.ts +122 -0
- package/dist/internal/progress.js +1 -0
- package/dist/internal/styles.d.ts +224 -0
- package/dist/internal/styles.js +1 -0
- package/dist/styles.css +758 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.js +8 -0
- package/package.json +75 -19
- package/pnpm-workspace.yaml +0 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { NebaColor, NebaDensity, NebaSize } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* What a menu item inherits from the menu around it.
|
|
5
|
+
*
|
|
6
|
+
* The same arrangement `ButtonGroup` uses, and for the same reason: `size`,
|
|
7
|
+
* `color` and `density` are properties of the *menu*, not of any one row in it,
|
|
8
|
+
* and passing them per item would be three chances per row to get one wrong —
|
|
9
|
+
* with a silent failure, a menu where the fourth item is a size bigger.
|
|
10
|
+
*
|
|
11
|
+
* It lives in `internal/` rather than in `Menu.tsx` because a submenu is a menu
|
|
12
|
+
* inside a menu and a context menu is the same rows hung off a right-click, so
|
|
13
|
+
* three components read this and none of them should have to import the others.
|
|
14
|
+
*/
|
|
15
|
+
export interface MenuContextValue {
|
|
16
|
+
size: NebaSize;
|
|
17
|
+
color: NebaColor;
|
|
18
|
+
density: NebaDensity;
|
|
19
|
+
}
|
|
20
|
+
export declare const MenuContext: React.Context<MenuContextValue>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as t from"react";export const MenuContext=t.createContext({size:"md",color:"primary",density:"default"});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the three progress indicators share.
|
|
3
|
+
*
|
|
4
|
+
* `ProgressLinear`, `ProgressCircular` and `ProgressBox` are three different
|
|
5
|
+
* shapes answering one question — how far along is this, and is it moving at
|
|
6
|
+
* all — so the parts that are *not* the shape belong here: the colour slots,
|
|
7
|
+
* the size ladders, and the arithmetic that turns `value`/`min`/`max` into a
|
|
8
|
+
* fraction.
|
|
9
|
+
*
|
|
10
|
+
* The shapes themselves are all that is left in each component, which is the
|
|
11
|
+
* point: they are the only thing that genuinely differs.
|
|
12
|
+
*/
|
|
13
|
+
import type * as React from 'react';
|
|
14
|
+
import type { NebaColor, NebaSize } from '../types';
|
|
15
|
+
/**
|
|
16
|
+
* The props all three indicators take.
|
|
17
|
+
*
|
|
18
|
+
* Declared once and extended rather than copied three times, because the whole
|
|
19
|
+
* claim being made is that these are the same component in three shapes: a
|
|
20
|
+
* `value` of `null` has to mean the same thing on a bar, a ring and a row of
|
|
21
|
+
* plates, or the trio is three components that happen to share a prefix.
|
|
22
|
+
*/
|
|
23
|
+
export interface ProgressSharedProps {
|
|
24
|
+
/**
|
|
25
|
+
* How far along, between `min` and `max`.
|
|
26
|
+
*
|
|
27
|
+
* `null` — the default — is the indeterminate case: something is happening
|
|
28
|
+
* and nobody knows how much of it is left. That is the default on purpose. An
|
|
29
|
+
* indicator that has not been told a value should say so rather than draw an
|
|
30
|
+
* empty bar, which is a claim that no progress has been made.
|
|
31
|
+
* @default null
|
|
32
|
+
*/
|
|
33
|
+
value?: number | null;
|
|
34
|
+
/** @default 0 */
|
|
35
|
+
min?: number;
|
|
36
|
+
/** @default 100 */
|
|
37
|
+
max?: number;
|
|
38
|
+
/** A name for what is loading. Read out with the value by a screen reader. */
|
|
39
|
+
label?: React.ReactNode;
|
|
40
|
+
/**
|
|
41
|
+
* Shows the value as text beside the shape. Percentage of the range unless
|
|
42
|
+
* `format` says otherwise.
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
showValue?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* How to format the value when it is shown — `Intl.NumberFormat` options, so
|
|
48
|
+
* bytes and currencies work as well as plain numbers. Without it the value is
|
|
49
|
+
* a percentage of `min`…`max`, which is the only formatting that holds for a
|
|
50
|
+
* range nobody described.
|
|
51
|
+
*/
|
|
52
|
+
format?: Intl.NumberFormatOptions;
|
|
53
|
+
className?: string;
|
|
54
|
+
style?: React.CSSProperties;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The slots a progress indicator reads.
|
|
58
|
+
*
|
|
59
|
+
* A progress bar *is* the thing being coloured — unlike a Box, which holds
|
|
60
|
+
* other people's content — so the fill is the family's own. There is no
|
|
61
|
+
* elevation ladder here on purpose: an indicator is drawn into the surface it
|
|
62
|
+
* sits on, the way a groove is cut into a sheet, and a groove does not float.
|
|
63
|
+
*/
|
|
64
|
+
export declare function progressSlots(color: NebaColor): React.CSSProperties;
|
|
65
|
+
/**
|
|
66
|
+
* How thick the linear track is.
|
|
67
|
+
*
|
|
68
|
+
* Its own ladder rather than a fraction of `controlHeightClasses`: a bar is not
|
|
69
|
+
* a control you can put a label inside, and at `md` it wants to be the weight of
|
|
70
|
+
* a rule between two paragraphs, not a third of a button.
|
|
71
|
+
*/
|
|
72
|
+
export declare const barThicknessClasses: Record<NebaSize, string>;
|
|
73
|
+
/**
|
|
74
|
+
* The diameter of the ring, in pixels.
|
|
75
|
+
*
|
|
76
|
+
* Numbers rather than classes because the same value has to reach the SVG's
|
|
77
|
+
* `viewBox` arithmetic, and a ring is one of the few things in the library that
|
|
78
|
+
* cannot be described by a Tailwind class alone.
|
|
79
|
+
*
|
|
80
|
+
* They land just under the control ladder at every step — a `md` ring is 20px
|
|
81
|
+
* inside a 32px control — so a spinner dropped into a button, a field or a
|
|
82
|
+
* table row never makes the row taller than it already was.
|
|
83
|
+
*/
|
|
84
|
+
export declare const ringDiameters: Record<NebaSize, number>;
|
|
85
|
+
/** The ring's stroke, thickening with the ring so the hole stays in proportion. */
|
|
86
|
+
export declare const ringStrokes: Record<NebaSize, number>;
|
|
87
|
+
/** One plate of a `ProgressBox`, on the tick ladder — an indicator, not a control. */
|
|
88
|
+
export declare const plateSizeClasses: Record<NebaSize, string>;
|
|
89
|
+
/** The corner cut off a plate: the same ~30% the tick boxes use. */
|
|
90
|
+
export declare const plateRadiusClasses: Record<NebaSize, string>;
|
|
91
|
+
/** Between the plates. Tight — they are one object, not a row of squares. */
|
|
92
|
+
export declare const plateGapClasses: Record<NebaSize, string>;
|
|
93
|
+
/**
|
|
94
|
+
* `value` as a fraction of the range, or `null` when there is nothing to say.
|
|
95
|
+
*
|
|
96
|
+
* `null` is the indeterminate case and it is the default: a component that has
|
|
97
|
+
* not been told how far along it is should say so, not draw an empty bar that
|
|
98
|
+
* looks like zero progress.
|
|
99
|
+
*
|
|
100
|
+
* The clamp is not defensive programming for its own sake — `value` usually
|
|
101
|
+
* arrives from a division somewhere, and a bar that renders 140% wide because
|
|
102
|
+
* one request finished twice is a worse bug than a bar that sits full.
|
|
103
|
+
*/
|
|
104
|
+
export declare function progressFraction(value: number | null | undefined, min: number, max: number): number | null;
|
|
105
|
+
/**
|
|
106
|
+
* What the value reads as, both on screen and to a screen reader.
|
|
107
|
+
*
|
|
108
|
+
* Base UI's own default is `${value}%`, which is right only when the range
|
|
109
|
+
* happens to be 0–100 — "3%" for step 3 of 4 is worse than saying nothing. So
|
|
110
|
+
* the percentage is computed from the fraction, and a caller who passed
|
|
111
|
+
* `format` gets Base UI's formatted string instead, because at that point they
|
|
112
|
+
* have said what the number means.
|
|
113
|
+
*/
|
|
114
|
+
export declare function progressText(fraction: number | null, formatted: string | null, hasFormat: boolean): string | null;
|
|
115
|
+
/**
|
|
116
|
+
* The same string, shaped for Base UI's `getAriaValueText`.
|
|
117
|
+
*
|
|
118
|
+
* `undefined` when there is no value, which hands the indeterminate case back
|
|
119
|
+
* to Base UI — it already announces "indeterminate progress", and re-inventing
|
|
120
|
+
* that here would be one more English string the library has to own.
|
|
121
|
+
*/
|
|
122
|
+
export declare function progressAriaText(fraction: number | null, hasFormat: boolean): ((formatted: string | null) => string) | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function progressSlots(e){return{"--n-fill":`var(--neba-${e}-fill)`,"--n-accent":`var(--neba-${e}-accent)`,"--n-soft":`var(--neba-${e}-soft)`,"--n-soft-hover":`var(--neba-${e}-soft-hover)`,"--n-soft-press":`var(--neba-${e}-soft-press)`,"--n-line":`var(--neba-${e}-line)`}}export const barThicknessClasses={xs:"h-0.5",sm:"h-[3px]",md:"h-1",lg:"h-1.5",xl:"h-2"};export const ringDiameters={xs:14,sm:16,md:20,lg:26,xl:32};export const ringStrokes={xs:1.5,sm:1.75,md:2,lg:2.5,xl:3};export const plateSizeClasses={xs:"size-2",sm:"size-2.5",md:"size-3",lg:"size-4",xl:"size-5"};export const plateRadiusClasses={xs:"rounded-[0.1875rem]",sm:"rounded-[0.25rem]",md:"rounded-[0.28125rem]",lg:"rounded-[0.375rem]",xl:"rounded-[0.4375rem]"};export const plateGapClasses={xs:"gap-1",sm:"gap-1",md:"gap-1.5",lg:"gap-1.5",xl:"gap-2"};export function progressFraction(e,s,r){return null==e||Number.isNaN(e)||r<=s?null:Math.min(1,Math.max(0,(e-s)/(r-s)))}export function progressText(e,s,r){return null===e?null:r?s:`${Math.round(100*e)}%`}export function progressAriaText(e,s){if(null!==e)return r=>progressText(e,r,s)??""}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pieces every Neba component is built out of.
|
|
3
|
+
*
|
|
4
|
+
* None of this is exported from `src/index.ts` — it is the library talking to
|
|
5
|
+
* itself. It lives here for one reason: a `size` of `md` has to be 32px on a
|
|
6
|
+
* Button, a TextField, a Select and a Chip, and a table copied into eleven
|
|
7
|
+
* files is a table that will disagree with itself by the twelfth.
|
|
8
|
+
*
|
|
9
|
+
* The two things that cannot move out of a component are its variant classes
|
|
10
|
+
* and its layout — those genuinely differ. Heights, radii, type scale, padding
|
|
11
|
+
* tracks, the frosted surface, the transition and the colour slots do not.
|
|
12
|
+
*
|
|
13
|
+
* Tailwind only sees class names written out literally, so everything here is a
|
|
14
|
+
* complete class string rather than something assembled at runtime. `@source
|
|
15
|
+
* '.'` in `styles.css` covers this folder in the repository and in `dist/`.
|
|
16
|
+
*/
|
|
17
|
+
import type * as React from 'react';
|
|
18
|
+
import type { NebaColor, NebaDensity, NebaElevation, NebaSize, NebaVariant } from '../types';
|
|
19
|
+
/**
|
|
20
|
+
* Corner radius. ~45% of the control height at every step, held just short of
|
|
21
|
+
* the 50% that would make it a pill.
|
|
22
|
+
*/
|
|
23
|
+
export declare const radiusClasses: Record<NebaSize, string>;
|
|
24
|
+
/**
|
|
25
|
+
* The height of a control, and the one number the whole library lines up on:
|
|
26
|
+
* a Button, a TextField, a Select and a Chip of the same `size` sit on the same
|
|
27
|
+
* baseline in the same row.
|
|
28
|
+
*
|
|
29
|
+
* The steps are deliberately uneven. `md` (32px) is the desktop workhorse,
|
|
30
|
+
* `xs`/`sm` are for dense toolbars and table rows, `lg`/`xl` are for the one
|
|
31
|
+
* action a screen is actually about — so the gaps widen at both ends rather
|
|
32
|
+
* than marching up in equal 4px increments.
|
|
33
|
+
*
|
|
34
|
+
* Density never touches these.
|
|
35
|
+
*/
|
|
36
|
+
export declare const controlHeightClasses: Record<NebaSize, string>;
|
|
37
|
+
/** The same numbers as a width, for a control with nothing to pad against. */
|
|
38
|
+
export declare const controlSquareClasses: Record<NebaSize, string>;
|
|
39
|
+
/** A control's label. One line, so the leading comes from `leading-none`. */
|
|
40
|
+
export declare const controlTextClasses: Record<NebaSize, string>;
|
|
41
|
+
/**
|
|
42
|
+
* The same type scale with an explicit leading, for the controls that hold text
|
|
43
|
+
* which may wrap — a textarea, a select option, a table cell. The line heights
|
|
44
|
+
* have to agree with `controlHeightClasses` or a one-row control would stop
|
|
45
|
+
* lining up with a single-line one.
|
|
46
|
+
*/
|
|
47
|
+
export declare const controlTextLeadingClasses: Record<NebaSize, string>;
|
|
48
|
+
/** Labels, descriptions and error messages: one step below the control's text. */
|
|
49
|
+
export declare const metaTextClasses: Record<NebaSize, string>;
|
|
50
|
+
/**
|
|
51
|
+
* Horizontal padding, and the only thing `density` is allowed to touch. The two
|
|
52
|
+
* tracks are roughly 2:1 so the difference is legible at a glance rather than a
|
|
53
|
+
* two-pixel nudge.
|
|
54
|
+
*/
|
|
55
|
+
export declare const paddingXClasses: Record<NebaDensity, Record<NebaSize, string>>;
|
|
56
|
+
/**
|
|
57
|
+
* A tick box: the square a Checkbox draws and the circle a Radio draws.
|
|
58
|
+
*
|
|
59
|
+
* Its own ladder rather than a step off `controlHeightClasses`, because a tick
|
|
60
|
+
* is not a control you can put a label inside — it is an indicator next to one,
|
|
61
|
+
* and it is sized against the text beside it rather than against the row.
|
|
62
|
+
*/
|
|
63
|
+
export declare const tickSizeClasses: Record<NebaSize, string>;
|
|
64
|
+
/**
|
|
65
|
+
* And its own radius, at ~30% rather than the ~45% the control ladder uses.
|
|
66
|
+
* `--neba-radius-md` is 14px, which on an 18px box is a circle — and a checkbox
|
|
67
|
+
* that is round is a radio button. The intent is the same as everywhere else:
|
|
68
|
+
* a sheet with the corners cut off, never a pill.
|
|
69
|
+
*/
|
|
70
|
+
export declare const tickRadiusClasses: Record<NebaSize, string>;
|
|
71
|
+
/**
|
|
72
|
+
* The same two tracks again, as raw lengths.
|
|
73
|
+
*
|
|
74
|
+
* These exist for one element: a table cell. `<td>` and `<th>` are among the
|
|
75
|
+
* very few tags that host stylesheets still style by name — VitePress's
|
|
76
|
+
* `.vp-doc td`, Tailwind Typography's `.prose td`, every CSS framework ever —
|
|
77
|
+
* and all of those are two-class selectors that a utility cannot outrank. A
|
|
78
|
+
* Table therefore writes its cell padding inline, where nothing can reach it.
|
|
79
|
+
*
|
|
80
|
+
* Keep these in step with `paddingXClasses`. They are the same numbers: the
|
|
81
|
+
* Tailwind spacing scale is 0.25rem per step.
|
|
82
|
+
*/
|
|
83
|
+
export declare const paddingXValues: Record<NebaDensity, Record<NebaSize, string>>;
|
|
84
|
+
/** Between a control's own parts — an icon and its label. */
|
|
85
|
+
export declare const gapClasses: Record<NebaSize, string>;
|
|
86
|
+
/** Between a label, the control under it and the text under that. */
|
|
87
|
+
export declare const stackGapClasses: Record<NebaSize, string>;
|
|
88
|
+
/**
|
|
89
|
+
* A sheet's heading: one step above the body, on the same ladder the controls
|
|
90
|
+
* use, so a card's title lines up with the buttons that end up inside it.
|
|
91
|
+
*/
|
|
92
|
+
export declare const sheetTitleClasses: Record<NebaSize, string>;
|
|
93
|
+
/**
|
|
94
|
+
* Body copy: the control type scale with the leading opened up, because a
|
|
95
|
+
* label is one line and a body is a paragraph.
|
|
96
|
+
*/
|
|
97
|
+
export declare const sheetBodyClasses: Record<NebaSize, string>;
|
|
98
|
+
/** Title to subtitle. Tight — they are one block of text, not two sections. */
|
|
99
|
+
export declare const sheetHeaderGapClasses: Record<NebaSize, string>;
|
|
100
|
+
/** Between a sheet's sections, when there are no dividers to separate them. */
|
|
101
|
+
export declare const sheetSectionGapClasses: Record<NebaSize, string>;
|
|
102
|
+
/**
|
|
103
|
+
* The frosted surface: a translucent fill over a blurred backdrop, a tile of
|
|
104
|
+
* noise blended into it for tooth, and an angled sheen. The blur makes it a
|
|
105
|
+
* sheet of something; the noise makes that something acrylic rather than glass.
|
|
106
|
+
*/
|
|
107
|
+
export declare const surfaceClasses = "[background-image:var(--neba-grain),var(--neba-sheen)] [background-blend-mode:overlay,normal] [backdrop-filter:var(--neba-blur)]";
|
|
108
|
+
/**
|
|
109
|
+
* The house transition. Per-property durations in the order the property list
|
|
110
|
+
* declares them: the fill drains back slowly while edges and shadows keep up
|
|
111
|
+
* with the pointer.
|
|
112
|
+
*
|
|
113
|
+
* No `transform` is in the list, and none should ever be added — scaling a
|
|
114
|
+
* control resamples its label, and a label that shimmers under the cursor is
|
|
115
|
+
* what reads as cheap.
|
|
116
|
+
*/
|
|
117
|
+
export declare const transitionClasses: string;
|
|
118
|
+
/**
|
|
119
|
+
* Press is instant, release is slow — the house interaction signature. Pressing
|
|
120
|
+
* zeroes every duration, so the whole control lands on the frame of the click
|
|
121
|
+
* and then decays.
|
|
122
|
+
*/
|
|
123
|
+
export declare const pressTransitionClasses = "active:[transition-duration:0ms]";
|
|
124
|
+
/**
|
|
125
|
+
* The focus ring, written as the `outline` shorthand rather than Tailwind's
|
|
126
|
+
* `outline-2` + colour pair: the utilities route the style through
|
|
127
|
+
* `--tw-outline-style`, which any `outline-none` on the element (ours or a
|
|
128
|
+
* consumer's) would zero out.
|
|
129
|
+
*/
|
|
130
|
+
export declare const focusRingClasses = "focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2";
|
|
131
|
+
/** The same ring, drawn by whichever descendant actually takes focus. */
|
|
132
|
+
export declare const focusWithinRingClasses = "has-[:focus-visible]:[outline:2px_solid_var(--n-ring)] has-[:focus-visible]:outline-offset-2";
|
|
133
|
+
/** Icons track their label rather than carrying a size of their own. */
|
|
134
|
+
export declare const iconClasses = "[&_svg]:pointer-events-none [&_svg]:size-[1.2em] [&_svg]:shrink-0";
|
|
135
|
+
/**
|
|
136
|
+
* Text for a screen reader and nobody else: the sentence behind a bare number
|
|
137
|
+
* on a Badge, the page number under a Pagination chevron, the file count a
|
|
138
|
+
* FilePicker reports.
|
|
139
|
+
*
|
|
140
|
+
* Not `hidden`, not `display:none` and not `opacity:0` — the first two take the
|
|
141
|
+
* text off the accessibility tree along with the screen, and the third leaves a
|
|
142
|
+
* clickable ghost the size of the words. A 1px clipped box is the one form that
|
|
143
|
+
* is invisible to a sighted reader and present to every other kind.
|
|
144
|
+
*/
|
|
145
|
+
export declare const srOnlyClasses = "absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]";
|
|
146
|
+
/**
|
|
147
|
+
* Every slot a control reads, with the panel ladder dyed by the family.
|
|
148
|
+
*
|
|
149
|
+
* A control's surface *is* the thing being coloured, so it takes the tint. The
|
|
150
|
+
* two light slots switch with the variant: light thrown onto a filled surface is
|
|
151
|
+
* white; onto a tinted or bare one it has to be the accent, or the surface
|
|
152
|
+
* washes out to grey.
|
|
153
|
+
*/
|
|
154
|
+
export declare function controlSlots(color: NebaColor, elevation: NebaElevation, variant: NebaVariant): React.CSSProperties;
|
|
155
|
+
/**
|
|
156
|
+
* The same slots with the panel ladder left *undyed* — the neutral
|
|
157
|
+
* `--neba-panel*` steps rather than the family's own.
|
|
158
|
+
*
|
|
159
|
+
* This is what a container uses. A Box, a Card, a TextField or a Select popup
|
|
160
|
+
* holds other people's content, and that content arrives with its own colours;
|
|
161
|
+
* tinting the sheet under it puts every one of them on a background they were
|
|
162
|
+
* not chosen against. So the family shows up in the hairline, the focus ring and
|
|
163
|
+
* the caret, and the sheet stays white.
|
|
164
|
+
*/
|
|
165
|
+
export declare function surfaceSlots(color: NebaColor, elevation: NebaElevation): React.CSSProperties;
|
|
166
|
+
/**
|
|
167
|
+
* Disabled drops the colour family entirely. Fading the coloured surface would
|
|
168
|
+
* still read as "this is the primary action", only blurrier.
|
|
169
|
+
*/
|
|
170
|
+
export declare const disabledClasses: Record<NebaVariant, string>;
|
|
171
|
+
/**
|
|
172
|
+
* The shell a field-shaped control is drawn on — a TextField's box and a
|
|
173
|
+
* Select's trigger, which have to be indistinguishable or a form looks like two
|
|
174
|
+
* different forms stacked on each other.
|
|
175
|
+
*
|
|
176
|
+
* The variants say the same three things they say on Button — filled, hairline,
|
|
177
|
+
* bare — with one deliberate difference: `solid` does not flood the control with
|
|
178
|
+
* `--n-fill`. What a field holds is user data, and a caret, a text selection, a
|
|
179
|
+
* placeholder and a chosen option all have to stay legible on top of it, which
|
|
180
|
+
* they are not on an accent fill.
|
|
181
|
+
*
|
|
182
|
+
* So the sheet is not dyed at all — `--n-panel` is the *undyed* acrylic, and the
|
|
183
|
+
* three steps below it are opacity rather than tint. `solid` rests one step up
|
|
184
|
+
* the ladder from `outline`, and hover and focus climb it; the colour family
|
|
185
|
+
* shows up in the edge, the ring and the caret instead.
|
|
186
|
+
*/
|
|
187
|
+
export declare const fieldRestClasses: Record<NebaVariant, string>;
|
|
188
|
+
/**
|
|
189
|
+
* Read-only keeps the colour and the edge, goes flat, and drains most of the
|
|
190
|
+
* saturation — the same axis Button uses. The caret and the text selection stay,
|
|
191
|
+
* because a read-only field is still something you copy out of.
|
|
192
|
+
*/
|
|
193
|
+
export declare const fieldReadOnlyClasses: Record<NebaVariant, string>;
|
|
194
|
+
/**
|
|
195
|
+
* Read-only keeps the shape and the edge but goes flat, loses its sheen and
|
|
196
|
+
* drains most of the saturation. It reads as a label that happens to be
|
|
197
|
+
* control-shaped, which is what a read-only control is.
|
|
198
|
+
*
|
|
199
|
+
* The desaturation is doing the work: with `elevation` defaulting to 0 there is
|
|
200
|
+
* no drop shadow on a normal control either, so "flat" alone says nothing.
|
|
201
|
+
*
|
|
202
|
+
* The cursor is left to the component. A read-only button stops being something
|
|
203
|
+
* you click; a read-only field is still something you select text out of.
|
|
204
|
+
*/
|
|
205
|
+
export declare const readOnlyFilterClasses = "[filter:saturate(0.55)]";
|
|
206
|
+
/**
|
|
207
|
+
* The × that removes a chip.
|
|
208
|
+
*
|
|
209
|
+
* Written once because two components draw it: Chip's own `onDelete`, and the
|
|
210
|
+
* chips a multi-select Combobox puts inside its field. The second one is a Base
|
|
211
|
+
* UI `Combobox.ChipRemove` rather than a plain button, so what is shared is the
|
|
212
|
+
* class string and not the element — which is exactly the split the rest of
|
|
213
|
+
* this file makes.
|
|
214
|
+
*
|
|
215
|
+
* Sized in `em` so it tracks the chip's label at every step of the scale, and
|
|
216
|
+
* it is the one place in the library where `opacity` carries a state: this is
|
|
217
|
+
* not a control changing what it is, it is an affordance that stays out of the
|
|
218
|
+
* way of the word beside it until the pointer is on it.
|
|
219
|
+
*/
|
|
220
|
+
export declare const chipRemoveClasses: string;
|
|
221
|
+
/** `false`, `null`, `undefined` and `''` all mean "this slot is not filled". */
|
|
222
|
+
export declare function hasContent(node: React.ReactNode): boolean;
|
|
223
|
+
/** Joins class name fragments, dropping the empty ones. */
|
|
224
|
+
export declare function cx(...parts: Array<string | false | null | undefined>): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const radiusClasses={xs:"rounded-(--neba-radius-xs)",sm:"rounded-(--neba-radius-sm)",md:"rounded-(--neba-radius-md)",lg:"rounded-(--neba-radius-lg)",xl:"rounded-(--neba-radius-xl)"};export const controlHeightClasses={xs:"h-5.5",sm:"h-6.5",md:"h-8",lg:"h-10",xl:"h-12"};export const controlSquareClasses={xs:"w-5.5",sm:"w-6.5",md:"w-8",lg:"w-10",xl:"w-12"};export const controlTextClasses={xs:"text-[0.6875rem]",sm:"text-[0.75rem]",md:"text-[0.8125rem]",lg:"text-[0.9375rem]",xl:"text-[1.0625rem]"};export const controlTextLeadingClasses={xs:"text-[0.6875rem]/[0.875rem]",sm:"text-[0.75rem]/[1rem]",md:"text-[0.8125rem]/[1.25rem]",lg:"text-[0.9375rem]/[1.375rem]",xl:"text-[1.0625rem]/[1.625rem]"};export const metaTextClasses={xs:"text-[0.625rem]",sm:"text-[0.6875rem]",md:"text-[0.75rem]",lg:"text-[0.8125rem]",xl:"text-[0.875rem]"};export const paddingXClasses={default:{xs:"px-2.5",sm:"px-3",md:"px-4",lg:"px-5",xl:"px-6"},compact:{xs:"px-1.5",sm:"px-2",md:"px-2.5",lg:"px-3",xl:"px-4"}};export const tickSizeClasses={xs:"size-3.5",sm:"size-4",md:"size-4.5",lg:"size-5",xl:"size-6"};export const tickRadiusClasses={xs:"rounded-[0.25rem]",sm:"rounded-[0.3125rem]",md:"rounded-[0.375rem]",lg:"rounded-[0.4375rem]",xl:"rounded-[0.5rem]"};export const paddingXValues={default:{xs:"0.625rem",sm:"0.75rem",md:"1rem",lg:"1.25rem",xl:"1.5rem"},compact:{xs:"0.375rem",sm:"0.5rem",md:"0.625rem",lg:"0.75rem",xl:"1rem"}};export const gapClasses={xs:"gap-1",sm:"gap-1.5",md:"gap-1.5",lg:"gap-2",xl:"gap-2.5"};export const stackGapClasses={xs:"gap-1",sm:"gap-1",md:"gap-1.5",lg:"gap-1.5",xl:"gap-2"};export const sheetTitleClasses={xs:"text-[0.75rem]/[1rem]",sm:"text-[0.8125rem]/[1.125rem]",md:"text-[0.9375rem]/[1.25rem]",lg:"text-[1.0625rem]/[1.5rem]",xl:"text-[1.25rem]/[1.75rem]"};export const sheetBodyClasses={xs:"text-[0.6875rem]/[1rem]",sm:"text-[0.75rem]/[1.125rem]",md:"text-[0.8125rem]/[1.375rem]",lg:"text-[0.9375rem]/[1.5rem]",xl:"text-[1.0625rem]/[1.75rem]"};export const sheetHeaderGapClasses={xs:"gap-0.5",sm:"gap-0.5",md:"gap-1",lg:"gap-1",xl:"gap-1.5"};export const sheetSectionGapClasses={xs:"gap-1.5",sm:"gap-2",md:"gap-3",lg:"gap-3.5",xl:"gap-4"};export const surfaceClasses="[background-image:var(--neba-grain),var(--neba-sheen)] [background-blend-mode:overlay,normal] [backdrop-filter:var(--neba-blur)]";export const transitionClasses=["[transition-property:background-color,border-color,box-shadow,color]","[transition-duration:var(--neba-duration-fill),var(--neba-duration),var(--neba-duration),var(--neba-duration)]","[transition-timing-function:var(--neba-ease)]"].join(" ");export const pressTransitionClasses="active:[transition-duration:0ms]";export const focusRingClasses="focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2";export const focusWithinRingClasses="has-[:focus-visible]:[outline:2px_solid_var(--n-ring)] has-[:focus-visible]:outline-offset-2";export const iconClasses="[&_svg]:pointer-events-none [&_svg]:size-[1.2em] [&_svg]:shrink-0";export const srOnlyClasses="absolute size-px overflow-hidden whitespace-nowrap [clip-path:inset(50%)]";export function controlSlots(e,s,r){const n="solid"===r;return{"--n-fill":`var(--neba-${e}-fill)`,"--n-fill-hover":`var(--neba-${e}-fill-hover)`,"--n-fill-active":`var(--neba-${e}-fill-active)`,"--n-on-solid":`var(--neba-${e}-on-solid)`,"--n-accent":`var(--neba-${e}-accent)`,"--n-soft":`var(--neba-${e}-soft)`,"--n-soft-hover":`var(--neba-${e}-soft-hover)`,"--n-soft-press":`var(--neba-${e}-soft-press)`,"--n-panel":`var(--neba-${e}-panel)`,"--n-panel-hover":`var(--neba-${e}-panel-hover)`,"--n-panel-press":`var(--neba-${e}-panel-press)`,"--n-line":`var(--neba-${e}-line)`,"--n-line-hover":`var(--neba-${e}-line-hover)`,"--n-ring":`var(--neba-${e}-ring)`,"--n-glow":n?"var(--neba-glow-on-fill)":`var(--neba-${e}-soft)`,"--n-flash":n?"var(--neba-flash-on-fill)":`var(--neba-${e}-soft-press)`,"--n-elev":`var(--neba-shadow-${s})`,"--n-elev-hover":`var(--neba-shadow-${Math.min(s+1,4)})`,"--n-elev-press":`var(--neba-shadow-${Math.max(s-1,0)})`}}export function surfaceSlots(e,s){return{"--n-accent":`var(--neba-${e}-accent)`,"--n-soft":`var(--neba-${e}-soft)`,"--n-soft-hover":`var(--neba-${e}-soft-hover)`,"--n-soft-press":`var(--neba-${e}-soft-press)`,"--n-panel":"var(--neba-panel)","--n-panel-hover":"var(--neba-panel-hover)","--n-panel-press":"var(--neba-panel-press)","--n-line":`var(--neba-${e}-line)`,"--n-line-hover":`var(--neba-${e}-line-hover)`,"--n-ring":`var(--neba-${e}-ring)`,"--n-elev":`var(--neba-shadow-${s})`}}export const disabledClasses={solid:"cursor-not-allowed bg-(--neba-disabled-bg) text-(--neba-disabled-fg) shadow-none",outline:"cursor-not-allowed border bg-transparent text-(--neba-disabled-fg) [border-color:var(--neba-disabled-border)] shadow-none",text:"cursor-not-allowed bg-transparent text-(--neba-disabled-fg) shadow-none"};export const fieldRestClasses={solid:[surfaceClasses,"text-(--neba-fg) bg-(--n-panel-hover)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]","hover:bg-(--n-panel-press)","focus-within:bg-(--n-panel-press)"].join(" "),outline:[surfaceClasses,"border text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]","hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)]","focus-within:bg-(--n-panel-hover) focus-within:[border-color:var(--n-ring)]"].join(" "),text:["text-(--neba-fg) bg-transparent","hover:bg-(--n-soft)","focus-within:bg-(--n-soft-hover)"].join(" ")};export const fieldReadOnlyClasses={solid:[surfaceClasses,"text-(--neba-fg) bg-(--n-panel-hover)","[box-shadow:var(--neba-plate-solid)] [filter:saturate(0.55)]"].join(" "),outline:[surfaceClasses,"border text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)] [box-shadow:var(--neba-plate-glass)] [filter:saturate(0.55)]"].join(" "),text:"text-(--neba-fg) bg-transparent [filter:saturate(0.55)]"};export const readOnlyFilterClasses="[filter:saturate(0.55)]";export const chipRemoveClasses=["ms-0.5 inline-flex shrink-0 items-center justify-center rounded-full","size-[1.15em] cursor-pointer 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-1","disabled:cursor-not-allowed"].join(" ");export function hasContent(e){return null!=e&&!1!==e&&""!==e}export function cx(...e){return e.filter(Boolean).join(" ")}
|