@khanacademy/perseus-editor 28.8.6 → 28.8.7
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/dist/content-preview.d.ts +6 -1
- package/dist/es/index.js +3 -3
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -12,7 +12,7 @@ import type { LinterContextProps } from "@khanacademy/perseus-linter";
|
|
|
12
12
|
* `previewDevice` is phone or tablet. Note that the styling cannot be matched
|
|
13
13
|
* 100% due to the above `@media` query limitation.
|
|
14
14
|
*/
|
|
15
|
-
declare function ContentPreview({ question, apiOptions, seamless, linterContext, legacyPerseusLint, previewDevice, }: {
|
|
15
|
+
declare function ContentPreview({ question, apiOptions, seamless, linterContext, legacyPerseusLint, previewDevice, reviewMode, }: {
|
|
16
16
|
/** The Perseus question to preview. */
|
|
17
17
|
question?: PerseusRenderer;
|
|
18
18
|
/** API Options to use when previewing. */
|
|
@@ -30,5 +30,10 @@ declare function ContentPreview({ question, apiOptions, seamless, linterContext,
|
|
|
30
30
|
* media queries based on the screen width).
|
|
31
31
|
*/
|
|
32
32
|
previewDevice: DeviceType;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the preview is in review mode. When true, widgets will show
|
|
35
|
+
* correct answers with explanations and prevent interaction.
|
|
36
|
+
*/
|
|
37
|
+
reviewMode?: boolean;
|
|
33
38
|
}): React.JSX.Element;
|
|
34
39
|
export default ContentPreview;
|
package/dist/es/index.js
CHANGED
|
@@ -63,7 +63,7 @@ import xIcon from '@phosphor-icons/core/regular/x.svg';
|
|
|
63
63
|
import checkIcon from '@phosphor-icons/core/bold/check-bold.svg';
|
|
64
64
|
import minusCircleIcon from '@phosphor-icons/core/bold/minus-circle-bold.svg';
|
|
65
65
|
|
|
66
|
-
const libName="@khanacademy/perseus-editor";const libVersion="28.8.
|
|
66
|
+
const libName="@khanacademy/perseus-editor";const libVersion="28.8.7";addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
67
67
|
|
|
68
68
|
var jsxRuntime = {exports: {}};
|
|
69
69
|
|
|
@@ -1471,7 +1471,7 @@ const UNCHANGED="unchanged";const CHANGED="changed";const ADDED="added";const RE
|
|
|
1471
1471
|
|
|
1472
1472
|
const{SvgImage: SvgImage$1}=components;class ImageWidgetDiff extends React.Component{render(){const{before,after}=this.props;const beforeSrc=before.options?.backgroundImage?.url?before.options.backgroundImage.url:"";const afterSrc=after.options?.backgroundImage?.url?after.options.backgroundImage.url:"";const beforeAlt=before.options?.alt?before.options.alt:"";const afterAlt=after.options?.alt?after.options.alt:"";return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{className:"diff-row before",children:beforeSrc&&jsxRuntimeExports.jsx("div",{className:classNames({image:true,"image-unchanged":beforeSrc===afterSrc,"image-removed":beforeSrc!==afterSrc}),children:jsxRuntimeExports.jsx(SvgImage$1,{src:beforeSrc,title:beforeSrc,allowZoom:false,alt:beforeAlt})})}),jsxRuntimeExports.jsx("div",{className:"diff-row after",children:afterSrc&&jsxRuntimeExports.jsx("div",{className:classNames({image:true,"image-unchanged":beforeSrc===afterSrc,"image-added":beforeSrc!==afterSrc}),children:jsxRuntimeExports.jsx(SvgImage$1,{src:afterSrc,title:afterSrc,allowZoom:false,alt:afterAlt})})})]})}}class WidgetDiff extends React.Component{render(){const{after,before,title,type}=this.props;const diff=performDiff(before,after);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("div",{className:"diff-header",children:title}),jsxRuntimeExports.jsx("div",{className:"diff-header",children:title}),jsxRuntimeExports.jsxs("div",{className:"diff-body ui-helper-clearfix",children:[type==="image"&&jsxRuntimeExports.jsx(ImageWidgetDiff,{before:before,after:after}),jsxRuntimeExports.jsx(DiffEntry,{entry:diff})]})]})}}
|
|
1473
1473
|
|
|
1474
|
-
const filterWidgetInfo=function(widgetInfo,showAlignmentOptions){const{alignment,options,type}=widgetInfo;const filteredWidgetInfo={options};if(showAlignmentOptions&&CoreWidgetRegistry.getSupportedAlignments(type).length>1){filteredWidgetInfo.alignment=alignment;}if(Widgets.supportsStaticMode(type)){filteredWidgetInfo.static=widgetInfo?.static??undefined;}return filteredWidgetInfo};class RendererDiff extends React.Component{render(){const{after,before,showAlignmentOptions,showSeparator,title}=this.props;let textDiff;let widgetsDiff=[];if(before.content||after.content){textDiff=jsxRuntimeExports.jsx(TextDiff,{before:before.content,after:after.content,title:title});}const beforeWidgets=Object.keys(before.widgets??{}).filter(widget=>before.content.includes(widget));const afterWidgets=Object.keys(after.widgets??{}).filter(widget=>after.content.includes(widget));if(beforeWidgets.length>0||afterWidgets.length>0){const widgets=_.union(beforeWidgets,afterWidgets);widgetsDiff=widgets.map(widget=>jsxRuntimeExports.jsx(WidgetDiff,{before:filterWidgetInfo(before.widgets?.[widget],showAlignmentOptions),after:filterWidgetInfo(after.widgets?.[widget],showAlignmentOptions),title:widget,type:(before.widgets?.[widget]??{}).type||(after.widgets?.[widget]??{}).type},widget));}return jsxRuntimeExports.jsxs("div",{children:[textDiff,widgetsDiff,showSeparator&&jsxRuntimeExports.jsx("div",{className:"diff-separator"})]})}}RendererDiff.defaultProps={after:{content:"",images:{},widgets:{}},before:{content:"",images:{},widgets:{}},showAlignmentOptions:false,showSeparator:false};
|
|
1474
|
+
const filterWidgetInfo=function(widgetInfo,showAlignmentOptions){if(widgetInfo==null){return undefined}const{alignment,options,type}=widgetInfo;const filteredWidgetInfo={options};if(showAlignmentOptions&&CoreWidgetRegistry.getSupportedAlignments(type).length>1){filteredWidgetInfo.alignment=alignment;}if(Widgets.supportsStaticMode(type)){filteredWidgetInfo.static=widgetInfo?.static??undefined;}return filteredWidgetInfo};class RendererDiff extends React.Component{render(){const{after,before,showAlignmentOptions,showSeparator,title}=this.props;let textDiff;let widgetsDiff=[];if(before.content||after.content){textDiff=jsxRuntimeExports.jsx(TextDiff,{before:before.content,after:after.content,title:title});}const beforeWidgets=Object.keys(before.widgets??{}).filter(widget=>before.content.includes(widget));const afterWidgets=Object.keys(after.widgets??{}).filter(widget=>after.content.includes(widget));if(beforeWidgets.length>0||afterWidgets.length>0){const widgets=_.union(beforeWidgets,afterWidgets);widgetsDiff=widgets.map(widget=>jsxRuntimeExports.jsx(WidgetDiff,{before:filterWidgetInfo(before.widgets?.[widget],showAlignmentOptions),after:filterWidgetInfo(after.widgets?.[widget],showAlignmentOptions),title:widget,type:(before.widgets?.[widget]??{}).type||(after.widgets?.[widget]??{}).type},widget));}return jsxRuntimeExports.jsxs("div",{children:[textDiff,widgetsDiff,showSeparator&&jsxRuntimeExports.jsx("div",{className:"diff-separator"})]})}}RendererDiff.defaultProps={after:{content:"",images:{},widgets:{}},before:{content:"",images:{},widgets:{}},showAlignmentOptions:false,showSeparator:false};
|
|
1475
1475
|
|
|
1476
1476
|
class ArticleDiff extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){this.setState(ArticleDiff._stateFromProps(nextProps));}render(){const{before,after}=this.state;const sectionCount=Math.max(before.length,after.length);const sections=_.times(sectionCount,n=>jsxRuntimeExports.jsx(RendererDiff,{before:n<before.length?before[n]:undefined,after:n<after.length?after[n]:undefined,title:`Section ${n+1}`,showAlignmentOptions:true,showSeparator:n<sectionCount-1},n));return jsxRuntimeExports.jsx(Dependencies.DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsx("div",{className:"framework-perseus",children:sections})})}constructor(...args){super(...args),this.state=ArticleDiff._stateFromProps(this.props);}}ArticleDiff._stateFromProps=props=>{const{before,after}=props;return {before:Array.isArray(before)?before:[before],after:Array.isArray(after)?after:[after]}};
|
|
1477
1477
|
|
|
@@ -1487,7 +1487,7 @@ class ItemEditor extends React.Component{static getDerivedStateFromProps(props){
|
|
|
1487
1487
|
|
|
1488
1488
|
const{HUD}=components;class EditorPage extends React.Component{componentDidMount(){this._isMounted=true;this.updateRenderer();}componentDidUpdate(){setTimeout(()=>{this.updateRenderer();});}componentWillUnmount(){this._isMounted=false;}updateRenderer(){const hasEditor=!this.props.developerMode||!this.props.jsonMode;if(!this._isMounted||!hasEditor){return}const touch=this.props.previewDevice==="phone"||this.props.previewDevice==="tablet";const deviceBasedApiOptions={...this.getApiOptions(),customKeypad:touch,isMobile:touch};this.itemEditor.current?.triggerPreviewUpdate({type:"question",data:_({item:this.serialize(),apiOptions:deviceBasedApiOptions,initialHintsVisible:0,device:this.props.previewDevice,linterContext:{contentType:"exercise",highlightLint:this.state.highlightLint,paths:this.props.contentPaths||[]},reviewMode:true,legacyPerseusLint:this.itemEditor.current?.getSaveWarnings()}).extend(_(this.props).pick("problemNum"))});}getApiOptions(){return {...ApiOptions.defaults,...this.props.apiOptions}}getSaveWarnings(){const issues1=this.itemEditor.current?.getSaveWarnings();const issues2=this.hintsEditor.current?.getSaveWarnings();return issues1.concat(issues2)}serialize(options){if(this.props.jsonMode){return this.state.json}return _.extend(this.itemEditor.current?.serialize(options),{hints:this.hintsEditor.current?.serialize(options)})}render(){let className="framework-perseus";const editingDisabled=this.props.apiOptions?.editingDisabled??false;const touch=this.props.previewDevice==="phone"||this.props.previewDevice==="tablet";const deviceBasedApiOptions={...this.getApiOptions(),customKeypad:touch,isMobile:touch};if(deviceBasedApiOptions.isMobile){className+=" "+ClassNames.MOBILE;}return jsxRuntimeExports.jsx(Dependencies.DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{id:"perseus",className:className,children:[jsxRuntimeExports.jsxs("div",{style:{marginBottom:10},children:[this.props.developerMode&&jsxRuntimeExports.jsxs("span",{children:[jsxRuntimeExports.jsxs("label",{children:[" ","Developer JSON Mode:"," ",jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.jsonMode,disabled:this.props.apiOptions?.editingDisabled,onChange:this.toggleJsonMode})]})," "]}),!this.props.jsonMode&&jsxRuntimeExports.jsx(ViewportResizer,{deviceType:this.props.previewDevice,onViewportSizeChanged:this.props.onPreviewDeviceChange}),!this.props.jsonMode&&jsxRuntimeExports.jsx(HUD,{message:"Style warnings",enabled:this.state.highlightLint,onClick:()=>{this.setState({highlightLint:!this.state.highlightLint});}})]}),this.props.developerMode&&this.props.jsonMode&&jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsx(JsonEditor,{multiLine:true,value:this.state.json,onChange:this.changeJSON,editingDisabled:editingDisabled})}),(!this.props.developerMode||!this.props.jsonMode)&&jsxRuntimeExports.jsx(ItemEditor,{ref:this.itemEditor,itemId:this.props.itemId,question:this.props.question,answerArea:this.props.answerArea,imageUploader:this.props.imageUploader,onChange:this.handleChange,deviceType:this.props.previewDevice,widgetIsOpen:this.state.widgetsAreOpen,apiOptions:deviceBasedApiOptions,previewURL:this.props.previewURL,issues:this.props.issues,additionalTemplates:this.props.additionalTemplates}),(!this.props.developerMode||!this.props.jsonMode)&&jsxRuntimeExports.jsx(CombinedHintsEditor,{ref:this.hintsEditor,itemId:this.props.itemId,hints:this.props.hints,imageUploader:this.props.imageUploader,onChange:this.handleChange,deviceType:this.props.previewDevice,apiOptions:deviceBasedApiOptions,previewURL:this.props.previewURL,highlightLint:this.state.highlightLint,widgetIsOpen:this.state.widgetsAreOpen})]})})}constructor(props){super(props),this.itemEditor=React.createRef(),this.hintsEditor=React.createRef(),this.toggleJsonMode=()=>{this.setState({json:this.serialize({keepDeletedWidgets:true})},()=>{this.props.onChange({jsonMode:!this.props.jsonMode});});},this.handleChange=(toChange,cb,silent)=>{const newProps=_(this.props).pick("question","hints","answerArea");_(newProps).extend(toChange);this.props.onChange(newProps,cb,silent);},this.changeJSON=newJson=>{this.setState({json:newJson});this.props.onChange(newJson);};this.state={json:_.pick(this.props,"question","answerArea","hints"),gradeMessage:"",wasAnswered:false,highlightLint:true,widgetsAreOpen:this.props.widgetsAreOpen??true};this._isMounted=false;}}EditorPage.defaultProps={developerMode:false,jsonMode:false,onChange:()=>{}};
|
|
1489
1489
|
|
|
1490
|
-
function ContentPreview({question,apiOptions,seamless,linterContext,legacyPerseusLint,previewDevice}){const i18n=usePerseusI18n();const isMobile=previewDevice!=="desktop";const className=isMobile?"perseus-mobile":"";return jsxRuntimeExports.jsx(View,{className:`framework-perseus ${className}`,style:[styles$P.container,!seamless?styles$P.gutter:undefined],children:jsxRuntimeExports.jsx(StatefulKeypadContextProvider,{children:jsxRuntimeExports.jsx(KeypadContext.Consumer,{children:({setKeypadActive,keypadElement,setKeypadElement})=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(UserInputManager,{widgets:question?.widgets||{},problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>jsxRuntimeExports.jsx(Renderer,{strings:i18n.strings,apiOptions:{...apiOptions,isMobile},keypadElement:keypadElement,linterContext:linterContext,legacyPerseusLint:legacyPerseusLint,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,...question})}),jsxRuntimeExports.jsx(MobileKeypad,{onAnalyticsEvent:()=>Promise.resolve(),onDismiss:()=>setKeypadActive(false),onElementMounted:setKeypadElement})]})})})})}const styles$P=StyleSheet.create({container:{padding:spacing.xxxSmall_4,containerType:"inline-size",containerName:"perseus-root"},gutter:{marginRight:lintGutterWidth}});
|
|
1490
|
+
function ContentPreview({question,apiOptions,seamless,linterContext,legacyPerseusLint,previewDevice,reviewMode}){const i18n=usePerseusI18n();const isMobile=previewDevice!=="desktop";const className=isMobile?"perseus-mobile":"";return jsxRuntimeExports.jsx(View,{className:`framework-perseus ${className}`,style:[styles$P.container,!seamless?styles$P.gutter:undefined],children:jsxRuntimeExports.jsx(StatefulKeypadContextProvider,{children:jsxRuntimeExports.jsx(KeypadContext.Consumer,{children:({setKeypadActive,keypadElement,setKeypadElement})=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(UserInputManager,{widgets:question?.widgets||{},problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>jsxRuntimeExports.jsx(Renderer,{strings:i18n.strings,apiOptions:{...apiOptions,isMobile},keypadElement:keypadElement,linterContext:linterContext,legacyPerseusLint:legacyPerseusLint,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,reviewMode:reviewMode,...question})}),jsxRuntimeExports.jsx(MobileKeypad,{onAnalyticsEvent:()=>Promise.resolve(),onDismiss:()=>setKeypadActive(false),onElementMounted:setKeypadElement})]})})})})}const styles$P=StyleSheet.create({container:{padding:spacing.xxxSmall_4,containerType:"inline-size",containerName:"perseus-root"},gutter:{marginRight:lintGutterWidth}});
|
|
1491
1491
|
|
|
1492
1492
|
const{TextListEditor: TextListEditor$4}=components;const Categorizer=Categorizer$1.widget;class CategorizerEditor extends React.Component{render(){const categorizerProps={items:this.props.items,categories:this.props.categories,userInput:{values:this.props.values},handleUserInput:userInput=>{this.props.onChange({values:userInput.values});},apiOptions:this.props.apiOptions,trackInteraction:function(){}};return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Randomize item order",checked:this.props.randomizeItems,onChange:value=>{this.props.onChange({randomizeItems:value});}})}),"Categories:",jsxRuntimeExports.jsx(TextListEditor$4,{options:this.props.categories,onChange:cat=>{this.change("categories",cat);},layout:"horizontal"}),"Items:",jsxRuntimeExports.jsx(TextListEditor$4,{options:this.props.items,onChange:items=>{this.change({items:items,values:_.first(this.props.values,items.length)});},layout:"vertical"}),jsxRuntimeExports.jsx(Categorizer,{...categorizerProps})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}CategorizerEditor.propTypes={...Changeable.propTypes,apiOptions:ApiOptions.propTypes,items:PropTypes.arrayOf(PropTypes.string),categories:PropTypes.arrayOf(PropTypes.string),values:PropTypes.arrayOf(PropTypes.number),randomizeItems:PropTypes.bool};CategorizerEditor.widgetName="categorizer";CategorizerEditor.defaultProps=categorizerLogic.defaultWidgetOptions;
|
|
1493
1493
|
|