neba 1.15.0 → 1.16.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 (57) hide show
  1. package/dist/components/area-chart/AreaChart.d.ts +16 -5
  2. package/dist/components/area-chart/AreaChart.js +1 -1
  3. package/dist/components/bar-chart/BarChart.js +1 -1
  4. package/dist/components/combobox/Combobox.js +1 -1
  5. package/dist/components/gauge-chart/GaugeChart.d.ts +1 -1
  6. package/dist/components/heatmap-chart/HeatmapChart.d.ts +20 -1
  7. package/dist/components/heatmap-chart/HeatmapChart.js +1 -1
  8. package/dist/components/line-chart/LineChart.d.ts +16 -5
  9. package/dist/components/line-chart/LineChart.js +1 -1
  10. package/dist/components/menu/Menu.d.ts +18 -7
  11. package/dist/components/menu/Menu.js +1 -1
  12. package/dist/components/number-field/NumberField.js +1 -1
  13. package/dist/components/pie-chart/PieChart.d.ts +29 -0
  14. package/dist/components/pie-chart/PieChart.js +1 -1
  15. package/dist/components/prompt-input/PromptInput.js +1 -1
  16. package/dist/components/scatter-chart/ScatterChart.js +1 -1
  17. package/dist/components/select/Select.js +1 -1
  18. package/dist/components/sparkline/Sparkline.d.ts +14 -1
  19. package/dist/components/sparkline/Sparkline.js +1 -1
  20. package/dist/components/switch/Switch.js +1 -1
  21. package/dist/components/tabs/Tabs.d.ts +17 -1
  22. package/dist/components/tabs/Tabs.js +1 -1
  23. package/dist/components/text-field/TextField.js +1 -1
  24. package/dist/internal/chart-brush.d.ts +53 -0
  25. package/dist/internal/chart-brush.js +1 -0
  26. package/dist/internal/chart-frame.d.ts +123 -9
  27. package/dist/internal/chart-frame.js +1 -1
  28. package/dist/internal/chart-line.js +1 -1
  29. package/dist/internal/chart.d.ts +78 -2
  30. package/dist/internal/chart.js +1 -1
  31. package/dist/internal/glow.d.ts +44 -0
  32. package/dist/internal/glow.js +1 -1
  33. package/dist/internal/i18n.d.ts +2 -0
  34. package/dist/internal/i18n.js +1 -1
  35. package/dist/internal/picker.js +1 -1
  36. package/dist/locales/ar.js +1 -1
  37. package/dist/locales/de.js +1 -1
  38. package/dist/locales/es.js +1 -1
  39. package/dist/locales/fr.js +1 -1
  40. package/dist/locales/hi.js +1 -1
  41. package/dist/locales/id.js +1 -1
  42. package/dist/locales/it.js +1 -1
  43. package/dist/locales/ja.js +1 -1
  44. package/dist/locales/ko.js +1 -1
  45. package/dist/locales/nl.js +1 -1
  46. package/dist/locales/pl.js +1 -1
  47. package/dist/locales/pt.js +1 -1
  48. package/dist/locales/ru.js +1 -1
  49. package/dist/locales/th.js +1 -1
  50. package/dist/locales/tr.js +1 -1
  51. package/dist/locales/vi.js +1 -1
  52. package/dist/locales/zh-hans.js +1 -1
  53. package/dist/locales/zh-hant.js +1 -1
  54. package/dist/styles.css +1 -1
  55. package/dist/tailwind.css +15 -0
  56. package/dist/types.d.ts +133 -0
  57. package/package.json +1 -1
package/dist/tailwind.css CHANGED
@@ -2254,6 +2254,21 @@
2254
2254
  }
2255
2255
  }
2256
2256
 
2257
+ /*
2258
+ * And out again while the reader is typing at it.
2259
+ *
2260
+ * `internal/glow.ts` writes the mark on a keystroke and takes it off on the
2261
+ * next `pointermove`, which is the whole rule: a pointer resting on a field is
2262
+ * where the hand left it — over the text — so the one moment the bloom is least
2263
+ * wanted is the one moment it cannot move out of the way on its own.
2264
+ *
2265
+ * After the hover rule and not before it: the two selectors are the same
2266
+ * specificity, so the one written second is the one that decides.
2267
+ */
2268
+ .neba-glow[data-typing]::before {
2269
+ opacity: 0;
2270
+ }
2271
+
2257
2272
  /*
2258
2273
  * Release afterglow. The asymmetry is the whole trick: 0ms in, ~900ms out, so
2259
2274
  * the flash lands on the frame of the press and is still visibly draining a
package/dist/types.d.ts CHANGED
@@ -467,6 +467,21 @@ export interface NebaChartSeries {
467
467
  * @default false
468
468
  */
