npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

droplinked-editor-configs

v1.9.17

Published

A visual page builder library based on React and Puck Editor for creating and managing configurable e-commerce components. This library provides both an editor component for building pages and renderer components for displaying them.

Readme

Droplinked Designer

A visual page builder library based on React and Puck Editor for creating and managing configurable e-commerce components. This library provides both an editor component for building pages and renderer components for displaying them.


📦 Installation

npm install droplinked-editor-configs

🚀 Quick Start

As an Editor

import { Editor, AppStoreProvider, Data } from 'droplinked-editor-configs';
import 'droplinked-editor-configs/dist/index.css';

const initialData: Data = {
  root: { props: {} },
  content: []
};

function App() {
  return (
    <Editor
      shopName="your-shop-name"
      initialData={initialData}
      isLive={false}
      onPublish={(data) => console.log('Published:', data)}
      onDraft={(data) => console.log('Draft saved:', data)}
    />
  );
}

As a Renderer

import { PageHeader, PageFooter, InnerContent } from 'droplinked-editor-configs';
import { ShopProvider } from 'droplinked-editor-configs';

function MyShop() {
  const headerData = { /* your header data */ };
  const footerData = { /* your footer data */ };
  const contentData = { /* your content data */ };

  return (
    <ShopProvider shopName="your-shop-name">
      <PageHeader 
        data={headerData}
        cartItemCount={5}
        onCartClick={() => {}}
        handleNavigate={(path) => {}}
      />
      <InnerContent 
        data={contentData}
        handleNavigate={(path) => {}}
      />
      <PageFooter 
        data={footerData}
        handleNavigate={(path) => {}}
      />
    </ShopProvider>
  );
}

🏗️ Architecture Overview

Core Components

Editor

The main editor component that provides the visual page builder interface. It integrates:

  • Puck Editor: The visual drag-and-drop editor
  • Shop Data Fetching: Automatically fetches shop configuration based on shopName
  • State Management: Uses AppStore for global state management
  • React Query: For server state management

Props:

  • shopName: Name of the shop to load configuration for
  • initialData: Initial page structure
  • isLive: Whether the editor is in live/preview mode
  • isNewTheme: Flag for new theme creation
  • onPublish: Callback when user publishes changes
  • onDraft: Callback when user saves draft
  • onUpdate: Callback for updates
  • onChange: Callback on any data change
  • themeName: Name of the theme being edited
  • publishLoading: Loading state for publish action
  • draftLoading: Loading state for draft action
  • permissions: User permissions object
  • overrides: UI component overrides
  • iframe: Iframe configuration for preview
  • token: Authentication token

PageHeader

Renders the header component with navigation and cart functionality.

Props:

  • data: Header component data structure
  • onCartClick: Callback for cart icon click
  • cartItemCount: Number of items in cart
  • handleNavigate: Navigation handler function
  • profileDropdownWrapper: Custom profile dropdown component

PageFooter

Renders the footer component with links and social media.

Props:

  • data: Footer component data structure
  • handleNavigate: Navigation handler function

InnerContent

Renders the main content area with all configured components.

Props:

  • data: Content data structure
  • handleNavigate: Navigation handler function

🧠 State Management

AppStore (Zustand)

The library uses Zustand for global state management with persistence.

Structure:

interface IAppStore {
  states: {
    cart: { [shopName: string]: ICart };      // Shopping cart state
    user: { [shopName: string]: { token: string; user: IUser } } | null;  // User authentication
    shop: IShop;                               // Shop configuration
  };
  methods: {
    updateState: (props: { state: string; value: any }) => void;
  };
}

Usage:

import useAppStore from 'lib/stores/app/appStore';

function MyComponent() {
  const { states, methods } = useAppStore();
  
  // Access cart
  const cart = states.cart['my-shop'];
  
  // Update state
  methods.updateState({ state: 'cart', value: newCart });
}

AppStoreProvider: The AppStoreProvider wraps components and provides AppStore context via React Context API. This is necessary for the Editor component to access global state.

<AppStoreProvider appStoreData={appStoreData}>
  <YourComponent />
</AppStoreProvider>

ShopProvider

Handles shop data fetching and provides loading state.

<ShopProvider shopName="your-shop-name">
  <YourComponents />
</ShopProvider>

📁 Project Structure

