diff --git a/src/atoms/prompt.ts b/src/atoms/prompt.ts index c1ea234e1..320d4fadc 100644 --- a/src/atoms/prompt.ts +++ b/src/atoms/prompt.ts @@ -83,26 +83,10 @@ export class PromptAtom extends Atom { : null; const emptyHeight = placeholderMetrics?.height ?? context.metrics.xHeight; const emptyDepth = placeholderMetrics?.depth ?? emptyHeight / 2; + const effectiveHeight = Math.max(content.height ?? 0, emptyHeight); + const effectiveDepth = Math.max(content.depth ?? 0, emptyDepth); - // An empty prompt should not be too small, pretend content - // has height sigma 5 (x-height) - - if (!content.height) { - content.height = isEffectivelyEmpty - ? emptyHeight - : context.metrics.xHeight; - } - - if (!content.depth) { - content.depth = isEffectivelyEmpty - ? emptyDepth - : context.metrics.defaultRuleThickness; - } - - const verticalShift = isEffectivelyEmpty - ? emptyDepth - emptyHeight - : content.depth - content.height; - content.setStyle('vertical-align', verticalShift, 'em'); + content.setStyle('vertical-align', `calc(-${effectiveHeight}em + 2px)`); if (this.correctness === 'correct') { content.setStyle( 'color', @@ -115,14 +99,20 @@ export class PromptAtom extends Atom { ); } + const squareSide = effectiveHeight + effectiveDepth + 2 * vPadding; + const minInnerWidth = squareSide - 2 * hPadding; + const base = new Box(content, { type: 'ord' }); - base.height = content.height; - base.depth = content.depth; base.setStyle('display', 'inline-block'); - base.setStyle('height', content.height + content.depth, 'em'); + base.height = effectiveHeight; + base.depth = effectiveDepth; + base.setStyle('height', effectiveHeight + effectiveDepth, 'em'); base.setStyle('vertical-align', -vPadding, 'em'); - base.setStyle('position', 'relative'); - base.setStyle('z-index', 1); + + if ((content.width ?? 0) < minInnerWidth) { + base.width = minInnerWidth; + base.setStyle('width', minInnerWidth, 'em'); + } // This box will represent the box (background and border). // It's positioned to overlap the base. @@ -148,21 +138,13 @@ export class PromptAtom extends Atom { box.depth = base.depth + vPadding; box.width = base.width + 2 * hPadding; box.setStyle('position', 'absolute'); - box.setStyle('z-index', 0); - box.setStyle('display', 'block'); - box.setStyle('pointer-events' as any, 'auto'); - - const overlayHeight = base.height + base.depth + 2 * vPadding; - box.setStyle('height', Math.max(overlayHeight, 0.6), 'em'); - - let overlayWidth = base.width + 2 * hPadding; - if (isEffectivelyEmpty) - overlayWidth = Math.max(overlayWidth, 3 * hPadding || 0.8); - box.setStyle('width', Math.max(overlayWidth, 0.6), 'em'); - - box.setStyle('top', fboxsep + vPadding, 'em'); - if (isEffectivelyEmpty) box.setStyle('left', -1.5 * hPadding, 'em'); - else if (hPadding !== 0) box.setStyle('left', -hPadding, 'em'); + box.setStyle('height', base.height + base.depth + 2 * vPadding, 'em'); + if (hPadding === 0) box.setStyle('width', '100%'); + if (hPadding !== 0) { + box.setStyle('width', `calc(100% + ${2 * hPadding}em)`); + box.setStyle('top', fboxsep, 'em'); + box.setStyle('left', -hPadding, 'em'); + } let svg = ''; // strike through incorrect prompt, for users with impaired color vision if (this.correctness === 'incorrect') { @@ -183,14 +165,17 @@ export class PromptAtom extends Atom { result.setStyle('display', 'inline-block'); result.setStyle('line-height', 0); - // The padding adds to the width and height of the pod - result.height = base.height + vPadding + 0.2; - result.depth = base.depth + vPadding; + result.height = effectiveHeight + vPadding + 0.2; + result.depth = effectiveDepth + vPadding; result.left = hPadding; result.right = hPadding; - result.setStyle('height', base.height + 2 * vPadding, 'em'); - result.setStyle('top', base.depth - base.height - vPadding / 2, 'em'); - result.setStyle('vertical-align', base.depth + vPadding / 2, 'em'); + result.setStyle('height', effectiveHeight + 2 * vPadding, 'em'); + result.setStyle( + 'top', + effectiveDepth - effectiveHeight - vPadding / 2, + 'em' + ); + result.setStyle('vertical-align', base.depth, 'em'); result.setStyle('margin-left', 0.5, 'em'); result.setStyle('margin-right', 0.5, 'em');