Popcorn Hack: Refactor Base Inputs





<!-- Reusable UI Runner Component -->
<div class="ui-runner-container" id="ui-runner-inputs-popcorn-runner" data-storage-key="_sass_inputs-hw__inputs-popcorn-runner">
  
<div class="challenge-box">
  <h3>Challenge</h3>
  <p>
Refactor non-standard inline styles and made-up classes using the official OCS input grammar.
</p>
</div>


  
  
  <div class="editor-container">
  
  <div class="control-panel">
    
      <button type="button" class="ocs__btn utility run" data-hook="run" title="Run" aria-label="Run"></button>
      <button type="button" class="ocs__btn utility stop" data-hook="stop" title="Stop" aria-label="Stop"></button>
      <button type="button" class="ocs__btn utility copy" data-hook="copy" title="Copy Code" aria-label="Copy Code"></button>
      <button type="button" class="ocs__btn utility save" data-hook="save" title="Save Code" aria-label="Save Code"></button>
      <button type="button" class="ocs__btn utility clear" data-hook="clear" title="Clear Storage" aria-label="Clear Storage"></button>
  
  </div>
  

  <textarea class="editor-textarea"></textarea>

  
  <div class="control-panel">
    
    <span class="lineCount">Lines: 1</span>
<span class="charCount">Characters: 0</span>


  
  </div>
  
</div>


  <div class="output-container">
    <div class="control-panel">
      <span>UI Output</span>
      <button type="button" class="ocs__btn utility reset" data-hook="reset" title="Reset" aria-label="Reset"></button>
    </div>
    <div class="ui-output" id="ui-output-inputs-popcorn-runner"></div>
  </div>
</div>

<script type="module">
import { BaseRunner, UiExecutor } from '/assets/js/pages/runners/index.js';

(function() {
  const container = document.getElementById('ui-runner-inputs-popcorn-runner');
  if (!container) return;
  
  const defaultCode = `
// UI_RUNNER: Inputs Popcorn Base
outputElement.innerHTML = [
  '<label for="search-input" class="ocs__label">Search</label>',
  '<input id="search-input" type="text" class="ocs__input ocs__input--large ocs__input--gradient" placeholder="Search PVO resources...">',
  '<br><br>',
  '<label for="first-name" class="ocs__label">First Name</label>',
  '<input id="first-name" type="text" class="ocs__input ocs__input--small" placeholder="Volunteer First Name">'
].join('');
`.trim();
  const autostart = "true" === "true";
  const editorHeight = "";
  const outputHeight = "";
  const storageKey = container.dataset.storageKey;
  const runner = new BaseRunner(container, { storageKey });

  const editor = runner.initializeEditor({
    defaultCode,
    editorHeight,
    fallbackCode: "// Write your JavaScript code here",
    codeMirrorOptions: {
      lineNumbers: true,
      mode: "javascript",
      theme: "darcula",
      indentUnit: 2,
      tabSize: 4,
      styleSelectedText: true
    }
  });

  if (outputHeight) {
    runner.applyScopedStyle(`#ui-output-inputs-popcorn-runner { min-height: ${outputHeight}; max-height: ${outputHeight}; height: ${outputHeight}; }`);
  }

  const uiOutput = container.querySelector('.ui-output');
  const uiExecutor = new UiExecutor({
    editor,
    outputElement: uiOutput,
  });

  runner.bindEditorButtons({
    resetValue: defaultCode || "// Write your JavaScript code here",
    onClear: () => {
      stopExecution();
    },
    saveFeedback: '✔',
    copyFeedback: '✔'
  });

  // Stop execution
  function stopExecution() {
    uiExecutor.stop();
  }

  // Reset button
  container.querySelector('[data-hook="reset"]').onclick = () => {
    stopExecution();
  };

  // Stop button
  container.querySelector('[data-hook="stop"]').onclick = () => {
    stopExecution();
  };

  // Run button logic
  function runCode() {
    return uiExecutor.run();
  }

  runner.bindButton('', runCode, 'run');

  // Keyboard shortcut
  runner.bindShortcut(runCode);

  if (autostart) {
    // Defer to next tick so output container is present before execution.
    setTimeout(() => {
      runCode();
    }, 0);
  }
})();
</script>

Homework Hack





<!-- Reusable UI Runner Component -->
<div class="ui-runner-container" id="ui-runner-inputs-hw-runner" data-storage-key="_sass_inputs-hw__inputs-hw-runner">
  
