diff --git a/.changeset/display-element-sizing.md b/.changeset/display-element-sizing.md new file mode 100644 index 0000000000..0498a4675c --- /dev/null +++ b/.changeset/display-element-sizing.md @@ -0,0 +1,5 @@ +--- +"jspsych": patch +--- + +Add `width: 100%` and `height: 100%` to `.jspsych-content` CSS to allow plugins to use percentage-based dimensions. This enables plugins to use `height: 100%` and `width: 100%` to fill the display element. The nested DOM structure (`.jspsych-display-element` > `.jspsych-content-wrapper` > `.jspsych-content`) is preserved to maintain compatibility with the progress bar and existing plugins. diff --git a/examples/test-height-demo.html b/examples/test-height-demo.html new file mode 100644 index 0000000000..9eb9f776f2 --- /dev/null +++ b/examples/test-height-demo.html @@ -0,0 +1,74 @@ + + + + jsPsych Display Element Height Test + + + + + + +

jsPsych Display Element Sizing Test

+
+ + + + diff --git a/packages/jspsych/src/index.scss b/packages/jspsych/src/index.scss index 6e55f8d23d..052b5417ac 100644 --- a/packages/jspsych/src/index.scss +++ b/packages/jspsych/src/index.scss @@ -32,6 +32,8 @@ .jspsych-content { text-align: center; margin: auto; /* this is for overflowing content */ + width: 100%; + height: 100%; } .jspsych-top { diff --git a/packages/jspsych/tests/core/display-element-sizing.test.ts b/packages/jspsych/tests/core/display-element-sizing.test.ts new file mode 100644 index 0000000000..2cbf563a74 --- /dev/null +++ b/packages/jspsych/tests/core/display-element-sizing.test.ts @@ -0,0 +1,86 @@ +import { clickTarget, startTimeline } from "@jspsych/test-utils"; +import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from "jspsych"; + +import { initJsPsych } from "../../src"; + +describe("Display element sizing", () => { + test("jspsych-content should have the jspsych-content class", async () => { + const jsPsych = initJsPsych(); + + class TestSizingPlugin implements JsPsychPlugin { + static info = { + name: "test-sizing", + version: "1.0.0", + parameters: {}, + data: {}, + }; + + constructor(private jsPsych: JsPsych) {} + + trial(display_element: HTMLElement, trial: any) { + display_element.innerHTML = '
Test
'; + + // Check that the display element has the jspsych-content class + expect(display_element.classList.contains("jspsych-content")).toBe(true); + + // Check that it's wrapped in jspsych-content-wrapper + const contentWrapper = display_element.parentElement; + expect(contentWrapper?.classList.contains("jspsych-content-wrapper")).toBe(true); + + // Check that the content wrapper is inside jspsych-display-element + const displayContainer = contentWrapper?.parentElement; + expect(displayContainer?.classList.contains("jspsych-display-element")).toBe(true); + + this.jsPsych.finishTrial(); + } + } + + await jsPsych.run([ + { + type: TestSizingPlugin, + }, + ]); + }); + + test("jspsych-content-wrapper should exist with progress bar", async () => { + const jsPsych = initJsPsych({ + show_progress_bar: true, + }); + + class TestProgressPlugin implements JsPsychPlugin { + static info = { + name: "test-progress", + version: "1.0.0", + parameters: {}, + data: {}, + }; + + constructor(private jsPsych: JsPsych) {} + + trial(display_element: HTMLElement, trial: any) { + // Verify progress bar exists + const progressBar = document.querySelector("#jspsych-progressbar-container"); + expect(progressBar).not.toBeNull(); + + // Verify content wrapper still exists and has proper styling + const contentWrapper = display_element.parentElement; + expect(contentWrapper?.classList.contains("jspsych-content-wrapper")).toBe(true); + + // Verify display element structure + const displayContainer = contentWrapper?.parentElement; + expect(displayContainer?.classList.contains("jspsych-display-element")).toBe(true); + + // Progress bar should be a sibling of the content wrapper (both inside display element) + expect(displayContainer?.contains(progressBar)).toBe(true); + + this.jsPsych.finishTrial(); + } + } + + await jsPsych.run([ + { + type: TestProgressPlugin, + }, + ]); + }); +});