469
469
  hidden?: boolean;
470
+ /**
471
+ * Which value axis this series is measured against.
472
+ *
473
+ * `secondary` is for the series whose units are not the others' — revenue
474
+ * beside a conversion rate, a count beside a duration. It is read only when
475
+ * the chart was given a `secondaryAxis`, and never on a stacked chart: a
476
+ * stack is a total, and a total across two units is not a number.
477
+ *
478
+ * Reach for it rarely. Two scales on one plot let a caller make any two
479
+ * series look like they move together by choosing the ranges, and a reader
480
+ * has no way to see that it was done — which is why the second axis is drawn
481
+ * on the far edge and labelled rather than merely implied.
482
+ * @default 'primary'
483
+ */
484
+ axis?: 'primary' | 'secondary';
470
485
  }
471
486
  /**
472
487
  * One span on a [TimelineChart] — a stretch of time with two ends.
@@ -510,6 +525,24 @@ export interface NebaTimelineSeries {
510
525
  }
511
526
  /** How a line gets from one point to the next. */
512
527
  export type NebaChartCurve = 'linear' | 'smooth' | 'step';
528
+ /**
529
+ * What a line or a band does where a value is missing.
530
+ *
531
+ * - `gap` — breaks. The default, and the honest one: a `null` is a month that
532
+ * has not closed or a sensor that was offline, and a chart that draws over
533
+ * the hole has stated a number nobody measured.
534
+ * - `connect` — joins the two sides with a straight segment. For a gap that is
535
+ * an artefact of how the data was collected rather than a fact about the
536
+ * world — a reading that failed to arrive for something that never stopped.
537
+ * - `zero` — reads the gap as a nought, everywhere: the line goes to the
538
+ * baseline, the axis takes the nought into its range, and the tooltip and the
539
+ * table say `0` rather than nothing. That last part is the point of it being
540
+ * here rather than a change to the drawing alone — a picture that touches
541
+ * zero over a table that says "no reading" is two answers to one question.
542
+ * Reach for it when a missing row genuinely means none happened, which is
543
+ * what an event count usually means and what a rate never does.
544
+ */
545
+ export type NebaChartNulls = 'gap' | 'connect' | 'zero';
513
546
  /**
514
547
  * Which values are written onto the marks themselves.
515
548
  *
@@ -560,6 +593,86 @@ export interface NebaChartTooltip {
560
593
  /** Draws the panel. Without it the chart draws its own. */
561
594
  render?: (context: NebaChartTooltipContext) => React.ReactNode;
562
595
  }
