JSPM

@config-driven-testimonials/editor

1.0.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 36
  • Score
    100M100P100Q64261F
  • License MIT

Visual config builder for config-driven-testimonials — import, edit, export JSON

Package Exports

  • @config-driven-testimonials/editor

Readme

@config-driven-testimonials/editor

Visual config builder for config-driven-testimonials. Fill in your testimonials, upload avatars, tweak the theme — then export a single JSON file and drop it into your app.

  • No backend required — everything happens in the browser
  • Avatar upload built-in — center-crops and encodes to base64 automatically
  • Import / export JSON — with full Zod validation and per-field error messages
  • Drag & drop reordering — native HTML5, no extra dependencies
  • Live preview — see exactly what the widget will look like as you type

npm license


Try it without installing

✏ Open the hosted editor


Install

npm install @config-driven-testimonials/editor
# or
pnpm add @config-driven-testimonials/editor

React 18+ is a peer dependency. Requires Tailwind CSS v4 in the host app.


Quick start

The editor is designed for a split-screen layout: editor on the left, live TestimonialsWidget preview on the right.

import { useState } from 'react';
import { TestimonialsEditor, Toolbar, ExportPanel, ImportPanel } from '@config-driven-testimonials/editor';
import { TestimonialsWidget, parseConfig, type TestimonialConfig } from 'config-driven-testimonials';
import configJson from './testimonials.config.json';

export function EditorPage() {
  const [config, setConfig] = useState<TestimonialConfig>(parseConfig(configJson));
  const [activePanel, setActivePanel] = useState<string | null>(null);
  const [activeId, setActiveId] = useState<string | null>(null);

  return (
    <div style={{ display: 'flex', height: '100vh' }}>
      <div style={{ width: '50%', overflowY: 'auto' }}>
        <Toolbar
          activePanel={activePanel}
          onPanelChange={setActivePanel}
          exportPanel={<ExportPanel config={config} />}
          importPanel={<ImportPanel onApply={setConfig} />}
          onClearRequest={() => setConfig(parseConfig({ author: {}, testimonials: [], theme: { variant: 'cards' } }))}
          backHref="/"
        />
        <TestimonialsEditor
          value={config}
          onChange={setConfig}
          onRecommendationOpen={setActiveId}
        />
      </div>
      <div style={{ width: '50%', overflowY: 'auto' }}>
        <TestimonialsWidget config={config} activeTestimonialId={activeId ?? undefined} />
      </div>
    </div>
  );
}

API

TestimonialsEditor

The main form component. Renders sections for author profile, testimonials list, and theme settings.

Prop Type Default Description
value TestimonialConfig required Current config state
onChange (config) => void required Called on every field change
showValidation boolean false Highlights cards green/red based on validity
onRecommendationOpen (id: string | null) => void Fired when a card is expanded
onAuthorFocus () => void Fired when any author field is focused

Toolbar

Fixed top bar with Import, Export, and Clear actions.

Prop Type Description
activePanel string | null Controls which panel is open
onPanelChange (id: string | null) => void Panel open/close handler
exportPanel ReactNode Slot — pass <ExportPanel config={config} />
importPanel ReactNode Slot — pass <ImportPanel onApply={fn} />
onClearRequest () => void Called when user confirms "Clear all"
backHref string URL for the back navigation link

ExportPanel

Downloads the current config as a .json file.

<ExportPanel config={config} />

ImportPanel

Accepts a .json file (click or drag & drop), validates with Zod, calls onApply with the parsed config.

<ImportPanel onApply={(config) => setConfig(config)} />

ConfirmModal

Generic confirmation dialog used internally by the Toolbar. Export it if you need it elsewhere.

<ConfirmModal
  title="Clear all data?"
  description="This will remove all testimonials and reset the config."
  confirmLabel="Clear"
  onConfirm={handleClear}
  onCancel={handleCancel}
/>