or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

demo-layout.mddevice-preview.mdenhanced-previewer.mdindex.mdpreviewer-actions.md
tile.json

enhanced-previewer.mddocs/

Enhanced Previewer

The Enhanced Previewer extends dumi's default previewer with mobile-specific functionality, providing seamless integration between desktop and mobile preview modes.

Capabilities

MobilePreviewer Component

Wraps dumi's default previewer with mobile enhancements and device frame integration.

import { IPreviewerProps, useLocale, useRouteMeta, useSiteData } from 'dumi';
import Previewer from 'dumi/theme-default/builtins/Previewer';
import Device from 'dumi/theme/slots/Device';
import React, { useCallback, useEffect, useState, type FC } from 'react';

/**
 * Mobile-enhanced previewer component
 * Extends default dumi previewer with mobile-specific features
 * Uses IPreviewerProps directly from dumi - no custom interface needed
 */
const MobilePreviewer: FC<IPreviewerProps>;

// IPreviewerProps from dumi includes props like:
// - demoUrl, iframe, compact, background, children, title, description, etc.

Key Features:

  • Mobile/desktop mode detection via route frontmatter
  • Dynamic URL generation with query parameters
  • Device frame integration for mobile previews
  • Force show code functionality for mobile mode
  • CSS custom property support for device width

URL Generation

Generates demo URLs with appropriate query parameters for mobile rendering.

/**
 * Generates demo URL with mobile-specific query parameters
 * Handles compact mode, background color, and locale settings
 */
const generateUrl = useCallback((p: IPreviewerProps) => {
  const [pathname, search] = p.demoUrl.split('?');
  const params = new URLSearchParams(search);

  if (p.compact) params.set('compact', '');
  if (p.background) params.set('background', p.background);
  if (locale.id) params.set('locale', locale.id);

  return `${pathname}?${params.toString()}`.replace(/\?$/, '');
}, []);

Query Parameters Added:

  • compact: Added when compact mode is enabled
  • background: Added when background color is specified
  • locale: Added when locale is configured

Mobile Mode Behavior

The previewer behavior changes based on the mobile frontmatter property:

Mobile Mode (mobile: true - Default): Note: mobile defaults to true when not specified in frontmatter

  • Disables iframe rendering (iframe={false})
  • Adds dumi-mobile-previewer CSS class
  • Forces code display (forceShowCode={true})
  • Enables live iframe rendering (_live_in_iframe={true})
  • Renders Device component for mobile frame

Desktop Mode (mobile: false):

  • Uses standard iframe rendering
  • Renders children components normally
  • Standard dumi previewer behavior

Configuration and Styling

CSS Custom Properties:

.dumi-mobile-previewer {
  --device-width: 375px; /* Configurable via theme */
}

Theme Configuration:

// .dumirc.ts
export default {
  themeConfig: {
    deviceWidth: 375, // Applied as CSS custom property
  }
};

Usage Examples

Frontmatter Configuration:

---
mobile: true
---

# Mobile Demo

This demo will be rendered in mobile mode with device frame.

Desktop Mode:

---
mobile: false
---

# Desktop Demo  

This demo will use standard desktop previewer.

With Custom Background:

---
mobile: true
---

<!-- Previewer will automatically add background query parameter -->

Integration Points

Device Component Integration: When in mobile mode, the previewer renders a Device component:

{mobile && (
  <Device
    url={demoUrl}
    inlineHeight={typeof props.iframe === 'number' ? props.iframe : undefined}
  />
)}

Default Previewer Wrapping:

<Previewer
  {...props}
  demoUrl={demoUrl}
  iframe={mobile ? false : props?.iframe}
  className={mobile ? 'dumi-mobile-previewer' : undefined}
  forceShowCode={mobile}
  style={{ '--device-width': `${deviceWidth}px` }}
  _live_in_iframe={mobile}
>
  {/* Mobile or desktop content */}
</Previewer>

State Management

The component manages demo URL state with React hooks:

// URL regeneration on prop changes
useEffect(() => {
  setDemoUrl(generateUrl(props));
}, [props.compact, props.background]);

This ensures the demo URL stays synchronized with configuration changes, enabling real-time preview updates when switching between display modes or adjusting settings.