596
+ /**
597
+ * A line, or a band, drawn across a plot at a value the data has none of.
598
+ *
599
+ * A target, an SLA, a budget, last year's average, the window a forecast
600
+ * covers. It is the one thing on a chart that is neither a mark nor chrome: it
601
+ * carries meaning, so it is drawn heavier than a gridline — and it is not the
602
+ * reader's data, so it is dashed and neutral rather than taking one of the
603
+ * eight series hues.
604
+ *
605
+ * The scale is widened to hold it. A target drawn off the top of the plot is a
606
+ * target nobody can see, and moving every mark down a little to make room is
607
+ * the cheaper of the two costs.
608
+ */
609
+ export interface NebaChartReference {
610
+ /** Where it sits, in the units of the axis it is read against. */
611
+ value: number;
612
+ /**
613
+ * Turns the line into a band that runs from `value` to here — a tolerance, a
614
+ * quarter, the range a forecast covers. Drawn as a wash with an edge at each
615
+ * end, so what is inside it stays readable.
616
+ */
617
+ to?: number;
618
+ /**
619
+ * Which axis the numbers are read against.
620
+ *
621
+ * - `value` — the one the marks are measured on. A target, a budget, a limit.
622
+ * - `category` — the one they are placed along, for a rule that says *when*:
623
+ * a release, a policy change. On an axis of columns the number is the
624
+ * column's index; on one of dates or numbers it is a point on that scale.
625
+ * @default 'value'
626
+ */
627
+ axis?: 'value' | 'category';
628
+ /**
629
+ * What it is called, written at the far end of it. SVG text, so a string:
630
+ * an element has nowhere to go.
631
+ */
632
+ label?: string;
633
+ /**
634
+ * Its colour. A `NebaColor` family, or any CSS colour.
635
+ *
636
+ * Neutral by default, and that is the right answer more often than it looks:
637
+ * a reference in `danger` says the line is the bad thing, when usually the
638
+ * bad thing is the data crossing it.
639
+ * @default the muted ink
640
+ */
641
+ color?: NebaColor | (string & {});
642
+ /**
643
+ * Draws it as a solid rule. Dashed otherwise, which is what says a line is a
644
+ * threshold rather than one more gridline.
645
+ * @default false
646
+ */
647
+ solid?: boolean;
648
+ }
649
+ /**
650
+ * The strip under a plot that says which part of a long series is drawn.
651
+ *
652
+ * A chart of two thousand points is a chart with no points on it: every column
653
+ * is a fraction of a pixel wide and the shape is a smear. The answer is not to
654
+ * draw fewer of them — that is the caller's data — but to draw a window of
655
+ * them, and to put the whole series under the plot small so the reader can see
656
+ * where the window is and move it.
657
+ *
658
+ * The window is in **category indices**, inclusive at both ends, because that
659
+ * is what a category axis is indexed by whether it holds dates, numbers or
660
+ * columns.
661
+ */
662
+ export interface NebaChartBrush {
663
+ /** Which categories the window covers to begin with. Defaults to all of them. */
664
+ defaultRange?: readonly [number, number];
665
+ /** The window, for a chart whose range the caller holds. */
666
+ range?: readonly [number, number];
667
+ /** Called with the new window whenever the reader moves it. */
668
+ onRangeChange?: (range: [number, number]) => void;
669
+ /**
670
+ * How tall the strip is, in pixels. Drawn **inside** the chart's own height,
671
+ * like the axis labels, so a card sized to the chart is a card it fits in.
672
+ * @default 32
673
+ */
674
+ height?: number;
675
+ }
563
676
  /** One axis of a cartesian chart. */
564
677
  export interface NebaChartAxis {
565
678
  /** Leaves the axis undrawn — its rule, its ticks and its labels. */
@@ -587,6 +700,26 @@ export interface NebaChartAxis {
587
700
  * was written out as `[object Object]`.
588
701
  */
589
702
  tickFormat?: (value: NebaChartCategory, index: number) => string | number;
703
+ /**
704
+ * Turns the labels by this many degrees, between `-90` and `90`. Negative
705
+ * tilts them up to the right, which is the one most readers have met;
706
+ * positive tilts them down, and `-90` stands them on end.
707
+ *
708
+ * What it buys is **all** of the labels. Flat, a long category name has one
709
+ * slot to fit in, so the axis either cuts it to an ellipsis or drops every
710
+ * second one; turned, each label only has to clear its neighbour across its
711
+ * own height, and a dozen product names fit where three did. What it costs is
712
+ * a band of the plot and a label nobody can read at a glance, so it is worth
713
+ * it when the names are what the reader came for and not when the shape is.
714
+ *
715
+ * Only the **category** axis reads it, and only on a chart that draws that
716
+ * axis along the bottom: a horizontal chart already gives each label a row of
717
+ * its own, and a value tick is a rounded number that was never cut. The band
718
+ * under the plot grows to hold the turned labels, up to a cap — past that
719
+ * they are still cut, because a chart that is mostly axis is not a chart.
720
+ * @default 0
721
+ */
722
+ tickAngle?: number;
590
723
  /**
591
724
  * How much room the axis keeps for its ticks and its label, in pixels.
592
725
  * Measured from the ticks themselves otherwise; set it when a long category
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neba",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "description": "A comprehensive React UI component library — buttons, fields, menus, dialogs, tables and much more — accessible and themeable, sharing one prop vocabulary and a translucent acrylic design language. ESM only, types included, dark mode built in.",
5
5
  "type": "module",
6
6
  "types": "dist/index.d.ts",