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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@darksnow-ui/fractal-layout

v0.0.3

Published

Advanced panel management system for web applications with dynamic splitting, resizing, and recursive layouts

Downloads

11

Readme

@darksnow-ui/fractal-layout

✨ Features

  • 🎯 Divisão Dinâmica - Divida qualquer painel horizontal ou verticalmente
  • 📐 Redimensionamento Fluído - Arraste para redimensionar com constraints min/max
  • 🔄 Layouts Recursivos - Crie layouts dentro de layouts infinitamente
  • 🧩 Sistema de Widgets - Plugável e extensível
  • 🎨 Totalmente Customizável - Estilos, comportamentos e configurações
  • Alta Performance - Otimizado para layouts complexos
  • 📱 Responsivo - Funciona em desktop e mobile (em desenvolvimento)

📦 Instalação

npm install @darksnow-ui/fractal-layout
# ou
pnpm add @darksnow-ui/fractal-layout
# ou
yarn add @darksnow-ui/fractal-layout

🚀 Quick Start

ResizablePanels Básico

import { ResizablePanels } from '@darksnow-ui/fractal-layout'

function App() {
  const panels = [
    {
      id: "sidebar",
      size: 30,
      minSize: 20,
      maxSize: 40,
      children: <Sidebar />
    },
    {
      id: "content",
      size: 70,
      children: <Content />
    }
  ]

  return (
    <ResizablePanels 
      panels={panels}
      direction="horizontal"
      onSizeChange={(sizes) => console.log(sizes)}
    />
  )
}

FractalLayout Completo

import { FractalLayout } from '@darksnow-ui/fractal-layout'

// Defina seus widgets
const widgets = {
  editor: {
    id: "editor",
    component: EditorWidget,
    icon: FileTextIcon
  },
  terminal: {
    id: "terminal",
    component: TerminalWidget
  },
  preview: {
    id: "preview",
    component: PreviewWidget
  }
}

// Layout inicial com props
const initialLayout = {
  id: "root",
  type: "layout",
  direction: "horizontal",
  children: [
    {
      id: "left",
      type: "widget",
      widget: "editor",
      props: {
        filename: "App.tsx",
        language: "typescript",
        theme: "dark"
      },
      size: 60
    },
    {
      id: "right",
      type: "widget",
      widget: "preview",
      props: {
        url: "http://localhost:3000",
        zoom: 0.8
      },
      size: 40
    }
  ]
}

function App() {
  const [layout, setLayout] = useState(initialLayout)

  return (
    <FractalLayout
      layout={layout}
      widgets={widgets}
      onLayoutChange={setLayout}
      config={{
        enableContextMenu: true,
        minPanelSize: 200
      }}
    />
  )
}

📖 Documentação

ResizablePanels

Componente base para painéis redimensionáveis.

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | panels | Panel[] | - | Array de painéis a renderizar | | direction | "horizontal" \| "vertical" | "horizontal" | Direção do layout | | handleSize | number | 6 | Tamanho do handle em pixels | | onSizeChange | (sizes: Record<string, number>) => void | - | Callback quando tamanhos mudam | | className | string | - | Classes CSS adicionais |

Tipo Panel

interface Panel {
  id: string
  size?: number      // Porcentagem (0-100)
  minSize?: number   // Tamanho mínimo
  maxSize?: number   // Tamanho máximo
  children: ReactNode
}

FractalLayout

Sistema completo de gerenciamento de layouts com recursos avançados.

Props

| Prop | Tipo | Descrição | |------|------|-----------| | layout | FractalPanel | Estrutura do layout | | widgets | WidgetRegistry | Registro de widgets disponíveis | | onLayoutChange | (layout: FractalPanel) => void | Callback para mudanças | | config | FractalConfig | Configurações opcionais |

Tipos Principais

interface FractalPanel {
  id: string
  type: "widget" | "layout"
  widget?: string              // ID do widget
  props?: Record<string, any>  // Props específicas para a instância do widget
  children?: FractalPanel[]    // Sub-painéis
  direction?: "horizontal" | "vertical"
  size?: number
  minSize?: number
  maxSize?: number
}

interface Widget {
  id: string
  component: React.ComponentType
  icon?: React.ComponentType
  config?: Record<string, any>
}

interface FractalConfig {
  minPanelSize?: number      // Default: 300
  scrollThreshold?: number   // Default: 3
  enableContextMenu?: boolean // Default: true
  handleSize?: number        // Default: 6
}

🎮 Exemplos Avançados

Persistência de Layout

function PersistentLayout() {
  const [layout, setLayout] = useState(() => {
    const saved = localStorage.getItem('app-layout')
    return saved ? JSON.parse(saved) : defaultLayout
  })

  const handleLayoutChange = (newLayout) => {
    setLayout(newLayout)
    localStorage.setItem('app-layout', JSON.stringify(newLayout))
  }

  return <FractalLayout layout={layout} onLayoutChange={handleLayoutChange} />
}

