@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.154 → 2.0.0-next.156
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/LICENSE-AGPL.txt +661 -0
- package/LICENSE-APACHE.txt +177 -0
- package/LICENSE.txt +35 -0
- package/bundle/openbridge-webcomponents.bundle.js +3629 -3281
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +236 -37
- package/dist/automation/transmitter/transmitter-shared.d.ts +11 -0
- package/dist/automation/transmitter/transmitter-shared.d.ts.map +1 -0
- package/dist/automation/transmitter/transmitter-shared.js +16 -0
- package/dist/automation/transmitter/transmitter-shared.js.map +1 -0
- package/dist/automation/transmitter/transmitter.css.js +12 -1
- package/dist/automation/transmitter/transmitter.css.js.map +1 -1
- package/dist/automation/transmitter/transmitter.d.ts +9 -10
- package/dist/automation/transmitter/transmitter.d.ts.map +1 -1
- package/dist/automation/transmitter/transmitter.js +12 -15
- package/dist/automation/transmitter/transmitter.js.map +1 -1
- package/dist/automation/transmitter-button/transmitter-button.css.js +18 -42
- package/dist/automation/transmitter-button/transmitter-button.css.js.map +1 -1
- package/dist/automation/transmitter-button/transmitter-button.d.ts +31 -21
- package/dist/automation/transmitter-button/transmitter-button.d.ts.map +1 -1
- package/dist/automation/transmitter-button/transmitter-button.js +37 -39
- package/dist/automation/transmitter-button/transmitter-button.js.map +1 -1
- package/dist/automation/transmitter-stack/transmitter-stack.css.js +144 -0
- package/dist/automation/transmitter-stack/transmitter-stack.css.js.map +1 -0
- package/dist/automation/transmitter-stack/transmitter-stack.d.ts +93 -0
- package/dist/automation/transmitter-stack/transmitter-stack.d.ts.map +1 -0
- package/dist/automation/transmitter-stack/transmitter-stack.js +97 -0
- package/dist/automation/transmitter-stack/transmitter-stack.js.map +1 -0
- package/dist/building-blocks/readout-block/readout-block.d.ts +1 -1
- package/dist/building-blocks/readout-block/readout-block.js.map +1 -1
- package/dist/components/textarea-field/textarea-field.css.js +0 -2
- package/dist/components/textarea-field/textarea-field.css.js.map +1 -1
- package/dist/components/textbox/textbox.d.ts +1 -1
- package/dist/components/textbox/textbox.js.map +1 -1
- package/dist/components/user-button/user-button.css.js +68 -1
- package/dist/components/user-button/user-button.css.js.map +1 -1
- package/dist/components/user-button/user-button.d.ts +8 -1
- package/dist/components/user-button/user-button.d.ts.map +1 -1
- package/dist/components/user-button/user-button.js +12 -3
- package/dist/components/user-button/user-button.js.map +1 -1
- package/dist/components/user-menu/user-menu.css.js +15 -0
- package/dist/components/user-menu/user-menu.css.js.map +1 -1
- package/dist/components/user-menu/user-menu.d.ts +22 -2
- package/dist/components/user-menu/user-menu.d.ts.map +1 -1
- package/dist/components/user-menu/user-menu.js +34 -2
- package/dist/components/user-menu/user-menu.js.map +1 -1
- package/dist/generated/locales/es-419.d.ts +1 -0
- package/dist/generated/locales/es-419.d.ts.map +1 -1
- package/dist/generated/locales/es-419.js +1 -0
- package/dist/generated/locales/es-419.js.map +1 -1
- package/dist/generated/locales/fi-FI.d.ts +1 -0
- package/dist/generated/locales/fi-FI.d.ts.map +1 -1
- package/dist/generated/locales/fi-FI.js +1 -0
- package/dist/generated/locales/fi-FI.js.map +1 -1
- package/dist/navigation-instruments/readout/readout.d.ts +1 -1
- package/dist/navigation-instruments/readout/readout.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +1 -0
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js +3 -0
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
- package/package.json +6 -3
- package/script/prepare-full-bundle.ts +5 -0
- package/src/automation/transmitter/transmitter-shared.ts +16 -0
- package/src/automation/transmitter/transmitter.css +3 -71
- package/src/automation/transmitter/transmitter.stories.ts +13 -1
- package/src/automation/transmitter/transmitter.ts +19 -16
- package/src/automation/transmitter-button/transmitter-button.css +11 -36
- package/src/automation/transmitter-button/transmitter-button.stories.ts +3 -1
- package/src/automation/transmitter-button/transmitter-button.ts +62 -66
- package/src/automation/transmitter-stack/transmitter-stack.css +56 -0
- package/src/automation/transmitter-stack/transmitter-stack.spec.ts +210 -0
- package/src/automation/transmitter-stack/transmitter-stack.stories.ts +149 -0
- package/src/automation/transmitter-stack/transmitter-stack.ts +172 -0
- package/src/building-blocks/readout-block/readout-block.stories.ts +1 -1
- package/src/building-blocks/readout-block/readout-block.ts +1 -1
- package/src/components/textarea-field/textarea-field.css +1 -8
- package/src/components/textbox/textbox.stories.ts +1 -1
- package/src/components/textbox/textbox.ts +1 -1
- package/src/components/user-button/user-button.css +27 -1
- package/src/components/user-button/user-button.stories.ts +29 -0
- package/src/components/user-button/user-button.ts +22 -3
- package/src/components/user-menu/user-menu.css +8 -0
- package/src/components/user-menu/user-menu.stories.ts +53 -0
- package/src/components/user-menu/user-menu.ts +55 -4
- package/src/generated/locales/es-419.ts +1 -0
- package/src/generated/locales/fi-FI.ts +1 -0
- package/src/mixins/transmitter.css +90 -0
- package/src/mixins/visually-hidden.css +10 -0
- package/src/navigation-instruments/readout/readout.stories.ts +1 -1
- package/src/navigation-instruments/readout/readout.ts +1 -1
- package/src/navigation-instruments/readout-list-item/readout-list-item.css +1 -0
- package/src/navigation-instruments/readout-list-item/readout-list-item.stories.ts +1 -1
- package/src/navigation-instruments/readout-list-item/readout-list-item.ts +12 -2
package/custom-elements.json
CHANGED
|
@@ -3891,7 +3891,7 @@
|
|
|
3891
3891
|
{
|
|
3892
3892
|
"kind": "variable",
|
|
3893
3893
|
"name": "ObcTransmitterButton",
|
|
3894
|
-
"default": "class extends LitElement { constructor() { super(...arguments); this.variant = \"value\"; this.size = \"regular\"; this.unit = \"\"; this.fractionDigits = 1; this.maxDigits = 0; this.hintedZeros = false; this.hasSignSpacer = false; this.hasIcon = false; this.hasAdvice = false; this.hasSetPoint = false; this.label = \"\"; } get isTag() { return this.variant === \"tag\"; }
|
|
3894
|
+
"default": "class extends LitElement { constructor() { super(...arguments); this.variant = \"value\"; this.size = \"regular\"; this.unit = \"\"; this.fractionDigits = 1; this.maxDigits = 0; this.hintedZeros = false; this.hasSignSpacer = false; this.hasDegree = false; this.hasIcon = false; this.hasAdvice = false; this.hasSetPoint = false; this.label = \"\"; this.idTag = \"\"; } get isTag() { return this.variant === \"tag\"; } renderReading() { const format = { hintedZeros: this.hintedZeros, hasSignSpacer: this.hasSignSpacer }; return html` <obc-readout-list-item .size=${readoutSizeBySize[this.size]} .value=${this.value ?? null} .unit=${this.unit} .hasDegree=${this.hasDegree} .fractionDigits=${this.fractionDigits} .maxDigits=${this.maxDigits} .valueOptions=${{ ...format, hasIcon: this.hasIcon }} .hasSetpoint=${this.hasSetPoint} .setpoint=${this.setpointValue ?? void 0} .setpointOptions=${format} .hasAdvice=${this.hasAdvice} .advice=${this.adviceValue ?? void 0} .adviceOptions=${format} > ${this.hasIcon ? html`<slot name=\"icon\" slot=\"value-icon\"></slot>` : nothing} </obc-readout-list-item> `; } render() { return html` <button type=\"button\" class=\"button ${this.variant} size-${this.size}\"> <div part=\"button\" class=${classMap({ \"visible-wrapper\": true, tag: this.isTag })} > ${this.isTag ? html`<span class=\"label\">${this.label}</span>` : this.renderReading()} </div> ${this.idTag ? html`<span class=\"visually-hidden\">${this.idTag}</span>` : nothing} </button> `; } }"
|
|
3895
3895
|
}
|
|
3896
3896
|
],
|
|
3897
3897
|
"exports": [
|
|
@@ -3921,6 +3921,27 @@
|
|
|
3921
3921
|
}
|
|
3922
3922
|
]
|
|
3923
3923
|
},
|
|
3924
|
+
{
|
|
3925
|
+
"kind": "javascript-module",
|
|
3926
|
+
"path": "dist/automation/transmitter-stack/transmitter-stack.js",
|
|
3927
|
+
"declarations": [
|
|
3928
|
+
{
|
|
3929
|
+
"kind": "variable",
|
|
3930
|
+
"name": "ObcTransmitterStack",
|
|
3931
|
+
"default": "class extends LitElement { constructor() { super(...arguments); this.orientation = TransmitterOrientation.bottom; this.lineType = void 0; this.values = []; } handleValueClick(index, value) { this.dispatchEvent( new CustomEvent(\"value-click\", { detail: { index, value }, bubbles: true, composed: true }) ); } renderValue(entry, index, hasIdTags) { return html` <div class=\"cell\" part=\"cell\"> <obc-transmitter-button class=\"segment\" .variant=${TransmitterButtonVariant.value} .value=${entry.value} .unit=${entry.unit ?? \"\"} .fractionDigits=${\"fractionDigits\" in entry ? entry.fractionDigits ?? NaN : 1} .maxDigits=${\"maxDigits\" in entry ? entry.maxDigits ?? NaN : 0} .hintedZeros=${entry.hintedZeros ?? false} .hasSignSpacer=${entry.hasSignSpacer ?? false} .hasDegree=${entry.hasDegree ?? false} .hasIcon=${Boolean(entry.iconSlotName)} .idTag=${entry.idTag ?? \"\"} @click=${() => this.handleValueClick(index, entry)} > ${entry.iconSlotName ? html`<slot name=${entry.iconSlotName} slot=\"icon\"></slot>` : nothing} </obc-transmitter-button> ${hasIdTags ? html`<div class=\"id-tag\" aria-hidden=\"true\"> ${entry.idTag ?? \"\"} </div>` : nothing} </div> `; } render() { if (this.values.length === 0) { return nothing; } const hasIdTags = this.values.some((entry) => Boolean(entry.idTag)); return html` <div class=${classMap({ transmitter: true, [`orientation-${this.orientation}`]: true })} style=\"--offset: ${transmitterLeaderOffset(this.lineType)}px;\" > <div class=\"values\" part=\"values\"> ${this.values.map( (entry, index) => this.renderValue(entry, index, hasIdTags) )} </div> </div> `; } }"
|
|
3932
|
+
}
|
|
3933
|
+
],
|
|
3934
|
+
"exports": [
|
|
3935
|
+
{
|
|
3936
|
+
"kind": "js",
|
|
3937
|
+
"name": "ObcTransmitterStack",
|
|
3938
|
+
"declaration": {
|
|
3939
|
+
"name": "ObcTransmitterStack",
|
|
3940
|
+
"module": "dist/automation/transmitter-stack/transmitter-stack.js"
|
|
3941
|
+
}
|
|
3942
|
+
}
|
|
3943
|
+
]
|
|
3944
|
+
},
|
|
3924
3945
|
{
|
|
3925
3946
|
"kind": "javascript-module",
|
|
3926
3947
|
"path": "dist/automation/transmitter/transmitter.js",
|
|
@@ -3928,7 +3949,7 @@
|
|
|
3928
3949
|
{
|
|
3929
3950
|
"kind": "variable",
|
|
3930
3951
|
"name": "ObcTransmitter",
|
|
3931
|
-
"default": "class extends LitElement { constructor() { super(...arguments); this.orientation =
|
|
3952
|
+
"default": "class extends LitElement { constructor() { super(...arguments); this.orientation = TransmitterOrientation.bottom; this.type = \"value\"; this.lineType = void 0; this.unit = \"\"; this.fractionDigits = 1; this.maxDigits = 0; this.hintedZeros = false; this.hasSignSpacer = false; this.hasDegree = false; this.size = TransmitterButtonSize.regular; this.hasIcon = false; this.hasAdvice = false; this.hasAlert = false; this.hasSetPoint = false; this.tag = \"\"; this.idTag = \"\"; this.data = [[], []]; } get hasGraph() { return this.type === \"horizontal-graph\" || this.type === \"vertical-graph\"; } renderButton() { const isIndicator = this.type === \"indicator\"; return html` <obc-transmitter-button class=\"chip\" .variant=${isIndicator ? TransmitterButtonVariant.tag : TransmitterButtonVariant.value} .size=${this.size} .value=${this.value} .unit=${this.unit} .fractionDigits=${this.fractionDigits} .maxDigits=${this.maxDigits} .hintedZeros=${this.hintedZeros} .hasSignSpacer=${this.hasSignSpacer} .hasDegree=${this.hasDegree} .hasIcon=${this.hasIcon} .hasAdvice=${this.hasAdvice} .adviceValue=${this.adviceValue} .hasSetPoint=${this.hasSetPoint} .setpointValue=${this.setpointValue} .label=${this.tag} .idTag=${this.idTag} > <slot name=\"icon\" slot=\"icon\"></slot> </obc-transmitter-button> `; } renderGraph() { if (!this.hasGraph) { return nothing; } const layout = { size: ObcIndicatorGraphSize.small, fill: true }; return html` <div class=\"graph-box\"> <obc-indicator-graph .data=${this.data} .layout=${layout}> </obc-indicator-graph> </div> `; } renderLabel() { if (!this.idTag) { return nothing; } return html`<div class=\"id-tag\" aria-hidden=\"true\">${this.idTag}</div>`; } renderContent() { return html` <div class=\"content\"> <div class=\"body\">${this.renderButton()} ${this.renderGraph()}</div> ${this.renderLabel()} </div> `; } render() { const content = this.hasAlert ? html` <obc-alert-frame class=\"alert-frame\" .type=${ObcAlertFrameType.Regular} .wrapContent=${true} > ${this.renderContent()} </obc-alert-frame> ` : this.renderContent(); return html` <div class=${classMap({ transmitter: true, \"has-alert\": this.hasAlert, [`orientation-${this.orientation}`]: true, [`type-${this.type}`]: true })} style=\"--offset: ${transmitterLeaderOffset(this.lineType)}px;\" > ${content} </div> `; } }"
|
|
3932
3953
|
}
|
|
3933
3954
|
],
|
|
3934
3955
|
"exports": [
|
|
@@ -3955,6 +3976,14 @@
|
|
|
3955
3976
|
"name": "TransmitterType",
|
|
3956
3977
|
"module": "dist/automation/transmitter/transmitter.js"
|
|
3957
3978
|
}
|
|
3979
|
+
},
|
|
3980
|
+
{
|
|
3981
|
+
"kind": "js",
|
|
3982
|
+
"name": "transmitterLeaderOffset",
|
|
3983
|
+
"declaration": {
|
|
3984
|
+
"name": "transmitterLeaderOffset",
|
|
3985
|
+
"module": "dist/automation/transmitter/transmitter.js"
|
|
3986
|
+
}
|
|
3958
3987
|
}
|
|
3959
3988
|
]
|
|
3960
3989
|
},
|
|
@@ -8548,7 +8577,7 @@
|
|
|
8548
8577
|
{
|
|
8549
8578
|
"kind": "variable",
|
|
8550
8579
|
"name": "ObcUserButton",
|
|
8551
|
-
"default": "class extends LitElement { constructor() { super(...arguments); this.variant = \"icon\"; this.size = \"regular\"; this.styleType = \"flat\"; this.static = false; this.disabled = false; this.initials = \"\"; } get formattedInitials() { if (!this.initials) return \"\"; const clean = this.initials.replace(/\\s+/g, \"\").toUpperCase(); const maxInitialsLength = this.size === \"large\" ? 3 : 2; if (clean.length > maxInitialsLength) { console.warn( `Initials \"${this.initials}\" are longer than ${maxInitialsLength} characters.` ); return clean.slice(0, maxInitialsLength); } return clean; } get shouldShowIcon() { return this.variant === \"icon\"; } render() { const styleType = this.size === \"large\" && this.styleType === \"flat\" ? \"normal\" : this.styleType; const wrapperClasses = { wrapper: true, \"wrapper-static\": this.static, [`style-${styleType}`]: true, \"mode-icon\": this.shouldShowIcon, \"mode-initials\": !this.shouldShowIcon, \"state-static\": this.static, [`size-${this.size}`]: true }; const tag = this.static ? literal`div` : literal`button`; const label = this.label && !this.static ? html`<span class=\"user-label\" part=\"label\">${this.label}</span>` : nothing; return html` <${tag} class=${classMap(wrapperClasses)} ?disabled=${this.disabled} aria-label=${
|
|
8580
|
+
"default": "class extends LitElement { constructor() { super(...arguments); this.variant = \"icon\"; this.size = \"regular\"; this.styleType = \"flat\"; this.static = false; this.disabled = false; this.initials = \"\"; } get formattedInitials() { if (!this.initials) return \"\"; const clean = this.initials.replace(/\\s+/g, \"\").toUpperCase(); const maxInitialsLength = this.size === \"large\" ? 3 : 2; if (clean.length > maxInitialsLength) { console.warn( `Initials \"${this.initials}\" are longer than ${maxInitialsLength} characters.` ); return clean.slice(0, maxInitialsLength); } return clean; } get shouldShowIcon() { return this.variant === \"icon\"; } render() { const styleType = this.size === \"large\" && this.styleType === \"flat\" ? \"normal\" : this.styleType; const wrapperClasses = { wrapper: true, \"wrapper-static\": this.static, [`style-${styleType}`]: true, \"mode-icon\": this.shouldShowIcon, \"mode-initials\": !this.shouldShowIcon, \"state-static\": this.static, [`size-${this.size}`]: true, \"has-sublabel\": Boolean(this.sublabel) && !this.static }; const tag = this.static ? literal`div` : literal`button`; const visibleText = [this.label, this.sublabel].filter(Boolean).join(\", \"); const accessibleName = !this.static && visibleText || this.initials || \"User button\"; const label = this.label && !this.static ? html`<span class=\"user-label\" part=\"label\">${this.label}</span>` : nothing; const sublabel = this.sublabel && !this.static ? html`<span class=\"user-sublabel\" part=\"sublabel\"> ${this.sublabel} </span>` : nothing; return html` <${tag} class=${classMap(wrapperClasses)} ?disabled=${this.disabled} aria-label=${accessibleName} > <div class=\"content-container\" part=\"content-container\"> <div class=\"user-button-circle\"> ${this.shouldShowIcon ? html` <div class=\"icon-container\"> <slot name=\"icon\"> <!-- Fallback to default icon if no slot content --> <obi-user></obi-user> </slot> </div> ` : html` <span class=\"user-initials\"> ${this.formattedInitials} </span> `} </div> ${label} ${sublabel} </div> </${tag}> `; } }"
|
|
8552
8581
|
}
|
|
8553
8582
|
],
|
|
8554
8583
|
"exports": [
|
|
@@ -8601,7 +8630,7 @@
|
|
|
8601
8630
|
{
|
|
8602
8631
|
"kind": "variable",
|
|
8603
8632
|
"name": "ObcUserMenu",
|
|
8604
|
-
"default": "class extends LitElement { constructor() { super(...arguments); this.type = \"sign-in\"; this.size = \"regular\"; this.hasRecentlySignedIn = false; this.showUsername = true; this.username = \"\"; this.showPassword = true; this.password = \"\"; this.usernameError = \"\"; this.passwordError = \"\"; this.recentUsers = []; this.signedInActions = []; } get showRecentUsers() { return this.hasRecentlySignedIn && this.recentUsers.length > 0; } renderTextInput(placeholder, type = HTMLInputTypeAttribute.Text, value = \"\", onInput, errorText = \"\") { const isPassword = type === HTMLInputTypeAttribute.Password; return html` <obc-text-input-field .placeholder=${placeholder} .type=${type} .textAlign=${ObcTextInputFieldTextAlign.Left} .value=${value} .error=${Boolean(errorText)} .errorText=${errorText} .required=${true} .hasClearButton=${!isPassword} @input=${onInput} > </obc-text-input-field> `; } renderUserButtons(count, isLarge) { const size = isLarge ? Size.large : Size.regular; const users = this.recentUsers.slice(0, count); return html` <div class=${classMap({ users: true, large: isLarge, single: users.length === 1 })} > ${users.map( (user) => html` <obc-user-button .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${size} .initials=${user.initials} .label=${user.label} @click=${() => this.handleRecentUserClick(user)} ></obc-user-button> ` )} </div> `; } renderUserProfile(layout, size) { if (!this.userInitials && !this.userLabel) { return nothing; } const userButtonSize = size === \"large\" ? Size.large : Size.regular; return html` <div class=${classMap({ \"user-profile\": true, [layout]: true })} > <obc-user-button class=${classMap({ \"user-avatar\": true, [`size-${size}`]: true })} .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${userButtonSize} .initials=${this.userInitials ?? \"\"} .label=${this.userLabel ?? \"\"} ></obc-user-button> </div> `; } getSignedInActionIcon(actionId) { switch (actionId) { case \"calendar\": return html`<obi-calendar-google></obi-calendar-google>`; case \"log\": return html`<obi-log-open-google></obi-log-open-google>`; case \"preferences\": return html`<obi-settings-iec></obi-settings-iec>`; case \"user-account\": return html`<obi-user></obi-user>`; default: return nothing; } } normalizeActionId(actionId) { return actionId.trim().toLowerCase().replace(/[^a-z0-9]+/g, \"-\"); } handleSignedInActionClick(action) { this.dispatchEvent( new CustomEvent(\"signed-in-action-click\", { detail: { id: action.id, label: action.label } }) ); } handleRecentUserClick(user) { this.dispatchEvent( new CustomEvent(\"recent-user-click\", { detail: { initials: user.initials, label: user.label } }) ); } handleUsernameInput(event) { const target = event.target; this.username = target.value ?? \"\"; if (this.username) { this.usernameError = \"\"; } } handlePasswordInput(event) { const target = event.target; this.password = target.value ?? \"\"; if (this.password) { this.passwordError = \"\"; } } validateSignIn() { let valid = true; const needsUsername = this.type === \"sign-in\" && this.showUsername; const needsPassword = this.showPassword; if (needsUsername && !this.username) { this.usernameError = msg(\"Username is required\"); valid = false; } if (needsPassword && !this.password) { this.passwordError = msg(\"Password is required\"); valid = false; } return valid; } handleSignInClick() { if (!this.validateSignIn()) { return; } this.dispatchEvent( new CustomEvent(\"sign-in-click\", { detail: { username: this.showUsername ? this.username : void 0, password: this.showPassword ? this.password : void 0 } }) ); } handleSignOutClick() { this.dispatchEvent(new CustomEvent(\"sign-out-click\")); } renderSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderUserSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > <div class=\"user-primary\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"fields\"> ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderUserSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderLoadingSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"vertical\", \"large\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderLoadingSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderSignedIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-primary signed-in\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"divider\" aria-hidden=\"true\"></div> ${this.signedInActions.length ? html` <div class=\"nav-container\"> ${this.signedInActions.map((action) => { const normalizedId = this.normalizeActionId(action.id); return html` <obc-navigation-item .label=${action.label} hasIcon @click=${() => this.handleSignedInActionClick(action)} > <span slot=\"icon\"> <slot name=\"signed-in-action-icon-${normalizedId}\"> ${this.getSignedInActionIcon(normalizedId)} </slot> </span> </obc-navigation-item> `; })} </div> ` : nothing} <div class=\"button-container\"> <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } renderSignedInSmall() { const primaryAction = this.signedInActions.find( (action) => action.id === this.primaryActionId ); return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=\"button-container\"> ${primaryAction ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${() => this.handleSignedInActionClick(primaryAction)} > ${primaryAction.label} </obc-button> ` : nothing} <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } render() { let content = nothing; if (this.type === \"sign-in\") { content = this.size === \"small\" ? this.renderSignInSmall() : this.renderSignIn(); } if (this.type === \"user-sign-in\") { content = this.size === \"small\" ? this.renderUserSignInSmall() : this.renderUserSignIn(); } if (this.type === \"loading-sign-in\") { content = this.size === \"small\" ? this.renderLoadingSignInSmall() : this.renderLoadingSignIn(); } if (this.type === \"signed-in\") { content = this.size === \"small\" ? this.renderSignedInSmall() : this.renderSignedIn(); } return html` <div class=${classMap({ card: true, [`size-${this.size}`]: true, [`type-${this.type}`]: true })} > ${content} </div> `; } }"
|
|
8633
|
+
"default": "class extends LitElement { constructor() { super(...arguments); this.type = \"sign-in\"; this.size = \"regular\"; this.hasRecentlySignedIn = false; this.showUsername = true; this.username = \"\"; this.showPassword = true; this.password = \"\"; this.usernameError = \"\"; this.passwordError = \"\"; this.recentUsers = []; this.signedInActions = []; this.showUseAnotherAccount = true; } get showRecentUsers() { return this.hasRecentlySignedIn && this.recentUsers.length > 0; } renderTextInput(placeholder, type = HTMLInputTypeAttribute.Text, value = \"\", onInput, errorText = \"\") { const isPassword = type === HTMLInputTypeAttribute.Password; return html` <obc-text-input-field .placeholder=${placeholder} .type=${type} .textAlign=${ObcTextInputFieldTextAlign.Left} .value=${value} .error=${Boolean(errorText)} .errorText=${errorText} .required=${true} .hasClearButton=${!isPassword} @input=${onInput} > </obc-text-input-field> `; } renderUserButtons(count, isLarge) { const size = isLarge ? Size.large : Size.regular; const users = this.recentUsers.slice(0, count); return html` <div class=${classMap({ users: true, large: isLarge, single: users.length === 1 })} > ${users.map( (user) => html` <obc-user-button .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${size} .initials=${user.initials} .label=${user.label} .sublabel=${isLarge ? user.role : void 0} @click=${() => this.handleRecentUserClick(user)} ></obc-user-button> ` )} </div> `; } renderUserProfile(layout, size) { if (!this.userInitials && !this.userLabel) { return nothing; } const userButtonSize = size === \"large\" ? Size.large : Size.regular; const role = size === \"large\" ? this.userRole : void 0; return html` <div class=${classMap({ \"user-profile\": true, [layout]: true })} > <obc-user-button class=${classMap({ \"user-avatar\": true, [`size-${size}`]: true, \"has-role\": Boolean(role) })} .variant=${Variant.initials} .styleType=${StyleType.normal} .size=${userButtonSize} .initials=${this.userInitials ?? \"\"} .label=${this.userLabel ?? \"\"} .sublabel=${role} ></obc-user-button> </div> `; } getSignedInActionIcon(actionId) { switch (actionId) { case \"calendar\": return html`<obi-calendar-google></obi-calendar-google>`; case \"log\": return html`<obi-log-open-google></obi-log-open-google>`; case \"preferences\": return html`<obi-settings-iec></obi-settings-iec>`; case \"user-account\": return html`<obi-user></obi-user>`; default: return nothing; } } normalizeActionId(actionId) { return actionId.trim().toLowerCase().replace(/[^a-z0-9]+/g, \"-\"); } handleSignedInActionClick(action) { this.dispatchEvent( new CustomEvent(\"signed-in-action-click\", { detail: { id: action.id, label: action.label } }) ); } handleRecentUserClick(user) { this.dispatchEvent( new CustomEvent(\"recent-user-click\", { detail: { ...user } }) ); } handleUsernameInput(event) { const target = event.target; this.username = target.value ?? \"\"; if (this.username) { this.usernameError = \"\"; } } handlePasswordInput(event) { const target = event.target; this.password = target.value ?? \"\"; if (this.password) { this.passwordError = \"\"; } } validateSignIn() { let valid = true; const needsUsername = this.type === \"sign-in\" && this.showUsername; const needsPassword = this.showPassword; if (needsUsername && !this.username) { this.usernameError = msg(\"Username is required\"); valid = false; } if (needsPassword && !this.password) { this.passwordError = msg(\"Password is required\"); valid = false; } return valid; } handleSignInClick() { if (!this.validateSignIn()) { return; } this.dispatchEvent( new CustomEvent(\"sign-in-click\", { detail: { username: this.showUsername ? this.username : void 0, password: this.showPassword ? this.password : void 0 } }) ); } handleSignOutClick() { this.dispatchEvent(new CustomEvent(\"sign-out-click\")); } handleUseAnotherAccountClick() { this.dispatchEvent(new CustomEvent(\"use-another-account-click\")); } renderSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showUsername ? this.renderTextInput( msg(\"Username\"), HTMLInputTypeAttribute.Text, this.username, this.handleUsernameInput.bind(this), this.usernameError ) : nothing} ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderUserSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > <div class=\"user-primary\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"fields\"> ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> ${this.showUseAnotherAccount ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleUseAnotherAccountClick} > ${msg(\"Use another account\")} </obc-button> ` : nothing} </div> </div> ${this.showRecentUsers ? html` <div class=\"recent-container\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recently signed in\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, true)} </div> </div> ` : nothing} `; } renderUserSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=${classMap({ \"login-container\": true, \"signin-only\": !this.showRecentUsers })} > ${this.showPassword ? this.renderTextInput( msg(\"Password\"), HTMLInputTypeAttribute.Password, this.password, this.handlePasswordInput.bind(this), this.passwordError ) : nothing} <obc-button variant=${ButtonVariant.raised} fullWidth @click=${this.handleSignInClick} > ${msg(\"Sign in\")} </obc-button> ${this.showUseAnotherAccount ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleUseAnotherAccountClick} > ${msg(\"Use another account\")} </obc-button> ` : nothing} </div> ${this.showRecentUsers ? html` <div class=\"divider\" aria-hidden=\"true\"></div> <div class=\"recent-container recent\"> <div class=\"title-container\"> <div class=\"subtitle\">${msg(\"Recent\")}</div> </div> <div class=\"actions-container\"> ${this.renderUserButtons(3, false)} </div> </div> ` : nothing} `; } renderLoadingSignIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"vertical\", \"large\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderLoadingSignInSmall() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"Sign in\")}</h3> </div> <div class=\"user-primary loading\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} <obc-progress-bar class=\"progress\" type=${ProgressBarType.linear} mode=${ProgressBarMode.indeterminate} .showValue=${false} ></obc-progress-bar> </div> `; } renderSignedIn() { return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-primary signed-in\"> ${this.renderUserProfile(\"vertical\", \"large\")} </div> <div class=\"divider\" aria-hidden=\"true\"></div> ${this.signedInActions.length ? html` <div class=\"nav-container\"> ${this.signedInActions.map((action) => { const normalizedId = this.normalizeActionId(action.id); return html` <obc-navigation-item .label=${action.label} hasIcon @click=${() => this.handleSignedInActionClick(action)} > <span slot=\"icon\"> <slot name=\"signed-in-action-icon-${normalizedId}\"> ${this.getSignedInActionIcon(normalizedId)} </slot> </span> </obc-navigation-item> `; })} </div> ` : nothing} <div class=\"button-container\"> <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } renderSignedInSmall() { const primaryAction = this.signedInActions.find( (action) => action.id === this.primaryActionId ); return html` <div class=\"title-container\"> <h3 class=\"title\">${msg(\"User\")}</h3> </div> <div class=\"user-container\"> ${this.renderUserProfile(\"horizontal\", \"regular\")} </div> <div class=\"button-container\"> ${primaryAction ? html` <obc-button variant=${ButtonVariant.normal} fullWidth @click=${() => this.handleSignedInActionClick(primaryAction)} > ${primaryAction.label} </obc-button> ` : nothing} <obc-button variant=${ButtonVariant.normal} fullWidth @click=${this.handleSignOutClick} > ${msg(\"Sign out\")} </obc-button> </div> `; } render() { let content = nothing; if (this.type === \"sign-in\") { content = this.size === \"small\" ? this.renderSignInSmall() : this.renderSignIn(); } if (this.type === \"user-sign-in\") { content = this.size === \"small\" ? this.renderUserSignInSmall() : this.renderUserSignIn(); } if (this.type === \"loading-sign-in\") { content = this.size === \"small\" ? this.renderLoadingSignInSmall() : this.renderLoadingSignIn(); } if (this.type === \"signed-in\") { content = this.size === \"small\" ? this.renderSignedInSmall() : this.renderSignedIn(); } return html` <div class=${classMap({ card: true, [`size-${this.size}`]: true, [`type-${this.type}`]: true })} > ${content} </div> `; } }"
|
|
8605
8634
|
}
|
|
8606
8635
|
],
|
|
8607
8636
|
"exports": [
|
|
@@ -10270,7 +10299,7 @@
|
|
|
10270
10299
|
{
|
|
10271
10300
|
"kind": "variable",
|
|
10272
10301
|
"name": "ObcReadoutListItem",
|
|
10273
|
-
"default": "class extends LitElement { constructor() { super(...arguments); this.hasValue = true; this.value = null; this.valueType = ReadoutValueType.number; this.off = false; this.offText = \"OFF\"; this.hasSetpoint = false; this.hasAdvice = false; this.clickable = false; this.hasLeadingIcon = false; this.hasDegree = false; this.hasDegreeSpacer = false; this.fractionDigits = 0; this.maxDigits = 0; this.alert = false; this.showDebugOverlay = false; this.deferredSetpointHidePhase = ReadoutBlockHidePhase.none; this.hasCompletedFirstUpdate = false; } get resolvedSize() { return this.size ?? ReadoutListItemSize.small; } get resolvedStacking() { return this.stacking ?? \"trailing-unit\"; } /** Both leading-src stackings move the source into the label stack. */ get hasLeadingSrc() { const stacking = this.resolvedStacking; return stacking === \"leading-src\" || stacking === \"leading-src-inline\"; } get resolvedPriority() { return this.priority ?? \"regular\"; } /** * Whether a unit box follows the value: a unit, or a reserver alone — the * blank reserved column keeps a unit-less row aligned with its neighbours. */ get hasTrailingUnitBox() { return this.resolvedStacking !== \"leading-unit\" && (Boolean(this.unit) || Boolean(this.unitOptions?.spaceReserver)); } get resolvedFractionDigits() { return this.fractionDigits ?? 0; } get resolvedMaxDigits() { return resolveReadoutDigitCount(this.maxDigits); } /** * Whether a digit knob failed to arrive (`NaN` / `null` / `undefined`). * The raw knobs are forwarded to the blocks, which render the reading as * the unavailable dash (see `obc-readout-block.digitCountsMissing`); this * getter only keeps the setpoint comparison in agreement with what is * displayed. */ get digitCountsMissing() { return isReadoutDigitCountMissing(this.fractionDigits) || isReadoutDigitCountMissing(this.maxDigits); } get resolvedClickable() { const clickable = this.clickable; if (!clickable) { return false; } if (clickable === true) { return { border: \"squared\" /* squared */ }; } return { border: clickable.border ?? \"squared\" /* squared */ }; } get isAtSetpoint() { if (!this.hasSetpoint) { return false; } if (this.digitCountsMissing) { return false; } return isDisplayedAtSetpoint( resolveReadoutNumericValue(this.value, this.valueType) ?? null, this.setpoint, this.numericFormatOptions(this.resolvedMaxDigits) ); } get resolvedSetpointInteraction() { return this.setpointOptions?.interaction ?? \"always-visible\"; } get isFlipFlop() { return this.resolvedSetpointInteraction === \"flip-flop\"; } get isEqualSize() { return this.resolvedSetpointInteraction === \"equal-size\"; } get isPopUp() { return this.resolvedSetpointInteraction === \"pop-up\"; } get setpointTouching() { return this.setpointOptions?.touching ?? false; } /** * The setpoint is rendered \"emphasised\" (primary size + SemiBold weight) when * it is the focus of attention: while actively adjusting (`touching`), or while * a flip-flop has the value away from the setpoint. Otherwise it is a secondary * (smaller, regular-weight) reference next to the value. */ get isSetpointEmphasized() { if (!this.hasSetpoint) { return false; } if (this.setpointTouching) { return true; } return this.isFlipFlop && !this.isAtSetpoint; } /** * The row's enhanced (in-command) colour state, applied uniformly to BOTH the * value and the setpoint — they are always either both neutral or both enhanced * (never a blue setpoint next to a grey value). Driven by `priority` only; * `valueOptions.weight` changes weight, not colour. */ get rowEnhanced() { return this.resolvedPriority === \"enhanced\"; } /** Primary value-typography size for the current density tier. */ get primarySize() { return readoutPrimarySize(this.resolvedSize); } /** Secondary (de-emphasised) value-typography size for the current density tier. */ get secondarySize() { return readoutSecondarySize(this.resolvedSize); } get valueSize() { return readoutValueSize({ primary: this.primarySize, secondary: this.secondarySize, setpointEmphasized: this.isSetpointEmphasized, equalSize: this.isEqualSize }); } get setpointSize() { return readoutSetpointSize({ primary: this.primarySize, secondary: this.secondarySize, emphasized: this.isSetpointEmphasized, equalSize: this.isEqualSize }); } /** Value font weight passes straight to obc-textbox; regular when unset. Colour is separate. */ get valueWeight() { return this.valueOptions?.weight ?? ObcTextboxFontWeight.regular; } /** Label size: `xs` for dense list rows unless overridden (see {@link ReadoutLabelOptions}). */ get labelSize() { return this.labelOptions?.size ?? ObcTextboxSize.xs; } /** * Label weight: SemiBold only for enhanced (in-command) rows, regular * otherwise — the designer reduced the amount of semibold in the interface * (Figma 6.1 review). */ get labelWeight() { return this.rowEnhanced ? ObcTextboxFontWeight.semibold : ObcTextboxFontWeight.regular; } /** Setpoint is SemiBold only while emphasised, otherwise regular weight. */ get setpointWeight() { return readoutSetpointWeight(this.isSetpointEmphasized); } numericFormatOptions(maxDigits) { return readoutNumericFormatOptions(maxDigits, this.resolvedFractionDigits); } /** classMap fragment for a block / source carrying per-block data quality. */ dataQualityClasses(dataQuality) { return readoutDataQualityClasses(dataQuality); } /** * Forward the matching list-item icon slot into the block's single `icon` * slot. The variant's default marker lives in `obc-readout-block` and shows * when nothing is assigned here (an empty forwarded slot flattens to nothing). */ renderForwardedIcon(variant) { if (variant === ReadoutBlockVariant.setpoint) { return html`<slot name=\"setpoint-icon\" slot=\"icon\"></slot>`; } if (variant === ReadoutBlockVariant.advice) { return html`<slot name=\"advice-icon\" slot=\"icon\"></slot>`; } return html`<slot name=\"value-icon\" slot=\"icon\"></slot>`; } renderBlock(config) { return html` <obc-readout-block exportparts=\"block, block-content, block-text, block-icon, degree\" .variant=${config.variant} .value=${config.value ?? null} .valueType=${config.valueType ?? ReadoutValueType.number} .size=${this.resolvedSize} .valueSize=${config.valueSize} .enhanced=${config.enhanced} .weight=${config.weight} .hasDegree=${config.hasDegree ?? false} .hasIcon=${config.hasIcon ?? false} .fractionDigits=${this.fractionDigits} .maxDigits=${this.maxDigits} .hintedZeros=${config.hintedZeros} .hasSignSpacer=${config.hasSignSpacer ?? false} .spaceReserver=${config.spaceReserver} .off=${config.off ?? false} .offText=${this.offText} .touching=${config.touching ?? false} .hidePhase=${config.hidePhase ?? ReadoutBlockHidePhase.none} .dataQuality=${config.dataQuality} .alert=${config.alert ?? false} .category=${config.category ?? ReadoutAdviceCategory.regular} .active=${config.active ?? false} > ${this.renderForwardedIcon(config.variant)} </obc-readout-block> `; } /** * A cap-height `°` column whose width scales with the value size. Used after * the value (as the value↔unit boundary, via {@link renderValueUnitGap}) and * inside the setpoint / advice blocks. `inherit` makes the glyph take the * surrounding block's colour (setpoint/advice); otherwise it uses the value * colour, optionally `enhanced`. */ renderDegreeGlyph(size, opts = {}) { return html` <span class=${classMap({ \"degree-column\": true, [`degree-${size}`]: true, \"tone-enhanced\": !opts.inherit && Boolean(opts.enhanced), \"degree-inherit\": Boolean(opts.inherit) })} part=\"degree\" > <obc-textbox class=\"degree-glyph\" .size=${size} alignment=\"center\" >°</obc-textbox > </span> `; } /** * The gap rendered between the value digits and the unit. * * - `hasDegree`: a cap-height `°` column whose width scales with the value * size (the `°` replaces the default gap). * - otherwise: the default 2px gap (only when a trailing unit follows). * * `hasDegreeSpacer` deliberately does NOT add anything here — it keeps the 2px * gap and instead widens the unit column via {@link renderDegreeSpacer} (a * spacer AFTER the unit). That way a non-degree row's value digits stay * aligned with degree rows (degree column width = spacer width + 2px gap) * while its unit shifts left. Mirrors Figma `1:2920` (spacer) / `1:2970` * (degree). * * TODO(designer): cross-size alignment is deferred. Degree rows of different * value sizes have different `°` column widths (6/8/12px), so their value digit * edges stagger by `degree-width`. For degree rows of mixed sizes you cannot * align the value digit edges AND keep the unit column aligned — resolving it * needs a design decision (a constant degree reserve, which widens the smaller * rows' `°`, OR pinning the value edge and letting the unit column stagger). */ renderValueUnitGap() { if (!this.hasValue) { return nothing; } if ((this.hasDegree ?? false) && !this.off) { return this.renderDegreeGlyph(this.valueSize, { enhanced: this.rowEnhanced }); } if (this.hasTrailingUnitBox) { return html`<span class=\"value-unit-gap\" aria-hidden=\"true\"></span>`; } return nothing; } /** * A spacer rendered AFTER the unit when `hasDegreeSpacer` is set on a * non-degree row. Its width (`degree-compensation-padding`) = the degree * column width minus the 2px gap, so the row's value digits align with degree * rows in the same column while its unit shifts left. See * {@link renderValueUnitGap}. */ renderDegreeSpacer() { const hasDegree = this.hasDegree ?? false; const hasDegreeSpacer = this.hasDegreeSpacer ?? false; if (hasDegree || !hasDegreeSpacer) { return nothing; } return html`<span class=\"degree-spacer\" part=\"degree-spacer\" aria-hidden=\"true\" ></span>`; } renderTextbox(role, text, reserver, state2) { const weight = role === \"label\" ? this.labelWeight : ObcTextboxFontWeight.regular; const size = role === \"label\" ? this.labelSize : ObcTextboxSize.xs; const box = html` <obc-textbox class=${classMap({ [role]: true, ...this.dataQualityClasses(state2?.dataQuality) })} part=${role} .size=${size} .fontWeight=${weight} alignment=\"left\" > ${text} ${reserver ? html`<span slot=\"length\">${reserver}</span>` : nothing} </obc-textbox> `; return wrapWithAlertFrame(state2?.alert ?? false, box); } renderValueCluster() { const popUpAtSetpoint = this.isPopUp && this.isAtSetpoint && !this.setpointTouching; const setpointHidePhase = resolveSetpointHidePhase( popUpAtSetpoint, this.deferredSetpointHidePhase ); return html` <div class=\"value-cluster\" part=\"value-cluster\"> ${this.hasAdvice ? this.renderBlock({ variant: ReadoutBlockVariant.advice, value: this.advice, valueSize: this.secondarySize, enhanced: false, weight: ObcTextboxFontWeight.regular, hintedZeros: this.adviceOptions?.hintedZeros ?? false, hasSignSpacer: this.adviceOptions?.hasSignSpacer ?? false, spaceReserver: this.adviceOptions?.spaceReserver, hasDegree: this.hasDegree ?? false, dataQuality: this.adviceOptions?.dataQuality, alert: this.adviceOptions?.alert, category: this.adviceOptions?.category, active: this.adviceOptions?.active }) : nothing} ${this.hasSetpoint ? this.renderBlock({ variant: ReadoutBlockVariant.setpoint, value: this.setpoint, valueSize: this.setpointSize, // Value and setpoint share the enhanced colour state (both neutral // or both enhanced); the setpoint is bold only while emphasised. enhanced: this.rowEnhanced, weight: this.setpointWeight, hintedZeros: this.setpointOptions?.hintedZeros ?? false, hasSignSpacer: this.setpointOptions?.hasSignSpacer ?? false, spaceReserver: this.setpointOptions?.spaceReserver, hasDegree: this.hasDegree ?? false, touching: this.setpointTouching, hidePhase: setpointHidePhase, dataQuality: this.setpointOptions?.dataQuality, alert: this.setpointOptions?.alert }) : nothing} ${this.renderValueReading()} </div> `; } /** * The value reading: the value block, its degree column and the trailing unit * grouped in one relatively-positioned wrapper so the value alert frame AND the * value data-quality chip can wrap value + degree + unit together (Figma * 58:10120). * * Moving the degree / unit into this wrapper (the new last child of * `.value-cluster`) preserves every existing gap, so the underlying content * stays column-aligned with or without the frame / chip. Both the value alert * (overlay) and the value data-quality chip are applied here — NOT inside * `obc-readout-block` — so they extend over the unit; setpoint/advice keep their * own block-level frame and chip. The chip uses `outline` (not `border`), so it * never shifts the value's width / column alignment. */ renderValueReading() { return html` <div class=${classMap({ \"value-reading\": true, ...this.dataQualityClasses(this.valueOptions?.dataQuality) })} part=\"value-reading\" > ${this.hasValue ? this.renderBlock({ variant: ReadoutBlockVariant.value, value: this.value, valueType: this.valueType, valueSize: this.valueSize, enhanced: this.rowEnhanced, weight: this.valueWeight, hintedZeros: this.valueOptions?.hintedZeros ?? false, hasSignSpacer: this.valueOptions?.hasSignSpacer ?? false, spaceReserver: this.valueOptions?.spaceReserver, off: this.off, hasIcon: this.valueOptions?.hasIcon ?? false }) : nothing} ${this.renderValueUnitGap()} <div class=\"unit-area\" part=\"unit-area\"> ${this.renderTrailingUnit()} ${this.renderDegreeSpacer()} </div> ${this.renderValueAlertOverlay()} </div> `; } /** * The value alert frame, drawn as a pure overlay around the value reading * (value + degree + unit). It reserves no space — the `obc-alert-frame` sits in * an absolutely-positioned box offset outward (see `.value-alert-overlay` in * the CSS) so its stroke is centred on the 4px/2px padding line and toggling it * never shifts content or row height. Renders only when `valueOptions.alert` is * a config object. */ renderValueAlertOverlay() { const alert = this.valueOptions?.alert; if (typeof alert !== \"object\" || alert === null) { return nothing; } const thickness = alert.thickness ?? ObcAlertFrameThickness.Small; return html` <div class=\"value-alert-overlay\" aria-hidden=\"true\"> <obc-alert-frame part=\"value-alert-frame\" .type=${alert.type ?? ObcAlertFrameType.Regular} .thickness=${thickness} .status=${alert.status ?? AlertType.Alarm} .mode=${alert.mode ?? ObcAlertFrameMode.ackedActive} .flashingSpeed=${alert.flashingSpeed ?? FlashingSpeed.Default} .showIcon=${alert.showIcon ?? false} .showAlertCategoryIcon=${alert.showAlertCategoryIcon ?? true} .wrapContent=${false} .fullWidth=${false} ></obc-alert-frame> </div> `; } renderLabelContainer() { const stacking = this.resolvedStacking; const showLeadingUnit = stacking === \"leading-unit\" && Boolean(this.unit); const showLeadingSrc = this.hasLeadingSrc && Boolean(this.src); return html` <div class=\"label-container\" part=\"label-container\"> ${this.hasLeadingIcon ? html`<span class=\"leading-icon\" aria-hidden=\"true\" ><slot name=\"leading-icon\"></slot ></span>` : nothing} <div class=\"label-stack\" part=\"label-stack\"> ${this.label ? this.renderTextbox( \"label\", this.label, this.labelOptions?.spaceReserver ) : nothing} ${showLeadingUnit ? this.renderTextbox( \"unit\", this.unit ?? \"\", this.unitOptions?.spaceReserver ) : nothing} ${showLeadingSrc ? this.renderSourceBlock() : nothing} </div> </div> `; } renderTrailingUnit() { if (!this.hasTrailingUnitBox) { return nothing; } return this.renderTextbox( \"unit\", this.unit ?? \"\", this.unitOptions?.spaceReserver ); } /** * The source text plus its optional state chip and deviation line. The * plain (regular, no-deviation) case renders the bare textbox; a state or a * deviation wraps it in the `.source-block` stack. */ renderSourceBlock() { const state2 = this.srcOptions?.state ?? \"regular\"; const deviation = this.srcOptions?.deviation; const hasDeviation = deviation !== void 0 && Number.isFinite(deviation); const box = this.renderTextbox( \"source\", this.src ?? \"\", this.srcOptions?.spaceReserver, this.srcOptions ); if (state2 === \"regular\" && !hasDeviation) { return box; } return html` <div class=${classMap({ \"source-block\": true, [`source-state-${state2}`]: state2 !== \"regular\" /* regular */ })} part=\"source-block\" > ${box} ${hasDeviation ? html`<span class=\"source-deviation\"> <obi-delta aria-hidden=\"true\"></obi-delta> <obc-textbox class=\"source-deviation-value\" .size=${ObcTextboxSize.xs} .tabularNums=${true} alignment=\"left\" >${deviation}</obc-textbox > </span>` : nothing} </div> `; } renderTrailingSource() { if (this.hasLeadingSrc || !this.src) { return nothing; } return html` <div class=\"divider\" part=\"divider\" aria-hidden=\"true\"></div> ${this.renderSourceBlock()} `; } renderContent() { return html` <div class=\"content\" part=\"content\"> ${this.renderLabelContainer()} <div class=\"value-area\" part=\"value-area\"> ${this.renderValueCluster()} </div> ${this.renderTrailingSource()} </div> `; } willUpdate(changed) { super.willUpdate(changed); assertReadoutValueType(\"obc-readout-list-item\", this.value, this.valueType); assertReadoutFractionDigits(\"obc-readout-list-item\", this.fractionDigits); } updated(changed) { super.updated(changed); const firstUpdate = !this.hasCompletedFirstUpdate; this.hasCompletedFirstUpdate = true; if (!this.isPopUp || this.setpointTouching) { this.clearDeferredSetpointHide(); return; } const shouldHide = this.hasSetpoint && this.isAtSetpoint; if (firstUpdate) { this.deferredSetpointHidePhase = shouldHide ? ReadoutBlockHidePhase.hidden : ReadoutBlockHidePhase.none; return; } if (!shouldHide) { this.clearDeferredSetpointHide(); return; } if (this.deferredSetpointHidePhase !== ReadoutBlockHidePhase.none) { return; } this.deferredSetpointHidePhase = ReadoutBlockHidePhase.hiding; window.clearTimeout(this.deferredSetpointHideTimer); this.deferredSetpointHideTimer = window.setTimeout(() => { this.deferredSetpointHidePhase = ReadoutBlockHidePhase.hidden; this.deferredSetpointHideTimer = void 0; }, 100); } clearDeferredSetpointHide() { if (this.deferredSetpointHidePhase !== ReadoutBlockHidePhase.none) { this.deferredSetpointHidePhase = ReadoutBlockHidePhase.none; } window.clearTimeout(this.deferredSetpointHideTimer); this.deferredSetpointHideTimer = void 0; } disconnectedCallback() { window.clearTimeout(this.deferredSetpointHideTimer); this.deferredSetpointHideTimer = void 0; if (this.deferredSetpointHidePhase === ReadoutBlockHidePhase.hiding) { this.deferredSetpointHidePhase = ReadoutBlockHidePhase.hidden; } super.disconnectedCallback(); } render() { const clickable = this.resolvedClickable; const dataQuality = this.dataQuality; const classes = classMap({ root: true, [`size-${this.resolvedSize}`]: true, [`stacking-${this.resolvedStacking}`]: true, [`priority-${this.resolvedPriority}`]: true, \"data-low-integrity\": dataQuality === ReadoutListItemDataQuality.lowIntegrity, \"data-invalid\": dataQuality === ReadoutListItemDataQuality.invalid, \"flip-flop\": this.isFlipFlop, clickable: Boolean(clickable), [`border-${clickable ? clickable.border : \"squared\"}`]: Boolean(clickable) }); const surface = html`<div class=\"surface\" part=\"surface\"> ${this.renderContent()} </div>`; const root = clickable ? html`<button class=${classes} part=\"root\" type=\"button\"> ${surface} </button>` : html`<div class=${classes} part=\"root\">${surface}</div>`; const alert = this.alert === true ? {} : this.alert; return wrapWithAlertFrame(alert, root, true); } }"
|
|
10302
|
+
"default": "class extends LitElement { constructor() { super(...arguments); this.hasValue = true; this.value = null; this.valueType = ReadoutValueType.number; this.off = false; this.offText = \"OFF\"; this.hasSetpoint = false; this.hasAdvice = false; this.clickable = false; this.hasLeadingIcon = false; this.hasDegree = false; this.hasDegreeSpacer = false; this.fractionDigits = 0; this.maxDigits = 0; this.alert = false; this.showDebugOverlay = false; this.deferredSetpointHidePhase = ReadoutBlockHidePhase.none; this.hasCompletedFirstUpdate = false; } get resolvedSize() { return this.size ?? ReadoutListItemSize.small; } get resolvedStacking() { return this.stacking ?? \"trailing-unit\"; } /** Both leading-src stackings move the source into the label stack. */ get hasLeadingSrc() { const stacking = this.resolvedStacking; return stacking === \"leading-src\" || stacking === \"leading-src-inline\"; } get resolvedPriority() { return this.priority ?? \"regular\"; } /** * Whether a unit box follows the value: a unit, or a reserver alone — the * blank reserved column keeps a unit-less row aligned with its neighbours. */ get hasTrailingUnitBox() { return this.resolvedStacking !== \"leading-unit\" && (Boolean(this.unit) || Boolean(this.unitOptions?.spaceReserver)); } get resolvedFractionDigits() { return this.fractionDigits ?? 0; } get resolvedMaxDigits() { return resolveReadoutDigitCount(this.maxDigits); } /** * Whether a digit knob failed to arrive (`NaN` / `null` / `undefined`). * The raw knobs are forwarded to the blocks, which render the reading as * the unavailable dash (see `obc-readout-block.digitCountsMissing`); this * getter only keeps the setpoint comparison in agreement with what is * displayed. */ get digitCountsMissing() { return isReadoutDigitCountMissing(this.fractionDigits) || isReadoutDigitCountMissing(this.maxDigits); } get resolvedClickable() { const clickable = this.clickable; if (!clickable) { return false; } if (clickable === true) { return { border: \"squared\" /* squared */ }; } return { border: clickable.border ?? \"squared\" /* squared */ }; } get isAtSetpoint() { if (!this.hasSetpoint) { return false; } if (this.digitCountsMissing) { return false; } return isDisplayedAtSetpoint( resolveReadoutNumericValue(this.value, this.valueType) ?? null, this.setpoint, this.numericFormatOptions(this.resolvedMaxDigits) ); } get resolvedSetpointInteraction() { return this.setpointOptions?.interaction ?? \"always-visible\"; } get isFlipFlop() { return this.resolvedSetpointInteraction === \"flip-flop\"; } get isEqualSize() { return this.resolvedSetpointInteraction === \"equal-size\"; } get isPopUp() { return this.resolvedSetpointInteraction === \"pop-up\"; } get setpointTouching() { return this.setpointOptions?.touching ?? false; } /** * The setpoint is rendered \"emphasised\" (primary size + SemiBold weight) when * it is the focus of attention: while actively adjusting (`touching`), or while * a flip-flop has the value away from the setpoint. Otherwise it is a secondary * (smaller, regular-weight) reference next to the value. */ get isSetpointEmphasized() { if (!this.hasSetpoint) { return false; } if (this.setpointTouching) { return true; } return this.isFlipFlop && !this.isAtSetpoint; } /** * The row's enhanced (in-command) colour state, applied uniformly to BOTH the * value and the setpoint — they are always either both neutral or both enhanced * (never a blue setpoint next to a grey value). Driven by `priority` only; * `valueOptions.weight` changes weight, not colour. */ get rowEnhanced() { return this.resolvedPriority === \"enhanced\"; } /** Primary value-typography size for the current density tier. */ get primarySize() { return readoutPrimarySize(this.resolvedSize); } /** Secondary (de-emphasised) value-typography size for the current density tier. */ get secondarySize() { return readoutSecondarySize(this.resolvedSize); } get valueSize() { return readoutValueSize({ primary: this.primarySize, secondary: this.secondarySize, setpointEmphasized: this.isSetpointEmphasized, equalSize: this.isEqualSize }); } get setpointSize() { return readoutSetpointSize({ primary: this.primarySize, secondary: this.secondarySize, emphasized: this.isSetpointEmphasized, equalSize: this.isEqualSize }); } /** Value font weight passes straight to obc-textbox; regular when unset. Colour is separate. */ get valueWeight() { return this.valueOptions?.weight ?? ObcTextboxFontWeight.regular; } /** Label size: `xs` for dense list rows unless overridden (see {@link ReadoutLabelOptions}). */ get labelSize() { return this.labelOptions?.size ?? ObcTextboxSize.xs; } /** * Label weight: SemiBold only for enhanced (in-command) rows, regular * otherwise — the designer reduced the amount of semibold in the interface * (Figma 6.1 review). */ get labelWeight() { return this.rowEnhanced ? ObcTextboxFontWeight.semibold : ObcTextboxFontWeight.regular; } /** Setpoint is SemiBold only while emphasised, otherwise regular weight. */ get setpointWeight() { return readoutSetpointWeight(this.isSetpointEmphasized); } numericFormatOptions(maxDigits) { return readoutNumericFormatOptions(maxDigits, this.resolvedFractionDigits); } /** classMap fragment for a block / source carrying per-block data quality. */ dataQualityClasses(dataQuality) { return readoutDataQualityClasses(dataQuality); } /** * Forward the matching list-item icon slot into the block's single `icon` * slot. The variant's default marker lives in `obc-readout-block` and shows * when nothing is assigned here (an empty forwarded slot flattens to nothing). */ renderForwardedIcon(variant) { if (variant === ReadoutBlockVariant.setpoint) { return html`<slot name=\"setpoint-icon\" slot=\"icon\"></slot>`; } if (variant === ReadoutBlockVariant.advice) { return html`<slot name=\"advice-icon\" slot=\"icon\"></slot>`; } return html`<slot name=\"value-icon\" slot=\"icon\"></slot>`; } renderBlock(config) { return html` <obc-readout-block exportparts=\"block, block-content, block-text, block-icon, degree\" .variant=${config.variant} .value=${config.value ?? null} .valueType=${config.valueType ?? ReadoutValueType.number} .size=${this.resolvedSize} .valueSize=${config.valueSize} .enhanced=${config.enhanced} .weight=${config.weight} .hasDegree=${config.hasDegree ?? false} .hasIcon=${config.hasIcon ?? false} .fractionDigits=${this.fractionDigits} .maxDigits=${this.maxDigits} .hintedZeros=${config.hintedZeros} .hasSignSpacer=${config.hasSignSpacer ?? false} .spaceReserver=${config.spaceReserver} .off=${config.off ?? false} .offText=${this.offText} .touching=${config.touching ?? false} .hidePhase=${config.hidePhase ?? ReadoutBlockHidePhase.none} .dataQuality=${config.dataQuality} .alert=${config.alert ?? false} .category=${config.category ?? ReadoutAdviceCategory.regular} .active=${config.active ?? false} > ${this.renderForwardedIcon(config.variant)} </obc-readout-block> `; } /** * A cap-height `°` column whose width scales with the value size. Used after * the value (as the value↔unit boundary, via {@link renderValueUnitGap}) and * inside the setpoint / advice blocks. `inherit` makes the glyph take the * surrounding block's colour (setpoint/advice); otherwise it uses the value * colour, optionally `enhanced`. */ renderDegreeGlyph(size, opts = {}) { return html` <span class=${classMap({ \"degree-column\": true, [`degree-${size}`]: true, \"tone-enhanced\": !opts.inherit && Boolean(opts.enhanced), \"degree-inherit\": Boolean(opts.inherit) })} part=\"degree\" > <obc-textbox class=\"degree-glyph\" .size=${size} alignment=\"center\" >°</obc-textbox > </span> `; } /** * The gap rendered between the value digits and the unit. * * - `hasDegree`: a cap-height `°` column whose width scales with the value * size (the `°` replaces the default gap). * - otherwise: the default 2px gap (only when a trailing unit follows). * * `hasDegreeSpacer` deliberately does NOT add anything here — it keeps the 2px * gap and instead widens the unit column via {@link renderDegreeSpacer} (a * spacer AFTER the unit). That way a non-degree row's value digits stay * aligned with degree rows (degree column width = spacer width + 2px gap) * while its unit shifts left. Mirrors Figma `1:2920` (spacer) / `1:2970` * (degree). * * TODO(designer): cross-size alignment is deferred. Degree rows of different * value sizes have different `°` column widths (6/8/12px), so their value digit * edges stagger by `degree-width`. For degree rows of mixed sizes you cannot * align the value digit edges AND keep the unit column aligned — resolving it * needs a design decision (a constant degree reserve, which widens the smaller * rows' `°`, OR pinning the value edge and letting the unit column stagger). */ renderValueUnitGap() { if (!this.hasValue) { return nothing; } if ((this.hasDegree ?? false) && !this.off) { return this.renderDegreeGlyph(this.valueSize, { enhanced: this.rowEnhanced }); } if (this.hasTrailingUnitBox) { return html`<span class=\"value-unit-gap\" aria-hidden=\"true\"></span>`; } return nothing; } /** * A spacer rendered AFTER the unit when `hasDegreeSpacer` is set on a * non-degree row. Its width (`degree-compensation-padding`) = the degree * column width minus the 2px gap, so the row's value digits align with degree * rows in the same column while its unit shifts left. See * {@link renderValueUnitGap}. */ renderDegreeSpacer() { const hasDegree = this.hasDegree ?? false; const hasDegreeSpacer = this.hasDegreeSpacer ?? false; if (hasDegree || !hasDegreeSpacer) { return nothing; } return html`<span class=\"degree-spacer\" part=\"degree-spacer\" aria-hidden=\"true\" ></span>`; } renderTextbox(role, text, reserver, state2) { const weight = role === \"label\" ? this.labelWeight : ObcTextboxFontWeight.regular; const size = role === \"label\" ? this.labelSize : ObcTextboxSize.xs; const box = html` <obc-textbox class=${classMap({ [role]: true, ...this.dataQualityClasses(state2?.dataQuality) })} part=${role} .size=${size} .fontWeight=${weight} alignment=\"left\" > ${text} ${reserver ? html`<span slot=\"length\">${reserver}</span>` : nothing} </obc-textbox> `; return wrapWithAlertFrame(state2?.alert ?? false, box); } renderValueCluster() { const popUpAtSetpoint = this.isPopUp && this.isAtSetpoint && !this.setpointTouching; const setpointHidePhase = resolveSetpointHidePhase( popUpAtSetpoint, this.deferredSetpointHidePhase ); return html` <div class=\"value-cluster\" part=\"value-cluster\"> ${this.hasAdvice ? this.renderBlock({ variant: ReadoutBlockVariant.advice, value: this.advice, valueSize: this.secondarySize, enhanced: false, weight: ObcTextboxFontWeight.regular, hintedZeros: this.adviceOptions?.hintedZeros ?? false, hasSignSpacer: this.adviceOptions?.hasSignSpacer ?? false, spaceReserver: this.adviceOptions?.spaceReserver, hasDegree: this.hasDegree ?? false, dataQuality: this.adviceOptions?.dataQuality, alert: this.adviceOptions?.alert, category: this.adviceOptions?.category, active: this.adviceOptions?.active }) : nothing} ${this.hasSetpoint ? this.renderBlock({ variant: ReadoutBlockVariant.setpoint, value: this.setpoint, valueSize: this.setpointSize, // Value and setpoint share the enhanced colour state (both neutral // or both enhanced); the setpoint is bold only while emphasised. enhanced: this.rowEnhanced, weight: this.setpointWeight, hintedZeros: this.setpointOptions?.hintedZeros ?? false, hasSignSpacer: this.setpointOptions?.hasSignSpacer ?? false, spaceReserver: this.setpointOptions?.spaceReserver, hasDegree: this.hasDegree ?? false, touching: this.setpointTouching, hidePhase: setpointHidePhase, dataQuality: this.setpointOptions?.dataQuality, alert: this.setpointOptions?.alert }) : nothing} ${this.renderValueReading()} </div> `; } /** * The value reading: the value block, its degree column and the trailing unit * grouped in one relatively-positioned wrapper so the value alert frame AND the * value data-quality chip can wrap value + degree + unit together (Figma * 58:10120). * * Moving the degree / unit into this wrapper (the new last child of * `.value-cluster`) preserves every existing gap, so the underlying content * stays column-aligned with or without the frame / chip. Both the value alert * (overlay) and the value data-quality chip are applied here — NOT inside * `obc-readout-block` — so they extend over the unit; setpoint/advice keep their * own block-level frame and chip. The chip uses `outline` (not `border`), so it * never shifts the value's width / column alignment. */ renderValueReading() { return html` <div class=${classMap({ \"value-reading\": true, ...this.dataQualityClasses(this.valueOptions?.dataQuality) })} part=\"value-reading\" > ${this.hasValue ? this.renderBlock({ variant: ReadoutBlockVariant.value, value: this.value, valueType: this.valueType, valueSize: this.valueSize, enhanced: this.rowEnhanced, weight: this.valueWeight, hintedZeros: this.valueOptions?.hintedZeros ?? false, hasSignSpacer: this.valueOptions?.hasSignSpacer ?? false, spaceReserver: this.valueOptions?.spaceReserver, off: this.off, hasIcon: this.valueOptions?.hasIcon ?? false }) : nothing} ${this.renderValueUnitGap()} <div class=\"unit-area\" part=\"unit-area\"> ${this.renderTrailingUnit()} ${this.renderDegreeSpacer()} </div> ${this.renderValueAlertOverlay()} </div> `; } /** * The value alert frame, drawn as a pure overlay around the value reading * (value + degree + unit). It reserves no space — the `obc-alert-frame` sits in * an absolutely-positioned box offset outward (see `.value-alert-overlay` in * the CSS) so its stroke is centred on the 4px/2px padding line and toggling it * never shifts content or row height. Renders only when `valueOptions.alert` is * a config object. */ renderValueAlertOverlay() { const alert = this.valueOptions?.alert; if (typeof alert !== \"object\" || alert === null) { return nothing; } const thickness = alert.thickness ?? ObcAlertFrameThickness.Small; return html` <div class=\"value-alert-overlay\" aria-hidden=\"true\"> <obc-alert-frame part=\"value-alert-frame\" .type=${alert.type ?? ObcAlertFrameType.Regular} .thickness=${thickness} .status=${alert.status ?? AlertType.Alarm} .mode=${alert.mode ?? ObcAlertFrameMode.ackedActive} .flashingSpeed=${alert.flashingSpeed ?? FlashingSpeed.Default} .showIcon=${alert.showIcon ?? false} .showAlertCategoryIcon=${alert.showAlertCategoryIcon ?? true} .wrapContent=${false} .fullWidth=${false} ></obc-alert-frame> </div> `; } renderLabelContainer() { const stacking = this.resolvedStacking; const showLeadingUnit = stacking === \"leading-unit\" && Boolean(this.unit); const showLeadingSrc = this.hasLeadingSrc && Boolean(this.src); if (!this.hasLeadingIcon && !this.label && !showLeadingUnit && !showLeadingSrc) { return nothing; } return html` <div class=\"label-container\" part=\"label-container\"> ${this.hasLeadingIcon ? html`<span class=\"leading-icon\" aria-hidden=\"true\" ><slot name=\"leading-icon\"></slot ></span>` : nothing} <div class=\"label-stack\" part=\"label-stack\"> ${this.label ? this.renderTextbox( \"label\", this.label, this.labelOptions?.spaceReserver ) : nothing} ${showLeadingUnit ? this.renderTextbox( \"unit\", this.unit ?? \"\", this.unitOptions?.spaceReserver ) : nothing} ${showLeadingSrc ? this.renderSourceBlock() : nothing} </div> </div> `; } renderTrailingUnit() { if (!this.hasTrailingUnitBox) { return nothing; } return this.renderTextbox( \"unit\", this.unit ?? \"\", this.unitOptions?.spaceReserver ); } /** * The source text plus its optional state chip and deviation line. The * plain (regular, no-deviation) case renders the bare textbox; a state or a * deviation wraps it in the `.source-block` stack. */ renderSourceBlock() { const state2 = this.srcOptions?.state ?? \"regular\"; const deviation = this.srcOptions?.deviation; const hasDeviation = deviation !== void 0 && Number.isFinite(deviation); const box = this.renderTextbox( \"source\", this.src ?? \"\", this.srcOptions?.spaceReserver, this.srcOptions ); if (state2 === \"regular\" && !hasDeviation) { return box; } return html` <div class=${classMap({ \"source-block\": true, [`source-state-${state2}`]: state2 !== \"regular\" /* regular */ })} part=\"source-block\" > ${box} ${hasDeviation ? html`<span class=\"source-deviation\"> <obi-delta aria-hidden=\"true\"></obi-delta> <obc-textbox class=\"source-deviation-value\" .size=${ObcTextboxSize.xs} .tabularNums=${true} alignment=\"left\" >${deviation}</obc-textbox > </span>` : nothing} </div> `; } renderTrailingSource() { if (this.hasLeadingSrc || !this.src) { return nothing; } return html` <div class=\"divider\" part=\"divider\" aria-hidden=\"true\"></div> ${this.renderSourceBlock()} `; } renderContent() { return html` <div class=\"content\" part=\"content\"> ${this.renderLabelContainer()} <div class=\"value-area\" part=\"value-area\"> ${this.renderValueCluster()} </div> ${this.renderTrailingSource()} </div> `; } willUpdate(changed) { super.willUpdate(changed); assertReadoutValueType(\"obc-readout-list-item\", this.value, this.valueType); assertReadoutFractionDigits(\"obc-readout-list-item\", this.fractionDigits); } updated(changed) { super.updated(changed); const firstUpdate = !this.hasCompletedFirstUpdate; this.hasCompletedFirstUpdate = true; if (!this.isPopUp || this.setpointTouching) { this.clearDeferredSetpointHide(); return; } const shouldHide = this.hasSetpoint && this.isAtSetpoint; if (firstUpdate) { this.deferredSetpointHidePhase = shouldHide ? ReadoutBlockHidePhase.hidden : ReadoutBlockHidePhase.none; return; } if (!shouldHide) { this.clearDeferredSetpointHide(); return; } if (this.deferredSetpointHidePhase !== ReadoutBlockHidePhase.none) { return; } this.deferredSetpointHidePhase = ReadoutBlockHidePhase.hiding; window.clearTimeout(this.deferredSetpointHideTimer); this.deferredSetpointHideTimer = window.setTimeout(() => { this.deferredSetpointHidePhase = ReadoutBlockHidePhase.hidden; this.deferredSetpointHideTimer = void 0; }, 100); } clearDeferredSetpointHide() { if (this.deferredSetpointHidePhase !== ReadoutBlockHidePhase.none) { this.deferredSetpointHidePhase = ReadoutBlockHidePhase.none; } window.clearTimeout(this.deferredSetpointHideTimer); this.deferredSetpointHideTimer = void 0; } disconnectedCallback() { window.clearTimeout(this.deferredSetpointHideTimer); this.deferredSetpointHideTimer = void 0; if (this.deferredSetpointHidePhase === ReadoutBlockHidePhase.hiding) { this.deferredSetpointHidePhase = ReadoutBlockHidePhase.hidden; } super.disconnectedCallback(); } render() { const clickable = this.resolvedClickable; const dataQuality = this.dataQuality; const classes = classMap({ root: true, [`size-${this.resolvedSize}`]: true, [`stacking-${this.resolvedStacking}`]: true, [`priority-${this.resolvedPriority}`]: true, \"data-low-integrity\": dataQuality === ReadoutListItemDataQuality.lowIntegrity, \"data-invalid\": dataQuality === ReadoutListItemDataQuality.invalid, \"flip-flop\": this.isFlipFlop, clickable: Boolean(clickable), [`border-${clickable ? clickable.border : \"squared\"}`]: Boolean(clickable) }); const surface = html`<div class=\"surface\" part=\"surface\"> ${this.renderContent()} </div>`; const root = clickable ? html`<button class=${classes} part=\"root\" type=\"button\"> ${surface} </button>` : html`<div class=${classes} part=\"root\">${surface}</div>`; const alert = this.alert === true ? {} : this.alert; return wrapWithAlertFrame(alert, root, true); } }"
|
|
10274
10303
|
}
|
|
10275
10304
|
],
|
|
10276
10305
|
"exports": [
|
|
@@ -39658,7 +39687,7 @@
|
|
|
39658
39687
|
"declarations": [
|
|
39659
39688
|
{
|
|
39660
39689
|
"kind": "class",
|
|
39661
|
-
"description": "`<obc-transmitter-button>` – The pressable readout chip
|
|
39690
|
+
"description": "`<obc-transmitter-button>` – The pressable readout chip at the core of a\ntransmitter: a bordered button around one reading.\n\nThe reading is a label-less `<obc-readout-list-item>` (the Figma \"automation\nvalue\"): leading icon, optional advice and setpoint, value, optional degree\nand unit, all rendered by the readout family. The leading icon is slotted so\nthe consumer provides the type-specific content.\n\n### Features / Variants\n- **`value`** – bordered chip showing an icon, value and unit. Opt into a\n leading advice segment with `hasAdvice`/`adviceValue`, a setpoint segment\n with `hasSetPoint`/`setpointValue`, and a degree column before the unit\n with `hasDegree`.\n- **`tag`** – a static rounded pill showing a short identifier (e.g. `TT`)\n from the `label` property, with no live value.\n- **`size`** – `regular`, `medium` or `large`, the list item's `small`,\n `medium` and `large` tiers: the value text, the icon and the advice/setpoint\n segments scale, the unit stays extra small.\n- **Formatting** – `fractionDigits` sets the decimal precision, `maxDigits`\n reserves a number of integer digits, and `hintedZeros` renders the reserved\n leading positions as muted zeros (e.g. `0012.3`). The sign never consumes\n a reserved position (`-0012.3`), so a negative value is one character\n wider than a positive one; `hasSignSpacer` reserves the sign column so\n the width does not change across zero. All three segments share this\n formatting — it is `obc-readout-block`'s.\n- **Missing values** – `value`, `adviceValue` and `setpointValue` each render\n dashes when they are `NaN`, `null` or `undefined`; with `hintedZeros` the\n dashes fill the whole reserved width (e.g. `---.-`).\n\n### Usage Guidelines\nUse as a building block for `<obc-transmitter>` and `<obc-transmitter-stack>`;\nit is the part that carries the measured value or the tag identifier. Slot in\nthe type-specific icon; the advice and setpoint segments are value-driven and\nread-only.\n\n**TODO(designer):** the hit area is the visible chip, 24 px high at `regular`:\nat the WCAG 2.5.8 floor of 24 px, below the 48 px touch-target token. A\n48 px target would overlap the id tag, the leader line and neighbouring\n`<obc-transmitter-stack>` segments, so the size needs a design decision.\n\n### Slots\n| Slot Name | Conditions | Purpose |\n|-----------|-------------------------------|--------------------------------|\n| icon | `value` variant and `hasIcon` | Leading icon beside the value. |",
|
|
39662
39691
|
"name": "ObcTransmitterButton",
|
|
39663
39692
|
"slots": [
|
|
39664
39693
|
{
|
|
@@ -39730,6 +39759,15 @@
|
|
|
39730
39759
|
"default": "false",
|
|
39731
39760
|
"description": "Reserve a minus-sign column on every segment, filled by the real sign only while a value is negative, so the width does not change across zero."
|
|
39732
39761
|
},
|
|
39762
|
+
{
|
|
39763
|
+
"kind": "field",
|
|
39764
|
+
"name": "hasDegree",
|
|
39765
|
+
"type": {
|
|
39766
|
+
"text": "boolean"
|
|
39767
|
+
},
|
|
39768
|
+
"default": "false",
|
|
39769
|
+
"description": "Show a degree column between the value and the unit (e.g. `12.3°` then `C`)."
|
|
39770
|
+
},
|
|
39733
39771
|
{
|
|
39734
39772
|
"kind": "field",
|
|
39735
39773
|
"name": "hasIcon",
|
|
@@ -39779,6 +39817,15 @@
|
|
|
39779
39817
|
"default": "''",
|
|
39780
39818
|
"description": "Short tag identifier shown in the `tag` variant (e.g. `TT`)."
|
|
39781
39819
|
},
|
|
39820
|
+
{
|
|
39821
|
+
"kind": "field",
|
|
39822
|
+
"name": "idTag",
|
|
39823
|
+
"type": {
|
|
39824
|
+
"text": "string"
|
|
39825
|
+
},
|
|
39826
|
+
"default": "''",
|
|
39827
|
+
"description": "Identifier appended to the button's accessible name only (e.g. `#0001`); the parent transmitter draws the visible tag outside the button, where it cannot join the name."
|
|
39828
|
+
},
|
|
39782
39829
|
{
|
|
39783
39830
|
"kind": "field",
|
|
39784
39831
|
"name": "isTag",
|
|
@@ -39787,37 +39834,120 @@
|
|
|
39787
39834
|
},
|
|
39788
39835
|
{
|
|
39789
39836
|
"kind": "method",
|
|
39790
|
-
"name": "
|
|
39837
|
+
"name": "renderReading",
|
|
39838
|
+
"privacy": "private"
|
|
39839
|
+
},
|
|
39840
|
+
{
|
|
39841
|
+
"kind": "method",
|
|
39842
|
+
"name": "render"
|
|
39843
|
+
},
|
|
39844
|
+
{
|
|
39845
|
+
"kind": "field",
|
|
39846
|
+
"name": "styles",
|
|
39847
|
+
"static": true
|
|
39848
|
+
}
|
|
39849
|
+
],
|
|
39850
|
+
"superclass": {
|
|
39851
|
+
"name": "LitElement",
|
|
39852
|
+
"package": "lit"
|
|
39853
|
+
},
|
|
39854
|
+
"customElement": true
|
|
39855
|
+
}
|
|
39856
|
+
],
|
|
39857
|
+
"exports": [
|
|
39858
|
+
{
|
|
39859
|
+
"kind": "js",
|
|
39860
|
+
"name": "ObcTransmitterButton",
|
|
39861
|
+
"declaration": {
|
|
39862
|
+
"name": "ObcTransmitterButton",
|
|
39863
|
+
"module": "src/automation/transmitter-button/transmitter-button.ts"
|
|
39864
|
+
}
|
|
39865
|
+
}
|
|
39866
|
+
]
|
|
39867
|
+
},
|
|
39868
|
+
{
|
|
39869
|
+
"kind": "javascript-module",
|
|
39870
|
+
"path": "src/automation/transmitter-stack/transmitter-stack.ts",
|
|
39871
|
+
"declarations": [
|
|
39872
|
+
{
|
|
39873
|
+
"kind": "class",
|
|
39874
|
+
"description": "`<obc-transmitter-stack>` – Several transmitter readings side by side in one\njoined chip, attached to a line by a single leader line.\n\nEach entry of `values` renders an `<obc-transmitter-button>` segment with its\nown icon, value, unit and id tag. The segments take equal widths, set by the\nwidest reading, and share their borders. Positioning and the leader line\nfollow `<obc-transmitter>`.\n\n### Features / Variants\n- **`orientation`** – `top`, `right`, `bottom`, `left`; the edge the leader\n line attaches to. `top` places the id tags above the chip.\n- **Values** – `value` and `unit` per segment. `idTag` adds a label row under\n every segment once any value has one, so the chip stays aligned.\n- **Formatting** – per value `fractionDigits` (default `1`), `maxDigits`\n (default `0`), `hintedZeros`, `hasSignSpacer` and `hasDegree`, formatted like\n `<obc-transmitter-button>`. An omitted key takes its default; a key set to\n `null`, `undefined` or `NaN` renders the reading as the unavailable dash.\n- **Icons** – `iconSlotName` projects the light-DOM element with that slot\n name as the segment's icon; names must be unique within the stack. The\n name is chosen per value, so it carries no `@slot` tag (the wrapper\n generator needs literal names).\n- **Accessible name** – each segment is a native button named by its\n reading, unit and `idTag`; the visible tag is hidden from assistive\n technology so it is not read twice.\n- **Empty** – with no `values` nothing renders, leader line included.\n\n### Usage Guidelines\nUse when one source reports several readings that share one leader line. For\na single reading, a tag pill or a trend graph, use `<obc-transmitter>`. Each\nsegment's hit area is `<obc-transmitter-button>`'s chip (24 px high), below\nthe 48 px touch-target token; see its design note.\n\n### Slots\n| Slot Name | Conditions | Purpose |\n|------------------|---------------------------------|-------------------------------|\n| `<iconSlotName>` | a value declares `iconSlotName` | Icon in that value's segment. |",
|
|
39875
|
+
"name": "ObcTransmitterStack",
|
|
39876
|
+
"members": [
|
|
39877
|
+
{
|
|
39878
|
+
"kind": "field",
|
|
39879
|
+
"name": "orientation",
|
|
39880
|
+
"type": {
|
|
39881
|
+
"text": "TransmitterOrientation"
|
|
39882
|
+
},
|
|
39883
|
+
"description": "Edge of the chip the leader line attaches to."
|
|
39884
|
+
},
|
|
39885
|
+
{
|
|
39886
|
+
"kind": "field",
|
|
39887
|
+
"name": "lineType",
|
|
39888
|
+
"type": {
|
|
39889
|
+
"text": "LineType | undefined"
|
|
39890
|
+
},
|
|
39891
|
+
"default": "undefined",
|
|
39892
|
+
"description": "Line the transmitter sits on; offsets the leader line by half its stroke."
|
|
39893
|
+
},
|
|
39894
|
+
{
|
|
39895
|
+
"kind": "field",
|
|
39896
|
+
"name": "values",
|
|
39897
|
+
"type": {
|
|
39898
|
+
"text": "TransmitterStackValue[]"
|
|
39899
|
+
},
|
|
39900
|
+
"default": "[]",
|
|
39901
|
+
"description": "One segment per entry, in order."
|
|
39902
|
+
},
|
|
39903
|
+
{
|
|
39904
|
+
"kind": "method",
|
|
39905
|
+
"name": "handleValueClick",
|
|
39791
39906
|
"privacy": "private",
|
|
39907
|
+
"return": {
|
|
39908
|
+
"type": {
|
|
39909
|
+
"text": "void"
|
|
39910
|
+
}
|
|
39911
|
+
},
|
|
39792
39912
|
"parameters": [
|
|
39793
39913
|
{
|
|
39794
|
-
"name": "
|
|
39914
|
+
"name": "index",
|
|
39795
39915
|
"type": {
|
|
39796
|
-
"text": "
|
|
39916
|
+
"text": "number"
|
|
39797
39917
|
}
|
|
39798
39918
|
},
|
|
39799
39919
|
{
|
|
39800
39920
|
"name": "value",
|
|
39801
39921
|
"type": {
|
|
39802
|
-
"text": "
|
|
39922
|
+
"text": "TransmitterStackValue"
|
|
39803
39923
|
}
|
|
39804
39924
|
}
|
|
39805
39925
|
]
|
|
39806
39926
|
},
|
|
39807
39927
|
{
|
|
39808
39928
|
"kind": "method",
|
|
39809
|
-
"name": "
|
|
39810
|
-
"privacy": "private"
|
|
39811
|
-
|
|
39812
|
-
|
|
39813
|
-
|
|
39814
|
-
|
|
39815
|
-
|
|
39816
|
-
|
|
39817
|
-
|
|
39818
|
-
|
|
39819
|
-
|
|
39820
|
-
|
|
39929
|
+
"name": "renderValue",
|
|
39930
|
+
"privacy": "private",
|
|
39931
|
+
"parameters": [
|
|
39932
|
+
{
|
|
39933
|
+
"name": "entry",
|
|
39934
|
+
"type": {
|
|
39935
|
+
"text": "TransmitterStackValue"
|
|
39936
|
+
}
|
|
39937
|
+
},
|
|
39938
|
+
{
|
|
39939
|
+
"name": "index",
|
|
39940
|
+
"type": {
|
|
39941
|
+
"text": "number"
|
|
39942
|
+
}
|
|
39943
|
+
},
|
|
39944
|
+
{
|
|
39945
|
+
"name": "hasIdTags",
|
|
39946
|
+
"type": {
|
|
39947
|
+
"text": "boolean"
|
|
39948
|
+
}
|
|
39949
|
+
}
|
|
39950
|
+
]
|
|
39821
39951
|
},
|
|
39822
39952
|
{
|
|
39823
39953
|
"kind": "method",
|
|
@@ -39829,6 +39959,19 @@
|
|
|
39829
39959
|
"static": true
|
|
39830
39960
|
}
|
|
39831
39961
|
],
|
|
39962
|
+
"events": [
|
|
39963
|
+
{
|
|
39964
|
+
"name": "value-click",
|
|
39965
|
+
"type": {
|
|
39966
|
+
"text": "CustomEvent<TransmitterStackValueClickDetail>"
|
|
39967
|
+
},
|
|
39968
|
+
"description": "Fired when a segment is activated, with its value and index."
|
|
39969
|
+
},
|
|
39970
|
+
{
|
|
39971
|
+
"description": "Fired when any segment is clicked; `value-click` tells which.",
|
|
39972
|
+
"name": "click"
|
|
39973
|
+
}
|
|
39974
|
+
],
|
|
39832
39975
|
"superclass": {
|
|
39833
39976
|
"name": "LitElement",
|
|
39834
39977
|
"package": "lit"
|
|
@@ -39839,10 +39982,10 @@
|
|
|
39839
39982
|
"exports": [
|
|
39840
39983
|
{
|
|
39841
39984
|
"kind": "js",
|
|
39842
|
-
"name": "
|
|
39985
|
+
"name": "ObcTransmitterStack",
|
|
39843
39986
|
"declaration": {
|
|
39844
|
-
"name": "
|
|
39845
|
-
"module": "src/automation/transmitter-
|
|
39987
|
+
"name": "ObcTransmitterStack",
|
|
39988
|
+
"module": "src/automation/transmitter-stack/transmitter-stack.ts"
|
|
39846
39989
|
}
|
|
39847
39990
|
}
|
|
39848
39991
|
]
|
|
@@ -39853,7 +39996,7 @@
|
|
|
39853
39996
|
"declarations": [
|
|
39854
39997
|
{
|
|
39855
39998
|
"kind": "class",
|
|
39856
|
-
"description": "`<obc-transmitter>` – A readout label that attaches to a line
|
|
39999
|
+
"description": "`<obc-transmitter>` – A readout label that attaches to a line via a leader\nline, showing a measured value, a tag identifier, or a value paired with a\ntrend graph.\n\nPositioning (orientation + leader line) follows `<obc-automation-readout>`.\nThe value chip is an `<obc-transmitter-button>` and the trend is an\n`<obc-indicator-graph>` with its area fill enabled.\n\n### Features / Variants\n- **`type`** – `indicator` (tag pill), `value` (icon/value/unit), or value\n paired with a `horizontal-graph` (beside) or `vertical-graph` (below).\n- **`orientation`** – `top`, `right`, `bottom`, `left`; controls which edge\n the leader line attaches to.\n- **Segments** – opt into a leading advice segment with `hasAdvice`/\n `adviceValue` and a setpoint segment with `hasSetPoint`/`setpointValue`;\n both are read-only and shown in the value chip for non-`indicator` types.\n- **`hasAlert`** – wraps the whole transmitter in an alarm `<obc-alert-frame>`.\n- **Formatting** – `fractionDigits`, `maxDigits`, `hintedZeros` and\n `hasSignSpacer` are forwarded to the value chip to control decimal\n precision, muted leading-zero padding (e.g. `0012.3`) and the sign\n column. The advice and setpoint segments reuse the same formatting.\n `hasDegree` adds a degree column between the value and the unit.\n `value`, `adviceValue` and `setpointValue` render dashes when they are\n `NaN`, `null` or `undefined`.\n\n### Slots\n| Slot Name | Conditions | Purpose |\n|-----------|-------------------------|---------------------------------|\n| icon | value/graph + `hasIcon` | Leading icon in the value chip. |",
|
|
39857
40000
|
"name": "ObcTransmitter",
|
|
39858
40001
|
"slots": [
|
|
39859
40002
|
{
|
|
@@ -39933,6 +40076,15 @@
|
|
|
39933
40076
|
"default": "false",
|
|
39934
40077
|
"description": "Reserve a minus-sign column on every segment, filled by the real sign only while a value is negative, so the chip's width does not change across zero."
|
|
39935
40078
|
},
|
|
40079
|
+
{
|
|
40080
|
+
"kind": "field",
|
|
40081
|
+
"name": "hasDegree",
|
|
40082
|
+
"type": {
|
|
40083
|
+
"text": "boolean"
|
|
40084
|
+
},
|
|
40085
|
+
"default": "false",
|
|
40086
|
+
"description": "Show a degree column between the value and the unit (e.g. `12.3°` then `C`)."
|
|
40087
|
+
},
|
|
39936
40088
|
{
|
|
39937
40089
|
"kind": "field",
|
|
39938
40090
|
"name": "size",
|
|
@@ -40022,12 +40174,6 @@
|
|
|
40022
40174
|
"privacy": "private",
|
|
40023
40175
|
"readonly": true
|
|
40024
40176
|
},
|
|
40025
|
-
{
|
|
40026
|
-
"kind": "field",
|
|
40027
|
-
"name": "lineOffset",
|
|
40028
|
-
"privacy": "private",
|
|
40029
|
-
"readonly": true
|
|
40030
|
-
},
|
|
40031
40177
|
{
|
|
40032
40178
|
"kind": "method",
|
|
40033
40179
|
"name": "renderButton",
|
|
@@ -40066,6 +40212,22 @@
|
|
|
40066
40212
|
}
|
|
40067
40213
|
],
|
|
40068
40214
|
"exports": [
|
|
40215
|
+
{
|
|
40216
|
+
"kind": "js",
|
|
40217
|
+
"name": "TransmitterOrientation",
|
|
40218
|
+
"declaration": {
|
|
40219
|
+
"name": "TransmitterOrientation",
|
|
40220
|
+
"module": "./transmitter-shared.js"
|
|
40221
|
+
}
|
|
40222
|
+
},
|
|
40223
|
+
{
|
|
40224
|
+
"kind": "js",
|
|
40225
|
+
"name": "transmitterLeaderOffset",
|
|
40226
|
+
"declaration": {
|
|
40227
|
+
"name": "transmitterLeaderOffset",
|
|
40228
|
+
"module": "./transmitter-shared.js"
|
|
40229
|
+
}
|
|
40230
|
+
},
|
|
40069
40231
|
{
|
|
40070
40232
|
"kind": "js",
|
|
40071
40233
|
"name": "ObcTransmitter",
|
|
@@ -72180,7 +72342,7 @@
|
|
|
72180
72342
|
"declarations": [
|
|
72181
72343
|
{
|
|
72182
72344
|
"kind": "class",
|
|
72183
|
-
"description": "`obc-user-button` – A compact, circular button for representing a user via icon or initials.\n\nDisplays either a user icon or user initials inside a circular button, with optional label text. Commonly used for user profile access, account switching, or avatar actions in toolbars and navigation. The button supports multiple visual styles and can be rendered as a static (non-interactive) element.\n\nAppears as a button by default, but switches to a non-interactive div when the `static` property is set.\n\n## Features\n- **Variants:**\n - `icon`: Shows a user icon (default, fallback if initials are invalid or missing).\n - `initials`: Shows up to two uppercase initials (falls back to icon if input is empty or longer than two characters).\n- **Style Types:**\n - `flat`: Minimal, flat appearance (default).\n - `normal`: Outlined with background and border.\n - `selected`: Highlighted to indicate selection or active state.\n- **Static Mode:**\n - Set `static` to render as a non-interactive element for use in read-only or decorative contexts.\n- **Disabled State:**\n - Set `disabled` to visually and functionally disable the button.\n- **Custom Icon Slot:**\n - Provide a custom icon via the `icon` slot when using the `icon` variant.\n- **Label Support:**\n - Optional `label` property displays text next to the button (not shown in static mode).\n\n## Usage Guidelines\nUse `obc-user-button` to represent a user in navigation bars, toolbars, or menus where a compact, recognizable user indicator is needed. Ideal for profile menus, account switching, or user-related quick actions.\n- Use the `icon` variant for generic user representation, or when no initials are available.\n- Use the `initials` variant to personalize the button with user initials (max two characters).\n- Use `styleType=\"selected\"` to indicate the current user or active selection.\n- Use `static` for non-interactive displays, such as in lists or summaries.\n- Avoid using for critical actions or as a replacement for full user profile cards.\n\n**TODO(designer):** Confirm if there are recommended scenarios for when to use `flat`, `normal`, or `selected` style types, and if there are accessibility guidelines for initials fallback.\n\n## Slots\n\n| Slot Name | Renders When... | Purpose |\n|-----------|-----------------|---------|\n| `icon` | `variant=\"icon\"` | Custom icon to display instead of the default user icon. |\n\n## Best Practices & Constraints\n- Initials longer than two characters are truncated and a warning is logged.\n- If `initials` is empty or invalid, the button falls back to the user icon.\n- The `label` is only visible when the button is interactive (not static).\n- For accessibility, the button
|
|
72345
|
+
"description": "`obc-user-button` – A compact, circular button for representing a user via icon or initials.\n\nDisplays either a user icon or user initials inside a circular button, with optional label text. Commonly used for user profile access, account switching, or avatar actions in toolbars and navigation. The button supports multiple visual styles and can be rendered as a static (non-interactive) element.\n\nAppears as a button by default, but switches to a non-interactive div when the `static` property is set.\n\n## Features\n- **Variants:**\n - `icon`: Shows a user icon (default, fallback if initials are invalid or missing).\n - `initials`: Shows up to two uppercase initials (falls back to icon if input is empty or longer than two characters).\n- **Style Types:**\n - `flat`: Minimal, flat appearance (default).\n - `normal`: Outlined with background and border.\n - `selected`: Highlighted to indicate selection or active state.\n- **Static Mode:**\n - Set `static` to render as a non-interactive element for use in read-only or decorative contexts.\n- **Disabled State:**\n - Set `disabled` to visually and functionally disable the button.\n- **Custom Icon Slot:**\n - Provide a custom icon via the `icon` slot when using the `icon` variant.\n- **Label Support:**\n - Optional `label` property displays text next to the button (not shown in static mode).\n - Optional `sublabel` adds a second, lighter line under the label, for a\n secondary detail such as the user's role.\n\n## Usage Guidelines\nUse `obc-user-button` to represent a user in navigation bars, toolbars, or menus where a compact, recognizable user indicator is needed. Ideal for profile menus, account switching, or user-related quick actions.\n- Use the `icon` variant for generic user representation, or when no initials are available.\n- Use the `initials` variant to personalize the button with user initials (max two characters).\n- Use `styleType=\"selected\"` to indicate the current user or active selection.\n- Use `static` for non-interactive displays, such as in lists or summaries.\n- Avoid using for critical actions or as a replacement for full user profile cards.\n\n**TODO(designer):** Confirm if there are recommended scenarios for when to use `flat`, `normal`, or `selected` style types, and if there are accessibility guidelines for initials fallback.\n\n## Slots\n\n| Slot Name | Renders When... | Purpose |\n|-----------|-----------------|---------|\n| `icon` | `variant=\"icon\"` | Custom icon to display instead of the default user icon. |\n\n## Best Practices & Constraints\n- Initials longer than two characters are truncated and a warning is logged.\n- If `initials` is empty or invalid, the button falls back to the user icon.\n- The `label` is only visible when the button is interactive (not static).\n- For accessibility, the button is named after its visible text — `label` and\n `sublabel` — falling back to the initials when it shows no text.\n- Only use the `static` property for non-interactive contexts; otherwise, the button is clickable.\n\n## Example:\n```html\n<obc-user-button variant=\"initials\" initials=\"JD\" styleType=\"normal\" label=\"John Doe\"></obc-user-button>\n<obc-user-button variant=\"icon\" styleType=\"flat\">\n <obi-placeholder slot=\"icon\"></obi-placeholder>\n</obc-user-button>\n```",
|
|
72184
72346
|
"name": "ObcUserButton",
|
|
72185
72347
|
"slots": [
|
|
72186
72348
|
{
|
|
@@ -72247,6 +72409,14 @@
|
|
|
72247
72409
|
},
|
|
72248
72410
|
"description": "Optional label text to display next to the button (not shown in static mode)."
|
|
72249
72411
|
},
|
|
72412
|
+
{
|
|
72413
|
+
"kind": "field",
|
|
72414
|
+
"name": "sublabel",
|
|
72415
|
+
"type": {
|
|
72416
|
+
"text": "string | undefined"
|
|
72417
|
+
},
|
|
72418
|
+
"description": "Optional second line under the label, for a secondary detail such as a role (not shown in static mode)."
|
|
72419
|
+
},
|
|
72250
72420
|
{
|
|
72251
72421
|
"kind": "field",
|
|
72252
72422
|
"name": "formattedInitials",
|
|
@@ -72293,7 +72463,7 @@
|
|
|
72293
72463
|
"declarations": [
|
|
72294
72464
|
{
|
|
72295
72465
|
"kind": "class",
|
|
72296
|
-
"description": "`<obc-user-menu>` – A user menu component with sign-in and signed-in layouts.\n\nProvides multiple layouts for authentication and account access states, including\nsign-in forms, user-specific sign-in, loading states, and signed-in navigation.\n\n### Features\n- **Multiple States:** Supports sign-in, user sign-in, loading, and signed-in layouts.\n- **Size Options:** Regular and small sizes for compact layouts.\n- **Recent Users:** Optional \"Recently signed in\" section for quick access.\n- **Navigation Actions:** Signed-in state lists the actions it is given.\n\n### Variants\n- `type`: `sign-in`, `user-sign-in`, `loading-sign-in`, `signed-in`\n- `size`: `regular`, `small`\n\n### Usage Guidelines\nUse `obc-user-menu` in authentication or account panels where quick access to\nsign-in, profile, or account actions is needed. The `user-sign-in` type is\nbest for fast re-auth flows; `loading-sign-in` is for pending auth states.\n\n### Properties and Configuration\n- `type` (`ObcUserMenuType`): Controls the layout state. Defaults to `sign-in`.\n- `size` (`ObcUserMenuSize`): Controls the overall size. Defaults to `regular`.\n- `hasRecentlySignedIn` (`boolean`): Toggles the recent users section.\n Defaults to `false`.\n- `showUsername` (`boolean`): Toggles the username field. Defaults to `true`.\n- `showPassword` (`boolean`): Toggles the password field. Defaults to `true`.\n- `username` (`string`): Current username value for sign-in layouts.\n- `password` (`string`): Current password value for sign-in layouts.\n- `usernameError` (`string`): Error message for the username field.\n- `passwordError` (`string`): Error message for the password field.\n- `userInitials` (`string`): Initials for the primary user profile.\n- `userLabel` (`string`): Label for the primary user profile.\n- `recentUsers` (`ObcUserMenuUser[]`): List of recent users shown in the\n \"Recently signed in\" section. Empty renders no section
|
|
72466
|
+
"description": "`<obc-user-menu>` – A user menu component with sign-in and signed-in layouts.\n\nProvides multiple layouts for authentication and account access states, including\nsign-in forms, user-specific sign-in, loading states, and signed-in navigation.\n\n### Features\n- **Multiple States:** Supports sign-in, user sign-in, loading, and signed-in layouts.\n- **Size Options:** Regular and small sizes for compact layouts.\n- **Recent Users:** Optional \"Recently signed in\" section for quick access.\n- **Navigation Actions:** Signed-in state lists the actions it is given.\n\n### Variants\n- `type`: `sign-in`, `user-sign-in`, `loading-sign-in`, `signed-in`\n- `size`: `regular`, `small`\n\n### Usage Guidelines\nUse `obc-user-menu` in authentication or account panels where quick access to\nsign-in, profile, or account actions is needed. The `user-sign-in` type is\nbest for fast re-auth flows; `loading-sign-in` is for pending auth states.\n\n### Properties and Configuration\n- `type` (`ObcUserMenuType`): Controls the layout state. Defaults to `sign-in`.\n- `size` (`ObcUserMenuSize`): Controls the overall size. Defaults to `regular`.\n- `hasRecentlySignedIn` (`boolean`): Toggles the recent users section.\n Defaults to `false`.\n- `showUsername` (`boolean`): Toggles the username field. Defaults to `true`.\n- `showPassword` (`boolean`): Toggles the password field. Defaults to `true`.\n- `username` (`string`): Current username value for sign-in layouts.\n- `password` (`string`): Current password value for sign-in layouts.\n- `usernameError` (`string`): Error message for the username field.\n- `passwordError` (`string`): Error message for the password field.\n- `userInitials` (`string`): Initials for the primary user profile.\n- `userLabel` (`string`): Label for the primary user profile.\n- `userRole` (`string`): Role shown under the primary user's label. Omit it\n to show no role; only the regular size draws one.\n- `recentUsers` (`ObcUserMenuUser[]`): List of recent users shown in the\n \"Recently signed in\" section. Empty renders no section. Each user may\n carry its own `role`.\n- `showUseAnotherAccount` (`boolean`): Toggles the \"Use another account\"\n button in the `user-sign-in` layouts, both sizes. Defaults to `true`.\n- `signedInActions` (`ObcUserMenuSignedInAction[]`): Actions shown in the\n signed-in navigation list. Empty renders no actions.\n- `primaryActionId` (`string`): Id of the action promoted to a button in the\n small signed-in layout.\n\n### Events\n- `sign-in-click` – Fired when a sign-in button is clicked.\n- `sign-out-click` – Fired when the sign-out button is clicked.\n- `use-another-account-click` – Fired when the \"Use another account\" button\n is clicked. The menu does not change its own type; set it to `sign-in` in\n the handler to show the full form.\n- `signed-in-action-click` – Fired when a signed-in action is clicked.\n- `recent-user-click` – Fired when a recent user button is clicked.\n\n### Slots\n- `signed-in-action-icon-{id}`: Optional icon for a signed-in action. The\n `{id}` is the normalized action id.\n\n### Example\n```html\n<obc-user-menu\n type=\"user-sign-in\"\n size=\"small\"\n hasRecentlySignedIn=\"false\"\n userInitials=\"JD\"\n userLabel=\"John Doe\"\n></obc-user-menu>\n```",
|
|
72297
72467
|
"name": "ObcUserMenu",
|
|
72298
72468
|
"slots": [
|
|
72299
72469
|
{
|
|
@@ -72397,6 +72567,14 @@
|
|
|
72397
72567
|
},
|
|
72398
72568
|
"description": "Label for the primary user profile."
|
|
72399
72569
|
},
|
|
72570
|
+
{
|
|
72571
|
+
"kind": "field",
|
|
72572
|
+
"name": "userRole",
|
|
72573
|
+
"type": {
|
|
72574
|
+
"text": "string | undefined"
|
|
72575
|
+
},
|
|
72576
|
+
"description": "Role shown under the primary user's label; omit it to show no role."
|
|
72577
|
+
},
|
|
72400
72578
|
{
|
|
72401
72579
|
"kind": "field",
|
|
72402
72580
|
"name": "recentUsers",
|
|
@@ -72423,6 +72601,15 @@
|
|
|
72423
72601
|
},
|
|
72424
72602
|
"description": "Id of the action promoted to a button in the small signed-in layout."
|
|
72425
72603
|
},
|
|
72604
|
+
{
|
|
72605
|
+
"kind": "field",
|
|
72606
|
+
"name": "showUseAnotherAccount",
|
|
72607
|
+
"type": {
|
|
72608
|
+
"text": "boolean"
|
|
72609
|
+
},
|
|
72610
|
+
"default": "true",
|
|
72611
|
+
"description": "Controls the visibility of the \"Use another account\" button."
|
|
72612
|
+
},
|
|
72426
72613
|
{
|
|
72427
72614
|
"kind": "field",
|
|
72428
72615
|
"name": "showRecentUsers",
|
|
@@ -72595,6 +72782,11 @@
|
|
|
72595
72782
|
"name": "handleSignOutClick",
|
|
72596
72783
|
"privacy": "private"
|
|
72597
72784
|
},
|
|
72785
|
+
{
|
|
72786
|
+
"kind": "method",
|
|
72787
|
+
"name": "handleUseAnotherAccountClick",
|
|
72788
|
+
"privacy": "private"
|
|
72789
|
+
},
|
|
72598
72790
|
{
|
|
72599
72791
|
"kind": "method",
|
|
72600
72792
|
"name": "renderSignIn",
|
|
@@ -72656,9 +72848,9 @@
|
|
|
72656
72848
|
{
|
|
72657
72849
|
"name": "recent-user-click",
|
|
72658
72850
|
"type": {
|
|
72659
|
-
"text": "
|
|
72851
|
+
"text": "ObcUserMenuRecentUserClickEvent"
|
|
72660
72852
|
},
|
|
72661
|
-
"description": "Fired when a recent user button is clicked."
|
|
72853
|
+
"description": "Fired when a recent user button is clicked, carrying that user's entry."
|
|
72662
72854
|
},
|
|
72663
72855
|
{
|
|
72664
72856
|
"name": "sign-in-click",
|
|
@@ -72673,6 +72865,13 @@
|
|
|
72673
72865
|
"text": "CustomEvent<void>"
|
|
72674
72866
|
},
|
|
72675
72867
|
"description": "Fired when the sign-out button is clicked."
|
|
72868
|
+
},
|
|
72869
|
+
{
|
|
72870
|
+
"name": "use-another-account-click",
|
|
72871
|
+
"type": {
|
|
72872
|
+
"text": "CustomEvent<void>"
|
|
72873
|
+
},
|
|
72874
|
+
"description": "Fired when the \"Use another account\" button is clicked."
|
|
72676
72875
|
}
|
|
72677
72876
|
],
|
|
72678
72877
|
"superclass": {
|
|
@@ -87604,7 +87803,7 @@
|
|
|
87604
87803
|
"privacy": "private",
|
|
87605
87804
|
"return": {
|
|
87606
87805
|
"type": {
|
|
87607
|
-
"text": "TemplateResult"
|
|
87806
|
+
"text": "TemplateResult | typeof nothing"
|
|
87608
87807
|
}
|
|
87609
87808
|
}
|
|
87610
87809
|
},
|