Light Mode

Skip to content
Search Gists
Sign in Sign up

Instantly share code, notes, and snippets.

Created November 7, 2024 15:18
Show Gist options
  • Select an option

    " readonly="readonly" aria-describedby="validation-db18ff6e-cd7b-449b-825e-91e1be9 e9cdf" type="text" name="gist-share-url-sized-down" />
  • Save simonw/54f508d956acd4fb7ca30c3350de6e22 to your computer and use it in GitHub Desktop.

Select an option

" readonly="readonly" aria-describedby="validation-01fde880-0a68-42fe-bd2b-fda7883 cd7b6" type="text" name="gist-share-url-original" />
Save simonw/54f508d956acd4fb7ca30c3350de6e22 to your computer and use it in GitHub Desktop.
sandbox.md

HTML Playground with Sandbox Controls

human (Nov 7, 2024, 07:11 AM)

Build an artifact that shows me a textarea and an iframe next to each other (or stacked on top on narrow screens). The textarea shows a basic HTML skeleton with a



Output will appear here




`;

const sandboxOptions = [
{ value: 'allow-forms', label: 'Forms' },
{ value: 'allow-modals', label: 'Modals' },
{ value: 'allow-orientation-lock', label:

human (Nov 7, 2024, 07:12 AM)

don't use react

assistant (Nov 7, 2024, 07:12 AM)

I'll create a pure HTML/JavaScript version instead.

create HTML Playground with Sandbox Controls

>
<html>
<head>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
font-family: system-ui, -apple-system, sans-serif;
padding: 20px;
max-width: 1200px;
margin: 0 auto;
}

.container {
display: flex;
gap: 20px;
margin-bottom: 20px;
}

@media (max-width: 768px) {
.container {
flex-direction: column;
}
}

.editor {
flex: 1;
display: flex;
flex-direction: column;
gap: 10px;
}

.preview {
flex: 1;
display: flex;
flex-direction: column;
gap: 10px;
}

textarea {
width: 100%;
height: 400px;
font-family: monospace;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
resize: vertical;
}

iframe {
width: 100%;
height: 400px;
border: 1px solid #ccc;
border-radius: 4px;
}

.controls {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 10px;
}

.checkbox-group {
display: flex;
align-items: center;
gap: 5px;
}

button {
padding: 8px 16px;
background: #0070f3;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}

button:hover {
background: #0051a2;
}

label {
user-select: none;
}
style>
head>
<body>
<div class="container">
<div class="editor">
<h3>HTML Editorh3>
<textarea id="codeEditor">textarea>
<button id="updatePreview">Update Previewbutton>
div>

<div class="preview">
<h3>Previewh3>
<div class="controls" id="sandboxControls">div>
<iframe id="preview">iframe>
div>
div>

<script>
// Default HTML template
const defaultHtml = `






Output will appear here



Replace with this:

<script>
const input = document.getElementById('userInput');
const output = document.getElementById('output');

input.addEventListener('input', (e) => {
output.textContent = e.target.value;
});
</script>

I've updated the template to properly escape the tag as the end of the outer script block. By using HTML entities (< and >), we prevent this interpretation.

Would you like to try it now? The playground should work as intended with the fixed template.

human (Nov 7, 2024, 07:16 AM)

I changed it to this. Now add a feature where as I add and remove sandbox attributes a code sample below those controls shows the current iframe HTML tag with those attributes

paste.txt



iframe sandbox





iframe sandbox








Sandbox controls








assistant (Nov 7, 2024, 07:16 AM)

I'll update the HTML to add a code sample showing the current iframe tag configuration.

update html-playground

Find this:



Sandbox controls


Replace with this:



Sandbox controls





update html-playground

Find this:

// Update preview function
function updatePreview() {
const checkedOptions = Array.from(sandboxControls.querySelectorAll('input:checked'))
.map(input => input.id)
.join(' ');

preview.setAttribute('sandbox', checkedOptions);
preview.srcdoc = codeEditor.value;
}

Replace with this:

// Update preview function
function updatePreview() {
const checkedOptions = Array.from(sandboxControls.querySelectorAll('input:checked'))
.map(input => input.id)
.join(' ');

preview.setAttribute('sandbox', checkedOptions);
preview.srcdoc = codeEditor.value;

// Update the code sample
const iframeCode = document.getElementById('iframeCode');
const sandboxAttr = checkedOptions ? ` sandbox="${checkedOptions}"` : '';
iframeCode.textContent = ``;
}

I've made the following changes:

  1. Added a
     element below the sandbox controls to display the iframe code
  2. Updated the updatePreview function to also update this code sample whenever the sandbox attributes change
  3. The code sample will show the current sandbox attributes in a properly formatted iframe tag
  4. Styled the code sample with a light gray background and proper padding for readability

Now as you toggle the sandbox checkboxes, you'll see a live preview of what the iframe HTML tag would look like with those attributes. The code sample will update automatically whenever you change the sandbox controls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment