Repository navigation
Expand the Example drawing over the editor panel #586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -16,6 +16,8 @@ const TOOL_ICONS = { | |||||||||||||||||||||||||||||||
| eraser: '<path d="m4 14 9-10 7 7-9 10H7Z M8 10l7 7 M11 21h10"/>', | ||||||||||||||||||||||||||||||||
| undo: '<path d="m9 5-5 5 5 5 M4 10h10a6 6 0 0 1 0 12"/>', | ||||||||||||||||||||||||||||||||
| clear: '<path d="M3 6h18 M9 6V3h6v3 M5 6l1 15h12l1-15 M10 10v7 M14 10v7"/>', | ||||||||||||||||||||||||||||||||
| expand: '<path d="M4 9V4h5 M15 4h5v5 M20 15v5h-5 M9 20H4v-5"/>', | ||||||||||||||||||||||||||||||||
| shrink: '<path d="M9 4v5H4 M20 9h-5V4 M15 20v-5h5 M4 15h5v5"/>', | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| function setToolIcon(button, name) { | ||||||||||||||||||||||||||||||||
|
|
@@ -44,7 +46,13 @@ export function mountExampleBoard( | |||||||||||||||||||||||||||||||
| const model = createBoard(); | ||||||||||||||||||||||||||||||||
| const pointers = createPointerGate(); | ||||||||||||||||||||||||||||||||
| const tools = root.querySelector("[data-tools]"); | ||||||||||||||||||||||||||||||||
| const status = root.querySelector(":scope > [role=status]"); | ||||||||||||||||||||||||||||||||
| // The interview wraps the board in `.example-pane` so it can lift out of | ||||||||||||||||||||||||||||||||
| // the drawer; the task page keeps it directly under the details element. | ||||||||||||||||||||||||||||||||
| const status = root.querySelector( | ||||||||||||||||||||||||||||||||
| ":scope > [role=status], :scope > .example-pane > [role=status]", | ||||||||||||||||||||||||||||||||
|
Disesfgewu marked this conversation as resolved.
Resolved
|
||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
| const expand = root.querySelector("[data-action=expand]"); | ||||||||||||||||||||||||||||||||
| const pane = root.querySelector(":scope > .example-pane"); | ||||||||||||||||||||||||||||||||
| let tool = "pen"; | ||||||||||||||||||||||||||||||||
| let color = PEN_COLORS[0].color; | ||||||||||||||||||||||||||||||||
| let drag = null; | ||||||||||||||||||||||||||||||||
|
|
@@ -269,6 +277,60 @@ export function mountExampleBoard( | |||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
| canvas.addEventListener("pointercancel", cancel); | ||||||||||||||||||||||||||||||||
| canvas.addEventListener("lostpointercapture", cancel); | ||||||||||||||||||||||||||||||||
| // Expanding moves no element: the pane is restyled in place, so the canvas, | ||||||||||||||||||||||||||||||||
| // its strokes and anything waiting to reach Jim stay exactly as they were. | ||||||||||||||||||||||||||||||||
| // Only the drawn size changes, and `boardPoint` already scales by it. | ||||||||||||||||||||||||||||||||
| function setExpanded(on) { | ||||||||||||||||||||||||||||||||
| root.toggleAttribute("data-expanded", on); | ||||||||||||||||||||||||||||||||
|
Disesfgewu marked this conversation as resolved.
Resolved
|
||||||||||||||||||||||||||||||||
| setToolIcon(expand, on ? "shrink" : "expand"); | ||||||||||||||||||||||||||||||||
| expand.setAttribute("aria-label", on ? "Shrink drawing" : "Expand drawing"); | ||||||||||||||||||||||||||||||||
| expand.title = expand.getAttribute("aria-label"); | ||||||||||||||||||||||||||||||||
| const panel = root.closest(".editor-panel"); | ||||||||||||||||||||||||||||||||
| // The panel can scroll a little on a short screen, and the pane would | ||||||||||||||||||||||||||||||||
| // scroll with it; the stylesheet stops it scrolling while expanded. | ||||||||||||||||||||||||||||||||
| if (on && panel) panel.scrollTop = 0; | ||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Expanding sets the panel's
Suggested change
|
||||||||||||||||||||||||||||||||
| // What the pane covers leaves the tab order with it, or Shift+Tab walks | ||||||||||||||||||||||||||||||||
| // into a code editor nobody can see. The sidebar is outside the panel. | ||||||||||||||||||||||||||||||||
| for (let node = pane; panel && node !== panel; node = node.parentElement) | ||||||||||||||||||||||||||||||||
| for (const sibling of node.parentElement.children) | ||||||||||||||||||||||||||||||||
| if (sibling !== node) sibling.inert = on; | ||||||||||||||||||||||||||||||||
|
Comment on lines
+294
to
+296
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shrinking sets
Suggested change
|
||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| if (expand) { | ||||||||||||||||||||||||||||||||
| setExpanded(false); | ||||||||||||||||||||||||||||||||
| // Nothing on the page closes it while expanded, but whatever does must | ||||||||||||||||||||||||||||||||
| // not leave the editor inert under a board that is gone. | ||||||||||||||||||||||||||||||||
| root.addEventListener("toggle", () => { | ||||||||||||||||||||||||||||||||
| if (!root.open) setExpanded(false); | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
| expand.addEventListener("click", () => { | ||||||||||||||||||||||||||||||||
| if (!drag && !textDraft.busy()) | ||||||||||||||||||||||||||||||||
| setExpanded(!root.hasAttribute("data-expanded")); | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
| // Not a modal dialog: the sidebar's turn and mute controls stay usable | ||||||||||||||||||||||||||||||||
| // while the board is large, so Escape is handled here rather than by | ||||||||||||||||||||||||||||||||
| // `showModal`. A text draft claims Escape first and stops it. An ink | ||||||||||||||||||||||||||||||||
| // stroke takes no focus, so after a sidebar button the key still arrives | ||||||||||||||||||||||||||||||||
| // there. A field or a dialog keeps Escape for itself, and so does an | ||||||||||||||||||||||||||||||||
| // input method, a modifier chord or a held key. | ||||||||||||||||||||||||||||||||
| document.addEventListener("keydown", (event) => { | ||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||
| event.key !== "Escape" || | ||||||||||||||||||||||||||||||||
| event.isComposing || | ||||||||||||||||||||||||||||||||
| event.keyCode === 229 || | ||||||||||||||||||||||||||||||||
| event.repeat || | ||||||||||||||||||||||||||||||||
| event.altKey || | ||||||||||||||||||||||||||||||||
| event.ctrlKey || | ||||||||||||||||||||||||||||||||
| event.metaKey || | ||||||||||||||||||||||||||||||||
| event.shiftKey || | ||||||||||||||||||||||||||||||||
| drag || | ||||||||||||||||||||||||||||||||
| textDraft.busy() || | ||||||||||||||||||||||||||||||||
| !root.hasAttribute("data-expanded") || | ||||||||||||||||||||||||||||||||
| event.target.closest?.("input, textarea, select, [role=dialog]") | ||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This listener is on
Suggested change
|
||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||
| setExpanded(false); | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| root.addEventListener("toggle", () => { | ||||||||||||||||||||||||||||||||
| if (!root.open) cancelTurn?.(); | ||||||||||||||||||||||||||||||||
| if (!root.open && drag) { | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -107,6 +107,12 @@ export function mountInterviewDrawer(panel) { | |
| }); | ||
| for (const details of drawer.querySelectorAll("details")) | ||
| details.addEventListener("toggle", paint); | ||
| // A shrinking board comes back to a drawer that may have been resized while | ||
| // it was out, so its docked height is measured again. | ||
| new MutationObserver(paint).observe(example, { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While the board is expanded, this observer (and the panel's |
||
| attributes: true, | ||
| attributeFilter: ["data-expanded"], | ||
| }); | ||
| new MutationObserver(paint).observe(results, { | ||
| attributes: true, | ||
| attributeFilter: ["hidden"], | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.