11import { html , nothing , type TemplateResult } from "lit" ;
2+ import { formatUnknownText } from "../format.ts" ;
23import { icons as sharedIcons } from "../icons.ts" ;
34import type { ConfigUiHints } from "../types.ts" ;
45import {
@@ -30,6 +31,27 @@ function jsonValue(value: unknown): string {
3031 }
3132}
3233
34+ function formatComparablePrimitive ( value : unknown ) : string | null {
35+ if (
36+ typeof value === "string" ||
37+ typeof value === "number" ||
38+ typeof value === "boolean" ||
39+ typeof value === "bigint"
40+ ) {
41+ return String ( value ) ;
42+ }
43+ return null ;
44+ }
45+
46+ function matchesComparablePrimitiveValue ( left : unknown , right : unknown ) : boolean {
47+ if ( Object . is ( left , right ) ) {
48+ return true ;
49+ }
50+ const leftComparable = formatComparablePrimitive ( left ) ;
51+ const rightComparable = formatComparablePrimitive ( right ) ;
52+ return leftComparable !== null && leftComparable === rightComparable ;
53+ }
54+
3355// SVG Icons as template literals
3456const icons = {
3557 chevronDown : html `
@@ -474,17 +496,13 @@ export function renderNode(params: {
474496 ( lit ) => html `
475497 < button
476498 type ="button "
477- class ="cfg-segmented__btn ${
478- // oxlint-disable typescript/no-base-to-string
479- lit === resolvedValue || String ( lit ) === String ( resolvedValue ) ? "active" : ""
480- } "
499+ class ="cfg-segmented__btn ${ matchesComparablePrimitiveValue ( lit , resolvedValue )
500+ ? "active"
501+ : "" } "
481502 ?disabled =${ disabled }
482503 @click =${ ( ) => onPatch ( path , lit ) }
483504 >
484- ${
485- // oxlint-disable typescript/no-base-to-string
486- String ( lit )
487- }
505+ ${ formatUnknownText ( lit ) }
488506 </ button >
489507 ` ,
490508 ) }
@@ -553,14 +571,13 @@ export function renderNode(params: {
553571 ( opt ) => html `
554572 < button
555573 type ="button "
556- class ="cfg-segmented__btn ${ opt === resolvedValue ||
557- String ( opt ) === String ( resolvedValue )
574+ class ="cfg-segmented__btn ${ matchesComparablePrimitiveValue ( opt , resolvedValue )
558575 ? "active"
559576 : "" } "
560577 ?disabled =${ disabled }
561578 @click =${ ( ) => onPatch ( path , opt ) }
562579 >
563- ${ String ( opt ) }
580+ ${ formatUnknownText ( opt ) }
564581 </ button >
565582 ` ,
566583 ) }
@@ -666,8 +683,7 @@ function renderTextInput(params: {
666683 : "Structured value (SecretRef) - edit the config file directly"
667684 : REDACTED_PLACEHOLDER
668685 : ( hint ?. placeholder ??
669- // oxlint-disable typescript/no-base-to-string
670- ( schema . default !== undefined ? `Default: ${ String ( schema . default ) } ` : "" ) ) ;
686+ ( schema . default !== undefined ? `Default: ${ formatUnknownText ( schema . default ) } ` : "" ) ) ;
671687 const displayValue = effectiveRedacted
672688 ? ""
673689 : isStructuredValue
@@ -684,7 +700,7 @@ function renderTextInput(params: {
684700 type =${ effectiveInputType }
685701 class ="cfg-input${ effectiveRedacted ? " cfg-input--redacted" : "" } "
686702 placeholder=${ placeholder }
687- .value=${ displayValue == null ? "" : String ( displayValue ) }
703+ .value=${ formatUnknownText ( displayValue ) }
688704 ?disabled=${ disabled }
689705 ?readonly=${ effectiveRedacted }
690706 @click=${ ( ) => {
@@ -778,7 +794,7 @@ function renderNumberInput(params: {
778794 < input
779795 type ="number "
780796 class ="cfg-number__input "
781- .value =${ displayValue == null ? "" : String ( displayValue ) }
797+ .value =${ formatUnknownText ( displayValue ) }
782798 ?disabled =${ disabled }
783799 @input=${ ( e : Event ) => {
784800 const raw = ( e . target as HTMLInputElement ) . value ;
0 commit comments