yukit-web 0.5.0 → 0.6.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 CHANGED
@@ -17,16 +17,17 @@ Angular UI component library for Yurest web applications. Built on [Spartan](htt
17
17
 
18
18
  ## Requirements
19
19
 
20
- | Dependency | Version | Notes |
21
- | :---------------------------------------------------------------- | :------ | :----------------------------- |
22
- | [Angular](https://angular.dev/) | 21+ | Standalone APIs, signal inputs |
23
- | [Tailwind CSS](https://tailwindcss.com/) | v4 | Required — see [Setup](#setup) |
24
- | [`@spartan-ng/brain`](https://spartan.ng) | ^1.3.0 | Headless primitives |
25
- | [`@angular/cdk`](https://material.angular.dev/cdk/categories) | ^21.0.0 | Overlays, a11y |
26
- | [`@ng-icons/core`](https://ng-icons.github.io/ng-icons/) + lucide | ^32.2.0 | Icons |
27
- | [`@tanstack/angular-table`](https://tanstack.com/table) | ^9.0.0 | `<yuw-datatable>` |
28
- | `embla-carousel-angular` | ^21.0.0 | Carousel primitives |
29
- | `ngx-scrollbar` | ^19.1.5 | Scroll areas |
20
+ | Dependency | Version | Notes |
21
+ | :---------------------------------------------------------------- | :------ | :------------------------------- |
22
+ | [Angular](https://angular.dev/) | 21+ | Standalone APIs, signal inputs |
23
+ | [Tailwind CSS](https://tailwindcss.com/) | v4 | Required — see [Setup](#setup) |
24
+ | [`@spartan-ng/brain`](https://spartan.ng) | ^1.3.0 | Headless primitives |
25
+ | [`@angular/cdk`](https://material.angular.dev/cdk/categories) | ^21.0.0 | Overlays, a11y |
26
+ | [`@ng-icons/core`](https://ng-icons.github.io/ng-icons/) + lucide | ^32.2.0 | Icons |
27
+ | [`@tanstack/angular-table`](https://tanstack.com/table) | ^9.0.0 | `<yuw-datatable>` |
28
+ | `embla-carousel-angular` | ^21.0.0 | Carousel primitives |
29
+ | `ngx-scrollbar` | ^19.1.5 | Scroll areas |
30
+ | `d3-scale` + `d3-shape` | ^4 / ^3 | Optional, only for `<yuw-chart>` |
30
31
 
31
32
  ## Installation
32
33
 
@@ -44,6 +45,12 @@ npm install -D tailwindcss @tailwindcss/postcss tw-animate-css
44
45
 
45
46
  `tw-animate-css` is required because `@spartan-ng/brain/hlm-tailwind-preset.css` imports it.
46
47
 
48
+ Apps that draw [charts](#chart) also install their two geometry packages, which no other component needs:
49
+
50
+ ```bash
51
+ npm install d3-scale d3-shape
52
+ ```
53
+
47
54
  ## Setup
48
55
 
49
56
  `yukit-web` does **not** ship compiled component CSS. Its templates carry Tailwind utility classes,
@@ -163,6 +170,7 @@ behave like any other Tailwind color:
163
170
  | `--warning` / `--warning-foreground` | `bg-warning`, `text-warning-foreground`, … |
164
171
  | `--info` / `--info-foreground` | `bg-info`, `text-info-foreground`, … |
165
172
  | `--destructive-foreground` | `text-destructive-foreground` — Spartan defines only `--destructive` and hardcodes `text-white`; Yurest names a contrast color, so the pair is completed. |
173
+ | `--chart-1` … `--chart-8` | `bg-chart-1`, `fill-chart-3`, … — the series palette of [`<yuw-chart>`](#chart), each at least 3:1 against the page in light and dark mode. |
166
174
 
167
175
  To override a token, redefine it in your own `:root` _after_ importing the theme.
168
176
 
@@ -297,6 +305,7 @@ neither source silently overrides the other.
297
305
  | [Empty](#empty) | `[yuwEmpty]` | `YuwEmptyImports` |
298
306
  | [Skeleton](#skeleton) | `[yuwSkeleton]` | `YuwSkeletonDirective` |
299
307
  | [Spinner](#spinner) | `yuw-spinner` | `YuwSpinnerComponent` |
308
+ | [Chart](#chart) | `yuw-chart` | `YuwChartComponent` (`yukit-web/chart`) |
300
309
  | **Navigation** | | |
301
310
  | [Accordion](#accordion) | `yuw-accordion` | `YuwAccordionImports` |
302
311
  | [Breadcrumb](#breadcrumb) | `yuw-breadcrumb` | `YuwBreadcrumbComponent` |
@@ -1068,6 +1077,84 @@ The spinner inherits its size from the container's font size — wrap it in `tex
1068
1077
 
1069
1078
  ---
1070
1079
 
1080
+ ### Chart
1081
+
1082
+ Bar, line, area, pie and donut charts drawn as SVG, modelled on shadcn/ui's chart: a `config` names
1083
+ each series, gives it a label and a color token, and the tooltip and legend read the same config.
1084
+ It lives in its own entry point, so apps that draw no chart never load it nor its `d3-scale` /
1085
+ `d3-shape` peers:
1086
+
1087
+ ```ts
1088
+ import { YuwChartComponent, type YuwChartConfigDto, yuwChartColorAt } from 'yukit-web/chart';
1089
+ ```
1090
+
1091
+ ```ts
1092
+ protected readonly config: YuwChartConfigDto = {
1093
+ food: { label: this.translate('purchases.food'), color: 'chart-1' },
1094
+ drinks: { label: this.translate('purchases.drinks'), color: 'chart-2' },
1095
+ };
1096
+ protected readonly rows = [
1097
+ { month: '2026-01-01', food: 4200, drinks: 1800 },
1098
+ { month: '2026-02-01', food: 3900, drinks: 1650 },
1099
+ ];
1100
+ protected readonly euros = (value: number) => this.currency.format(value);
1101
+ protected readonly month = (value: unknown) => this.monthFormat.format(new Date(String(value)));
1102
+ ```
1103
+
1104
+ ```html
1105
+ <yuw-chart
1106
+ kind="bar-stacked"
1107
+ class="h-80"
1108
+ ariaLabel="Purchases per month"
1109
+ emptyText="No purchases in this period"
1110
+ categoryKey="month"
1111
+ categoryLabel="Month"
1112
+ [config]="config"
1113
+ [data]="rows"
1114
+ [valueFormat]="euros"
1115
+ [categoryFormat]="month"
1116
+ />
1117
+
1118
+ <yuw-chart kind="donut" ariaLabel="Purchases by provider" emptyText="No purchases" [config]="config" [data]="rows" />
1119
+ ```
1120
+
1121
+ - **Kinds** (`YuwChartKindDto`): `bar`, `bar-stacked`, `bar-horizontal`, `bar-horizontal-stacked`,
1122
+ `line`, `area`, `area-stacked`, `pie`, `donut`. Bars group their series unless the kind is
1123
+ stacked. Pie and donut draw one slice per series, summing it across every row, so the rows of a
1124
+ stacked bar chart give the donut of its totals; for a distribution, pass one row.
1125
+ - **Colors** are the `chart-1` … `chart-8` theme tokens, applied as `var(--chart-n)`, so dark mode
1126
+ recolors with no redraw. `yuwChartColorAt(index)` cycles through them for a config built from
1127
+ data, such as one series per provider.
1128
+ - **Formatting is yours.** `valueFormat` and `categoryFormat` turn numbers and categories into the
1129
+ text of axes, tooltips and the accessible table; the library hardcodes no locale or currency.
1130
+ - **Missing values** (anything that is not a finite number) are gaps, never zeros.
1131
+ - **Size**: the chart fills its root, `h-72` by default; set the height with `class`. It redraws
1132
+ when its box resizes and draws nothing on the server, where only the accessible table renders.
1133
+ - **Accessibility**: the chart is a named figure (`ariaLabel`, optional `description`) with a
1134
+ visually hidden data table. The plot is focusable: the arrow keys, Home and End move the tooltip
1135
+ across categories or slices, Escape hides it, and the active one is announced politely.
1136
+ Transitions respect `prefers-reduced-motion`.
1137
+
1138
+ #### Inputs
1139
+
1140
+ | Input | Type | Default |
1141
+ | :--------------- | :---------------------------------------------------------- | :---------- |
1142
+ | `ariaLabel` | `string` — **required**, the accessible name | — |
1143
+ | `config` | `YuwChartConfigDto` — **required** | — |
1144
+ | `data` | `YuwChartRowDto[]` — **required** | — |
1145
+ | `emptyText` | `string` — **required** | — |
1146
+ | `kind` | `YuwChartKindDto` | `'bar'` |
1147
+ | `categoryKey` | `string|undefined` — cartesian kinds | `undefined` |
1148
+ | `categoryLabel` | `string|undefined` — category column header, for the table | `undefined` |
1149
+ | `categoryFormat` | `(category: unknown) => string` — cartesian kinds | `String` |
1150
+ | `valueFormat` | `(value: number) => string` | `String` |
1151
+ | `description` | `string|undefined` — accessible description | `undefined` |
1152
+ | `legend` | `boolean` | `true` |
1153
+ | `loading` | `boolean` — renders a skeleton and sets `aria-busy` | `false` |
1154
+ | `class` | `string` — merged last onto the root | `''` |
1155
+
1156
+ ---
1157
+
1071
1158
  ### Accordion
1072
1159
 
1073
1160
  ```html