src/
├── configured-components/        # Component library organized by category
│   ├── blog-posts/              # Blog components
│   ├── button/                  # Button variants
│   ├── design-layout/           # Layout containers (grid, vertical, horizontal)
│   ├── hero-section/            # Hero section variants
│   ├── image-with-text/         # Image with text components
│   ├── layout/                  # Header & Footer
│   ├── media/                   # Image and video components
│   ├── multicolumn/             # Multi-column layouts
│   ├── products/                # Product grid and summary components
│   └── text/                    # Text components (heading, body, caption, subtitle)
│
├── components/                   # Reusable UI components
│   ├── ui/                      # Shadcn UI components
│   ├── legacy-components/       # Legacy components
│   ├── header/                  # Header sub-components
│   ├── footer/                  # Footer sub-components
│   ├── productGrid/             # Product grid components
│   └── blog-posts/              # Blog post components
│
├── lib/
│   ├── stores/                  # Zustand stores
│   │   ├── app/                 # AppStore - global state
│   │   └── productQueryStore/  # Product query state
│   ├── models/                  # TypeScript interfaces
│   └── utils/                   # Utility functions
│
├── apis/                        # API services
│   ├── axiosConfig.ts          # Axios configuration
│   ├── blogs/                  # Blog API services
│   ├── product/                # Product API services
│   └── shop/                   # Shop API services
│
├── hooks/                       # Custom React hooks
│   ├── useCustomNavigate.ts   # Navigation hook
│   ├── useThemeInfo.ts        # Theme information hook
│   └── shop/                  # Shop-related hooks
│
├── types/                      # TypeScript type definitions
│   ├── editorProps.ts         # Editor component props
│   └── renderersProps.ts      # Renderer component props
│
├── App.tsx                     # Demo/Example application
├── Editor.tsx                  # Main editor component
├── PageHeader.tsx             # Header renderer
├── PageFooter.tsx             # Footer renderer
├── InnerContent.tsx           # Content renderer
├── AppStoreProvider.tsx       # AppStore context provider
├── ShopProvider.tsx           # Shop data provider
├── NavigationContext.tsx      # Navigation context
└── index.ts                   # Library entry point

🔧 Component Configuration System

Component Categories

Components are organized into categories:

  • Design Layout: Container components (Grid, Vertical, Horizontal)
  • Media: Image and video components
  • Button: Various button styles
  • Text: Typography components
  • Layout: Header and Footer
  • Hero Section: Hero/banner components
  • Image with Text: Combined image-text layouts
  • Products: Product display components
  • Blog Posts: Blog listing and post components
  • Multi Column: Multi-column layouts

Configuration Files

Each component category has:

  1. Component files (.tsx): React component implementation
  2. Config files (*Config.tsx): Puck editor configuration
  3. Interface files (interface.ts): TypeScript type definitions
  4. Category config (categoryConfig.ts): Category metadata
  5. Index file (index.tsx): Exports for the category

🎨 Adding a New Component

1. Create Component Structure

src/configured-components/[category]/[component]/
├── configs/
│   ├── interface.ts              # TypeScript interface
│   └── [component]Config.tsx     # Puck configuration
├── [Component].tsx                # Main component
└── [Component]VisualExample.tsx  # Visual preview

2. Define the Props Interface

configs/interface.ts:

export interface MyComponentProps {
  title: string;
  description?: string;
  backgroundColor?: string;
  id?: string;
}

3. Implement the Component

MyComponent.tsx:

import { MyComponentProps } from "./configs/interface";

const MyComponent: React.FC<MyComponentProps> = ({ 
  title, 
  description, 
  backgroundColor 
}) => {
  return (
    <div style={{ backgroundColor }}>
      <h2>{title}</h2>
      {description && <p>{description}</p>}
    </div>
  );
};

export default MyComponent;

4. Create Visual Example

MyComponentVisualExample.tsx:

const MyComponentVisualExample = () => (
  <div className="preview-container">
    <span>My Component Preview</span>
  </div>
);

export default MyComponentVisualExample;

5. Define Puck Configuration

configs/myComponentConfig.tsx:

import { Config } from "droplinked-editor-core";
import MyComponent from "../MyComponent";
import MyComponentVisualExample from "../MyComponentVisualExample";

export const myComponentConfig: Config["components"][string] = {
  label: "My Component",
  visualExample: <MyComponentVisualExample />,
  fields: {
    title: { 
      type: "text", 
      label: "Title" 
    },
    description: { 
      type: "textarea", 
      label: "Description" 
    },
    backgroundColor: { 
      type: "text", 
      label: "Background Color" 
    },
  },
  defaultProps: {
    title: "Default Title",
    description: "Default description",
    backgroundColor: "#ffffff",
  },
  render: (props) => <MyComponent {...props} />,
};

