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

flow-mindmap

v0.3.1

Published

A modern, minimalist mind mapping tool — xmind-style, embeddable as a Vue component.

Downloads

1,346

Readme

flow-mindmap

A modern, minimalist mind mapping tool — xmind-style, embeddable as a Vue 3 component.

  • 纯 SVG 渲染,矢量缩放无损
  • 拖拽、缩放、平移画布
  • 键盘快捷键: Tab 添加子节点 / Enter 添加同级 / F2 编辑 / Delete 删除节点
  • 一键折叠/展开子树
  • 多种布局模式: mindmap(默认) / tree(右向树) / org(向下组织结构)
  • 可调画板: 渐变锥形连线、彩虹分支、节点背景/边框/字体样式、嵌入图片、超链接、节点笔记(Markdown + 实时预览)
  • 撤销/重做、JSON 导入导出
  • 扁平化 SVG 线框图标,无任何 Emoji
  • Apache-2.0 开源协议,可在 npm 安装作为组件使用

安装

pnpm add flow-mindmap

快速开始

全局注册(Vue 插件)

import { createApp } from 'vue'
import App from './App.vue'
import FlowMindmap from 'flow-mindmap'
import 'flow-mindmap/style.css'

const app = createApp(App)
app.use(FlowMindmap) // 注册为 <FlowMindMap />
app.mount('#app')
<template>
  <FlowMindMap :data="data" style="width: 100vw; height: 100vh" />
</template>

局部导入

<script setup lang="ts">
import { MindMap } from 'flow-mindmap'
import 'flow-mindmap/style.css'
import type { MindMapNode } from 'flow-mindmap'

const data: MindMapNode = {
  id: 'root',
  text: '中心主题',
  children: [
    { id: 'a', text: '分支 A', children: [] },
    { id: 'b', text: '分支 B', children: [] },
  ],
}
</script>

<template>
  <MindMap :data="data" style="width: 100vw; height: 100vh" />
</template>

从 Markdown 渲染

<script setup lang="ts">
import { ref } from 'vue'
import { MindMap } from 'flow-mindmap'
import 'flow-mindmap/style.css'

const md = ref(`# 项目计划

## 第一阶段

调研 / 设计

## 第二阶段

实现

## 第三阶段

上线`)

// 监听变化把 markdown 同步回外部存储(可选)
function onMdChange(next: string) {
  // 写入 localStorage / autosave / 远端等
  console.log('md changed, length =', next.length)
}
</script>

<template>
  <MindMap
    :markdown="md"
    :theme="{ fontSize: 16, rainbowBranch: true }"
    :line-colors="['#5eead4', '#fbbf24', '#f472b6', '#a78bfa']"
    @markdown-change="onMdChange"
    style="width: 100vw; height: 100vh"
  />
</template>

markdown prop 接受标准 markdown:# / ## / ### 作为节点层级;紧跟 heading 的 [label](url) 作为节点的 link;```note ... ``` 围栏作为节点的 note;![alt](url) 作为图片。改节点文字会自动 emit markdownChange,你可以把它写回输入框或远端。

Props

| Prop | Type | Default | 说明 | | ---- | ---- | ------- | ---- | | data | MindMapNode | — | 必填。思维导图根节点。 | | previewMode | boolean | false | 预览模式:隐藏画布自带工具栏,禁用所有编辑(增删改、拖拽、编辑输入框),但保留节点的展开/折叠以方便浏览。适合做截图、嵌入展示。 | | theme | MindMapTheme | — | 主题色/字号/连线粗细等外观配置,见下表。 | | markdown | string | — | 可选:传入 markdown 文本,内部解析为 datadata 二选一,传了 markdowndata 被忽略。双向同步:数据变化时通过 markdownChange 事件回传序列化结果。 | | lineColors | string[] | — | 可选:顶层分支连线颜色列表(hex / rgb / 命名色)。优先级高于 branchPaletteId / customPalettes;留空走 palette 流程。 |

MindMapTheme 字段

