diff --git a/.changeset/chilly-singers-decide.md b/.changeset/chilly-singers-decide.md new file mode 100644 index 0000000000..d6c5c3bced --- /dev/null +++ b/.changeset/chilly-singers-decide.md @@ -0,0 +1,5 @@ +--- +"@khanacademy/perseus": patch +--- + +Add features to support show-your-work widget diff --git a/packages/perseus/src/components/math-input.tsx b/packages/perseus/src/components/math-input.tsx index 37aa4b0b63..884e47829c 100644 --- a/packages/perseus/src/components/math-input.tsx +++ b/packages/perseus/src/components/math-input.tsx @@ -68,6 +68,8 @@ type Props = { * - `never` means that the keypad is **never shown**. */ buttonsVisible?: ButtonsVisibleType; + disabled?: boolean; + noBackground?: boolean; onAnalyticsEvent: AnalyticsEventHandlerFn; }; @@ -165,6 +167,13 @@ class InnerMathInput extends React.Component { input?.focus(); }; + // TODO(kevinb): Port this to @khanacademy/math-input + setValue = (value: string) => { + const input = this.mathField(); + input?.select(); + input?.write(value); + }; + mathField: () => MathFieldInterface | null = () => { if (!this.__mathField && this.__mathFieldWrapperRef) { const {locale} = this.context; @@ -301,8 +310,10 @@ class InnerMathInput extends React.Component {
{ onFocus={() => this.focus()} onBlur={() => this.blur()} /> - this.closeKeypad()} - dismissEnabled - aria-label={this.context.strings.mathInputTitle} - aria-describedby={`popover-content-${popoverContentUniqueId}`} - content={() => ( - <> - - {this.context.strings.mathInputDescription} - - - this.closeKeypad()} + dismissEnabled + aria-label={this.context.strings.mathInputTitle} + aria-describedby={`popover-content-${popoverContentUniqueId}`} + content={() => ( + <> + + { + this.context.strings + .mathInputDescription } - {...(this.props.keypadButtonSets ?? - mapButtonSets( - this.props?.buttonSets, - ))} - /> - - - )} - > - {this.props.buttonsVisible === "never" ? ( - - ) : ( - - this.state.keypadOpen - ? this.closeKeypad() - : this.openKeypad() - } - > - {(props) => ( - - )} - - )} - + + + + + + )} + > + {this.props.buttonsVisible === "never" ? ( + + ) : ( + + this.state.keypadOpen + ? this.closeKeypad() + : this.openKeypad() + } + > + {(props) => ( + + )} + + )} + + )}
); @@ -530,9 +548,11 @@ const styles = StyleSheet.create({ borderWidth: 1, borderColor: color.offBlack50, borderRadius: 3, - background: color.white, ":hover": inputFocused, }, + outerWrapperBackground: { + background: color.white, + }, wrapperFocused: inputFocused, wrapperError: { borderColor: color.red, @@ -546,6 +566,9 @@ const styles = StyleSheet.create({ paddingBottom: spacing.xxSmall_6, maxWidth: "initial", }, + disabled: { + pointerEvents: "none", + }, }); export default MathInput; diff --git a/packages/perseus/src/widgets/expression/expression.tsx b/packages/perseus/src/widgets/expression/expression.tsx index bbb4d3bbb0..5e534edb49 100644 --- a/packages/perseus/src/widgets/expression/expression.tsx +++ b/packages/perseus/src/widgets/expression/expression.tsx @@ -81,6 +81,9 @@ export type Props = ExternalProps & visibleLabel: PerseusExpressionWidgetOptions["visibleLabel"]; ariaLabel: PerseusExpressionWidgetOptions["ariaLabel"]; value: string; + disabled?: boolean; + noBackground?: boolean; + noWrapper?: boolean; }; export type ExpressionState = { @@ -110,6 +113,7 @@ export class Expression _textareaId = `expression_textarea_${Date.now()}`; _isMounted = false; + _mathInput: React.MutableRefObject = React.createRef(); static getUserInputFromProps(props: Props): PerseusExpressionUserInput { return normalizeTex(props.value); @@ -275,6 +279,12 @@ export class Expression }; setInputValue(path: FocusPath, newValue: string, cb: () => void) { + if (this._mathInput.current) { + const inputRef = this._mathInput.current.inputRef; + if (inputRef.current) { + inputRef.current.setValue(newValue); + } + } this.props.onChange( { value: newValue, @@ -329,7 +339,13 @@ export class Expression const {ERROR_MESSAGE, ERROR_TITLE} = this.context.strings; return ( - + {!!this.props.visibleLabel && ( {this.props.visibleLabel} @@ -365,13 +381,14 @@ export class Expression content={ERROR_MESSAGE} >