6. Export from Category

src/configured-components/[category]/index.tsx:

import { myComponentConfig } from "./my-component/configs/myComponentConfig";

export const categoryComponents = {
  ...existingComponents,
  myComponent: myComponentConfig,
};

7. Add to Category Config

categoryConfig.ts:

export const categoryConfig: Config["categories"] = {
  myCategory: {
    title: "My Category",
    components: ["myComponent", /* other components */],
  },
};

8. Register in Main Config

src/index.ts:

export const editorMainConfig: Config = {
  categories: {
    ...existingCategories,
    ...myCategoryConfig,
  },
  components: {
    ...existingComponents,
    ...myCategoryComponents,
  }
};

🔨 Building & Development

Development Mode

Run the development server with hot reload:

npm install
npm run dev

Access at: http://localhost:5173

Build for Production

Build the library for npm distribution:

npm run build

This creates:

  • dist/droplinked-editor.es.js - ES module build
  • dist/droplinked-editor.umd.js - UMD build
  • dist/index.d.ts - TypeScript definitions
  • dist/style.css - Bundled styles

Publishing to npm

  1. Update version in package.json
  2. Build the library: npm run build
  3. Publish: npm publish

🧩 Advanced Usage

Custom Navigation

Implement custom navigation handler:

const handleNavigate = (path: string) => {
  // Your custom navigation logic
  router.push(path);
};

<InnerContent 
  data={contentData}
  handleNavigate={handleNavigate}
/>

Custom Profile Dropdown

Pass custom profile dropdown wrapper:

const CustomProfileDropdown = ({ children }) => (
  <div className="custom-dropdown">
    {children}
  </div>
);

<PageHeader
  data={headerData}
  profileDropdownWrapper={CustomProfileDropdown}
  // ... other props
/>

📚 API Reference

Exports

// Components
export { Editor }          // Main editor component
export { PageHeader }      // Header renderer
export { PageFooter }      // Footer renderer  
export { InnerContent }    // Content renderer
export { AppStoreProvider } // AppStore context provider

// Configs
export { editorMainConfig }      // Full editor configuration
export { innerContentConfig }    // Content-only configuration

// Types
export type { Config, Data }     // From droplinked-editor-core
export type { EditorProps }      // Editor component props
export type { PageHeaderProps, PageFooterProps, innerContentProps }

Data Structure

The Data type represents the page structure:

interface Data {
  root: {
    props: Record<string, any>;
  };
  content: Array<{
    type: string;           // Component type
    props: {
      id: string;           // Unique component ID
      [key: string]: any;   // Component-specific props
    };
  }>;
}

🛠️ Tech Stack

  • React 19 - UI library
  • TypeScript - Type safety
  • Vite - Build tool
  • Puck Editor - Visual editor core
  • Zustand - State management
  • React Query - Server state management
  • Axios - HTTP client
  • Tailwind CSS - Styling
  • Shadcn UI - UI components
  • Chakra UI - Additional UI components
  • Framer Motion - Animations

📖 Key Concepts

DropZone

Use DropZone from droplinked-editor-core to create droppable areas:

import { DropZone } from "droplinked-editor-core";

<div className="container">
  <DropZone zone="content" />
</div>

Component IDs

Each component instance requires a unique id prop for identification and updates.

Visual Examples

Always provide a visualExample component for the component picker UI.

Categories

Organize components into categories for better UX in the editor sidebar.


📝 Best Practices

  1. Type Safety: Always define TypeScript interfaces for component props
  2. Default Props: Provide sensible defaults in component config
  3. Visual Examples: Create clear, representative visual examples
  4. Unique IDs: Ensure component IDs are unique across the page
  5. Responsive Design: Make components responsive using Tailwind utilities
  6. Accessibility: Follow accessibility best practices
  7. Performance: Lazy load heavy components when possible
  8. State Management: Use AppStore for global state, local state for component-specific data

🤝 Contributing

When adding new components or features:

  1. Follow the established folder structure
  2. Create proper TypeScript interfaces
  3. Add visual examples for editor UI
  4. Update category configurations
  5. Export from appropriate index files
  6. Test in both editor and renderer modes
  7. Document any new patterns or APIs

📚 Resources & Documentation