Undo/Redo

function LayoutWithHistory() {
  const [history, setHistory] = useState([initialLayout])
  const [index, setIndex] = useState(0)
  
  const layout = history[index]
  
  const handleChange = (newLayout) => {
    const newHistory = history.slice(0, index + 1)
    newHistory.push(newLayout)
    setHistory(newHistory)
    setIndex(newHistory.length - 1)
  }
  
  const undo = () => index > 0 && setIndex(index - 1)
  const redo = () => index < history.length - 1 && setIndex(index + 1)
  
  return (
    <>
      <button onClick={undo} disabled={index === 0}>Undo</button>
      <button onClick={redo} disabled={index === history.length - 1}>Redo</button>
      <FractalLayout layout={layout} onLayoutChange={handleChange} />
    </>
  )
}

Widgets com Props Customizadas

Uma das features mais poderosas é a capacidade de passar props específicas para cada instância de widget através do campo props:

// Definir um widget que aceita props
const ChartWidget = ({ title, data, type = 'bar', color }) => {
  return (
    <div>
      <h3>{title}</h3>
      <Chart type={type} data={data} color={color} />
    </div>
  )
}

// Registrar o widget uma única vez
const widgets = {
  chart: {
    id: 'chart',
    component: ChartWidget
  }
}

// Criar múltiplas instâncias com configurações diferentes
const layout = {
  id: "root",
  type: "layout",
  direction: "horizontal",
  children: [
    {
      id: "sales-chart",
      type: "widget",
      widget: "chart",
      props: {
        title: "Vendas 2024",
        type: "bar",
        data: salesData,
        color: "#3b82f6"
      },
      size: 50
    },
    {
      id: "growth-chart",
      type: "widget",
      widget: "chart",
      props: {
        title: "Crescimento Anual",
        type: "line",
        data: growthData,
        color: "#10b981"
      },
      size: 50
    }
  ]
}

Persistência e Identificação

Cada widget pode receber um ID único através das props, permitindo:

const StatefulWidget = ({ id, initialValue }) => {
  // Usar o ID para persistir estado
  const [value, setValue] = usePersistedState(`widget-${id}`, initialValue)
  
  // Buscar dados específicos
  const { data } = useWidgetData(id)
  
  return <div>...</div>
}

// No layout
{
  widget: "stateful",
  props: {
    id: "metrics-dashboard-main",
    initialValue: { view: 'monthly' }
  }
}

Widget Recursivo

const LayoutWidget = () => {
  const nestedLayout = {
    id: "nested",
    type: "layout",
    direction: "vertical",
    children: [/* ... */]
  }
  
  return (
    <div className="nested-layout-widget">
      <h4>Sub-layout</h4>
      <FractalLayout 
        layout={nestedLayout}
        widgets={widgets}
        config={{ enableContextMenu: false }}
      />
    </div>
  )
}

// Registrar no widgets
const widgets = {
  // ... outros widgets
  layout: {
    id: "layout",
    component: LayoutWidget,
    acceptsChildren: true
  }
}

🎨 Customização

CSS Variables

:root {
  --fractal-border: #e2e8f0;
  --fractal-handle-color: #cbd5e1;
  --fractal-handle-hover: #94a3b8;
  --fractal-radius: 0.5rem;
}

Estilos Customizados

<FractalLayout
  className="my-custom-layout"
  layout={layout}
  widgets={widgets}
/>
.my-custom-layout .resize-handle {
  background: linear-gradient(90deg, #3b82f6, #8b5cf6);
}

.my-custom-layout .widget-panel {
  border-radius: 1rem;
  box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}

🛠️ Desenvolvimento

Setup

# Clone o repositório
git clone https://github.com/darksnow-ui/fractal-layout

# Instale dependências
pnpm install

# Rode a demo
pnpm demo

Scripts

pnpm build      # Build da biblioteca
pnpm test       # Rodar testes
pnpm demo       # Demo interativa (porta 3000)
pnpm typecheck  # Verificar tipos

Estrutura

fractal-layout/
├── src/
│   ├── components/
│   │   ├── ResizablePanels/   # Componente base
│   │   └── FractalLayout/     # Sistema completo
│   ├── demo/                  # Aplicação de demonstração
│   └── index.ts              # Exports principais
├── docs/                     # Documentação detalhada
└── package.json

🤝 Contribuindo

Contribuições são bem-vindas! Por favor:

  1. Fork o projeto
  2. Crie uma branch para sua feature (git checkout -b feature/AmazingFeature)
  3. Commit suas mudanças (git commit -m 'Add some AmazingFeature')
  4. Push para a branch (git push origin feature/AmazingFeature)
  5. Abra um Pull Request

📄 Licença

MIT © DarkSnow UI

🙏 Agradecimentos

Inspirado por:


Feito com ❤️ pela equipe DarkSnow UI