@joanroucoux/cairn-ui 0.3.0 → 0.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joanroucoux/cairn-ui",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Cairn UI — a monochrome, accessible Angular design system.",
5
5
  "keywords": [
6
6
  "angular",
@@ -32,6 +32,8 @@
32
32
  "@angular/core": "^22.0.0"
33
33
  },
34
34
  "dependencies": {
35
+ "d3-scale": "4.0.2",
36
+ "d3-shape": "3.2.0",
35
37
  "tslib": "2.8.1"
36
38
  },
37
39
  "sideEffects": false,
@@ -77,7 +77,7 @@ type AvatarSize = (typeof AVATAR_SIZES)[number];
77
77
  declare class UiAvatar {
78
78
  readonly initials: _angular_core.InputSignal<string>;
79
79
  readonly label: _angular_core.InputSignal<string>;
80
- readonly size: _angular_core.InputSignal<"md" | "sm">;
80
+ readonly size: _angular_core.InputSignal<"sm" | "md">;
81
81
  protected readonly classes: _angular_core.Signal<string>;
82
82
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiAvatar, never>;
83
83
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiAvatar, "ui-avatar", never, { "initials": { "alias": "initials"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
@@ -136,7 +136,7 @@ type CardPadding = (typeof CARD_PADDINGS)[number];
136
136
  */
137
137
  declare class UiCard {
138
138
  readonly variant: _angular_core.InputSignal<"default" | "elevated">;
139
- readonly padding: _angular_core.InputSignal<"md" | "sm" | "none">;
139
+ readonly padding: _angular_core.InputSignal<"sm" | "md" | "none">;
140
140
  protected readonly classes: _angular_core.Signal<string>;
141
141
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiCard, never>;
142
142
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiCard, "ui-card", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
@@ -211,6 +211,55 @@ declare class UiDialog {
211
211
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDialog, "ui-dialog", never, { "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "dismissed": "dismissed"; }, never, ["*", "[dialogActions]"], true, never>;
212
212
  }
213
213
 
214
+ type DonutSlice = {
215
+ id: string;
216
+ label: string;
217
+ value: number;
218
+ sublabel?: string;
219
+ };
220
+ type Ramp = 1 | 2 | 3 | 4 | 5 | 6;
221
+ type RankedSlice = DonutSlice & {
222
+ share: number;
223
+ ramp: Ramp;
224
+ members: string[];
225
+ };
226
+
227
+ type PositionedSlice = RankedSlice & {
228
+ path: string;
229
+ };
230
+
231
+ /**
232
+ * A ring chart with a legend: slices rank from largest to smallest on a grey ramp, and hovering,
233
+ * focusing or activating a legend row highlights its slice and centres it in the ring.
234
+ *
235
+ * @example
236
+ * <ui-donut [slices]="byAssetClass()" label="Par classe d'actif" othersLabel="Autres" [valueFormat]="formatEur" [shareFormat]="formatShare" (sliceSelect)="goToHoldings($event)" />
237
+ */
238
+ declare class UiDonut {
239
+ readonly slices: _angular_core.InputSignal<DonutSlice[]>;
240
+ readonly label: _angular_core.InputSignal<string>;
241
+ readonly othersLabel: _angular_core.InputSignal<string>;
242
+ readonly valueFormat: _angular_core.InputSignal<(value: number) => string>;
243
+ readonly shareFormat: _angular_core.InputSignal<(share: number) => string>;
244
+ readonly sliceSelect: _angular_core.OutputEmitterRef<string>;
245
+ protected readonly activeId: _angular_core.WritableSignal<string | null>;
246
+ protected readonly ranked: _angular_core.Signal<RankedSlice[]>;
247
+ protected readonly positioned: _angular_core.Signal<PositionedSlice[]>;
248
+ protected readonly active: _angular_core.Signal<RankedSlice | null>;
249
+ protected readonly ariaLabel: _angular_core.Signal<string>;
250
+ protected pathClasses(slice: RankedSlice): string;
251
+ protected dotClasses(slice: RankedSlice): string;
252
+ protected rowClasses(slice: RankedSlice): string;
253
+ protected subLabel(slice: RankedSlice): string;
254
+ protected arcTransform(slice: RankedSlice): string;
255
+ protected isActive(slice: RankedSlice): boolean;
256
+ protected highlight(id: string): void;
257
+ protected clearHighlight(id: string): void;
258
+ protected select(slice: RankedSlice): void;
259
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiDonut, never>;
260
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDonut, "ui-donut", never, { "slices": { "alias": "slices"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "othersLabel": { "alias": "othersLabel"; "required": true; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "shareFormat": { "alias": "shareFormat"; "required": false; "isSignal": true; }; }, { "sliceSelect": "sliceSelect"; }, never, never, true, never>;
261
+ }
262
+
214
263
  /**
215
264
  * Label, control, hint and error as one unit. The control stays a plain native element:
216
265
  * the field finds it in its own projected content and wires the ARIA attributes onto it.
@@ -269,7 +318,7 @@ type ControlSize = (typeof CONTROL_SIZES)[number];
269
318
  * <input uiInput type="email" placeholder="you@example.com" />
270
319
  */
271
320
  declare class UiInput implements UiControl {
272
- readonly size: _angular_core.InputSignal<"md" | "sm">;
321
+ readonly size: _angular_core.InputSignal<"sm" | "md">;
273
322
  readonly errors: _angular_core.InputSignal<readonly UiControlError[]>;
274
323
  readonly touched: _angular_core.InputSignal<boolean>;
275
324
  protected readonly classes: _angular_core.Signal<string>;
@@ -294,6 +343,81 @@ declare class UiTextarea implements UiControl {
294
343
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTextarea, "textarea[uiTextarea]", never, { "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
295
344
  }
296
345
 
346
+ type ChartPoint = {
347
+ t: number;
348
+ v: number;
349
+ };
350
+ type PlottedPoint = ChartPoint & {
351
+ x: number;
352
+ y: number;
353
+ };
354
+ type ChartGeometry = {
355
+ line: string;
356
+ end: {
357
+ x: number;
358
+ y: number;
359
+ };
360
+ start: {
361
+ y: number;
362
+ };
363
+ points: PlottedPoint[];
364
+ plotBottom: number;
365
+ plotTop: number;
366
+ };
367
+
368
+ type StartLabelPlacement = {
369
+ x: number;
370
+ y: number;
371
+ anchor: 'start' | 'end';
372
+ };
373
+
374
+ type PlotRef = ElementRef<SVGSVGElement>;
375
+ /**
376
+ * Value over time: a monotone curve with a dashed line at the starting value and a tooltip.
377
+ *
378
+ * @example
379
+ * <ui-line-chart [points]="points" label="Net worth over one month" startLabel="Since" [valueFormat]="formatEur" />
380
+ */
381
+ declare class UiLineChart {
382
+ #private;
383
+ readonly points: _angular_core.InputSignal<ChartPoint[]>;
384
+ readonly label: _angular_core.InputSignal<string>;
385
+ readonly valueFormat: _angular_core.InputSignal<(value: number) => string>;
386
+ readonly deltaFormat: _angular_core.InputSignal<(delta: number) => string>;
387
+ readonly timeFormat: _angular_core.InputSignal<(time: number) => string>;
388
+ readonly axisFormat: _angular_core.InputSignal<(time: number) => string>;
389
+ readonly startLabel: _angular_core.InputSignal<string>;
390
+ readonly timeColumnLabel: _angular_core.InputSignal<string>;
391
+ readonly valueColumnLabel: _angular_core.InputSignal<string>;
392
+ protected readonly svgRef: _angular_core.Signal<PlotRef>;
393
+ protected readonly activeIndex: _angular_core.WritableSignal<number | null>;
394
+ protected readonly animatedLine: _angular_core.WritableSignal<string | null>;
395
+ protected readonly measuredSize: _angular_core.WritableSignal<{
396
+ width: number;
397
+ height: number;
398
+ } | null>;
399
+ protected readonly effectiveWidth: _angular_core.Signal<number>;
400
+ protected readonly effectiveHeight: _angular_core.Signal<number>;
401
+ protected readonly geometry: _angular_core.Signal<ChartGeometry | null>;
402
+ protected readonly displayLine: _angular_core.Signal<string>;
403
+ protected readonly ticks: _angular_core.Signal<PlottedPoint[]>;
404
+ protected readonly active: _angular_core.Signal<PlottedPoint | null>;
405
+ protected readonly startLabelInfo: _angular_core.Signal<{
406
+ label: string;
407
+ placement: StartLabelPlacement;
408
+ } | null>;
409
+ constructor();
410
+ protected coreTick(index: number, count: number): boolean;
411
+ protected deltaFor(point: PlottedPoint): number;
412
+ protected deltaClasses(point: PlottedPoint): string;
413
+ protected tooltipStyle(point: PlottedPoint): string;
414
+ protected onPointerMove(event: PointerEvent): void;
415
+ protected onPointerLeave(): void;
416
+ protected onKeydown(event: KeyboardEvent): void;
417
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiLineChart, never>;
418
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiLineChart, "ui-line-chart", never, { "points": { "alias": "points"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "deltaFormat": { "alias": "deltaFormat"; "required": false; "isSignal": true; }; "timeFormat": { "alias": "timeFormat"; "required": false; "isSignal": true; }; "axisFormat": { "alias": "axisFormat"; "required": false; "isSignal": true; }; "startLabel": { "alias": "startLabel"; "required": false; "isSignal": true; }; "timeColumnLabel": { "alias": "timeColumnLabel"; "required": false; "isSignal": true; }; "valueColumnLabel": { "alias": "valueColumnLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
419
+ }
420
+
297
421
  /**
298
422
  * One action of a `ui-menu`; `destructive` paints it in `--negative`.
299
423
  *
@@ -363,7 +487,7 @@ declare class UiMeter {
363
487
  readonly value: _angular_core.InputSignal<number>;
364
488
  readonly label: _angular_core.InputSignal<string>;
365
489
  readonly valueText: _angular_core.InputSignal<string>;
366
- readonly tone: _angular_core.InputSignal<2 | 1 | 3 | 4 | 5 | 6>;
490
+ readonly tone: _angular_core.InputSignal<2 | 4 | 1 | 3 | 5 | 6>;
367
491
  protected readonly percent: _angular_core.Signal<number>;
368
492
  protected readonly fillClasses: _angular_core.Signal<string>;
369
493
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiMeter, never>;
@@ -437,7 +561,7 @@ declare class UiSegmented {
437
561
  * <select uiSelect><option value="pea">PEA</option></select>
438
562
  */
439
563
  declare class UiSelect implements UiControl {
440
- readonly size: _angular_core.InputSignal<"md" | "sm">;
564
+ readonly size: _angular_core.InputSignal<"sm" | "md">;
441
565
  readonly errors: _angular_core.InputSignal<readonly UiControlError[]>;
442
566
  readonly touched: _angular_core.InputSignal<boolean>;
443
567
  protected readonly classes: _angular_core.Signal<string>;
@@ -454,7 +578,7 @@ declare class UiSelect implements UiControl {
454
578
  * <ui-skeleton [lines]="3" />
455
579
  */
456
580
  declare class UiSkeleton {
457
- readonly shape: _angular_core.InputSignal<"figure" | "text" | "row" | "chart" | "ring">;
581
+ readonly shape: _angular_core.InputSignal<"text" | "figure" | "row" | "chart" | "ring">;
458
582
  readonly lines: _angular_core.InputSignal<number>;
459
583
  readonly height: _angular_core.InputSignal<number>;
460
584
  protected readonly animation = "cairn-pulse var(--pulse-duration) var(--ease-out) infinite alternate";
@@ -572,5 +696,5 @@ declare class UiTab {
572
696
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiTab, "a[ui-tab]", never, { "active": { "alias": "active"; "required": false; "isSignal": true; }; }, {}, never, ["[tabIcon]", "*"], true, never>;
573
697
  }
574
698
 
575
- export { AMOUNT_MASKINGS, AMOUNT_NUMERICS, ASYNC_STATES, AVATAR_SIZES, BADGE_VARIANTS, BUTTON_SIZES, BUTTON_VARIANTS, CARD_PADDINGS, CARD_VARIANTS, CELL_BREAKPOINTS, CONTROL_SIZES, DELTA_EMPHASES, DIALOG_WIDTHS, METER_TONES, STAT_SIZES, UI_AMOUNT_MASKED, UiAmount, UiAsync, UiAvatar, UiBadge, UiButton, UiCard, UiDelta, UiDialog, UiField, UiInput, UiMenu, UiMenuItem, UiMenuTrigger, UiMeter, UiNavItem, UiRow, UiSegmented, UiSelect, UiSkeleton, UiStat, UiSwitch, UiTab, UiTabBar, UiTable, UiTd, UiTextarea, UiTh, UiTr, formatAmount };
576
- export type { AmountFormatOptions, AmountMasking, AmountNumeric, AsyncState, AvatarSize, BadgeVariant, ButtonSize, ButtonVariant, CardPadding, CardVariant, CellBreakpoint, ControlSize, DeltaEmphasis, DialogWidth, MeterTone, SegmentedOption, StatSize, UiControlError };
699
+ export { AMOUNT_MASKINGS, AMOUNT_NUMERICS, ASYNC_STATES, AVATAR_SIZES, BADGE_VARIANTS, BUTTON_SIZES, BUTTON_VARIANTS, CARD_PADDINGS, CARD_VARIANTS, CELL_BREAKPOINTS, CONTROL_SIZES, DELTA_EMPHASES, DIALOG_WIDTHS, METER_TONES, STAT_SIZES, UI_AMOUNT_MASKED, UiAmount, UiAsync, UiAvatar, UiBadge, UiButton, UiCard, UiDelta, UiDialog, UiDonut, UiField, UiInput, UiLineChart, UiMenu, UiMenuItem, UiMenuTrigger, UiMeter, UiNavItem, UiRow, UiSegmented, UiSelect, UiSkeleton, UiStat, UiSwitch, UiTab, UiTabBar, UiTable, UiTd, UiTextarea, UiTh, UiTr, formatAmount };
700
+ export type { AmountFormatOptions, AmountMasking, AmountNumeric, AsyncState, AvatarSize, BadgeVariant, ButtonSize, ButtonVariant, CardPadding, CardVariant, CellBreakpoint, ChartPoint, ControlSize, DeltaEmphasis, DialogWidth, DonutSlice, MeterTone, SegmentedOption, StatSize, UiControlError };