Device Frame Web Component

A customizable web component that renders an iframe inside a mobile device frame, with options for device selection, orientation, folding, and scaling.

Installation

You can install the Device Frame component via NPM or download it manually.

NPM Installation

Install the package using NPM:

npm install @dustinpoissant/device-frame

Then include the minified script in your HTML:

<script type="module" src="node_modules/@dustinpoissant/device-frame/DeviceFrame.min.js"></script>

Manual Download

Download DeviceFrame.min.js directly from the repository and include it in your project:

<script type="module" src="DeviceFrame.min.js"></script>

Attributes

Attribute Description Default
src The URL to load in the iframe false
device Device type (e.g., iphone15promax, galaxys22ultra) "iphone15"
controls Comma-separated list of controls to show (device, orientation, fold, scaled) ""
orientation Device orientation (portrait/landscape) "portrait"
scaled Scales device to fit 80% of viewport false
devices Comma-separated list of device keys to show in device picker (leave empty to show all) ""

Available Devices

Examples

Basic Device Frame

<device-frame src="https://websiteipsum.com/index.html"></device-frame>

With Device Picker

<device-frame src="https://websiteipsum.com/index.html" controls="device"></device-frame>

Limited Device Options

<device-frame src="https://websiteipsum.com/index.html" devices="iphone15,galaxys22ultra,ipadpro12" controls="device"></device-frame>

With Orientation Control

<device-frame src="https://websiteipsum.com/index.html" device="galaxys22ultra" orientation="portrait" controls="orientation"></device-frame>

With All Controls

<device-frame src="https://websiteipsum.com/index.html" device="pixelfold" controls="device,orientation,fold,scaled"></device-frame>

JavaScript API

You can control the component programmatically in several ways:

Creating Instances Programmatically

You can create device frame elements dynamically in two ways:

Using the Constructor

import DeviceFrame from './DeviceFrame.js';

// Create with constructor
const frame = new DeviceFrame({
src: 'https://example.com',
device: 'iphone15',
controls: 'device,orientation'
});
document.body.appendChild(frame);

Using document.createElement

// Create a new device frame element
const frame = document.createElement('device-frame');
frame.src = 'https://example.com';
frame.device = 'iphone15';
frame.controls = 'device,orientation';

// Add it to the DOM
document.body.appendChild(frame);

Controlling Existing Elements

Control device frames that are already in the DOM:

const frame = document.querySelector('device-frame');

// Set properties
frame.src = 'https://new-url.com';
frame.device = 'galaxys22ultra';
frame.devices = 'iphone15,galaxys22ultra,ipadpro12'; // Limit device options
frame.orientation = 'landscape';
frame.controls = 'device,orientation';

// Get current values
console.log(frame.device); // 'galaxys22ultra'
console.log(frame.orientation); // 'landscape'

Adding Custom Devices

Extend the device library with custom devices:

import DeviceFrame from './DeviceFrame.js';

// Add a custom device
DeviceFrame.devices['customphone'] = {
name: 'Custom Phone',
resolution: [400, 800],
topFrameSize: 20,
bottomFrameSize: 20,
sideFrameSize: 15,
innerRadius: 10,
outerRadius: 15
};

// Now 'customphone' will appear in device pickers

Event Handling

Listen for component changes:

const frame = document.querySelector('device-frame');

frame.addEventListener('devicechange', (event) => {
console.log('Device changed to:', event.detail.device);
console.log('Previous device:', event.detail.previousDevice);
});

frame.addEventListener('orientationchange', (event) => {
console.log('Orientation changed to:', event.detail.orientation);
});

frame.addEventListener('controlschange', (event) => {
console.log('Controls changed to:', event.detail.controls);
});

frame.addEventListener('scalechange', (event) => {
console.log('Scaled changed to:', event.detail.scaled);
});

frame.addEventListener('deviceschange', (event) => {
console.log('Device list changed to:', event.detail.devices);
});

frame.addEventListener('load', (event) => {
console.log('Iframe loaded:', event.detail.src);
// Access the iframe directly
const iframe = event.detail.iframe;
// Or use the getter
const iframe2 = frame.iframe;
});

Iframe Access

Get direct access to the iframe element for advanced use cases:

const frame = document.querySelector('device-frame');
const iframe = frame.iframe;

// Post messages to the iframe
iframe.contentWindow.postMessage('Hello from parent!', '*');

// Listen for messages from the iframe
window.addEventListener('message', (event) => {
if (event.source === iframe.contentWindow) {
console.log('Message from iframe:', event.data);
}
});

Styling

The select controls inherit styles from the page. Use CSS custom properties to customize spacing:

Inline Styles

For a single component, use inline styles:

<device-frame src="https://example.com" controls="device" style="--spacer: 2rem;"></device-frame>

CSS Targeting

Use the CSS Custom Property --spacer to adjust the space between the controls and the device frame.

Target all device-frame components:

device-frame {
--spacer: 2rem;
}

Or target a specific instance:

<device-frame src="https://example.com" class="my-device-frame" controls="device"></device-frame>
.my-device-frame {
--spacer: 2rem;
}