@danxbot/ui 5.2.0 → 6.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.
@@ -137,18 +137,42 @@ declare const ring: import("tailwind-variants").TVReturnType<{
137
137
  sm: "size-10";
138
138
  md: "size-16";
139
139
  lg: "size-24";
140
+ /**
141
+ * A big donut standing in as a stat's own visual (`BigDonut`, demands'
142
+ * Extracted-tab EXTRACTED/AUDITS/HUMAN VERIFIED/answer-key row) needs more
143
+ * room than `lg` for a "count/total" fraction than a bare percentage ever
144
+ * did — `lg` was sized for two digits, and a real fraction runs to eight
145
+ * or nine characters even compacted ("1.1k/1.5k"). `xl` is that room.
146
+ */
147
+ xl: "size-32";
140
148
  };
141
149
  }, undefined, "relative grid shrink-0 place-items-center", {
142
150
  size: {
143
151
  sm: "size-10";
144
152
  md: "size-16";
145
153
  lg: "size-24";
154
+ /**
155
+ * A big donut standing in as a stat's own visual (`BigDonut`, demands'
156
+ * Extracted-tab EXTRACTED/AUDITS/HUMAN VERIFIED/answer-key row) needs more
157
+ * room than `lg` for a "count/total" fraction than a bare percentage ever
158
+ * did — `lg` was sized for two digits, and a real fraction runs to eight
159
+ * or nine characters even compacted ("1.1k/1.5k"). `xl` is that room.
160
+ */
161
+ xl: "size-32";
146
162
  };
147
163
  }, undefined, import("tailwind-variants").TVReturnTypeLike<{
148
164
  size: {
149
165
  sm: "size-10";
150
166
  md: "size-16";
151
167
  lg: "size-24";
168
+ /**
169
+ * A big donut standing in as a stat's own visual (`BigDonut`, demands'
170
+ * Extracted-tab EXTRACTED/AUDITS/HUMAN VERIFIED/answer-key row) needs more
171
+ * room than `lg` for a "count/total" fraction than a bare percentage ever
172
+ * did — `lg` was sized for two digits, and a real fraction runs to eight
173
+ * or nine characters even compacted ("1.1k/1.5k"). `xl` is that room.
174
+ */
175
+ xl: "size-32";
152
176
  };
153
177
  }, undefined>>;
154
178
  /** The tones a bar, meter or ring arc can be drawn in. */
