packages/core/src/lib/style/resolve-length.ts
This is the source snapshot used to build these API details. View this revision on GitHub.
1 import {
2 layoutDiagnostic,
3 type LayoutDiagnosticContext,
4 } from './diagnostics.js';
5 import type { Length } from './types.js';
6
7 const DECIMAL_PERCENTAGE = /^[+-]?(?:\d+(?:\.\d+)?|\.\d+)%$/;
8
9 /**
10 * Resolves a numeric or percentage length; automatic sizing returns undefined.
11 *
12 * @param value - Logical length or percentage to resolve. See {@link Length}.
13 * @param reference - Reference length for percentages, or undefined if unavailable.
14 * @param property - Property name used in diagnostics.
15 * @param context - Component and property context for diagnostic messages. See
16 * {@link LayoutDiagnosticContext} .
17 * @returns The resolved logical length, or undefined for an unresolved automatic length.
18 *
19 * @see {@link Length}
20 * @see {@link LayoutDiagnosticContext}
21 */
22 export function resolveLength(
23 value: Length,
24 reference: number | undefined,
25 property: string,
26 context: Readonly<LayoutDiagnosticContext> = {},
27 ): number | undefined {
28 if (value === 'auto') return undefined;
29
30 if (typeof value === 'number') {
31 if (!Number.isFinite(value)) {
32 throw diagnostic(property, value, 'must be a finite number', context);
33 }
34 return value;
35 }
36
37 if (typeof value !== 'string' || !DECIMAL_PERCENTAGE.test(value)) {
38 throw diagnostic(
39 property,
40 value,
41 `uses an unsupported length value ${String(value)}`,
42 context,
43 );
44 }
45
46 if (reference === undefined || !Number.isFinite(reference)) {
47 throw diagnostic(
48 property,
49 value,
50 'requires a definite finite percentage reference',
51 context,
52 );
53 }
54 if (reference < 0) {
55 throw diagnostic(
56 property,
57 value,
58 'percentage reference must be nonnegative',
59 context,
60 );
61 }
62
63 const resolved = (Number.parseFloat(value) / 100) * reference;
64 if (!Number.isFinite(resolved)) {
65 throw diagnostic(
66 property,
67 value,
68 'resolved percentage arithmetic must remain finite',
69 context,
70 );
71 }
72 return resolved;
73 }
74
75 function diagnostic(
76 property: string,
77 value: unknown,
78 reason: string,
79 context: Readonly<LayoutDiagnosticContext>,
80 ) {
81 return layoutDiagnostic({ ...context, property, value, reason });
82 }
83
Documentation version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.