@oicl/openbridge-webcomponents 2.0.0-next.114 → 2.0.0-next.116
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/bundle/openbridge-webcomponents.bundle.js +29 -8
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +21 -4
- package/dist/building-blocks/readout-block/readout-block.d.ts.map +1 -1
- package/dist/building-blocks/readout-block/readout-block.js +5 -2
- package/dist/building-blocks/readout-block/readout-block.js.map +1 -1
- package/dist/components/text-input-field/text-input-field.d.ts +1 -1
- package/dist/components/text-input-field/text-input-field.d.ts.map +1 -1
- package/dist/components/text-input-field/text-input-field.js +5 -2
- package/dist/components/text-input-field/text-input-field.js.map +1 -1
- package/dist/components/toggle-switch/toggle-switch.d.ts +16 -1
- package/dist/components/toggle-switch/toggle-switch.d.ts.map +1 -1
- package/dist/components/toggle-switch/toggle-switch.js +6 -1
- package/dist/components/toggle-switch/toggle-switch.js.map +1 -1
- package/dist/navigation-instruments/readout/readout-formatters.d.ts +23 -1
- package/dist/navigation-instruments/readout/readout-formatters.d.ts.map +1 -1
- package/dist/navigation-instruments/readout/readout-formatters.js +6 -4
- package/dist/navigation-instruments/readout/readout-formatters.js.map +1 -1
- package/dist/navigation-instruments/readout/readout-shared.d.ts.map +1 -1
- package/dist/navigation-instruments/readout/readout-shared.js +9 -0
- package/dist/navigation-instruments/readout/readout-shared.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readout-formatters.js","sources":["../../../src/navigation-instruments/readout/readout-formatters.ts"],"sourcesContent":["export type ReadoutNumericFormatOptions = {\n showZeroPadding: boolean;\n minValueLength: number;\n fractionDigits: number;\n};\n\n/**\n * How a readout's `value` is interpreted.\n * - `number`: formatted via `fractionDigits` / `maxDigits`.\n * - `text`: rendered verbatim, with the numeric format options ignored.\n */\nexport enum ReadoutValueType {\n number = 'number',\n text = 'text',\n}\n\nconst READOUT_VALUE_TYPES: readonly string[] = Object.values(ReadoutValueType);\n\n/** Whether `value` is one of the supported {@link ReadoutValueType} values. */\nexport function isReadoutValueType(value: unknown): value is ReadoutValueType {\n return typeof value === 'string' && READOUT_VALUE_TYPES.includes(value);\n}\n\nfunction isBlank(value: string): boolean {\n return value.trim() === '';\n}\n\n/**\n * Throws when `valueType` is not a supported value, or when `value` is text but\n * `valueType` is `number`.\n *\n * `valueType` is validated first because an attribute carries an unchecked\n * string: a typo such as `valuetype=\"strng\"` matches neither mode, so every\n * mode check falls through and the readout silently renders the unavailable\n * dash — the opposite of the loud failure this contract exists to give.\n * `undefined`/`null` are allowed and mean \"use the default\".\n *\n * Attributes are always strings, so a numeric-looking string (`value=\"10.12\"`)\n * is accepted and parsed. Blank strings resolve to the unavailable dash rather\n * than throwing — `value=\"${maybeUndefined}\"` is a common template shape, and\n * `Number('')` is `0`, a silently wrong reading.\n */\nexport function assertReadoutValueType(\n tagName: string,\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): void {\n // `undefined`/`null` mean \"use the default\", matching how the components and\n // the resolvers treat an unset `valueType`.\n const resolved = valueType ?? ReadoutValueType.number;\n if (!isReadoutValueType(resolved)) {\n throw new TypeError(\n `<${tagName}>: valueType must be ` +\n `${READOUT_VALUE_TYPES.map((t) => `\"${t}\"`).join(' or ')} ` +\n `(got ${JSON.stringify(valueType)}).`\n );\n }\n if (\n resolved !== ReadoutValueType.number ||\n typeof value !== 'string' ||\n isBlank(value)\n ) {\n return;\n }\n if (Number.isFinite(Number(value))) {\n return;\n }\n throw new TypeError(\n `<${tagName}>: value must be a number when valueType is \"number\" ` +\n `(got ${JSON.stringify(value)}). Set valueType=\"text\" to render text.`\n );\n}\n\n
|
|
1
|
+
{"version":3,"file":"readout-formatters.js","sources":["../../../src/navigation-instruments/readout/readout-formatters.ts"],"sourcesContent":["export type ReadoutNumericFormatOptions = {\n showZeroPadding: boolean;\n minValueLength: number;\n fractionDigits: number;\n};\n\n/**\n * How a readout's `value` is interpreted.\n * - `number`: formatted via `fractionDigits` / `maxDigits`.\n * - `text`: rendered verbatim, with the numeric format options ignored.\n */\nexport enum ReadoutValueType {\n number = 'number',\n text = 'text',\n}\n\nconst READOUT_VALUE_TYPES: readonly string[] = Object.values(ReadoutValueType);\n\n/** Whether `value` is one of the supported {@link ReadoutValueType} values. */\nexport function isReadoutValueType(value: unknown): value is ReadoutValueType {\n return typeof value === 'string' && READOUT_VALUE_TYPES.includes(value);\n}\n\nfunction isBlank(value: string): boolean {\n return value.trim() === '';\n}\n\n/**\n * Throws when `valueType` is not a supported value, or when `value` is text but\n * `valueType` is `number`.\n *\n * `valueType` is validated first because an attribute carries an unchecked\n * string: a typo such as `valuetype=\"strng\"` matches neither mode, so every\n * mode check falls through and the readout silently renders the unavailable\n * dash — the opposite of the loud failure this contract exists to give.\n * `undefined`/`null` are allowed and mean \"use the default\".\n *\n * Attributes are always strings, so a numeric-looking string (`value=\"10.12\"`)\n * is accepted and parsed. Blank strings resolve to the unavailable dash rather\n * than throwing — `value=\"${maybeUndefined}\"` is a common template shape, and\n * `Number('')` is `0`, a silently wrong reading.\n */\nexport function assertReadoutValueType(\n tagName: string,\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): void {\n // `undefined`/`null` mean \"use the default\", matching how the components and\n // the resolvers treat an unset `valueType`.\n const resolved = valueType ?? ReadoutValueType.number;\n if (!isReadoutValueType(resolved)) {\n throw new TypeError(\n `<${tagName}>: valueType must be ` +\n `${READOUT_VALUE_TYPES.map((t) => `\"${t}\"`).join(' or ')} ` +\n `(got ${JSON.stringify(valueType)}).`\n );\n }\n if (\n resolved !== ReadoutValueType.number ||\n typeof value !== 'string' ||\n isBlank(value)\n ) {\n return;\n }\n if (Number.isFinite(Number(value))) {\n return;\n }\n throw new TypeError(\n `<${tagName}>: value must be a number when valueType is \"number\" ` +\n `(got ${JSON.stringify(value)}). Set valueType=\"text\" to render text.`\n );\n}\n\n/**\n * The value as a number, or `undefined` when it is text / unavailable.\n *\n * A non-finite number (`NaN`, `±Infinity`) counts as unavailable and renders the\n * dash, the same as `null`. `NaN` is a runtime data condition — a sensor\n * dropout, a `0/0`, a bad parse — not a programmer error, so it must not throw;\n * and `value.toFixed()` would otherwise render the literal text `\"NaN\"` /\n * `\"Infinity\"` in place of a reading. This also makes the number path agree with\n * the string path below, which has always resolved a non-finite string to\n * `undefined` — before this, `<obc-readout value=\"NaN\">` rendered a dash while\n * `.value=${NaN}` rendered `\"NaN\"`.\n */\nexport function resolveReadoutNumericValue(\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): number | undefined {\n if (\n valueType === ReadoutValueType.text ||\n value === null ||\n value === undefined\n ) {\n return undefined;\n }\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : undefined;\n }\n if (isBlank(value)) {\n return undefined;\n }\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\n/** The value as display text, or `undefined` when not in text mode / blank. */\nexport function resolveReadoutTextValue(\n value: number | string | null | undefined,\n valueType: ReadoutValueType\n): string | undefined {\n if (\n valueType !== ReadoutValueType.text ||\n value === null ||\n value === undefined\n ) {\n return undefined;\n }\n const text = typeof value === 'number' ? String(value) : value;\n return isBlank(text) ? undefined : text;\n}\n\n/**\n * The character used for an unavailable (\"no reading\") value.\n *\n * U+2012 FIGURE DASH, not the ASCII hyphen-minus: it is defined to be the same\n * width as a digit, so the placeholder lines up with the reading it stands in\n * for. Measured in Noto Sans with tabular figures at `size=\"m\"` — digit 13.02px,\n * U+2012 13.02px, U+002D 7.02px, en dash 11.02px, em dash 22.02px. With a\n * hyphen, `-.--` sat 46% narrow per character and its decimal point missed the\n * reading's; with U+2012 the point and every fraction position align exactly.\n */\nexport const READOUT_UNAVAILABLE_DASH = '\\u2012';\n\n/**\n * The unavailable (\"no reading\") text: a single integer dash plus one dash per\n * fraction digit — `\\u2012` at `fractionDigits` 0, `\\u2012.\\u2012\\u2012` at 2.\n *\n * Deliberately NOT filled out to `maxDigits`: the placeholder stays short and\n * sits at the right edge of the reserved width, rather than spelling out every\n * reserved digit position. `maxDigits` still reserves the width, so nothing\n * shifts when a reading arrives.\n */\nfunction dashedGenerator({\n showZeroPadding,\n minValueLength,\n fractionDigits,\n}: ReadoutNumericFormatOptions): string {\n const visibleDigits = showZeroPadding ? Math.max(minValueLength, 1) : 1;\n\n if (fractionDigits < 1) {\n return READOUT_UNAVAILABLE_DASH.repeat(visibleDigits);\n }\n\n const integerDigits = visibleDigits - fractionDigits;\n\n return (\n READOUT_UNAVAILABLE_DASH.repeat(Math.max(integerDigits, 1)) +\n '.' +\n READOUT_UNAVAILABLE_DASH.repeat(fractionDigits)\n );\n}\n\nexport function formatNumericValue(\n value: number | undefined,\n options: ReadoutNumericFormatOptions\n): string {\n // Non-finite counts as unavailable here too, not only in\n // `resolveReadoutNumericValue`. Every caller normalises today, but this\n // function is exported, and `NaN.toFixed()` would put the literal text\n // \"NaN\" where a reading belongs — the exact failure this change removes.\n if (value === undefined || !Number.isFinite(value)) {\n return dashedGenerator(options);\n }\n\n return value.toFixed(options.fractionDigits);\n}\n\nexport function readoutFormattedInteger(valueText: string): number {\n const t = valueText.trim();\n if (!t) {\n return 0;\n }\n\n const rest = t.startsWith('-') ? t.slice(1) : t;\n const dot = rest.indexOf('.');\n return dot === -1 ? rest.length : dot;\n}\n\nexport function getHintZeros(\n value: number | undefined,\n {showZeroPadding, minValueLength, fractionDigits}: ReadoutNumericFormatOptions\n): string {\n const formattedValue = formatNumericValue(value, {\n showZeroPadding,\n minValueLength,\n fractionDigits,\n });\n const dotLength = fractionDigits > 0 ? 1 : 0;\n const integerLength = formattedValue.length - dotLength;\n const hintedDigits = Math.max(minValueLength - integerLength, 0);\n\n if (hintedDigits > 0) {\n return '0'.repeat(hintedDigits);\n }\n\n return '';\n}\n"],"names":["ReadoutValueType"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readout-shared.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/readout/readout-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACrB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,sDAAsD,CAAC;AAC9D,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACrB,2BAA2B,
|
|
1
|
+
{"version":3,"file":"readout-shared.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/readout/readout-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACrB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,sDAAsD,CAAC;AAC9D,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACrB,2BAA2B,CAY7B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,aAAa,EAAE,2BAA2B,GACzC,OAAO,CAkBT;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,cAAc,CASzE;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,cAAc,CAS3E;AAED,4EAA4E;AAC5E,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,OAAO,GAClB,oBAAoB,CAItB;AAED,8EAA8E;AAC9E,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,uBAAuB,GAAG,SAAS,GAC/C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,eAAe,EAAE,OAAO,EACxB,aAAa,EAAE,qBAAqB,GACnC,qBAAqB,CAEvB"}
|
|
@@ -3,6 +3,12 @@ import { ReadoutBlockSize, ReadoutBlockDataQuality, ReadoutBlockHidePhase } from
|
|
|
3
3
|
import { formatNumericValue } from "./readout-formatters.js";
|
|
4
4
|
function readoutNumericFormatOptions(maxDigits, fractionDigits) {
|
|
5
5
|
return {
|
|
6
|
+
// Comparison-only (see `isDisplayedAtSetpoint`), which returns early unless
|
|
7
|
+
// both operands are finite numbers — so `formatNumericValue` never reaches
|
|
8
|
+
// its unavailable-dash branch here and the padding would have no effect.
|
|
9
|
+
// `obc-readout-block` sets it to `false` for rendering as well, since the
|
|
10
|
+
// unavailable placeholder is deliberately short rather than filled out to
|
|
11
|
+
// `maxDigits`. Nothing enables it today.
|
|
6
12
|
showZeroPadding: false,
|
|
7
13
|
minValueLength: maxDigits,
|
|
8
14
|
fractionDigits
|
|
@@ -12,6 +18,9 @@ function isDisplayedAtSetpoint(value, setpoint, formatOptions) {
|
|
|
12
18
|
if (value === null || setpoint === void 0) {
|
|
13
19
|
return false;
|
|
14
20
|
}
|
|
21
|
+
if (!Number.isFinite(value) || !Number.isFinite(setpoint)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
15
24
|
return formatNumericValue(value, formatOptions) === formatNumericValue(setpoint, formatOptions);
|
|
16
25
|
}
|
|
17
26
|
function readoutPrimarySize(size) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readout-shared.js","sources":["../../../src/navigation-instruments/readout/readout-shared.ts"],"sourcesContent":["import {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n} from '../../components/textbox/textbox.js';\nimport {\n ReadoutBlockSize,\n ReadoutBlockDataQuality,\n ReadoutBlockHidePhase,\n} from '../../building-blocks/readout-block/readout-block.js';\nimport {\n formatNumericValue,\n type ReadoutNumericFormatOptions,\n} from './readout-formatters.js';\n\n/**\n * Pure helpers shared by `obc-readout` and `obc-readout-list-item`. The two\n * components are layout siblings built from the same primitives + per-block\n * options API (see #1012); this module keeps their behavioral logic in\n * lock-step until an eventual merge.\n *\n * ## Features\n * - **Numeric formatting:** {@link readoutNumericFormatOptions} builds the\n * shared `maxDigits`/`fractionDigits` format options (never zero-padded).\n * - **Setpoint comparison:** {@link isDisplayedAtSetpoint} compares the\n * DISPLAYED (rounded) value and setpoint strings, not the raw numbers.\n * - **Typography mapping:** {@link readoutPrimarySize} /\n * {@link readoutSecondarySize} map the density tier to the primary /\n * de-emphasised `obc-textbox` size; {@link readoutSetpointWeight} picks the\n * setpoint font weight from its emphasis state.\n * - **Data quality:** {@link readoutDataQualityClasses} produces the classMap\n * fragment for the low-integrity / invalid chip.\n * - **Pop-up hide phase:** {@link resolveSetpointHidePhase} maps the\n * component's deferred-hide state onto the block-level\n * `ReadoutBlockHidePhase`.\n *\n * ## Usage Guidelines\n * These helpers are consumed by the components' private getters — behavioral\n * changes belong here (once), not re-inlined per component.\n *\n * @example\n * const format = readoutNumericFormatOptions(3, 1);\n * const atSetpoint = isDisplayedAtSetpoint(29.99, 30, format);\n */\n\nexport function readoutNumericFormatOptions(\n maxDigits: number,\n fractionDigits: number\n): ReadoutNumericFormatOptions {\n return {\n showZeroPadding: false,\n minValueLength: maxDigits,\n fractionDigits,\n };\n}\n\n/**\n * Whether the value reads as \"at the setpoint\". Compares what is DISPLAYED\n * (rounded to fractionDigits), not the raw values, so e.g. 29.999 and 30 at\n * fractionDigits=0 both read \"30\" → at setpoint.\n */\nexport function isDisplayedAtSetpoint(\n value: number | null,\n setpoint: number | undefined,\n formatOptions: ReadoutNumericFormatOptions\n): boolean {\n if (value === null || setpoint === undefined) {\n return false;\n }\n return (\n formatNumericValue(value, formatOptions) ===\n formatNumericValue(setpoint, formatOptions)\n );\n}\n\n/** Primary value-typography size for a density tier. */\nexport function readoutPrimarySize(size: ReadoutBlockSize): ObcTextboxSize {\n switch (size) {\n case ReadoutBlockSize.large:\n return ObcTextboxSize.l;\n case ReadoutBlockSize.medium:\n return ObcTextboxSize.m;\n default:\n return ObcTextboxSize.s;\n }\n}\n\n/** Secondary (de-emphasised) value-typography size for a density tier. */\nexport function readoutSecondarySize(size: ReadoutBlockSize): ObcTextboxSize {\n switch (size) {\n case ReadoutBlockSize.large:\n return ObcTextboxSize.s;\n case ReadoutBlockSize.medium:\n return ObcTextboxSize.s;\n default:\n return ObcTextboxSize.xs;\n }\n}\n\n/** Setpoint is SemiBold only while emphasised, otherwise regular weight. */\nexport function readoutSetpointWeight(\n emphasized: boolean\n): ObcTextboxFontWeight {\n return emphasized\n ? ObcTextboxFontWeight.semibold\n : ObcTextboxFontWeight.regular;\n}\n\n/** classMap fragment for a block / source carrying per-block data quality. */\nexport function readoutDataQualityClasses(\n dataQuality: ReadoutBlockDataQuality | undefined\n): Record<string, boolean> {\n return {\n 'data-low-integrity': dataQuality === ReadoutBlockDataQuality.lowIntegrity,\n 'data-invalid': dataQuality === ReadoutBlockDataQuality.invalid,\n };\n}\n\n/**\n * The block-level hide phase for a pop-up setpoint: the component's deferred\n * phase while the value sits at the setpoint, `none` otherwise (value away\n * from the setpoint, or touching).\n */\nexport function resolveSetpointHidePhase(\n popUpAtSetpoint: boolean,\n deferredPhase: ReadoutBlockHidePhase\n): ReadoutBlockHidePhase {\n return popUpAtSetpoint ? deferredPhase : ReadoutBlockHidePhase.none;\n}\n"],"names":[],"mappings":";;;AA4CO,SAAS,4BACd,WACA,gBAC6B;AAC7B,SAAO;AAAA,
|
|
1
|
+
{"version":3,"file":"readout-shared.js","sources":["../../../src/navigation-instruments/readout/readout-shared.ts"],"sourcesContent":["import {\n ObcTextboxSize,\n ObcTextboxFontWeight,\n} from '../../components/textbox/textbox.js';\nimport {\n ReadoutBlockSize,\n ReadoutBlockDataQuality,\n ReadoutBlockHidePhase,\n} from '../../building-blocks/readout-block/readout-block.js';\nimport {\n formatNumericValue,\n type ReadoutNumericFormatOptions,\n} from './readout-formatters.js';\n\n/**\n * Pure helpers shared by `obc-readout` and `obc-readout-list-item`. The two\n * components are layout siblings built from the same primitives + per-block\n * options API (see #1012); this module keeps their behavioral logic in\n * lock-step until an eventual merge.\n *\n * ## Features\n * - **Numeric formatting:** {@link readoutNumericFormatOptions} builds the\n * shared `maxDigits`/`fractionDigits` format options (never zero-padded).\n * - **Setpoint comparison:** {@link isDisplayedAtSetpoint} compares the\n * DISPLAYED (rounded) value and setpoint strings, not the raw numbers.\n * - **Typography mapping:** {@link readoutPrimarySize} /\n * {@link readoutSecondarySize} map the density tier to the primary /\n * de-emphasised `obc-textbox` size; {@link readoutSetpointWeight} picks the\n * setpoint font weight from its emphasis state.\n * - **Data quality:** {@link readoutDataQualityClasses} produces the classMap\n * fragment for the low-integrity / invalid chip.\n * - **Pop-up hide phase:** {@link resolveSetpointHidePhase} maps the\n * component's deferred-hide state onto the block-level\n * `ReadoutBlockHidePhase`.\n *\n * ## Usage Guidelines\n * These helpers are consumed by the components' private getters — behavioral\n * changes belong here (once), not re-inlined per component.\n *\n * @example\n * const format = readoutNumericFormatOptions(3, 1);\n * const atSetpoint = isDisplayedAtSetpoint(29.99, 30, format);\n */\n\nexport function readoutNumericFormatOptions(\n maxDigits: number,\n fractionDigits: number\n): ReadoutNumericFormatOptions {\n return {\n // Comparison-only (see `isDisplayedAtSetpoint`), which returns early unless\n // both operands are finite numbers — so `formatNumericValue` never reaches\n // its unavailable-dash branch here and the padding would have no effect.\n // `obc-readout-block` sets it to `false` for rendering as well, since the\n // unavailable placeholder is deliberately short rather than filled out to\n // `maxDigits`. Nothing enables it today.\n showZeroPadding: false,\n minValueLength: maxDigits,\n fractionDigits,\n };\n}\n\n/**\n * Whether the value reads as \"at the setpoint\". Compares what is DISPLAYED\n * (rounded to fractionDigits), not the raw values, so e.g. 29.999 and 30 at\n * fractionDigits=0 both read \"30\" → at setpoint.\n */\nexport function isDisplayedAtSetpoint(\n value: number | null,\n setpoint: number | undefined,\n formatOptions: ReadoutNumericFormatOptions\n): boolean {\n if (value === null || setpoint === undefined) {\n return false;\n }\n // An unavailable reading is never \"at\" the setpoint. Callers normalise\n // `value` (via `resolveReadoutNumericValue`) but pass `setpoint` raw, so a\n // non-finite setpoint would otherwise be formatted as the literal \"NaN\" /\n // \"Infinity\" and compared as a string. The comparison result happens to be\n // correct either way — a normalised `value` can never also format to \"NaN\" —\n // but guarding both keeps the two operands symmetric and the invariant below\n // honest.\n if (!Number.isFinite(value) || !Number.isFinite(setpoint)) {\n return false;\n }\n return (\n formatNumericValue(value, formatOptions) ===\n formatNumericValue(setpoint, formatOptions)\n );\n}\n\n/** Primary value-typography size for a density tier. */\nexport function readoutPrimarySize(size: ReadoutBlockSize): ObcTextboxSize {\n switch (size) {\n case ReadoutBlockSize.large:\n return ObcTextboxSize.l;\n case ReadoutBlockSize.medium:\n return ObcTextboxSize.m;\n default:\n return ObcTextboxSize.s;\n }\n}\n\n/** Secondary (de-emphasised) value-typography size for a density tier. */\nexport function readoutSecondarySize(size: ReadoutBlockSize): ObcTextboxSize {\n switch (size) {\n case ReadoutBlockSize.large:\n return ObcTextboxSize.s;\n case ReadoutBlockSize.medium:\n return ObcTextboxSize.s;\n default:\n return ObcTextboxSize.xs;\n }\n}\n\n/** Setpoint is SemiBold only while emphasised, otherwise regular weight. */\nexport function readoutSetpointWeight(\n emphasized: boolean\n): ObcTextboxFontWeight {\n return emphasized\n ? ObcTextboxFontWeight.semibold\n : ObcTextboxFontWeight.regular;\n}\n\n/** classMap fragment for a block / source carrying per-block data quality. */\nexport function readoutDataQualityClasses(\n dataQuality: ReadoutBlockDataQuality | undefined\n): Record<string, boolean> {\n return {\n 'data-low-integrity': dataQuality === ReadoutBlockDataQuality.lowIntegrity,\n 'data-invalid': dataQuality === ReadoutBlockDataQuality.invalid,\n };\n}\n\n/**\n * The block-level hide phase for a pop-up setpoint: the component's deferred\n * phase while the value sits at the setpoint, `none` otherwise (value away\n * from the setpoint, or touching).\n */\nexport function resolveSetpointHidePhase(\n popUpAtSetpoint: boolean,\n deferredPhase: ReadoutBlockHidePhase\n): ReadoutBlockHidePhase {\n return popUpAtSetpoint ? deferredPhase : ReadoutBlockHidePhase.none;\n}\n"],"names":[],"mappings":";;;AA4CO,SAAS,4BACd,WACA,gBAC6B;AAC7B,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOL,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB;AAAA,EAAA;AAEJ;AAOO,SAAS,sBACd,OACA,UACA,eACS;AACT,MAAI,UAAU,QAAQ,aAAa,QAAW;AAC5C,WAAO;AAAA,EACT;AAQA,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,SAAS,QAAQ,GAAG;AACzD,WAAO;AAAA,EACT;AACA,SACE,mBAAmB,OAAO,aAAa,MACvC,mBAAmB,UAAU,aAAa;AAE9C;AAGO,SAAS,mBAAmB,MAAwC;AACzE,UAAQ,MAAA;AAAA,IACN,KAAK,iBAAiB;AACpB,aAAO,eAAe;AAAA,IACxB,KAAK,iBAAiB;AACpB,aAAO,eAAe;AAAA,IACxB;AACE,aAAO,eAAe;AAAA,EAAA;AAE5B;AAGO,SAAS,qBAAqB,MAAwC;AAC3E,UAAQ,MAAA;AAAA,IACN,KAAK,iBAAiB;AACpB,aAAO,eAAe;AAAA,IACxB,KAAK,iBAAiB;AACpB,aAAO,eAAe;AAAA,IACxB;AACE,aAAO,eAAe;AAAA,EAAA;AAE5B;AAGO,SAAS,sBACd,YACsB;AACtB,SAAO,aACH,qBAAqB,WACrB,qBAAqB;AAC3B;AAGO,SAAS,0BACd,aACyB;AACzB,SAAO;AAAA,IACL,sBAAsB,gBAAgB,wBAAwB;AAAA,IAC9D,gBAAgB,gBAAgB,wBAAwB;AAAA,EAAA;AAE5D;AAOO,SAAS,yBACd,iBACA,eACuB;AACvB,SAAO,kBAAkB,gBAAgB,sBAAsB;AACjE;"}
|