| 字段 | 类型 | 默认 | 说明 | | ---- | ---- | ---- | ---- | | rootBg | string | — | 根节点背景色 | | rootText | string | — | 根节点文字色 | | branchBg | string | — | 普通节点背景色 | | branchText | string | — | 普通节点文字色 | | lineColor | string | — | 连线颜色 | | bgColor | string | — | 画布背景色 | | fontSize | number | 14 | 基础字号(px)。节点的实际尺寸(高度/最小宽度/内边距/文本宽度)会按 fontSize / 14 等比缩放——fontSize=28 时所有节点都会变成两倍大;fontSize=10 时一半。 | | lineWidthStart | number | 2.2 | 父端连线粗细(px) | | lineWidthEnd | number | 0.8 | 子端连线粗细(px) | | rainbowBranch | boolean | false | 顶层分支按色板循环配色 |

Emits

| 事件 | 载荷 | 说明 | | ---- | ---- | ---- | | change | MindMapNode | 数据变更(增删改、导入、拖动)后触发,载荷是新的整棵根节点。 | | select | MindMapNode \| null | 用户点击节点时触发;null 表示点空白处取消选中。 | | edit-note | nodeId: string | 用户点击节点笔记图标 / 右键"添加/编辑笔记"时触发,由父组件决定如何展示笔记编辑界面。 | | markdownChange | markdown: string | 当使用了 markdown prop 且内部数据变化时触发,载荷是重新序列化后的 markdown 文本。markdown prop 写入触发时不会回环 emit。 |

Expose 方法(通过 ref 访问)

<MindMap ref="mm" :data="data" />
<script setup>
const mm = ref()
mm.value.addChild('a') // 给 id=a 的节点加一个子节点
</script>

节点增删改

| 方法 | 说明 | | ---- | ---- | | addChild(parentId) | 给指定节点添加子节点 | | addSibling(nodeId) | 给指定节点添加同级 | | removeNode(nodeId) | 删除节点及其子树 | | duplicateNode(nodeId) | 复制一个节点(包含子树)并插入到同级 | | setNodeText(nodeId, text) | 修改节点文字 | | moveNode(srcId, targetId, position) | 移动节点;position = 'before' / 'after'(同级)或 'child'(成为 target 最后一个子节点)。返回 true 表示成功。 |

节点内容扩展

| 方法 | 说明 | | ---- | ---- | | applyNodeStyle(nodeId, style) | 覆盖指定节点的样式({ bg, textColor, borderColor, fontWeight })。传空对象 {} 清除。 | | getNodeStyle(nodeId) | 读取指定节点的样式覆盖,无则返回 {}。 | | applyNodeLink(nodeId, url) | 设置节点的超链接,空字符串清除。 | | removeNodeLink(nodeId) | 删除节点的链接。 | | applyNodeNote(nodeId, text) | 设置节点的笔记,空字符串清除。 | | removeNodeNote(nodeId) | 删除节点的笔记。 |

视图

| 方法 | 说明 | | ---- | ---- | | getData() | 返回当前根节点(MindMapNode)。 | | setData(d) | 用新的根节点替换数据。 | | resetView() | 重置缩放/平移,让整棵树重新居中。 | | setBalanced(v) / isBalanced() / balance() | 强制布局平衡模式(暂停/恢复/立即执行)。autoBalanceOnChange 设置项决定默认是否平衡。 |

撤销/重做

| 方法 | 说明 | | ---- | ---- | | undo() / redo() | 撤销 / 重做最近一次数据变更。 | | canUndo() / canRedo() | 是否可撤销 / 重做。 |

导入/导出

| 方法 | 说明 | | ---- | ---- | | exportData() | 返回当前数据的 JSON 字符串。 | | importData(json) | 从 JSON 字符串恢复数据,成功返回 true。 | | getMarkdown() | 返回当前数据序列化后的 markdown 字符串。 | | setMarkdown(md, emitMarkdownChange?) | 用 markdown 解析结果替换数据。emitMarkdownChange 默认 true,传 false 可避免回环(比如用 markdown prop 接收外部值后写回时)。 |

设置项

通过 MindMapSettings 控制画板、布局、连线、分支色板等行为。