@@ -0,0 +1,76 @@
1
+ import { type ReactNode, type Ref } from "react";
2
+ declare const readMore: import("tailwind-variants").TVReturnType<{
3
+ [key: string]: {
4
+ [key: string]: import("tailwind-variants").ClassValue | {
5
+ bar?: import("tailwind-variants").ClassValue;
6
+ content?: import("tailwind-variants").ClassValue;
7
+ toggle?: import("tailwind-variants").ClassValue;
8
+ root?: import("tailwind-variants").ClassValue;
9
+ viewport?: import("tailwind-variants").ClassValue;
10
+ };
11
+ };
12
+ } | {
13
+ [x: string]: {
14
+ [x: string]: import("tailwind-variants").ClassValue | {
15
+ bar?: import("tailwind-variants").ClassValue;
16
+ content?: import("tailwind-variants").ClassValue;
17
+ toggle?: import("tailwind-variants").ClassValue;
18
+ root?: import("tailwind-variants").ClassValue;
19
+ viewport?: import("tailwind-variants").ClassValue;
20
+ };
21
+ };
22
+ } | {}, {
23
+ root: string;
24
+ viewport: string[];
25
+ content: string;
26
+ bar: string;
27
+ toggle: string;
28
+ }, undefined, {
29
+ [key: string]: {
30
+ [key: string]: import("tailwind-variants").ClassValue | {
31
+ bar?: import("tailwind-variants").ClassValue;
32
+ content?: import("tailwind-variants").ClassValue;
33
+ toggle?: import("tailwind-variants").ClassValue;
34
+ root?: import("tailwind-variants").ClassValue;
35
+ viewport?: import("tailwind-variants").ClassValue;
36
+ };
37
+ };
38
+ } | {}, {
39
+ root: string;
40
+ viewport: string[];
41
+ content: string;
42
+ bar: string;
43
+ toggle: string;
44
+ }, import("tailwind-variants").TVReturnTypeLike<unknown, {
45
+ root: string;
46
+ viewport: string[];
47
+ content: string;
48
+ bar: string;
49
+ toggle: string;
50
+ }>>;
51
+ export interface ReadMoreProps {
52
+ /** Collapsed line count — how many rendered lines show before the fade strip. Must be a positive integer; anything else throws. */
53
+ lines: number;
54
+ /** Typically rendered Markdown — paragraphs, headings, lists, code, images. See the module comment on why the clamp is a measured line boundary rather than a computed height. */
55
+ children: ReactNode;
56
+ /** Controlled expanded state. Omit to let the component hold its own (seeded by `defaultExpanded`). */
57
+ expanded?: boolean;
58
+ /** Uncontrolled initial state. Ignored once `expanded` is supplied. @default false */
59
+ defaultExpanded?: boolean;
60
+ /** Fires on every toggle, controlled or not. */
61
+ onExpandedChange?: (expanded: boolean) => void;
62
+ /** @default "Read more" */
63
+ moreLabel?: string;
64
+ /** @default "Show less" */
65
+ lessLabel?: string;
66
+ className?: string;
67
+ ref?: Ref<HTMLDivElement>;
68
+ }
69
+ /**
70
+ * Clamp block content to `lines` rendered lines behind a fade strip and a
71
+ * single "Read more" / "Show less" toggle. Renders neither the strip nor the
72
+ * toggle when the content already fits — see the module comment for how that
73
+ * is decided.
74
+ */
75
+ export declare function ReadMore({ lines, children, expanded: expandedProp, defaultExpanded, onExpandedChange, moreLabel, lessLabel, className, ref, }: ReadMoreProps): import("react").JSX.Element;
76
+ export { readMore as readMoreVariants };
@@ -45,6 +45,15 @@ export interface ProvenanceDetailProps {
45
45
  * consumer putting its editor in `actions`, which reads as "here is the
46
46
  * value, and separately, down here, a form about some value".
47
47
  *
48
+ * AN `InlineEdit` HERE STILL NEEDS THE OVERWRITE-PROTECTION CONTRACT IT
49
+ * SHIPS WITH (DX-2930) — this panel can stay open while the underlying
50
+ * record keeps changing (a re-extraction, another reviewer's own edit), so
51
+ * an `onCommit={(next, base) => …}` that compares `base` against whatever
52
+ * the caller currently believes is authoritative, plus an
53
+ * `onEditingChange` that suspends re-rendering `record` while someone is
54
+ * mid-edit, is what stops this panel from resetting a draft out from under
55
+ * whoever opened it. See `content/docs/provenance.mdx` for the shape.
56
+ *
48
57
  * IT OVERRIDES THE ABSENCES TOO — redacted, empty and failed alike. A slot
49
58
  * that disappeared whenever the value was missing would vanish in exactly the
50
59
  * case a value editor is most wanted: a field that was never extracted is the
@@ -57,7 +57,8 @@ export { Progress, Meter, ProgressRing, type ProgressProps, type MeterProps, typ
57
57
  export { Stat, StatRow, Sparkline, type StatProps, type StatRowProps, type SparklineProps, type StatSize, type StatTrend, type StatSentiment, } from "./components/Stat";
58
58
  export { DataTable, TableEmptyState, CellStack, type DataTableProps, type TableDensity, } from "./components/Table";
59
59
  export { CodeEditor, CodeEditorToolbar, CodeEditorCaption, CodeEditorCopyButton, CodeEditorWrapToggle, CodeEditorViewSwitch, type CodeEditorProps, type CodeEditorToolbarProps, type CodeEditorView, } from "./components/CodeEditor";
60
- export { MarkdownEditor, type MarkdownEditorProps } from "./components/MarkdownEditor";
60
+ export { MarkdownEditor, type MarkdownEditorProps, type MarkdownEditorHandle, } from "./components/MarkdownEditor";
61
+ export { ReadMore, readMoreVariants, type ReadMoreProps } from "./components/ReadMore";
61
62
  export { MarkdownSurface, type SurfaceOptions, type Splice } from "./lib/markdown/surface";
62
63
  export { project, projectedText, ProjectionError } from "./lib/markdown/project";
63
64
  export type { Projection, PNode, PText, PElement } from "./lib/markdown/project";
@@ -91,7 +92,7 @@ export { ModelSelector, type ModelSelectorProps, type ChatModel, } from "./compo
91
92
  export { EffortControl, DEFAULT_EFFORT_LEVELS, type EffortControlProps, type EffortLevel, } from "./components/chat/EffortControl";
92
93
  export { ContextMeter, ChatStatus, type ContextMeterProps, type ContextSegment, type UsageLimit, type ChatStatusProps, } from "./components/chat/ContextMeter";
93
94
  export { cn } from "./lib/cn";
94
- export { formatBytes, formatTokens } from "./lib/format";
95
+ export { formatBytes, formatTokens, formatCompactNumber } from "./lib/format";
95
96
  export { formatDate, parseDate, formatDateTime, parseDateTime, type FormatDateTimeOptions, type ParseDateTimeOptions, formatCurrency, parseCurrency, formatPhone, parsePhone, formatNumber, parseNumber, type FormatNumberOptions, formatBoolean, parseBoolean, type FormatBooleanOptions, } from "./lib/values";
96
97
  export { useFillHeight } from "./lib/use-fill-height";
97
98
  export { useTheme, useUiScale, useContrast, useMotionPreference, type Theme, type UiScale, type ContrastPreference, type MotionPreference, } from "./lib/preferences";
@@ -1,12 +1,32 @@
1
1
  /** Binary units, because these are file sizes and every OS reports them this way. */
2
2
  export declare function formatBytes(bytes: number): string;
3
3
  /**
4
- * 241_600 → "241.6k".
5
- *
6
- * One decimal all the way to 1M, and exact below 1k. Unlike a file size — where
7
- * a tenth of a kilobyte is noise on a number nobody acts on — the tenth here is
8
- * the digit that moves while you work: at 1M capacity, a whole percent is
9
- * 10_000 tokens, so rounding to "242k" holds a figure still for several
10
- * exchanges and makes a live meter look frozen.
4
+ * 241_600 → "241.6k". A thin, token-domain-named wrapper — see
5
+ * `formatCompactNumber` below for the shared algorithm and its own reasoning.
6
+ * Kept as its own function (rather than every call site switching to the
7
+ * generic one directly) because "tokens" is a real vocabulary word in this
8
+ * package's chat components, and renaming every call site to the generic name
9
+ * would cost real diff for zero behavioral gain.
11
10
  */
12
11
  export declare function formatTokens(tokens: number): string;
12
+ /**
13
+ * A GENERIC large count, abbreviated the way a person reads it aloud:
14
+ * `850` → `"850"`, `1_100` → `"1.1k"`, `3_400_000` → `"3.4M"`,
15
+ * `4_400_000_000` → `"4.4B"`. `null` / `undefined` / non-finite → `"—"`.
16
+ *
17
+ * One decimal per tier (k/M/B/T), trimmed of a trailing ".0" (`1_000_000` →
18
+ * `"1M"`, not `"1.0M"`), and exact below 1,000 — a count small enough to read
19
+ * digit-by-digit gets no abbreviation at all, since "850" is not improved by
20
+ * becoming "0.9k". This is the same one-decimal-per-tier shape `formatTokens`
21
+ * already used for a token budget; the difference that justified a SEPARATE,
22
+ * generic export rather than just widening that one is scope: `formatTokens`
23
+ * is a token-budget's own vocabulary (a live context meter), while this
24
+ * function is for any large count a screen needs to abbreviate — a field
25
+ * tally, a donut's fraction, a record count — with no token-specific meaning
26
+ * attached to its name.
27
+ *
28
+ * NEGATIVE VALUES keep their sign (`-1_100` → `"-1.1k"`) rather than being
29
+ * treated as absent — a generic count utility cannot assume its caller's
30
+ * domain never has one, the way `formatTokens`'s own callers do.
31
+ */
32
+ export declare function formatCompactNumber(value: number | null | undefined): string;
@@ -38,5 +38,5 @@
38
38
  * Everything exported here is ALSO exported from the main entry, so nothing
39
39
  * about this is a migration and no existing import has to change.
40
40
  */
41
- export { formatBytes, formatTokens } from "./lib/format";
41
+ export { formatBytes, formatTokens, formatCompactNumber } from "./lib/format";
42
42
  export { formatDate, parseDate, formatDateTime, parseDateTime, type FormatDateTimeOptions, type ParseDateTimeOptions, formatCurrency, parseCurrency, formatPhone, parsePhone, formatNumber, parseNumber, type FormatNumberOptions, formatBoolean, parseBoolean, type FormatBooleanOptions, } from "./lib/values";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "5.2.0",
3
+ "version": "6.0.0",
4
4
  "type": "module",
5
5
  "description": "Danxbot — a domain-agnostic React design system with motion as a first-class primitive.",
6
6
  "license": "MIT",
@@ -73,7 +73,7 @@
73
73
  "gates": "npm run shoot && npm run a11y && node scripts/shoot-overlays.mjs && npm run probe",
74
74
  "a11y": "node scripts/a11y-scan.mjs",
75
75
  "shoot": "node scripts/shoot.mjs",
76
- "probe": "node scripts/probe-scale.mjs && node scripts/probe-switch.mjs && node scripts/probe-slider.mjs && node scripts/probe-panel.mjs && node scripts/probe-popover-width.mjs && node scripts/probe-api.mjs && node scripts/probe-api-live.mjs && node scripts/probe-tabs-overflow.mjs && node scripts/probe-stat-row.mjs && node scripts/probe-packaging.mjs && node scripts/probe-containment.mjs && node scripts/probe-popover-containment.mjs && node scripts/probe-shell.mjs && node scripts/probe-card-header.mjs && node scripts/probe-inline-edit.mjs",
76
+ "probe": "node scripts/probe-scale.mjs && node scripts/probe-switch.mjs && node scripts/probe-slider.mjs && node scripts/probe-panel.mjs && node scripts/probe-popover-width.mjs && node scripts/probe-api.mjs && node scripts/probe-api-live.mjs && node scripts/probe-tabs-overflow.mjs && node scripts/probe-stat-row.mjs && node scripts/probe-packaging.mjs && node scripts/probe-containment.mjs && node scripts/probe-popover-containment.mjs && node scripts/probe-shell.mjs && node scripts/probe-card-header.mjs && node scripts/probe-inline-edit.mjs && node scripts/probe-read-more.mjs",
77
77
  "sync": "node scripts/sync.mjs",
78
78
  "visual": "node scripts/visual-docker.mjs",
79
79
  "visual:update": "node scripts/visual-docker.mjs --update-snapshots",