@danxbot/ui 2.7.1 → 2.8.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.
@@ -1,4 +1,4 @@
1
- import type { ReactNode, Ref } from "react";
1
+ import { type ReactNode, type Ref } from "react";
2
2
  import { type VariantProps } from "tailwind-variants";
3
3
  declare const bar: import("tailwind-variants").TVReturnType<{
4
4
  size: {
@@ -151,8 +151,28 @@ declare const ring: import("tailwind-variants").TVReturnType<{
151
151
  lg: "size-24";
152
152
  };
153
153
  }, undefined>>;
154
- export interface ProgressRingProps extends VariantProps<typeof ring> {
155
- value: number | null;
154
+ /** The tones a bar, meter or ring arc can be drawn in. */
155
+ export type ProgressTone = NonNullable<VariantProps<typeof bar>["tone"]>;
156
+ /** One arc of a segmented ring: how much, in what tone, called what. */
157
+ export interface ProgressRingSegment {
158
+ /**
159
+ * How much of `total` this arc covers, in the caller's own units — tokens,
160
+ * megabytes, jobs. Never a percentage of its own accord; the denominator is
161
+ * `total` and nothing else.
162
+ */
163
+ value: number;
164
+ tone: ProgressTone;
165
+ /**
166
+ * What this arc IS, in words.
167
+ *
168
+ * Not decorative and not optional: it is read out as part of the ring's
169
+ * description, and it is the only thing a legend beside the ring has to name
170
+ * a colour by. A segmented ring whose arcs had no names would encode its
171
+ * entire breakdown in hue alone.
172
+ */
173
+ label: string;
174
+ }
175
+ interface ProgressRingBase extends VariantProps<typeof ring> {
156
176
  /**
157
177
  * REQUIRED, and a plain string.
158
178
  *
@@ -163,16 +183,108 @@ export interface ProgressRingProps extends VariantProps<typeof ring> {
163
183
  * of this component existing.
164
184
  */
165
185
  label: string;
166
- tone?: VariantProps<typeof bar>["tone"];
186
+ /**
187
+ * Draw the number in the middle. On by default, which is the behaviour this
188
+ * component has always had.
189
+ *
190
+ * Worth turning off on a `sm` ring used as an affordance rather than a
191
+ * readout — two digits inside a 40px circle is a number nobody reads and a
192
+ * ring nobody can see past.
193
+ */
194
+ showValue?: boolean;
167
195
  className?: string;
168
196
  }
197
+ /** A ring showing ONE number. `null` is "working, length unknown". */
198
+ export interface ProgressRingValueProps extends ProgressRingBase {
199
+ value: number | null;
200
+ tone?: ProgressTone;
201
+ segments?: never;
202
+ total?: never;
203
+ remainderLabel?: never;
204
+ }
205
+ /**
206
+ * A ring showing a BREAKDOWN: contiguous arcs around one circle.
207
+ *
208
+ * The two shapes are a union rather than two optional props, so passing both
209
+ * `value` and `segments` does not type-check. There is no precedence rule to
210
+ * learn and no silent winner.
211
+ */
212
+ export interface ProgressRingSegmentsProps extends ProgressRingBase {
213
+ /** Drawn in order, starting at twelve o'clock and running clockwise. */
214
+ segments: ProgressRingSegment[];
215
+ /**
216
+ * The whole the segments are parts OF, in the same units as their values.
217
+ *
218
+ * REQUIRED, with no default. A default of 100 would read as "the values are
219
+ * percentages" and quietly turn a ring of token counts into a ring that
220
+ * overflows on its first render — and the denominator is the one fact that
221
+ * makes a remainder arc mean anything.
222
+ *
223
+ * SEGMENTS SUMMING TO MORE THAN THIS ARE **CLAMPED, NOT NORMALISED** — see
224
+ * the note above `layoutRingSegments`.
225
+ */
226
+ total: number;
227
+ /**
228
+ * What the unfilled part of the ring IS, for the description: "Remaining",
229
+ * "Free", "Unallocated".
230
+ *
231
+ * The arc itself needs no drawing — it is the track showing through — but it
232
+ * still needs a name, because "72% used" and "28% free" are the same fact
233
+ * and readers act on different halves of it.
234
+ */
235
+ remainderLabel?: string;
236
+ value?: never;
237
+ tone?: never;
238
+ }
239
+ export type ProgressRingProps = ProgressRingValueProps | ProgressRingSegmentsProps;
240
+ /** One arc, resolved to the two fractions an SVG dash actually needs. */
241
+ export interface ProgressRingArc {
242
+ label: string;
243
+ tone: ProgressTone;
244
+ /** The segment's own magnitude, in caller units, before any clamping. */
245
+ value: number;
246
+ /** Where the arc begins, as a fraction of the circumference. */
247
+ start: number;
248
+ /** How far it is drawn for, as a fraction, with its gap already taken off. */
249
+ length: number;
250
+ }
251
+ export interface ProgressRingLayout {
252
+ arcs: ProgressRingArc[];
253
+ /** Every segment added up, in caller units. NOT clamped — this is the fact. */
254
+ used: number;
255
+ /** How far `used` overshoots `total`. Zero when the segments fit. */
256
+ overflow: number;
257
+ }
258
+ export declare function layoutRingSegments(segments: ProgressRingSegment[], total: number): ProgressRingLayout;
169
259
  /**
170
260
  * Circular progress, for when the number belongs INSIDE the indicator —
171
261
  * a tile, a card corner, a stat.
172
262
  *
263
+ * Two shapes, chosen by which prop is passed:
264
+ *
265
+ * ```tsx
266
+ * <ProgressRing value={62} label="Context used" />
267
+ * <ProgressRing
268
+ * label="Context used"
269
+ * total={200_000}
270
+ * segments={[
271
+ * { label: "System prompt", value: 12_000, tone: "brand" },
272
+ * { label: "Conversation", value: 84_000, tone: "accent" },
273
+ * ]}
274
+ * remainderLabel="Free"
275
+ * />
276
+ * ```
277
+ *
173
278
  * Uses `pathLength="1"` so the dash numbers are fractions rather than
174
279
  * circumference maths: the same two values work at any radius, and it dodges
175
280
  * the Safari bug where a zoomed SVG rescales absolute dash lengths.
281
+ *
282
+ * THE ROLE IS `progressbar` IN BOTH SHAPES, and stays that way even though a
283
+ * breakdown of a budget is arguably a gauge. The role is a property of the
284
+ * component a caller reached for, not of the data they handed it — a component
285
+ * that announced itself as a different thing depending on the shape of its
286
+ * props would be two components sharing one name. A caller whose fact is a
287
+ * gauge has `Meter`.
176
288
  */
177
- export declare function ProgressRing({ value, label, size, tone, className, }: ProgressRingProps): import("react").JSX.Element;
289
+ export declare function ProgressRing(props: ProgressRingProps): import("react").JSX.Element;
178
290
  export {};
@@ -48,7 +48,7 @@ export { Toggle, ToggleGroup, Toolbar, ToolbarSeparator, type ToggleProps, type
48
48
  export { Separator, ScrollArea, Collapsible, EmptyState, Timeline, type SeparatorProps, type ScrollAreaProps, type CollapsibleProps, type EmptyStateProps, type TimelineProps, type TimelineItem, } from "./components/Surface";
49
49
  export { PanelGroup, Panel, PanelResizer, type PanelGroupProps, type PanelProps, type PanelResizerProps, type PanelDirection, type PanelNarrowMode, } from "./components/Panel";
50
50
  export { Avatar, AvatarGroup, type AvatarProps, type AvatarGroupProps, type AvatarStatus, } from "./components/Avatar";
51
- export { Progress, Meter, ProgressRing, type ProgressProps, type MeterProps, type ProgressRingProps, } from "./components/Progress";
51
+ export { Progress, Meter, ProgressRing, type ProgressProps, type MeterProps, type ProgressRingProps, type ProgressRingValueProps, type ProgressRingSegmentsProps, type ProgressRingSegment, type ProgressTone, } from "./components/Progress";
52
52
  export { Stat, Sparkline, type StatProps, type SparklineProps, type StatTrend, type StatSentiment, } from "./components/Stat";
53
53
  export { DataTable, TableEmptyState, CellStack, type DataTableProps, type TableDensity, } from "./components/Table";
54
54
  export { CodeEditor, CodeEditorToolbar, CodeEditorCaption, CodeEditorCopyButton, CodeEditorWrapToggle, CodeEditorViewSwitch, type CodeEditorProps, type CodeEditorToolbarProps, type CodeEditorView, } from "./components/CodeEditor";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "2.7.1",
3
+ "version": "2.8.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",