@joanroucoux/cairn-ui 0.7.1 → 0.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.
Files changed (111) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/fesm2022/joanroucoux-cairn-ui-action-bar.mjs +54 -0
  3. package/fesm2022/joanroucoux-cairn-ui-action-bar.mjs.map +1 -0
  4. package/fesm2022/joanroucoux-cairn-ui-alert.mjs +129 -0
  5. package/fesm2022/joanroucoux-cairn-ui-alert.mjs.map +1 -0
  6. package/fesm2022/joanroucoux-cairn-ui-amount.mjs +114 -0
  7. package/fesm2022/joanroucoux-cairn-ui-amount.mjs.map +1 -0
  8. package/fesm2022/joanroucoux-cairn-ui-async.mjs +282 -0
  9. package/fesm2022/joanroucoux-cairn-ui-async.mjs.map +1 -0
  10. package/fesm2022/joanroucoux-cairn-ui-avatar.mjs +71 -0
  11. package/fesm2022/joanroucoux-cairn-ui-avatar.mjs.map +1 -0
  12. package/fesm2022/joanroucoux-cairn-ui-back-link.mjs +79 -0
  13. package/fesm2022/joanroucoux-cairn-ui-back-link.mjs.map +1 -0
  14. package/fesm2022/joanroucoux-cairn-ui-badge.mjs +48 -0
  15. package/fesm2022/joanroucoux-cairn-ui-badge.mjs.map +1 -0
  16. package/fesm2022/joanroucoux-cairn-ui-button.mjs +128 -0
  17. package/fesm2022/joanroucoux-cairn-ui-button.mjs.map +1 -0
  18. package/fesm2022/joanroucoux-cairn-ui-card.mjs +146 -0
  19. package/fesm2022/joanroucoux-cairn-ui-card.mjs.map +1 -0
  20. package/fesm2022/joanroucoux-cairn-ui-choice-chips.mjs +172 -0
  21. package/fesm2022/joanroucoux-cairn-ui-choice-chips.mjs.map +1 -0
  22. package/fesm2022/joanroucoux-cairn-ui-control.mjs +18 -0
  23. package/fesm2022/joanroucoux-cairn-ui-control.mjs.map +1 -0
  24. package/fesm2022/joanroucoux-cairn-ui-delta.mjs +103 -0
  25. package/fesm2022/joanroucoux-cairn-ui-delta.mjs.map +1 -0
  26. package/fesm2022/joanroucoux-cairn-ui-dialog.mjs +626 -0
  27. package/fesm2022/joanroucoux-cairn-ui-dialog.mjs.map +1 -0
  28. package/fesm2022/joanroucoux-cairn-ui-donut.mjs +347 -0
  29. package/fesm2022/joanroucoux-cairn-ui-donut.mjs.map +1 -0
  30. package/fesm2022/joanroucoux-cairn-ui-empty.mjs +47 -0
  31. package/fesm2022/joanroucoux-cairn-ui-empty.mjs.map +1 -0
  32. package/fesm2022/joanroucoux-cairn-ui-external-link.mjs +65 -0
  33. package/fesm2022/joanroucoux-cairn-ui-external-link.mjs.map +1 -0
  34. package/fesm2022/joanroucoux-cairn-ui-fact.mjs +99 -0
  35. package/fesm2022/joanroucoux-cairn-ui-fact.mjs.map +1 -0
  36. package/fesm2022/joanroucoux-cairn-ui-field.mjs +232 -0
  37. package/fesm2022/joanroucoux-cairn-ui-field.mjs.map +1 -0
  38. package/fesm2022/joanroucoux-cairn-ui-filter-chips.mjs +89 -0
  39. package/fesm2022/joanroucoux-cairn-ui-filter-chips.mjs.map +1 -0
  40. package/fesm2022/joanroucoux-cairn-ui-input.mjs +90 -0
  41. package/fesm2022/joanroucoux-cairn-ui-input.mjs.map +1 -0
  42. package/fesm2022/joanroucoux-cairn-ui-line-chart.mjs +844 -0
  43. package/fesm2022/joanroucoux-cairn-ui-line-chart.mjs.map +1 -0
  44. package/fesm2022/joanroucoux-cairn-ui-menu.mjs +241 -0
  45. package/fesm2022/joanroucoux-cairn-ui-menu.mjs.map +1 -0
  46. package/fesm2022/joanroucoux-cairn-ui-meter.mjs +86 -0
  47. package/fesm2022/joanroucoux-cairn-ui-meter.mjs.map +1 -0
  48. package/fesm2022/joanroucoux-cairn-ui-motion.mjs +415 -0
  49. package/fesm2022/joanroucoux-cairn-ui-motion.mjs.map +1 -0
  50. package/fesm2022/joanroucoux-cairn-ui-nav-item.mjs +45 -0
  51. package/fesm2022/joanroucoux-cairn-ui-nav-item.mjs.map +1 -0
  52. package/fesm2022/joanroucoux-cairn-ui-row.mjs +164 -0
  53. package/fesm2022/joanroucoux-cairn-ui-row.mjs.map +1 -0
  54. package/fesm2022/joanroucoux-cairn-ui-segmented.mjs +165 -0
  55. package/fesm2022/joanroucoux-cairn-ui-segmented.mjs.map +1 -0
  56. package/fesm2022/joanroucoux-cairn-ui-select.mjs +69 -0
  57. package/fesm2022/joanroucoux-cairn-ui-select.mjs.map +1 -0
  58. package/fesm2022/joanroucoux-cairn-ui-skeleton.mjs +91 -0
  59. package/fesm2022/joanroucoux-cairn-ui-skeleton.mjs.map +1 -0
  60. package/fesm2022/joanroucoux-cairn-ui-stale-link.mjs +43 -0
  61. package/fesm2022/joanroucoux-cairn-ui-stale-link.mjs.map +1 -0
  62. package/fesm2022/joanroucoux-cairn-ui-stat.mjs +96 -0
  63. package/fesm2022/joanroucoux-cairn-ui-stat.mjs.map +1 -0
  64. package/fesm2022/joanroucoux-cairn-ui-switch.mjs +37 -0
  65. package/fesm2022/joanroucoux-cairn-ui-switch.mjs.map +1 -0
  66. package/fesm2022/joanroucoux-cairn-ui-tab-bar.mjs +75 -0
  67. package/fesm2022/joanroucoux-cairn-ui-tab-bar.mjs.map +1 -0
  68. package/fesm2022/joanroucoux-cairn-ui-table.mjs +321 -0
  69. package/fesm2022/joanroucoux-cairn-ui-table.mjs.map +1 -0
  70. package/fesm2022/joanroucoux-cairn-ui-toast.mjs +153 -0
  71. package/fesm2022/joanroucoux-cairn-ui-toast.mjs.map +1 -0
  72. package/fesm2022/joanroucoux-cairn-ui.mjs +0 -5386
  73. package/fesm2022/joanroucoux-cairn-ui.mjs.map +1 -1
  74. package/package.json +141 -1
  75. package/styles/motion.css +9 -0
  76. package/types/joanroucoux-cairn-ui-action-bar.d.ts +22 -0
  77. package/types/joanroucoux-cairn-ui-alert.d.ts +23 -0
  78. package/types/joanroucoux-cairn-ui-amount.d.ts +45 -0
  79. package/types/joanroucoux-cairn-ui-async.d.ts +58 -0
  80. package/types/joanroucoux-cairn-ui-avatar.d.ts +35 -0
  81. package/types/joanroucoux-cairn-ui-back-link.d.ts +22 -0
  82. package/types/joanroucoux-cairn-ui-badge.d.ts +23 -0
  83. package/types/joanroucoux-cairn-ui-button.d.ts +29 -0
  84. package/types/joanroucoux-cairn-ui-card.d.ts +36 -0
  85. package/types/joanroucoux-cairn-ui-choice-chips.d.ts +46 -0
  86. package/types/joanroucoux-cairn-ui-control.d.ts +27 -0
  87. package/types/joanroucoux-cairn-ui-delta.d.ts +38 -0
  88. package/types/joanroucoux-cairn-ui-dialog.d.ts +72 -0
  89. package/types/joanroucoux-cairn-ui-donut.d.ts +59 -0
  90. package/types/joanroucoux-cairn-ui-empty.d.ts +19 -0
  91. package/types/joanroucoux-cairn-ui-external-link.d.ts +15 -0
  92. package/types/joanroucoux-cairn-ui-fact.d.ts +44 -0
  93. package/types/joanroucoux-cairn-ui-field.d.ts +84 -0
  94. package/types/joanroucoux-cairn-ui-filter-chips.d.ts +28 -0
  95. package/types/joanroucoux-cairn-ui-input.d.ts +51 -0
  96. package/types/joanroucoux-cairn-ui-line-chart.d.ts +114 -0
  97. package/types/joanroucoux-cairn-ui-menu.d.ts +66 -0
  98. package/types/joanroucoux-cairn-ui-meter.d.ts +30 -0
  99. package/types/joanroucoux-cairn-ui-motion.d.ts +124 -0
  100. package/types/joanroucoux-cairn-ui-nav-item.d.ts +21 -0
  101. package/types/joanroucoux-cairn-ui-row.d.ts +78 -0
  102. package/types/joanroucoux-cairn-ui-segmented.d.ts +36 -0
  103. package/types/joanroucoux-cairn-ui-select.d.ts +23 -0
  104. package/types/joanroucoux-cairn-ui-skeleton.d.ts +26 -0
  105. package/types/joanroucoux-cairn-ui-stale-link.d.ts +24 -0
  106. package/types/joanroucoux-cairn-ui-stat.d.ts +32 -0
  107. package/types/joanroucoux-cairn-ui-switch.d.ts +17 -0
  108. package/types/joanroucoux-cairn-ui-tab-bar.d.ts +31 -0
  109. package/types/joanroucoux-cairn-ui-table.d.ts +139 -0
  110. package/types/joanroucoux-cairn-ui-toast.d.ts +51 -0
  111. package/types/joanroucoux-cairn-ui.d.ts +1 -1407
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joanroucoux-cairn-ui-line-chart.mjs","sources":["../../../projects/ui/line-chart/internal/chart-axis.ts","../../../projects/ui/line-chart/internal/chart-interaction.ts","../../../projects/ui/line-chart/internal/chart-layout.ts","../../../projects/ui/line-chart/internal/chart-scale.ts","../../../projects/ui/line-chart/internal/observe-size.ts","../../../projects/ui/line-chart/internal/start-label.ts","../../../projects/ui/line-chart/internal/transition.ts","../../../projects/ui/line-chart/internal/viewport.ts","../../../projects/ui/line-chart/line-chart.ts","../../../projects/ui/line-chart/joanroucoux-cairn-ui-line-chart.ts"],"sourcesContent":["import type { PlottedPoint } from './chart-scale';\n\nexport const axisTicks = <T extends PlottedPoint>(points: readonly T[], maxTicks = 5): T[] => {\n if (points.length <= maxTicks) {\n return [...points];\n }\n\n const count = Math.max(3, Math.min(maxTicks, points.length));\n const step = (points.length - 1) / (count - 1);\n\n const indexes = new Set<number>();\n\n for (let tick = 0; tick < count; tick++) {\n indexes.add(Math.round(tick * step));\n }\n\n return [...indexes].sort((a, b) => a - b).map((index) => points[index] as T);\n};\n\nexport const isCoreTick = (index: number, count: number): boolean => {\n if (count <= 3) {\n return true;\n }\n\n const middle = Math.floor((count - 1) / 2);\n\n return index === 0 || index === count - 1 || index === middle;\n};\n\nexport type TickLabel = { text: string; classes: string };\n\nconst firstOfEachRun = (labels: readonly string[], included: (index: number) => boolean): boolean[] => {\n let previous: string | null = null;\n\n return labels.map((text, index) => {\n if (!included(index)) {\n return false;\n }\n\n const distinct = text !== previous;\n\n previous = text;\n\n return distinct;\n });\n};\n\nexport const tickLabels = (\n ticks: readonly { t: number }[],\n format: (time: number) => string,\n mode: 3 | 5 | 'auto',\n): (TickLabel | null)[] => {\n const labels = ticks.map((tick) => format(tick.t));\n const count = labels.length;\n const core = (index: number): boolean => isCoreTick(index, count);\n const everyTick = firstOfEachRun(labels, () => true);\n const coreTicks = firstOfEachRun(labels, core);\n\n return labels.map((text, index) => {\n const wide = mode === 3 ? coreTicks[index]! : everyTick[index]!;\n const narrow = coreTicks[index]!;\n\n if (!wide && !narrow) {\n return null;\n }\n\n const classes =\n mode === 'auto' ? `${narrow ? '' : 'max-sm:hidden'} ${wide ? '' : 'sm:hidden'}`.trim() : wide ? '' : 'hidden';\n\n return { text, classes };\n });\n};\n","import type { PlottedPoint } from './chart-scale';\n\nconst clamp = (value: number, min: number, max: number): number => Math.min(Math.max(value, min), max);\n\nexport const nearestPointIndex = (points: readonly PlottedPoint[], x: number): number => {\n let nearest = 0;\n let nearestDistance = Infinity;\n\n points.forEach((point, index) => {\n const distance = Math.abs(point.x - x);\n\n if (distance < nearestDistance) {\n nearestDistance = distance;\n nearest = index;\n }\n });\n\n return nearest;\n};\n\nexport type KeyNavigation = { index: number | null; preventDefault: boolean };\n\nexport const navigateIndex = (key: string, current: number | null, last: number): KeyNavigation | null => {\n switch (key) {\n case 'ArrowRight':\n return { index: clamp((current ?? -1) + 1, 0, last), preventDefault: true };\n case 'ArrowLeft':\n return { index: clamp((current ?? last + 1) - 1, 0, last), preventDefault: true };\n case 'Home':\n return { index: 0, preventDefault: true };\n case 'End':\n return { index: last, preventDefault: true };\n case 'Escape':\n return { index: null, preventDefault: false };\n default:\n return null;\n }\n};\n","export const START_LABEL_HEIGHT = 16;\n\nconst AXIS_ROW = 17;\n\nexport const TOOLTIP_SIZES = ['compact', 'large'] as const;\nexport type TooltipSize = (typeof TOOLTIP_SIZES)[number];\n\nexport const TOOLTIP_CLASSES: Record<TooltipSize, { box: string; value: string; delta: string }> = {\n compact: { box: '-top-3 px-2.5', value: 'text-label', delta: 'text-caption' },\n large: { box: 'top-0 px-3', value: 'text-body', delta: 'text-label' },\n};\n\nconst PLOT_PADDING_RATIO = 16 / 240;\nconst SPARKLINE_PADDING = 4;\nconst START_LABEL_BASELINE_OFFSET = 4;\nconst TOOLTIP_OFFSET = 14;\nconst TOOLTIP_FLIP_RATIO = 0.55;\n\nexport const plotHeightFor = (height: number, sparkline: boolean, axisGap: number | 'auto', wide: boolean): number =>\n sparkline ? height : Math.max(height - resolveGap(axisGap, wide) - AXIS_ROW, 1);\n\nexport const plotPaddingFor = (plotHeight: number, sparkline: boolean): number =>\n sparkline ? SPARKLINE_PADDING : plotHeight * PLOT_PADDING_RATIO;\n\nexport const startLabelBaseline = (boxBottom: number): number => boxBottom - START_LABEL_BASELINE_OFFSET;\n\nexport const tooltipPlacement = (ratio: number): string => {\n const flipped = ratio > TOOLTIP_FLIP_RATIO;\n\n return `left: calc(${ratio * 100}% ${flipped ? '-' : '+'} ${TOOLTIP_OFFSET}px); transform: ${flipped ? 'translateX(-100%)' : 'none'}`;\n};\n\nexport const deltaTone = (delta: number): string =>\n delta > 0 ? 'text-(--positive)' : delta < 0 ? 'text-(--negative)' : 'text-(--muted-foreground)';\n\nexport const DEFAULT_WIDTH = 640;\nexport const DEFAULT_HEIGHT = 240;\n\nexport const identityValue = (value: number): string => `${value}`;\nexport const identityDelta = (delta: number): string => `${delta > 0 ? '+' : ''}${delta}`;\nexport const identityTime = (time: number): string => new Date(time).toISOString();\n\nexport type AxisTicks = 3 | 5 | 'auto';\n\nexport const parseAxisTicks = (value: AxisTicks | string): AxisTicks =>\n value === 'auto' ? 'auto' : (Number(value) as 3 | 5);\n\nconst resolveGap = (gap: number | 'auto', wide: boolean): number => (gap === 'auto' ? (wide ? 16 : 12) : gap);\n\nconst resolveTooltip = (size: TooltipSize | 'auto', wide: boolean): TooltipSize =>\n size === 'auto' ? (wide ? 'large' : 'compact') : size;\n\nexport const tooltipClassesFor = (size: TooltipSize | 'auto', wide: boolean): (typeof TOOLTIP_CLASSES)[TooltipSize] =>\n TOOLTIP_CLASSES[resolveTooltip(size, wide)];\n","import { scaleLinear } from 'd3-scale';\nimport { curveMonotoneX, line } from 'd3-shape';\n\nexport type ChartPoint = {\n t: number;\n v: number;\n};\n\nexport type PlottedPoint = ChartPoint & { x: number; y: number };\n\nexport type ChartGeometry = {\n line: string;\n end: { x: number; y: number };\n start: { y: number };\n points: PlottedPoint[];\n plotBottom: number;\n plotTop: number;\n};\n\nexport type GeometryPadding = { x?: number; top?: number; bottom?: number };\n\nexport const CURVE = curveMonotoneX;\n\nexport const buildGeometry = (\n points: ChartPoint[],\n width: number,\n height: number,\n padding: GeometryPadding = {},\n): ChartGeometry | null => {\n if (points.length === 0) {\n return null;\n }\n\n const { x: paddingX = 4, top: paddingTop = 4, bottom: paddingBottom = 4 } = padding;\n const plotTop = paddingTop;\n const plotBottom = height - paddingBottom;\n\n const times = points.map((point) => point.t);\n const values = points.map((point) => point.v);\n const minValue = Math.min(...values);\n const maxValue = Math.max(...values);\n\n const x = scaleLinear()\n .domain([Math.min(...times), Math.max(...times)])\n .range([paddingX, width - paddingX]);\n\n const y =\n minValue === maxValue\n ? () => (plotTop + plotBottom) / 2\n : scaleLinear().domain([minValue, maxValue]).range([plotBottom, plotTop]);\n\n const toX = (point: ChartPoint): number => (points.length === 1 ? paddingX : x(point.t));\n\n const lineGenerator = line<ChartPoint>()\n .x(toX)\n .y((point) => y(point.v))\n .curve(CURVE);\n\n const first = points[0] as ChartPoint;\n const last = points.at(-1) as ChartPoint;\n\n return {\n line: lineGenerator(points) as string,\n end: { x: toX(last), y: y(last.v) },\n start: { y: y(first.v) },\n points: points.map((point) => ({ ...point, x: toX(point), y: y(point.v) })),\n plotBottom,\n plotTop,\n };\n};\n","import type { DestroyRef } from '@angular/core';\n\nexport type Size = { width: number; height: number };\n\nexport const observeSize = (element: Element, destroyRef: DestroyRef, measured: (size: Size) => void): void => {\n if (typeof ResizeObserver === 'undefined') {\n return;\n }\n\n const { clientWidth: width, clientHeight: height } = element;\n\n if (width > 0 && height > 0) {\n measured({ width, height });\n }\n\n const observer = new ResizeObserver(([entry]) => {\n if (entry) {\n measured({ width: entry.contentRect.width, height: entry.contentRect.height });\n }\n });\n\n observer.observe(element);\n destroyRef.onDestroy(() => observer.disconnect());\n};\n","import type { PlottedPoint } from './chart-scale';\n\nexport type StartLabelBox = { width: number; height: number };\nexport type StartLabelSize = { width: number; height: number };\nexport type StartLabelPlacement = { x: number; y: number; anchor: 'start' | 'end' };\n\nconst LINE_GAP = 6;\nconst COLLISION_MARGIN = 6;\nconst EDGE_TOLERANCE = 3;\n\ntype Slot = { anchor: 'start' | 'end'; x: number; y: number; top: number; bottom: number };\n\nconst candidateSlots = (startY: number, box: StartLabelBox, label: StartLabelSize): Slot[] => {\n const aboveTop = startY - LINE_GAP - label.height;\n const aboveBottom = startY - LINE_GAP;\n const belowTop = startY + LINE_GAP;\n const belowBottom = startY + LINE_GAP + label.height;\n\n const slots: Slot[] = [\n { anchor: 'end', x: box.width, y: aboveBottom, top: aboveTop, bottom: aboveBottom },\n { anchor: 'end', x: box.width, y: belowBottom, top: belowTop, bottom: belowBottom },\n { anchor: 'start', x: 0, y: aboveBottom, top: aboveTop, bottom: aboveBottom },\n { anchor: 'start', x: 0, y: belowBottom, top: belowTop, bottom: belowBottom },\n { anchor: 'end', x: box.width, y: label.height, top: 0, bottom: label.height },\n { anchor: 'start', x: 0, y: label.height, top: 0, bottom: label.height },\n { anchor: 'end', x: box.width, y: box.height, top: box.height - label.height, bottom: box.height },\n { anchor: 'start', x: 0, y: box.height, top: box.height - label.height, bottom: box.height },\n ];\n\n return slots.filter((slot) => slot.top >= -EDGE_TOLERANCE && slot.bottom <= box.height + EDGE_TOLERANCE);\n};\n\nconst hitsFor = (slot: Slot, label: StartLabelSize, points: readonly PlottedPoint[]): number => {\n const left = slot.anchor === 'end' ? slot.x - label.width : slot.x;\n const right = slot.anchor === 'end' ? slot.x : slot.x + label.width;\n const top = slot.top - COLLISION_MARGIN;\n const bottom = slot.bottom + COLLISION_MARGIN;\n\n return points.filter((point) => point.x >= left && point.x <= right && point.y >= top && point.y <= bottom).length;\n};\n\nexport const placeStartLabel = (\n points: readonly PlottedPoint[],\n startY: number,\n box: StartLabelBox,\n label: StartLabelSize,\n): StartLabelPlacement => {\n let best: { slot: Slot; hits: number } | null = null;\n\n for (const slot of candidateSlots(startY, box, label)) {\n const hits = hitsFor(slot, label, points);\n\n if (!best || hits < best.hits) {\n best = { slot, hits };\n }\n if (hits === 0) {\n break;\n }\n }\n\n if (!best) {\n return { anchor: 'end', x: box.width, y: label.height };\n }\n\n const { anchor, x, y } = best.slot;\n\n return { anchor, x, y };\n};\n","import type { ChartGeometry, ChartPoint } from './chart-scale';\n\nexport const TRANSITION_SAMPLES = 120;\nexport const TRANSITION_DURATION = 260;\n\nexport type Vertex = { x: number; y: number };\n\nexport type ShapeTransition = { xs: number[]; from: number[]; to: number[] };\n\nexport const easeOutQuint = (t: number): number => 1 - (1 - t) ** 5;\n\nexport const durationFrom = (value: string): number => {\n const match = /^\\s*([\\d.]+)(ms|s)\\s*$/.exec(value);\n const duration = match ? Number(match[1]) * (match[2] === 's' ? 1000 : 1) : Number.NaN;\n\n return Number.isFinite(duration) ? duration : TRANSITION_DURATION;\n};\n\nexport const sameSeries = (a: readonly ChartPoint[], b: readonly ChartPoint[] | null): boolean =>\n a === b ||\n (b !== null &&\n a.length === b.length &&\n a.every((point, index) => point.t === b[index]!.t && point.v === b[index]!.v));\n\nconst monotoneTangents = (xs: readonly number[], ys: readonly number[]): number[] => {\n const n = xs.length;\n const slopes: number[] = [];\n\n for (let i = 0; i < n - 1; i++) {\n const dx = xs[i + 1]! - xs[i]!;\n\n slopes.push(dx === 0 ? 0 : (ys[i + 1]! - ys[i]!) / dx);\n }\n\n const tangents = new Array<number>(n).fill(0);\n tangents[0] = slopes[0]!;\n tangents[n - 1] = slopes[n - 2]!;\n\n for (let i = 1; i < n - 1; i++) {\n const a = slopes[i - 1]!;\n const b = slopes[i]!;\n\n tangents[i] = a * b <= 0 ? 0 : (a + b) / 2;\n }\n\n for (let i = 0; i < n - 1; i++) {\n const slope = slopes[i]!;\n\n if (slope === 0) {\n tangents[i] = 0;\n tangents[i + 1] = 0;\n continue;\n }\n\n const a = tangents[i]! / slope;\n const b = tangents[i + 1]! / slope;\n const s = a * a + b * b;\n\n if (s > 9) {\n const t = 3 / Math.sqrt(s);\n\n tangents[i] = t * a * slope;\n tangents[i + 1] = t * b * slope;\n }\n }\n\n return tangents;\n};\n\nconst sampleMonotone = (points: readonly Vertex[], sampleXs: readonly number[]): number[] => {\n const xs = points.map((point) => point.x);\n const ys = points.map((point) => point.y);\n const tangents = monotoneTangents(xs, ys);\n\n let segment = 0;\n\n return sampleXs.map((x) => {\n while (segment < xs.length - 2 && x > xs[segment + 1]!) {\n segment++;\n }\n\n const x0 = xs[segment]!;\n const x1 = xs[segment + 1]!;\n const dx = x1 - x0;\n const f = dx === 0 ? 0 : (x - x0) / dx;\n const f2 = f * f;\n const f3 = f2 * f;\n const y0 = ys[segment]!;\n const y1 = ys[segment + 1]!;\n const m0 = tangents[segment]!;\n const m1 = tangents[segment + 1]!;\n\n return (2 * f3 - 3 * f2 + 1) * y0 + (f3 - 2 * f2 + f) * m0 * dx + (-2 * f3 + 3 * f2) * y1 + (f3 - f2) * m1 * dx;\n });\n};\n\nexport const polyline = (xs: readonly number[], ys: readonly number[]): string =>\n xs.map((x, index) => `${index === 0 ? 'M' : 'L'}${x.toFixed(2)},${ys[index]!.toFixed(2)}`).join(' ');\n\nexport const shapeTransition = (from: readonly Vertex[], to: readonly Vertex[]): ShapeTransition => {\n const left = to[0]!.x;\n const right = to.at(-1)!.x;\n const xs = Array.from(\n { length: TRANSITION_SAMPLES },\n (_, index) => left + ((right - left) * index) / (TRANSITION_SAMPLES - 1),\n );\n\n return { xs, from: sampleMonotone(from, xs), to: sampleMonotone(to, xs) };\n};\n\nexport const shapeAt = (transition: ShapeTransition, progress: number): number[] =>\n transition.from.map((fromY, index) => fromY + (transition.to[index]! - fromY) * progress);\n\nexport const animateShape = (\n from: readonly Vertex[],\n to: readonly Vertex[],\n duration: number,\n draw: (shape: Vertex[], line: string) => void,\n done: () => void,\n): (() => void) => {\n const transition = shapeTransition(from, to);\n const start = performance.now();\n let frame = 0;\n\n const step = (now: number): void => {\n const t = Math.min(1, Math.max(0, (now - start) / duration));\n\n if (t === 1) {\n done();\n return;\n }\n\n const ys = shapeAt(transition, easeOutQuint(t));\n\n draw(\n transition.xs.map((x, index) => ({ x, y: ys[index]! })),\n polyline(transition.xs, ys),\n );\n frame = requestAnimationFrame(step);\n };\n\n frame = requestAnimationFrame(step);\n\n return () => cancelAnimationFrame(frame);\n};\n\nexport type ShapeView = {\n hold: (geometry: ChartGeometry | null) => void;\n draw: (line: string, end: Vertex) => void;\n};\n\nexport type ShapeMotionOptions = { reduced: boolean; duration: () => number; rangeKey: string | null };\n\nexport class ShapeMotion {\n readonly #view: ShapeView;\n #points: readonly ChartPoint[] | null = null;\n #rangeKey: string | null = null;\n #target: ChartGeometry | null = null;\n #held: ChartGeometry | null = null;\n #drawn: readonly Vertex[] | null = null;\n #stop: (() => void) | null = null;\n\n constructor(view: ShapeView) {\n this.#view = view;\n }\n\n follow(points: readonly ChartPoint[], geometry: ChartGeometry | null, options: ShapeMotionOptions): void {\n const newSeries = !sameSeries(points, this.#points);\n const newRange = options.rangeKey === null || options.rangeKey !== this.#rangeKey;\n\n this.#points = points;\n if (newSeries) {\n this.#rangeKey = options.rangeKey;\n }\n\n if (this.#stop && !newSeries && !options.reduced && geometry?.line === this.#target?.line) {\n this.#target = geometry;\n return;\n }\n\n const from = this.#drawn;\n const held = this.#held ?? this.#target;\n\n this.#target = geometry;\n this.stop();\n\n if (\n !newSeries ||\n !newRange ||\n !geometry ||\n !from ||\n from.length < 2 ||\n geometry.points.length < 2 ||\n options.reduced\n ) {\n this.#settle(geometry);\n return;\n }\n\n const duration = options.duration();\n\n if (duration <= 0) {\n this.#settle(geometry);\n return;\n }\n\n this.#hold(held);\n this.#stop = animateShape(\n from,\n geometry.points,\n duration,\n (shape, line) => this.#draw(shape, line, shape.at(-1)!),\n () => this.#settle(geometry),\n );\n }\n\n stop(): void {\n this.#stop?.();\n this.#stop = null;\n }\n\n #hold(geometry: ChartGeometry | null): void {\n this.#held = geometry;\n this.#view.hold(geometry);\n }\n\n #settle(geometry: ChartGeometry | null): void {\n this.#stop = null;\n this.#hold(null);\n this.#drawn = null;\n\n if (geometry) {\n this.#draw(geometry.points, geometry.line, geometry.end);\n }\n }\n\n #draw(shape: readonly Vertex[], line: string, end: Vertex): void {\n this.#drawn = shape;\n this.#view.draw(line, end);\n }\n}\n","import { DestroyRef, type Signal, inject, signal } from '@angular/core';\n\nconst WIDE_QUERY = '(min-width: 64rem)';\n\nexport const wideViewport = (): Signal<boolean> => {\n const query = typeof matchMedia === 'function' ? matchMedia(WIDE_QUERY) : null;\n const wide = signal(query?.matches ?? false);\n const onChange = (event: { matches: boolean }): void => wide.set(event.matches);\n\n if (query) {\n query.onchange = onChange;\n inject(DestroyRef).onDestroy(() => (query.onchange = null));\n }\n\n return wide;\n};\n","import {\n Component,\n DestroyRef,\n ElementRef,\n afterNextRender,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\n\nimport { injectReducedMotion } from '@joanroucoux/cairn-ui/motion';\n\nimport { axisTicks, tickLabels } from './internal/chart-axis';\nimport { navigateIndex, nearestPointIndex } from './internal/chart-interaction';\nimport {\n type AxisTicks,\n DEFAULT_HEIGHT,\n DEFAULT_WIDTH,\n START_LABEL_HEIGHT,\n deltaTone,\n identityDelta,\n identityTime,\n identityValue,\n parseAxisTicks,\n plotHeightFor,\n plotPaddingFor,\n startLabelBaseline,\n tooltipClassesFor,\n tooltipPlacement,\n} from './internal/chart-layout';\nimport { type ChartGeometry, type ChartPoint, type PlottedPoint, buildGeometry } from './internal/chart-scale';\nimport { observeSize } from './internal/observe-size';\nimport { placeStartLabel } from './internal/start-label';\nimport { ShapeMotion, durationFrom } from './internal/transition';\nimport { wideViewport } from './internal/viewport';\n\nexport type { AxisTicks, ChartPoint };\nexport type { TooltipSize } from './internal/chart-layout';\n\ntype PlotRef = ElementRef<SVGSVGElement>;\ntype LineRef = ElementRef<SVGPathElement>;\ntype EndRef = ElementRef<SVGCircleElement>;\n\n/**\n * Value over time: a monotone curve with a dashed line at the starting value and a tooltip.\n *\n * Axis labels are never repeated: a tick whose `axisFormat` text equals the previous drawn label is\n * not rendered. The first tick always is, so only the last edge label can drop. With `axisTicks=\"3\"`\n * only the first, middle and last ticks count; with `auto` every tick counts from `sm` up and the\n * three core ticks below it. Tick positions are unchanged.\n *\n * A new series interpolates from the drawn curve, fading the start label and the dashed line. With\n * `rangeKey` bound, only a series that comes with a new key does so: a new series under the same key\n * (a reload after a buy) is drawn at once, with no fade. The key may change before its series arrives.\n *\n * @example\n * <ui-line-chart [points]=\"points\" label=\"Net worth over one month\" startLabel=\"Since\" [valueFormat]=\"formatEur\" />\n */\n@Component({\n selector: 'ui-line-chart',\n template: `\n <div class=\"relative h-full\">\n <svg\n #svgRef\n class=\"block h-full w-full touch-pan-y overflow-visible\"\n role=\"img\"\n [attr.aria-label]=\"label()\"\n [attr.height]=\"effectiveHeight()\"\n [attr.tabindex]=\"sparkline() ? null : 0\"\n [attr.viewBox]=\"'0 0 ' + effectiveWidth() + ' ' + effectiveHeight()\"\n [attr.width]=\"effectiveWidth()\"\n (keydown)=\"onKeydown($event)\"\n (pointerleave)=\"onPointerLeave()\"\n (pointermove)=\"onPointerMove($event)\"\n >\n @if (shown(); as shape) {\n <path\n #lineRef\n class=\"stroke-(--foreground)\"\n data-chart-line\n fill=\"none\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [attr.d]=\"shape.line\"\n [attr.stroke-width]=\"sparkline() ? 1.5 : 2\"\n />\n\n @if (!sparkline()) {\n <line\n class=\"stroke-(--border) transition-opacity ease-(--ease-out)\"\n data-chart-start-line\n stroke-dasharray=\"3 4\"\n stroke-width=\"1\"\n x1=\"0\"\n [attr.x2]=\"effectiveWidth()\"\n [attr.y1]=\"shape.start.y\"\n [attr.y2]=\"shape.start.y\"\n [class]=\"startFade()\"\n />\n\n @if (startLabelInfo(); as info) {\n <text\n class=\"text-caption fill-(--subtle-foreground) tabular-nums transition-opacity ease-(--ease-out)\"\n data-chart-start-label\n [attr.text-anchor]=\"info.placement.anchor\"\n [attr.x]=\"info.placement.x\"\n [attr.y]=\"info.placement.y\"\n [class]=\"startFade()\"\n >\n {{ info.label }}\n </text>\n }\n\n <circle\n #endRef\n class=\"fill-(--foreground) stroke-(--card) [paint-order:stroke]\"\n data-chart-end\n r=\"4\"\n stroke-width=\"6\"\n [attr.cx]=\"shape.end.x\"\n [attr.cy]=\"shape.end.y\"\n />\n\n @for (tick of ticks(); track tick.t; let index = $index; let first = $first; let last = $last) {\n @if (tickTexts()[index]; as label) {\n <text\n class=\"text-caption fill-(--subtle-foreground) tabular-nums\"\n data-chart-axis-tick\n [attr.text-anchor]=\"first ? 'start' : last ? 'end' : 'middle'\"\n [attr.x]=\"tick.x\"\n [attr.y]=\"effectiveHeight() - 4\"\n [class]=\"label.classes\"\n >\n {{ label.text }}\n </text>\n }\n }\n\n @if (active(); as point) {\n <line\n class=\"stroke-(--border)\"\n data-chart-crosshair\n stroke-width=\"1\"\n y1=\"0\"\n [attr.x1]=\"point.x\"\n [attr.x2]=\"point.x\"\n [attr.y2]=\"plotHeight()\"\n />\n <circle\n class=\"fill-(--foreground) stroke-(--card) [paint-order:stroke]\"\n data-chart-active\n r=\"5\"\n stroke-width=\"6\"\n [attr.cx]=\"point.x\"\n [attr.cy]=\"point.y\"\n />\n }\n }\n }\n </svg>\n\n @if (active(); as point) {\n <div\n class=\"rounded-container pointer-events-none absolute bg-(--elevated) py-2 whitespace-nowrap [font-variant-numeric:var(--numeric)] shadow-[0_4px_16px_rgb(0_0_0/0.12),inset_0_0_0_1px_var(--border)]\"\n data-testid=\"chart-tooltip\"\n role=\"status\"\n [class]=\"tooltipClasses().box\"\n [style]=\"tooltipStyle(point)\"\n >\n <p class=\"font-medium text-(--foreground)\" [class]=\"tooltipClasses().value\">\n {{ tooltipFormat()?.(point) ?? valueFormat()(point.v) }}\n </p>\n @if (tooltipDelta()) {\n <p data-chart-delta [class]=\"deltaClasses(point)\">{{ deltaFormat()(deltaFor(point)) }}</p>\n }\n <p class=\"text-caption text-(--subtle-foreground)\" data-chart-date>{{ timeFormat()(point.t) }}</p>\n </div>\n }\n @if (points().length > 0) {\n <div class=\"sr-only\">\n <table>\n <caption [textContent]=\"label()\"></caption>\n <thead>\n <tr>\n <th scope=\"col\">{{ timeColumnLabel() }}</th>\n <th scope=\"col\">{{ valueColumnLabel() }}</th>\n </tr>\n </thead>\n <tbody>\n @for (point of points(); track point.t) {\n <tr>\n <td>{{ timeFormat()(point.t) }}</td>\n <td>{{ valueFormat()(point.v) }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n `,\n host: {\n class: 'block h-full',\n },\n})\nexport class UiLineChart {\n readonly points = input.required<ChartPoint[]>();\n readonly label = input.required<string>();\n readonly valueFormat = input<(value: number) => string>(identityValue);\n readonly tooltipFormat = input<(point: ChartPoint) => string>();\n readonly deltaFormat = input<(delta: number) => string>(identityDelta);\n readonly timeFormat = input<(time: number) => string>(identityTime);\n readonly axisFormat = input<(time: number) => string>(identityTime);\n readonly startLabel = input('');\n readonly timeColumnLabel = input('Time');\n readonly valueColumnLabel = input('Value');\n readonly sparkline = input(false, { transform: booleanAttribute });\n readonly tooltip = input<'compact' | 'large' | 'auto'>('compact');\n readonly tooltipDelta = input(true, { transform: booleanAttribute });\n readonly axisGap = input<number | 'auto'>(12);\n readonly axisTicks = input<AxisTicks, AxisTicks | string>('auto', { transform: parseAxisTicks });\n readonly rangeKey = input<string | null>(null);\n\n #destroyRef = inject(DestroyRef);\n #host = inject<ElementRef<HTMLElement>>(ElementRef);\n #wide = wideViewport();\n #reducedMotion = injectReducedMotion();\n #motion = new ShapeMotion({\n hold: (geometry) => {\n this.held.set(geometry);\n this.activeIndex.update((index) => (geometry ? null : index));\n },\n draw: (line, end) => {\n this.lineRef()?.nativeElement.setAttribute('d', line);\n this.endRef()?.nativeElement.setAttribute('cx', String(end.x));\n this.endRef()?.nativeElement.setAttribute('cy', String(end.y));\n },\n });\n\n protected readonly svgRef = viewChild.required<PlotRef>('svgRef');\n protected readonly lineRef = viewChild<LineRef>('lineRef');\n protected readonly endRef = viewChild<EndRef>('endRef');\n protected readonly activeIndex = signal<number | null>(null);\n protected readonly held = signal<ChartGeometry | null>(null);\n protected readonly measuredSize = signal<{ width: number; height: number } | null>(null);\n\n protected readonly effectiveWidth = computed(() => this.measuredSize()?.width ?? DEFAULT_WIDTH);\n protected readonly effectiveHeight = computed(() => this.measuredSize()?.height ?? DEFAULT_HEIGHT);\n\n protected readonly plotHeight = computed(() =>\n plotHeightFor(this.effectiveHeight(), this.sparkline(), this.axisGap(), this.#wide()),\n );\n\n protected readonly tooltipStyle = (point: PlottedPoint): string => tooltipPlacement(point.x / this.effectiveWidth());\n\n protected readonly tooltipClasses = computed(() => tooltipClassesFor(this.tooltip(), this.#wide()));\n\n protected readonly geometry = computed(() => {\n const plotHeight = this.plotHeight();\n const padding = plotPaddingFor(plotHeight, this.sparkline());\n\n return buildGeometry(this.points(), this.effectiveWidth(), plotHeight, { x: 0, top: padding, bottom: padding });\n });\n\n protected readonly shown = computed(() => this.held() ?? this.geometry());\n\n protected readonly startFade = computed(() =>\n this.held() ? 'opacity-0 duration-(--duration-exit)' : 'duration-(--duration-fast)',\n );\n\n protected readonly ticks = computed(() => axisTicks(this.geometry()!.points));\n\n protected readonly tickTexts = computed(() => tickLabels(this.ticks(), this.axisFormat(), this.axisTicks()));\n\n protected readonly active = computed<PlottedPoint | null>(() => {\n const geometry = this.geometry();\n const index = this.activeIndex();\n\n return geometry && index !== null && !this.held() ? (geometry.points[index] as PlottedPoint) : null;\n });\n\n protected readonly startLabelInfo = computed(() => {\n const text = this.startLabel();\n const geometry = this.shown();\n\n if (!text || !geometry) {\n return null;\n }\n\n const label = `${text} ${this.valueFormat()(geometry.points[0]!.v)}`;\n const size = { width: label.length * 0.56 * 12 + 8, height: START_LABEL_HEIGHT };\n const placement = placeStartLabel(\n geometry.points,\n geometry.start.y,\n { width: this.effectiveWidth(), height: this.plotHeight() },\n size,\n );\n\n return { label, placement: { ...placement, y: startLabelBaseline(placement.y) } };\n });\n\n #renderRef = afterNextRender(() => {\n this.#destroyRef.onDestroy(() => this.#renderRef.destroy());\n observeSize(this.svgRef().nativeElement, this.#destroyRef, (size) => this.measuredSize.set(size));\n });\n\n constructor() {\n effect(() => {\n const points = this.points();\n const geometry = this.geometry();\n const reduced = this.#reducedMotion();\n\n untracked(() =>\n this.#motion.follow(points, geometry, {\n reduced,\n rangeKey: this.rangeKey(),\n duration: () => durationFrom(getComputedStyle(this.#host.nativeElement).getPropertyValue('--duration-base')),\n }),\n );\n });\n\n this.#destroyRef.onDestroy(() => this.#motion.stop());\n }\n\n protected deltaFor(point: PlottedPoint): number {\n return point.v - this.points()[0]!.v;\n }\n\n protected deltaClasses(point: PlottedPoint): string {\n return `${this.tooltipClasses().delta} ${deltaTone(this.deltaFor(point))}`;\n }\n\n protected onPointerMove(event: PointerEvent): void {\n const geometry = this.geometry();\n\n if (this.sparkline() || !geometry || geometry.points.length === 0) {\n return;\n }\n\n const rect = this.svgRef().nativeElement.getBoundingClientRect();\n const ratio = rect.width === 0 ? 1 : this.effectiveWidth() / rect.width;\n const x = (event.clientX - rect.left) * ratio;\n\n this.activeIndex.set(nearestPointIndex(geometry.points, x));\n }\n\n protected onPointerLeave(): void {\n this.activeIndex.set(null);\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const geometry = this.geometry();\n\n if (this.sparkline() || !geometry || geometry.points.length === 0) {\n return;\n }\n\n const navigation = navigateIndex(event.key, this.activeIndex(), geometry.points.length - 1);\n\n if (!navigation) {\n return;\n }\n\n if (navigation.preventDefault) {\n event.preventDefault();\n }\n\n this.activeIndex.set(navigation.index);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,241 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, booleanAttribute, inject, ElementRef, computed, Directive, numberAttribute, signal, contentChildren, Component } from '@angular/core';
3
+
4
+ const MENU_CLASSES = 'm-0 min-w-44 p-1 rounded-container bg-(--elevated) shadow-[0_8px_24px_rgb(0_0_0/0.16),inset_0_0_0_1px_var(--border)] text-(--foreground) transition-[opacity,scale,overlay,display] transition-discrete duration-(--duration-fast) not-open:duration-[120ms] ease-out starting:open:opacity-0 starting:open:scale-(--enter-scale) opacity-0 scale-(--enter-scale) open:opacity-100 open:scale-100';
5
+ const SHEET_CLASSES = 'max-lg:fixed max-lg:inset-x-4 max-lg:top-auto max-lg:w-auto max-lg:bottom-[calc(76px+env(safe-area-inset-bottom))] max-lg:min-w-0 max-lg:p-1.5 max-lg:bg-(--card) max-lg:shadow-[0_12px_32px_rgb(0_0_0/0.2),inset_0_0_0_1px_var(--border)] max-lg:backdrop:bg-[rgb(0_0_0/0.36)] max-lg:transition-[opacity,translate,overlay,display] max-lg:scale-100 max-lg:translate-y-4 max-lg:open:translate-y-0 max-lg:starting:open:scale-100 max-lg:starting:open:translate-y-4 max-lg:motion-reduce:translate-y-0 max-lg:motion-reduce:starting:open:translate-y-0';
6
+ const SHEET_ITEM_CLASSES = 'flex w-full items-center gap-3 lg:pointer-fine:gap-2.5 min-h-12 lg:min-h-11 lg:pointer-fine:min-h-9 px-3 lg:pointer-fine:px-2.5 rounded-[calc(var(--radius-container)-6px)] lg:rounded-[calc(var(--radius-container)-4px)] text-body lg:pointer-fine:text-label text-left whitespace-nowrap hover:bg-(--glow) focus-visible:bg-(--glow) active:bg-(--soft) transition-[background-color] duration-(--duration-fast) ease-out outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) [:where(&>svg)]:size-5 [:where(&>svg)]:flex-none lg:[:where(&>svg)]:size-[18px] lg:pointer-fine:[:where(&>svg)]:size-4';
7
+ const ITEM_CLASSES = 'flex w-full items-center gap-3 pointer-fine:gap-2.5 min-h-11 pointer-fine:min-h-9 px-3 pointer-fine:px-2.5 rounded-[calc(var(--radius-container)-4px)] text-body pointer-fine:text-label text-left whitespace-nowrap hover:bg-(--glow) focus-visible:bg-(--glow) active:bg-(--soft) transition-[background-color] duration-(--duration-fast) ease-out outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) [:where(&>svg)]:size-[18px] [:where(&>svg)]:flex-none pointer-fine:[:where(&>svg)]:size-4';
8
+ const nextId = (() => {
9
+ let count = 0;
10
+ return () => `ui-menu-${++count}`;
11
+ })();
12
+ /**
13
+ * One action of a `ui-menu`; `destructive` paints it in `--negative`.
14
+ *
15
+ * @example
16
+ * <button uiMenuItem destructive (click)="remove()">Delete the line</button>
17
+ */
18
+ class UiMenuItem {
19
+ destructive = input(false, { ...(ngDevMode ? { debugName: "destructive" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
20
+ #host = inject(ElementRef).nativeElement;
21
+ #menu = inject(UiMenu);
22
+ classes = computed(() => `${this.#menu.sheet() ? SHEET_ITEM_CLASSES : ITEM_CLASSES}${this.destructive() ? ' text-(--negative)' : ''}`, /* @ts-ignore */
23
+ ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
24
+ focus() {
25
+ this.#host.focus();
26
+ }
27
+ hasFocus() {
28
+ return this.#host === document.activeElement;
29
+ }
30
+ onClick() {
31
+ this.#menu.close();
32
+ }
33
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Directive });
34
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: UiMenuItem, isStandalone: true, selector: "button[uiMenuItem]", inputs: { destructive: { classPropertyName: "destructive", publicName: "destructive", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menuitem", "tabindex": "-1" }, listeners: { "click": "onClick()" }, properties: { "class": "classes()" } }, ngImport: i0 });
35
+ }
36
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMenuItem, decorators: [{
37
+ type: Directive,
38
+ args: [{
39
+ selector: 'button[uiMenuItem]',
40
+ host: {
41
+ role: 'menuitem',
42
+ tabindex: '-1',
43
+ '[class]': 'classes()',
44
+ '(click)': 'onClick()',
45
+ },
46
+ }]
47
+ }], propDecorators: { destructive: [{ type: i0.Input, args: [{ isSignal: true, alias: "destructive", required: false }] }] } });
48
+ /**
49
+ * Secondary actions menu, opened from its trigger through the native Popover API. With `sheet`, below
50
+ * 64rem it opens as a bottom action sheet above the tab bar instead of beside its trigger, and
51
+ * `heading` names what the actions apply to. `width` fixes the outer popover width in pixels (the sheet
52
+ * always spans the screen below 64rem); without it the menu fits its content.
53
+ *
54
+ * @example
55
+ * <button ui-button size="icon" aria-label="More" [uiMenuTrigger]="menu">...</button>
56
+ * <ui-menu #menu label="Line actions">
57
+ * <button uiMenuItem (click)="edit()">Edit</button>
58
+ * <button uiMenuItem destructive (click)="remove()">Delete the line</button>
59
+ * </ui-menu>
60
+ */
61
+ class UiMenu {
62
+ label = input.required(/* @ts-ignore */
63
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
64
+ sheet = input(false, { ...(ngDevMode ? { debugName: "sheet" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
65
+ heading = input(/* @ts-ignore */
66
+ ...(ngDevMode ? [undefined, { debugName: "heading" }] : /* istanbul ignore next */ []));
67
+ width = input(undefined, { ...(ngDevMode ? { debugName: "width" } : /* istanbul ignore next */ {}), transform: numberAttribute });
68
+ menuId = nextId();
69
+ isOpen = signal(false, /* @ts-ignore */
70
+ ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
71
+ hasWidth = computed(() => Number.isFinite(this.width()), /* @ts-ignore */
72
+ ...(ngDevMode ? [{ debugName: "hasWidth" }] : /* istanbul ignore next */ []));
73
+ widthVar = computed(() => (this.hasWidth() ? `${this.width()}px` : null), /* @ts-ignore */
74
+ ...(ngDevMode ? [{ debugName: "widthVar" }] : /* istanbul ignore next */ []));
75
+ classes = computed(() => {
76
+ const width = !this.hasWidth() ? '' : this.sheet() ? ' lg:w-(--ui-menu-width)' : ' w-(--ui-menu-width)';
77
+ return `${MENU_CLASSES}${this.sheet() ? ` ${SHEET_CLASSES}` : ''}${width}`;
78
+ }, /* @ts-ignore */
79
+ ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
80
+ items = contentChildren(UiMenuItem, /* @ts-ignore */
81
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
82
+ #host = inject(ElementRef).nativeElement;
83
+ #trigger = null;
84
+ open(trigger) {
85
+ this.#trigger = trigger;
86
+ this.isOpen.set(true);
87
+ if (typeof this.#host.showPopover === 'function') {
88
+ this.#host.showPopover();
89
+ }
90
+ if (this.#isSheet()) {
91
+ this.#host.style.position = '';
92
+ this.#host.style.top = '';
93
+ this.#host.style.left = '';
94
+ this.#host.style.right = '';
95
+ this.#host.style.bottom = '';
96
+ }
97
+ else {
98
+ this.#position(trigger);
99
+ }
100
+ this.items()[0]?.focus();
101
+ }
102
+ close() {
103
+ const wasOpen = this.isOpen();
104
+ this.#applyClosed();
105
+ if (wasOpen && typeof this.#host.hidePopover === 'function') {
106
+ this.#host.hidePopover();
107
+ }
108
+ }
109
+ #applyClosed() {
110
+ this.isOpen.set(false);
111
+ this.#trigger?.focus();
112
+ this.#trigger = null;
113
+ }
114
+ onToggle(event) {
115
+ if (event.newState === 'closed') {
116
+ this.#applyClosed();
117
+ }
118
+ }
119
+ onKeydown(event) {
120
+ if (event.key === 'Tab' || event.key === 'Escape') {
121
+ event.preventDefault();
122
+ this.close();
123
+ return;
124
+ }
125
+ const items = this.items();
126
+ const currentIndex = items.findIndex((item) => item.hasFocus());
127
+ const lastIndex = items.length - 1;
128
+ let nextIndex;
129
+ switch (event.key) {
130
+ case 'ArrowDown':
131
+ nextIndex = currentIndex >= lastIndex ? 0 : currentIndex + 1;
132
+ break;
133
+ case 'ArrowUp':
134
+ nextIndex = currentIndex <= 0 ? lastIndex : currentIndex - 1;
135
+ break;
136
+ case 'Home':
137
+ nextIndex = 0;
138
+ break;
139
+ case 'End':
140
+ nextIndex = lastIndex;
141
+ break;
142
+ }
143
+ if (nextIndex === undefined) {
144
+ return;
145
+ }
146
+ event.preventDefault();
147
+ items[nextIndex]?.focus();
148
+ }
149
+ #isSheet() {
150
+ return this.sheet() && typeof window.matchMedia === 'function' && !window.matchMedia('(min-width: 64rem)').matches;
151
+ }
152
+ #position(trigger) {
153
+ const margin = 8;
154
+ const triggerRect = trigger.getBoundingClientRect();
155
+ const menuRect = { width: this.#host.offsetWidth, height: this.#host.offsetHeight };
156
+ const fitsBelow = window.innerHeight - triggerRect.bottom >= menuRect.height + margin;
157
+ const top = fitsBelow ? triggerRect.bottom + 4 : Math.max(margin, triggerRect.top - menuRect.height - 4);
158
+ const left = Math.min(Math.max(triggerRect.right - menuRect.width, margin), window.innerWidth - menuRect.width - margin);
159
+ this.#host.style.position = 'fixed';
160
+ this.#host.style.top = `${Math.min(top, window.innerHeight - menuRect.height - margin)}px`;
161
+ this.#host.style.left = `${left}px`;
162
+ this.#host.style.right = 'auto';
163
+ this.#host.style.bottom = 'auto';
164
+ this.#host.style.transformOrigin = fitsBelow ? 'top right' : 'bottom right';
165
+ }
166
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
167
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiMenu, isStandalone: true, selector: "ui-menu", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, sheet: { classPropertyName: "sheet", publicName: "sheet", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menu", "popover": "auto" }, listeners: { "toggle": "onToggle($event)", "keydown": "onKeydown($event)" }, properties: { "id": "menuId", "style.--ui-menu-width": "widthVar()", "class": "classes()", "attr.aria-label": "label()" } }, queries: [{ propertyName: "items", predicate: UiMenuItem, isSignal: true }], ngImport: i0, template: `
168
+ @if (sheet() && heading()) {
169
+ <div aria-hidden="true" class="text-label px-3 pt-2 pb-1.5 leading-[17px] text-(--muted-foreground) lg:hidden">
170
+ {{ heading() }}
171
+ </div>
172
+ }
173
+ <ng-content />
174
+ `, isInline: true });
175
+ }
176
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMenu, decorators: [{
177
+ type: Component,
178
+ args: [{
179
+ selector: 'ui-menu',
180
+ template: `
181
+ @if (sheet() && heading()) {
182
+ <div aria-hidden="true" class="text-label px-3 pt-2 pb-1.5 leading-[17px] text-(--muted-foreground) lg:hidden">
183
+ {{ heading() }}
184
+ </div>
185
+ }
186
+ <ng-content />
187
+ `,
188
+ host: {
189
+ role: 'menu',
190
+ popover: 'auto',
191
+ '[id]': 'menuId',
192
+ '[style.--ui-menu-width]': 'widthVar()',
193
+ '[class]': 'classes()',
194
+ '[attr.aria-label]': 'label()',
195
+ '(toggle)': 'onToggle($event)',
196
+ '(keydown)': 'onKeydown($event)',
197
+ },
198
+ }]
199
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], sheet: [{ type: i0.Input, args: [{ isSignal: true, alias: "sheet", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => UiMenuItem), { isSignal: true }] }] } });
200
+ /**
201
+ * Opens a `ui-menu` from a trigger element and wires `aria-haspopup`, `aria-expanded` and
202
+ * `aria-controls` on it.
203
+ *
204
+ * @example
205
+ * <button ui-button size="icon" aria-label="More" [uiMenuTrigger]="menu">...</button>
206
+ */
207
+ class UiMenuTrigger {
208
+ uiMenuTrigger = input.required(/* @ts-ignore */
209
+ ...(ngDevMode ? [{ debugName: "uiMenuTrigger" }] : /* istanbul ignore next */ []));
210
+ #host = inject(ElementRef).nativeElement;
211
+ toggle() {
212
+ const menu = this.uiMenuTrigger();
213
+ if (menu.isOpen()) {
214
+ menu.close();
215
+ }
216
+ else {
217
+ menu.open(this.#host);
218
+ }
219
+ }
220
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
221
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: UiMenuTrigger, isStandalone: true, selector: "[uiMenuTrigger]", inputs: { uiMenuTrigger: { classPropertyName: "uiMenuTrigger", publicName: "uiMenuTrigger", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "aria-haspopup": "menu" }, listeners: { "click": "toggle()" }, properties: { "attr.aria-expanded": "uiMenuTrigger().isOpen()", "attr.aria-controls": "uiMenuTrigger().menuId" } }, ngImport: i0 });
222
+ }
223
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMenuTrigger, decorators: [{
224
+ type: Directive,
225
+ args: [{
226
+ selector: '[uiMenuTrigger]',
227
+ host: {
228
+ 'aria-haspopup': 'menu',
229
+ '[attr.aria-expanded]': 'uiMenuTrigger().isOpen()',
230
+ '[attr.aria-controls]': 'uiMenuTrigger().menuId',
231
+ '(click)': 'toggle()',
232
+ },
233
+ }]
234
+ }], propDecorators: { uiMenuTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "uiMenuTrigger", required: true }] }] } });
235
+
236
+ /**
237
+ * Generated bundle index. Do not edit.
238
+ */
239
+
240
+ export { UiMenu, UiMenuItem, UiMenuTrigger };
241
+ //# sourceMappingURL=joanroucoux-cairn-ui-menu.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joanroucoux-cairn-ui-menu.mjs","sources":["../../../projects/ui/menu/menu.ts","../../../projects/ui/menu/joanroucoux-cairn-ui-menu.ts"],"sourcesContent":["import {\n Component,\n Directive,\n ElementRef,\n booleanAttribute,\n computed,\n contentChildren,\n inject,\n input,\n numberAttribute,\n signal,\n} from '@angular/core';\n\nconst MENU_CLASSES =\n 'm-0 min-w-44 p-1 rounded-container bg-(--elevated) shadow-[0_8px_24px_rgb(0_0_0/0.16),inset_0_0_0_1px_var(--border)] text-(--foreground) transition-[opacity,scale,overlay,display] transition-discrete duration-(--duration-fast) not-open:duration-[120ms] ease-out starting:open:opacity-0 starting:open:scale-(--enter-scale) opacity-0 scale-(--enter-scale) open:opacity-100 open:scale-100';\n\nconst SHEET_CLASSES =\n 'max-lg:fixed max-lg:inset-x-4 max-lg:top-auto max-lg:w-auto max-lg:bottom-[calc(76px+env(safe-area-inset-bottom))] max-lg:min-w-0 max-lg:p-1.5 max-lg:bg-(--card) max-lg:shadow-[0_12px_32px_rgb(0_0_0/0.2),inset_0_0_0_1px_var(--border)] max-lg:backdrop:bg-[rgb(0_0_0/0.36)] max-lg:transition-[opacity,translate,overlay,display] max-lg:scale-100 max-lg:translate-y-4 max-lg:open:translate-y-0 max-lg:starting:open:scale-100 max-lg:starting:open:translate-y-4 max-lg:motion-reduce:translate-y-0 max-lg:motion-reduce:starting:open:translate-y-0';\n\nconst SHEET_ITEM_CLASSES =\n 'flex w-full items-center gap-3 lg:pointer-fine:gap-2.5 min-h-12 lg:min-h-11 lg:pointer-fine:min-h-9 px-3 lg:pointer-fine:px-2.5 rounded-[calc(var(--radius-container)-6px)] lg:rounded-[calc(var(--radius-container)-4px)] text-body lg:pointer-fine:text-label text-left whitespace-nowrap hover:bg-(--glow) focus-visible:bg-(--glow) active:bg-(--soft) transition-[background-color] duration-(--duration-fast) ease-out outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) [:where(&>svg)]:size-5 [:where(&>svg)]:flex-none lg:[:where(&>svg)]:size-[18px] lg:pointer-fine:[:where(&>svg)]:size-4';\n\nconst ITEM_CLASSES =\n 'flex w-full items-center gap-3 pointer-fine:gap-2.5 min-h-11 pointer-fine:min-h-9 px-3 pointer-fine:px-2.5 rounded-[calc(var(--radius-container)-4px)] text-body pointer-fine:text-label text-left whitespace-nowrap hover:bg-(--glow) focus-visible:bg-(--glow) active:bg-(--soft) transition-[background-color] duration-(--duration-fast) ease-out outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) [:where(&>svg)]:size-[18px] [:where(&>svg)]:flex-none pointer-fine:[:where(&>svg)]:size-4';\n\nconst nextId = (() => {\n let count = 0;\n\n return () => `ui-menu-${++count}`;\n})();\n\n/**\n * One action of a `ui-menu`; `destructive` paints it in `--negative`.\n *\n * @example\n * <button uiMenuItem destructive (click)=\"remove()\">Delete the line</button>\n */\n@Directive({\n selector: 'button[uiMenuItem]',\n host: {\n role: 'menuitem',\n tabindex: '-1',\n '[class]': 'classes()',\n '(click)': 'onClick()',\n },\n})\nexport class UiMenuItem {\n readonly destructive = input(false, { transform: booleanAttribute });\n\n readonly #host = inject<ElementRef<HTMLButtonElement>>(ElementRef).nativeElement;\n readonly #menu = inject(UiMenu);\n\n protected readonly classes = computed(\n () => `${this.#menu.sheet() ? SHEET_ITEM_CLASSES : ITEM_CLASSES}${this.destructive() ? ' text-(--negative)' : ''}`,\n );\n\n focus(): void {\n this.#host.focus();\n }\n\n hasFocus(): boolean {\n return this.#host === document.activeElement;\n }\n\n protected onClick(): void {\n this.#menu.close();\n }\n}\n\n/**\n * Secondary actions menu, opened from its trigger through the native Popover API. With `sheet`, below\n * 64rem it opens as a bottom action sheet above the tab bar instead of beside its trigger, and\n * `heading` names what the actions apply to. `width` fixes the outer popover width in pixels (the sheet\n * always spans the screen below 64rem); without it the menu fits its content.\n *\n * @example\n * <button ui-button size=\"icon\" aria-label=\"More\" [uiMenuTrigger]=\"menu\">...</button>\n * <ui-menu #menu label=\"Line actions\">\n * <button uiMenuItem (click)=\"edit()\">Edit</button>\n * <button uiMenuItem destructive (click)=\"remove()\">Delete the line</button>\n * </ui-menu>\n */\n@Component({\n selector: 'ui-menu',\n template: `\n @if (sheet() && heading()) {\n <div aria-hidden=\"true\" class=\"text-label px-3 pt-2 pb-1.5 leading-[17px] text-(--muted-foreground) lg:hidden\">\n {{ heading() }}\n </div>\n }\n <ng-content />\n `,\n host: {\n role: 'menu',\n popover: 'auto',\n '[id]': 'menuId',\n '[style.--ui-menu-width]': 'widthVar()',\n '[class]': 'classes()',\n '[attr.aria-label]': 'label()',\n '(toggle)': 'onToggle($event)',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class UiMenu {\n readonly label = input.required<string>();\n readonly sheet = input(false, { transform: booleanAttribute });\n readonly heading = input<string>();\n readonly width = input<number | undefined, unknown>(undefined, { transform: numberAttribute });\n\n readonly menuId = nextId();\n readonly isOpen = signal(false);\n\n protected readonly hasWidth = computed(() => Number.isFinite(this.width()));\n protected readonly widthVar = computed(() => (this.hasWidth() ? `${this.width()}px` : null));\n protected readonly classes = computed(() => {\n const width = !this.hasWidth() ? '' : this.sheet() ? ' lg:w-(--ui-menu-width)' : ' w-(--ui-menu-width)';\n return `${MENU_CLASSES}${this.sheet() ? ` ${SHEET_CLASSES}` : ''}${width}`;\n });\n protected readonly items = contentChildren(UiMenuItem);\n\n readonly #host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n #trigger: HTMLElement | null = null;\n\n open(trigger: HTMLElement): void {\n this.#trigger = trigger;\n this.isOpen.set(true);\n if (typeof this.#host.showPopover === 'function') {\n this.#host.showPopover();\n }\n if (this.#isSheet()) {\n this.#host.style.position = '';\n this.#host.style.top = '';\n this.#host.style.left = '';\n this.#host.style.right = '';\n this.#host.style.bottom = '';\n } else {\n this.#position(trigger);\n }\n this.items()[0]?.focus();\n }\n\n close(): void {\n const wasOpen = this.isOpen();\n\n this.#applyClosed();\n\n if (wasOpen && typeof this.#host.hidePopover === 'function') {\n this.#host.hidePopover();\n }\n }\n\n #applyClosed(): void {\n this.isOpen.set(false);\n this.#trigger?.focus();\n this.#trigger = null;\n }\n\n protected onToggle(event: Event): void {\n if ((event as ToggleEvent).newState === 'closed') {\n this.#applyClosed();\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n if (event.key === 'Tab' || event.key === 'Escape') {\n event.preventDefault();\n this.close();\n return;\n }\n\n const items = this.items();\n const currentIndex = items.findIndex((item) => item.hasFocus());\n const lastIndex = items.length - 1;\n\n let nextIndex: number | undefined;\n switch (event.key) {\n case 'ArrowDown':\n nextIndex = currentIndex >= lastIndex ? 0 : currentIndex + 1;\n break;\n case 'ArrowUp':\n nextIndex = currentIndex <= 0 ? lastIndex : currentIndex - 1;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = lastIndex;\n break;\n }\n\n if (nextIndex === undefined) {\n return;\n }\n event.preventDefault();\n items[nextIndex]?.focus();\n }\n\n #isSheet(): boolean {\n return this.sheet() && typeof window.matchMedia === 'function' && !window.matchMedia('(min-width: 64rem)').matches;\n }\n\n #position(trigger: HTMLElement): void {\n const margin = 8;\n const triggerRect = trigger.getBoundingClientRect();\n const menuRect = { width: this.#host.offsetWidth, height: this.#host.offsetHeight };\n const fitsBelow = window.innerHeight - triggerRect.bottom >= menuRect.height + margin;\n\n const top = fitsBelow ? triggerRect.bottom + 4 : Math.max(margin, triggerRect.top - menuRect.height - 4);\n const left = Math.min(\n Math.max(triggerRect.right - menuRect.width, margin),\n window.innerWidth - menuRect.width - margin,\n );\n\n this.#host.style.position = 'fixed';\n this.#host.style.top = `${Math.min(top, window.innerHeight - menuRect.height - margin)}px`;\n this.#host.style.left = `${left}px`;\n this.#host.style.right = 'auto';\n this.#host.style.bottom = 'auto';\n this.#host.style.transformOrigin = fitsBelow ? 'top right' : 'bottom right';\n }\n}\n\n/**\n * Opens a `ui-menu` from a trigger element and wires `aria-haspopup`, `aria-expanded` and\n * `aria-controls` on it.\n *\n * @example\n * <button ui-button size=\"icon\" aria-label=\"More\" [uiMenuTrigger]=\"menu\">...</button>\n */\n@Directive({\n selector: '[uiMenuTrigger]',\n host: {\n 'aria-haspopup': 'menu',\n '[attr.aria-expanded]': 'uiMenuTrigger().isOpen()',\n '[attr.aria-controls]': 'uiMenuTrigger().menuId',\n '(click)': 'toggle()',\n },\n})\nexport class UiMenuTrigger {\n readonly uiMenuTrigger = input.required<UiMenu>();\n\n readonly #host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n protected toggle(): void {\n const menu = this.uiMenuTrigger();\n\n if (menu.isOpen()) {\n menu.close();\n } else {\n menu.open(this.#host);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, computed, Component } from '@angular/core';
3
+
4
+ /** Track thicknesses. `MeterSize` is derived from this tuple. */
5
+ const METER_SIZES = ['md', 'sm'];
6
+ const TRACK_CLASSES = {
7
+ md: 'h-1.5',
8
+ sm: 'h-1',
9
+ };
10
+ /** Ramp step used to paint the fill. `MeterTone` is derived from this tuple. */
11
+ const METER_TONES = [1, 2, 3, 4, 5, 6];
12
+ const TONE_CLASSES = {
13
+ 1: 'bg-(--ramp-1)',
14
+ 2: 'bg-(--ramp-2)',
15
+ 3: 'bg-(--ramp-3)',
16
+ 4: 'bg-(--ramp-4)',
17
+ 5: 'bg-(--ramp-5)',
18
+ 6: 'bg-(--ramp-6)',
19
+ };
20
+ /**
21
+ * Proportion of a whole, drawn as a single bar. One bar per category, never a stacked
22
+ * strip: without hue to separate segments, length has to do the work alone.
23
+ *
24
+ * @example
25
+ * <ui-meter [value]="0.463" label="Funds" valueText="46.3% - 128,656.00 EUR" [tone]="1" />
26
+ */
27
+ class UiMeter {
28
+ value = input.required(/* @ts-ignore */
29
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
30
+ label = input.required(/* @ts-ignore */
31
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
32
+ valueText = input.required(/* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "valueText" }] : /* istanbul ignore next */ []));
34
+ tone = input(1, /* @ts-ignore */
35
+ ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
36
+ size = input('md', /* @ts-ignore */
37
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
38
+ trackClasses = computed(() => TRACK_CLASSES[this.size()], /* @ts-ignore */
39
+ ...(ngDevMode ? [{ debugName: "trackClasses" }] : /* istanbul ignore next */ []));
40
+ percent = computed(() => Math.min(100, Math.max(0, this.value() * 100)), /* @ts-ignore */
41
+ ...(ngDevMode ? [{ debugName: "percent" }] : /* istanbul ignore next */ []));
42
+ fillClasses = computed(() => `h-full rounded-pill ${TONE_CLASSES[this.tone()]}`, /* @ts-ignore */
43
+ ...(ngDevMode ? [{ debugName: "fillClasses" }] : /* istanbul ignore next */ []));
44
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMeter, deps: [], target: i0.ɵɵFactoryTarget.Component });
45
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiMeter, isStandalone: true, selector: "ui-meter", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: true, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
46
+ <div
47
+ class="rounded-pill w-full overflow-hidden bg-(--muted)"
48
+ role="meter"
49
+ [attr.aria-label]="label()"
50
+ [attr.aria-valuemax]="1"
51
+ [attr.aria-valuemin]="0"
52
+ [attr.aria-valuenow]="value()"
53
+ [attr.aria-valuetext]="valueText()"
54
+ [class]="trackClasses()"
55
+ >
56
+ <div data-testid="meter-fill" [class]="fillClasses()" [style.width.%]="percent()"></div>
57
+ </div>
58
+ `, isInline: true });
59
+ }
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMeter, decorators: [{
61
+ type: Component,
62
+ args: [{
63
+ selector: 'ui-meter',
64
+ template: `
65
+ <div
66
+ class="rounded-pill w-full overflow-hidden bg-(--muted)"
67
+ role="meter"
68
+ [attr.aria-label]="label()"
69
+ [attr.aria-valuemax]="1"
70
+ [attr.aria-valuemin]="0"
71
+ [attr.aria-valuenow]="value()"
72
+ [attr.aria-valuetext]="valueText()"
73
+ [class]="trackClasses()"
74
+ >
75
+ <div data-testid="meter-fill" [class]="fillClasses()" [style.width.%]="percent()"></div>
76
+ </div>
77
+ `,
78
+ }]
79
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: true }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
80
+
81
+ /**
82
+ * Generated bundle index. Do not edit.
83
+ */
84
+
85
+ export { METER_SIZES, METER_TONES, UiMeter };
86
+ //# sourceMappingURL=joanroucoux-cairn-ui-meter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joanroucoux-cairn-ui-meter.mjs","sources":["../../../projects/ui/meter/meter.ts","../../../projects/ui/meter/joanroucoux-cairn-ui-meter.ts"],"sourcesContent":["import { Component, computed, input } from '@angular/core';\n\n/** Track thicknesses. `MeterSize` is derived from this tuple. */\nexport const METER_SIZES = ['md', 'sm'] as const;\nexport type MeterSize = (typeof METER_SIZES)[number];\n\nconst TRACK_CLASSES: Record<MeterSize, string> = {\n md: 'h-1.5',\n sm: 'h-1',\n};\n\n/** Ramp step used to paint the fill. `MeterTone` is derived from this tuple. */\nexport const METER_TONES = [1, 2, 3, 4, 5, 6] as const;\nexport type MeterTone = (typeof METER_TONES)[number];\n\nconst TONE_CLASSES: Record<MeterTone, string> = {\n 1: 'bg-(--ramp-1)',\n 2: 'bg-(--ramp-2)',\n 3: 'bg-(--ramp-3)',\n 4: 'bg-(--ramp-4)',\n 5: 'bg-(--ramp-5)',\n 6: 'bg-(--ramp-6)',\n};\n\n/**\n * Proportion of a whole, drawn as a single bar. One bar per category, never a stacked\n * strip: without hue to separate segments, length has to do the work alone.\n *\n * @example\n * <ui-meter [value]=\"0.463\" label=\"Funds\" valueText=\"46.3% - 128,656.00 EUR\" [tone]=\"1\" />\n */\n@Component({\n selector: 'ui-meter',\n template: `\n <div\n class=\"rounded-pill w-full overflow-hidden bg-(--muted)\"\n role=\"meter\"\n [attr.aria-label]=\"label()\"\n [attr.aria-valuemax]=\"1\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuenow]=\"value()\"\n [attr.aria-valuetext]=\"valueText()\"\n [class]=\"trackClasses()\"\n >\n <div data-testid=\"meter-fill\" [class]=\"fillClasses()\" [style.width.%]=\"percent()\"></div>\n </div>\n `,\n})\nexport class UiMeter {\n readonly value = input.required<number>();\n readonly label = input.required<string>();\n readonly valueText = input.required<string>();\n readonly tone = input<MeterTone>(1);\n readonly size = input<MeterSize>('md');\n\n protected readonly trackClasses = computed(() => TRACK_CLASSES[this.size()]);\n\n protected readonly percent = computed(() => Math.min(100, Math.max(0, this.value() * 100)));\n\n protected readonly fillClasses = computed(() => `h-full rounded-pill ${TONE_CLASSES[this.tone()]}`);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}