diff --git a/src/commons/assessmentWorkspace/__tests__/__snapshots__/AssessmentWorkspace.tsx.snap b/src/commons/assessmentWorkspace/__tests__/__snapshots__/AssessmentWorkspace.tsx.snap index f8fce30095..9b9db5f8e7 100644 --- a/src/commons/assessmentWorkspace/__tests__/__snapshots__/AssessmentWorkspace.tsx.snap +++ b/src/commons/assessmentWorkspace/__tests__/__snapshots__/AssessmentWorkspace.tsx.snap @@ -333,6 +333,34 @@ exports[`AssessmentWorkspace AssessmentWorkspace page with ContestVoting questio <div class="right-parent" > + <span + class="fullscreen-button bp5-popover-target" + > + <button + aria-expanded="false" + class="bp5-button bp5-minimal" + tabindex="0" + type="button" + > + <span + aria-hidden="true" + class="bp5-icon bp5-icon-maximize" + > + <svg + data-icon="maximize" + height="16" + role="img" + viewBox="0 0 16 16" + width="16" + > + <path + d="M5.99 8.99c-.28 0-.53.11-.71.29l-3.29 3.29v-1.59c0-.55-.45-1-1-1s-1 .45-1 1v4c0 .55.45 1 1 1h4c.55 0 1-.45 1-1s-.45-1-1-1H3.41L6.7 10.7a1.003 1.003 0 00-.71-1.71zm9-9h-4c-.55 0-1 .45-1 1s.45 1 1 1h1.59l-3.3 3.3a.99.99 0 00-.29.7 1.003 1.003 0 001.71.71l3.29-3.29V5c0 .55.45 1 1 1s1-.45 1-1V1c0-.56-.45-1.01-1-1.01z" + fill-rule="evenodd" + /> + </svg> + </span> + </button> + </span> <div class="resize-side-content" style="position: relative; user-select: auto; width: auto; height: auto; box-sizing: border-box; flex-shrink: 0;" @@ -1583,6 +1611,34 @@ exports[`AssessmentWorkspace AssessmentWorkspace page with MCQ question renders <div class="right-parent" > + <span + class="fullscreen-button bp5-popover-target" + > + <button + aria-expanded="false" + class="bp5-button bp5-minimal" + tabindex="0" + type="button" + > + <span + aria-hidden="true" + class="bp5-icon bp5-icon-maximize" + > + <svg + data-icon="maximize" + height="16" + role="img" + viewBox="0 0 16 16" + width="16" + > + <path + d="M5.99 8.99c-.28 0-.53.11-.71.29l-3.29 3.29v-1.59c0-.55-.45-1-1-1s-1 .45-1 1v4c0 .55.45 1 1 1h4c.55 0 1-.45 1-1s-.45-1-1-1H3.41L6.7 10.7a1.003 1.003 0 00-.71-1.71zm9-9h-4c-.55 0-1 .45-1 1s.45 1 1 1h1.59l-3.3 3.3a.99.99 0 00-.29.7 1.003 1.003 0 001.71.71l3.29-3.29V5c0 .55.45 1 1 1s1-.45 1-1V1c0-.56-.45-1.01-1-1.01z" + fill-rule="evenodd" + /> + </svg> + </span> + </button> + </span> <div class="resize-side-content" style="position: relative; user-select: auto; width: auto; height: auto; box-sizing: border-box; flex-shrink: 0;" @@ -2363,6 +2419,34 @@ exports[`AssessmentWorkspace AssessmentWorkspace page with overdue assessment re <div class="right-parent" > + <span + class="fullscreen-button bp5-popover-target" + > + <button + aria-expanded="false" + class="bp5-button bp5-minimal" + tabindex="0" + type="button" + > + <span + aria-hidden="true" + class="bp5-icon bp5-icon-maximize" + > + <svg + data-icon="maximize" + height="16" + role="img" + viewBox="0 0 16 16" + width="16" + > + <path + d="M5.99 8.99c-.28 0-.53.11-.71.29l-3.29 3.29v-1.59c0-.55-.45-1-1-1s-1 .45-1 1v4c0 .55.45 1 1 1h4c.55 0 1-.45 1-1s-.45-1-1-1H3.41L6.7 10.7a1.003 1.003 0 00-.71-1.71zm9-9h-4c-.55 0-1 .45-1 1s.45 1 1 1h1.59l-3.3 3.3a.99.99 0 00-.29.7 1.003 1.003 0 001.71.71l3.29-3.29V5c0 .55.45 1 1 1s1-.45 1-1V1c0-.56-.45-1.01-1-1.01z" + fill-rule="evenodd" + /> + </svg> + </span> + </button> + </span> <div class="resize-side-content" style="position: relative; user-select: auto; width: auto; height: auto; box-sizing: border-box; flex-shrink: 0;" @@ -3137,6 +3221,22 @@ exports[`AssessmentWorkspace AssessmentWorkspace page with programming question <div class="right-parent" > + <span + class="fullscreen-button bp5-popover-target" + > + <button + aria-expanded="false" + class="bp5-button bp5-minimal" + tabindex="0" + type="button" + > + <span + aria-hidden="true" + class="bp5-icon bp5-icon-standard bp5-icon-maximize" + data-icon="maximize" + /> + </button> + </span> <div class="resize-side-content" style="position: relative; user-select: auto; width: auto; height: auto; box-sizing: border-box; flex-shrink: 0;" @@ -3863,6 +3963,34 @@ exports[`AssessmentWorkspace AssessmentWorkspace renders Grading tab correctly i <div class="right-parent" > + <span + class="fullscreen-button bp5-popover-target" + > + <button + aria-expanded="false" + class="bp5-button bp5-minimal" + tabindex="0" + type="button" + > + <span + aria-hidden="true" + class="bp5-icon bp5-icon-maximize" + > + <svg + data-icon="maximize" + height="16" + role="img" + viewBox="0 0 16 16" + width="16" + > + <path + d="M5.99 8.99c-.28 0-.53.11-.71.29l-3.29 3.29v-1.59c0-.55-.45-1-1-1s-1 .45-1 1v4c0 .55.45 1 1 1h4c.55 0 1-.45 1-1s-.45-1-1-1H3.41L6.7 10.7a1.003 1.003 0 00-.71-1.71zm9-9h-4c-.55 0-1 .45-1 1s.45 1 1 1h1.59l-3.3 3.3a.99.99 0 00-.29.7 1.003 1.003 0 001.71.71l3.29-3.29V5c0 .55.45 1 1 1s1-.45 1-1V1c0-.56-.45-1.01-1-1.01z" + fill-rule="evenodd" + /> + </svg> + </span> + </button> + </span> <div class="resize-side-content" style="position: relative; user-select: auto; width: auto; height: auto; box-sizing: border-box; flex-shrink: 0;" diff --git a/src/commons/workspace/Workspace.tsx b/src/commons/workspace/Workspace.tsx index b15423a4cd..93fd2ca8c6 100644 --- a/src/commons/workspace/Workspace.tsx +++ b/src/commons/workspace/Workspace.tsx @@ -1,4 +1,6 @@ -import { FocusStyleManager } from '@blueprintjs/core'; +import { Button, FocusStyleManager, Tooltip } from '@blueprintjs/core'; +import { IconNames } from '@blueprintjs/icons'; +import { useFullscreen } from '@mantine/hooks'; import { Enable, NumberSize, Resizable, ResizableProps, ResizeCallback } from 're-resizable'; import { Direction } from 're-resizable/lib/resizer'; import React from 'react'; @@ -187,6 +189,21 @@ const Workspace: React.FC<WorkspaceProps> = props => { </Resizable> ); + const { + ref: fullscreenRef, + toggle: toggleFullscreen, + fullscreen: isFullscreen + } = useFullscreen<HTMLDivElement>(); + + const fullscreenContainerRef = React.useRef<HTMLDivElement | null>(null); + const setFullscreenRefs = React.useCallback( + (node: HTMLDivElement | null) => { + fullscreenContainerRef.current = node; + fullscreenRef(node); + }, + [fullscreenRef] + ); + return ( <div className="workspace"> <Prompt @@ -206,7 +223,18 @@ const Workspace: React.FC<WorkspaceProps> = props => { <div className="row content-parent" ref={contentContainerDiv}> <div className="editor-divider" ref={editorDividerDiv} /> <Resizable {...editorResizableProps()}>{createWorkspaceInput(props)}</Resizable> - <div className="right-parent"> + <div className="right-parent" ref={setFullscreenRefs}> + <Tooltip + className="fullscreen-button" + content={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'} + portalContainer={fullscreenContainerRef.current || undefined} + > + <Button + minimal + icon={isFullscreen ? IconNames.MINIMIZE : IconNames.MAXIMIZE} + onClick={toggleFullscreen} + /> + </Tooltip> {props.sideContentIsResizeable === undefined || props.sideContentIsResizeable ? resizableSideContent : sideContent} diff --git a/src/pages/playground/__tests__/__snapshots__/Playground.tsx.snap b/src/pages/playground/__tests__/__snapshots__/Playground.tsx.snap index 250b5fc50b..e0ee8352d6 100644 --- a/src/pages/playground/__tests__/__snapshots__/Playground.tsx.snap +++ b/src/pages/playground/__tests__/__snapshots__/Playground.tsx.snap @@ -412,6 +412,22 @@ exports[`Playground tests Playground renders correctly 1`] = ` <div class="right-parent" > + <span + class="fullscreen-button bp5-popover-target" + > + <button + aria-expanded="false" + class="bp5-button bp5-minimal" + tabindex="0" + type="button" + > + <span + aria-hidden="true" + class="bp5-icon bp5-icon-standard bp5-icon-maximize" + data-icon="maximize" + /> + </button> + </span> <div class="resize-side-content" style="position: relative; user-select: auto; width: auto; height: auto; box-sizing: border-box; flex-shrink: 0;" @@ -1749,6 +1765,34 @@ exports[`Playground tests Playground with link renders correctly 1`] = ` <div class="right-parent" > + <span + class="fullscreen-button bp5-popover-target" + > + <button + aria-expanded="false" + class="bp5-button bp5-minimal" + tabindex="0" + type="button" + > + <span + aria-hidden="true" + class="bp5-icon bp5-icon-maximize" + > + <svg + data-icon="maximize" + height="16" + role="img" + viewBox="0 0 16 16" + width="16" + > + <path + d="M5.99 8.99c-.28 0-.53.11-.71.29l-3.29 3.29v-1.59c0-.55-.45-1-1-1s-1 .45-1 1v4c0 .55.45 1 1 1h4c.55 0 1-.45 1-1s-.45-1-1-1H3.41L6.7 10.7a1.003 1.003 0 00-.71-1.71zm9-9h-4c-.55 0-1 .45-1 1s.45 1 1 1h1.59l-3.3 3.3a.99.99 0 00-.29.7 1.003 1.003 0 001.71.71l3.29-3.29V5c0 .55.45 1 1 1s1-.45 1-1V1c0-.56-.45-1.01-1-1.01z" + fill-rule="evenodd" + /> + </svg> + </span> + </button> + </span> <div class="resize-side-content" style="position: relative; user-select: auto; width: auto; height: auto; box-sizing: border-box; flex-shrink: 0;" diff --git a/src/styles/_workspace.scss b/src/styles/_workspace.scss index 1332cec81d..63af80872f 100755 --- a/src/styles/_workspace.scss +++ b/src/styles/_workspace.scss @@ -80,6 +80,13 @@ $code-color-notification: #f9f0d7; height: 100%; padding-bottom: 0.6rem; overflow: auto; + + .fullscreen-button { + position: absolute; + right: 8px; + padding: 5px; + z-index: 10; + } } .left-parent { diff --git a/yarn.lock b/yarn.lock index 4cab629156..9bf09f8e38 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1920,9 +1920,9 @@ integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== "@mantine/hooks@^7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@mantine/hooks/-/hooks-7.7.0.tgz#52f0fdc97e953798d2e632aa5e90959f389cbd1e" - integrity sha512-m99vMzeONMpBLv0Rcb2LD88xAhpvwVdTMBo/7WohBDYtk1shJKHAc/WbQ/cJPcNk11Bzp/mhx/EPNZfs9+NwZA== + version "7.7.1" + resolved "https://registry.yarnpkg.com/@mantine/hooks/-/hooks-7.7.1.tgz#04fd8999fe109615d064bf42a8ff04435c93b927" + integrity sha512-3YH2FzKMlg840tb04PBDcDXyBCi9puFOxEBVgc6Y/pN6KFqfOoAnQE/YvgOtwSNXZlbTWyDlQoYj+3je7pA7og== "@mapbox/node-pre-gyp@^1.0.0": version "1.0.10"