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.
Files changed (141) hide show
  1. package/README.md +169 -2
  2. package/dist/components/accordion/Accordion.d.ts +97 -0
  3. package/dist/components/accordion/Accordion.js +1 -0
  4. package/dist/components/accordion/index.d.ts +2 -0
  5. package/dist/components/accordion/index.js +1 -0
  6. package/dist/components/alert/Alert.d.ts +47 -0
  7. package/dist/components/alert/Alert.js +1 -0
  8. package/dist/components/alert/index.d.ts +2 -0
  9. package/dist/components/alert/index.js +1 -0
  10. package/dist/components/badge/Badge.d.ts +80 -0
  11. package/dist/components/badge/Badge.js +1 -0
  12. package/dist/components/badge/index.d.ts +2 -0
  13. package/dist/components/badge/index.js +1 -0
  14. package/dist/components/box/Box.d.ts +50 -0
  15. package/dist/components/box/Box.js +1 -0
  16. package/dist/components/box/index.d.ts +2 -0
  17. package/dist/components/box/index.js +1 -0
  18. package/dist/components/button/Button.d.ts +25 -3
  19. package/dist/components/button/Button.js +1 -1
  20. package/dist/components/button/index.d.ts +1 -0
  21. package/dist/components/button-group/ButtonGroup.d.ts +31 -0
  22. package/dist/components/button-group/ButtonGroup.js +1 -0
  23. package/dist/components/button-group/index.d.ts +2 -0
  24. package/dist/components/button-group/index.js +1 -0
  25. package/dist/components/card/Card.d.ts +45 -0
  26. package/dist/components/card/Card.js +1 -0
  27. package/dist/components/card/index.d.ts +2 -0
  28. package/dist/components/card/index.js +1 -0
  29. package/dist/components/checkbox/Checkbox.d.ts +39 -0
  30. package/dist/components/checkbox/Checkbox.js +1 -0
  31. package/dist/components/checkbox/index.d.ts +2 -0
  32. package/dist/components/checkbox/index.js +1 -0
  33. package/dist/components/chip/Chip.d.ts +50 -0
  34. package/dist/components/chip/Chip.js +1 -0
  35. package/dist/components/chip/index.d.ts +2 -0
  36. package/dist/components/chip/index.js +1 -0
  37. package/dist/components/combobox/Combobox.d.ts +131 -0
  38. package/dist/components/combobox/Combobox.js +1 -0
  39. package/dist/components/combobox/index.d.ts +2 -0
  40. package/dist/components/combobox/index.js +1 -0
  41. package/dist/components/dialog/Dialog.d.ts +111 -0
  42. package/dist/components/dialog/Dialog.js +1 -0
  43. package/dist/components/dialog/index.d.ts +2 -0
  44. package/dist/components/dialog/index.js +1 -0
  45. package/dist/components/divider/Divider.d.ts +48 -0
  46. package/dist/components/divider/Divider.js +1 -0
  47. package/dist/components/divider/index.d.ts +2 -0
  48. package/dist/components/divider/index.js +1 -0
  49. package/dist/components/file-picker/FilePicker.d.ts +103 -0
  50. package/dist/components/file-picker/FilePicker.js +1 -0
  51. package/dist/components/file-picker/index.d.ts +2 -0
  52. package/dist/components/file-picker/index.js +1 -0
  53. package/dist/components/list/List.d.ts +81 -0
  54. package/dist/components/list/List.js +1 -0
  55. package/dist/components/list/index.d.ts +2 -0
  56. package/dist/components/list/index.js +1 -0
  57. package/dist/components/menu/Menu.d.ts +216 -0
  58. package/dist/components/menu/Menu.js +1 -0
  59. package/dist/components/menu/index.d.ts +2 -0
  60. package/dist/components/menu/index.js +1 -0
  61. package/dist/components/number-field/NumberField.d.ts +113 -0
  62. package/dist/components/number-field/NumberField.js +1 -0
  63. package/dist/components/number-field/index.d.ts +2 -0
  64. package/dist/components/number-field/index.js +1 -0
  65. package/dist/components/overlay/Overlay.d.ts +85 -0
  66. package/dist/components/overlay/Overlay.js +1 -0
  67. package/dist/components/overlay/index.d.ts +2 -0
  68. package/dist/components/overlay/index.js +1 -0
  69. package/dist/components/pagination/Pagination.d.ts +65 -0
  70. package/dist/components/pagination/Pagination.js +1 -0
  71. package/dist/components/pagination/index.d.ts +2 -0
  72. package/dist/components/pagination/index.js +1 -0
  73. package/dist/components/progress-box/ProgressBox.d.ts +33 -0
  74. package/dist/components/progress-box/ProgressBox.js +1 -0
  75. package/dist/components/progress-box/index.d.ts +2 -0
  76. package/dist/components/progress-box/index.js +1 -0
  77. package/dist/components/progress-circular/ProgressCircular.d.ts +19 -0
  78. package/dist/components/progress-circular/ProgressCircular.js +1 -0
  79. package/dist/components/progress-circular/index.d.ts +2 -0
  80. package/dist/components/progress-circular/index.js +1 -0
  81. package/dist/components/progress-linear/ProgressLinear.d.ts +20 -0
  82. package/dist/components/progress-linear/ProgressLinear.js +1 -0
  83. package/dist/components/progress-linear/index.d.ts +2 -0
  84. package/dist/components/progress-linear/index.js +1 -0
  85. package/dist/components/radio-group/RadioGroup.d.ts +51 -0
  86. package/dist/components/radio-group/RadioGroup.js +1 -0
  87. package/dist/components/radio-group/index.d.ts +2 -0
  88. package/dist/components/radio-group/index.js +1 -0
  89. package/dist/components/select/Select.d.ts +76 -0
  90. package/dist/components/select/Select.js +1 -0
  91. package/dist/components/select/index.d.ts +2 -0
  92. package/dist/components/select/index.js +1 -0
  93. package/dist/components/slider/Slider.d.ts +38 -0
  94. package/dist/components/slider/Slider.js +1 -0
  95. package/dist/components/slider/index.d.ts +2 -0
  96. package/dist/components/slider/index.js +1 -0
  97. package/dist/components/switch/Switch.d.ts +39 -0
  98. package/dist/components/switch/Switch.js +1 -0
  99. package/dist/components/switch/index.d.ts +2 -0
  100. package/dist/components/switch/index.js +1 -0
  101. package/dist/components/table/Table.d.ts +80 -0
  102. package/dist/components/table/Table.js +1 -0
  103. package/dist/components/table/index.d.ts +2 -0
  104. package/dist/components/table/index.js +1 -0
  105. package/dist/components/tabs/Tabs.d.ts +92 -0
  106. package/dist/components/tabs/Tabs.js +1 -0
  107. package/dist/components/tabs/index.d.ts +2 -0
  108. package/dist/components/tabs/index.js +1 -0
  109. package/dist/components/text-field/TextField.d.ts +63 -0
  110. package/dist/components/text-field/TextField.js +1 -0
  111. package/dist/components/text-field/index.d.ts +2 -0
  112. package/dist/components/text-field/index.js +1 -0
  113. package/dist/components/toast/Toast.d.ts +116 -0
  114. package/dist/components/toast/Toast.js +1 -0
  115. package/dist/components/toast/index.d.ts +2 -0
  116. package/dist/components/toast/index.js +1 -0
  117. package/dist/components/tooltip/Tooltip.d.ts +81 -0
  118. package/dist/components/tooltip/Tooltip.js +1 -0
  119. package/dist/components/tooltip/index.d.ts +2 -0
  120. package/dist/components/tooltip/index.js +1 -0
  121. package/dist/components/typography/Typography.d.ts +62 -0
  122. package/dist/components/typography/Typography.js +1 -0
  123. package/dist/components/typography/index.d.ts +2 -0
  124. package/dist/components/typography/index.js +1 -0
  125. package/dist/index.d.ts +32 -1
  126. package/dist/index.js +1 -1
  127. package/dist/internal/button-group.d.ts +25 -0
  128. package/dist/internal/button-group.js +1 -0
  129. package/dist/internal/icons.d.ts +48 -0
  130. package/dist/internal/icons.js +1 -0
  131. package/dist/internal/menu.d.ts +20 -0
  132. package/dist/internal/menu.js +1 -0
  133. package/dist/internal/progress.d.ts +122 -0
  134. package/dist/internal/progress.js +1 -0
  135. package/dist/internal/styles.d.ts +224 -0
  136. package/dist/internal/styles.js +1 -0
  137. package/dist/styles.css +758 -0
  138. package/dist/types.d.ts +77 -0
  139. package/dist/types.js +8 -0
  140. package/package.json +75 -19
  141. 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(" ")}