| 方法 | 说明 | | ---- | ---- | | applySettings(s) | 部分更新设置,只覆盖传入的字段。 | | getSettings() | 读取当前生效的设置。 |

调色板

| 方法 | 说明 | | ---- | ---- | | setBranchPalette(id) | 切换到指定色板;id 可以是内置('default' / 'classic' / 'vivid' / 'dev' / 'mint')或在 settings.customPalettes 注册过的自定义 id。未知 id 静默 no-op。 | | getBranchPalette() | 读取当前色板 id。 | | getBranchPalettes() | 读取所有色板(内置 + 自定义),用于渲染选择器。 |

连线宽度(高级)

| 方法 | 说明 | | ---- | ---- | | lineWidthForDepth(depth) | 深度 depth 节点出发的连线父端宽度(px)。 | | endWidthForDepth(depth) | 深度 depth 节点出发的连线子端宽度(px)。 |

数据类型

import type {
  MindMapNode,
  MindMapImage,
  MindMapOptions,
  MindMapTheme,
  MindMapSettings,
  MindMapExpose,
  NodeStyle,
  LineStyle,
  LayoutMode,
  BranchPalette,
  BranchPaletteId,
} from 'flow-mindmap'

MindMapNode

interface MindMapNode {
  id: string
  text: string
  children: MindMapNode[]
  collapsed?: boolean   // 初始折叠状态
  image?: MindMapImage  // 节点上方嵌入的图片
  link?: { url: string }// 节点超链接(图标点击跳转)
  note?: { text: string }// 节点笔记(图标悬浮预览、点击展开编辑)
  _x?: number           // 内部:拖拽后的位置覆盖(库内部使用,勿读勿写)
  _y?: number
}

MindMapImage

interface MindMapImage {
  src: string           // 远程 URL 或 data URL
  naturalW: number      // 源图原始宽(用于锁定长宽比)
  naturalH: number      // 源图原始高
  width: number         // 当前渲染宽(用户可拖拽调整,24~400 px)
  height: number        // 当前渲染高
}

NodeStyle

interface NodeStyle {
  bg?: string                       // 背景色
  textColor?: string                // 文字色
  borderColor?: string              // 边框色
  fontWeight?: 400 | 600            // 字重
}

MindMapSettings

interface MindMapSettings {
  autoBalanceOnChange: boolean   // 增删/拖拽后自动回到平衡布局
  lineWidthStart: number         // 父端连线粗细
  lineWidthEnd: number           // 子端连线粗细
  rainbowBranch: boolean         // 顶层分支按色板循环配色
  branchPaletteId: string        // 当前色板 id
  customPalettes: BranchPalette[]// 用户自定义色板
  lineStyle: 'curve' | 'straight'// 连线形状:曲线(xmind 默认) / 直线
  layoutMode: 'mindmap' | 'tree' | 'org'  // 布局模式
  taperedEdge: boolean           // 锥形连线(每条独立锥化)
  showOrderBadge: boolean        // 节点上显示兄弟序号角标(调试用)
}

BranchPalette

interface BranchPalette {
  id: string      // 唯一 id
  name: string    // 在选择器里显示的名字
  colors: string[]// 十六进制色值,按顺序循环
}

工具函数

import {
  uid,         // 生成不重复 id
  clone,       // 深克隆节点
  findNode,    // (root, id) => 节点
  findParent,  // (root, id) => 父节点
  removeNode,  // (root, id) => 移除子树
  addChild,    // (parent, text) => 新子节点
  addSibling,  // (node, text) => 新同级节点
  markdownToMindMap, // (md, rootText?) => MindMapNode — 与 MindMap 内部解析逻辑一致
  mindMapToMarkdown, // (node, depth?) => string — 与 MindMap 内部序列化逻辑一致
} from 'flow-mindmap'

全局组件

app.use(FlowMindmap) 会把组件注册为 <FlowMindMap />(驼峰式),所有 prop / event 与 <MindMap> 一致。

本地开发

pnpm install
pnpm dev      # http://localhost:7851  — 应用 demo
pnpm build    # 打包为 npm 库

协议

Apache-2.0 © xuze