<div class="challenge-box">
  <h3>Challenge</h3>
  <p>
Refactor the signup form by removing inline styles and made-up classes, using proper ocs__input modifiers and accessible labels.
</p>
</div>


  
  
  <div class="editor-container">
  
  <div class="control-panel">
    
      <button type="button" class="ocs__btn utility run" data-hook="run" title="Run" aria-label="Run"></button>
      <button type="button" class="ocs__btn utility stop" data-hook="stop" title="Stop" aria-label="Stop"></button>
      <button type="button" class="ocs__btn utility copy" data-hook="copy" title="Copy Code" aria-label="Copy Code"></button>
      <button type="button" class="ocs__btn utility save" data-hook="save" title="Save Code" aria-label="Save Code"></button>
      <button type="button" class="ocs__btn utility clear" data-hook="clear" title="Clear Storage" aria-label="Clear Storage"></button>
  
  </div>
  

  <textarea class="editor-textarea"></textarea>

  
  <div class="control-panel">
    
    <span class="lineCount">Lines: 1</span>
<span class="charCount">Characters: 0</span>


  
  </div>
  
</div>


  <div class="output-container">
    <div class="control-panel">
      <span>UI Output</span>
      <button type="button" class="ocs__btn utility reset" data-hook="reset" title="Reset" aria-label="Reset"></button>
    </div>
    <div class="ui-output" id="ui-output-inputs-hw-runner"></div>
  </div>
</div>

<script type="module">
import { BaseRunner, UiExecutor } from '/assets/js/pages/runners/index.js';

(function() {
  const container = document.getElementById('ui-runner-inputs-hw-runner');
  if (!container) return;
  
  const defaultCode = `
// UI_RUNNER: Inputs Homework Base
outputElement.innerHTML = [
  '<form class="ocs__form">',
  '  <div class="ocs__field">',
  '    <label for="hw-category" class="ocs__label">Assistance Category</label>',
  '    <input id="hw-category" type="text" class="ocs__input ocs__input--large ocs__input--gradient" placeholder="Assistance Category">',
  '  </div>',
  '  <br>',
  '  <div class="ocs__field">',
  '    <label for="hw-first-name" class="ocs__label">Volunteer First Name</label>',
  '    <input id="hw-first-name" type="text" class="ocs__input ocs__input--small" placeholder="Volunteer First Name">',
  '  </div>',
  '  <br>',
  '  <div class="ocs__field">',
  '    <label for="hw-email" class="ocs__label">Volunteer Email</label>',
  '    <input id="hw-email" type="email" class="ocs__input ocs__input--medium" placeholder="Volunteer Email">',
  '  </div>',
  '</form>'
].join('');
`.trim();
  const autostart = "true" === "true";
  const editorHeight = "";
  const outputHeight = "";
  const storageKey = container.dataset.storageKey;
  const runner = new BaseRunner(container, { storageKey });

  const editor = runner.initializeEditor({
    defaultCode,
    editorHeight,
    fallbackCode: "// Write your JavaScript code here",
    codeMirrorOptions: {
      lineNumbers: true,
      mode: "javascript",
      theme: "darcula",
      indentUnit: 2,
      tabSize: 4,
      styleSelectedText: true
    }
  });

  if (outputHeight) {
    runner.applyScopedStyle(`#ui-output-inputs-hw-runner { min-height: ${outputHeight}; max-height: ${outputHeight}; height: ${outputHeight}; }`);
  }

  const uiOutput = container.querySelector('.ui-output');
  const uiExecutor = new UiExecutor({
    editor,
    outputElement: uiOutput,
  });

  runner.bindEditorButtons({
    resetValue: defaultCode || "// Write your JavaScript code here",
    onClear: () => {
      stopExecution();
    },
    saveFeedback: '✔',
    copyFeedback: '✔'
  });

  // Stop execution
  function stopExecution() {
    uiExecutor.stop();
  }

  // Reset button
  container.querySelector('[data-hook="reset"]').onclick = () => {
    stopExecution();
  };

  // Stop button
  container.querySelector('[data-hook="stop"]').onclick = () => {
    stopExecution();
  };

  // Run button logic
  function runCode() {
    return uiExecutor.run();
  }

  runner.bindButton('', runCode, 'run');

  // Keyboard shortcut
  runner.bindShortcut(runCode);

  if (autostart) {
    // Defer to next tick so output container is present before execution.
    setTimeout(() => {
      runCode();
    }, 0);
  }
})();
</script>