{"_id":"@amitkhare/layer-vue","name":"@amitkhare/layer-vue","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@amitkhare/layer-vue","version":"1.0.0","description":"A Vue 3 library for creating draggable/sortable list items with hierarchical structure support.","main":"dist/layer-vue.umd.js","module":"dist/layer-vue.es.js","types":"dist/index.d.ts","exports":{".":{"import":"./dist/layer-vue.es.js","require":"./dist/layer-vue.umd.js","types":"./dist/index.d.ts"},"./dist/style.css":"./dist/style.css"},"scripts":{"dev":"vite","build":"vue-tsc && vite build","preview":"vite preview","build-lib":"vite build --config vite.config.lib.ts","prepublishOnly":"npm run build-lib"},"keywords":["vue","vue3","draggable","sortable","layers","list","components","drag-drop","hierarchical","nested","tree","layer-panel","typescript"],"author":{"name":"Amit Kumar Khare"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/amitkhare/layer-vue.git"},"homepage":"https://github.com/amitkhare/layer-vue#readme","bugs":{"url":"https://github.com/amitkhare/layer-vue/issues"},"peerDependencies":{"vue":"^3.0.0"},"devDependencies":{"@types/node":"^20.0.0","@vitejs/plugin-vue":"^4.4.0","typescript":"^5.0.0","vite":"^4.4.0","vite-plugin-dts":"^3.6.0","vue":"^3.3.0","vue-tsc":"^1.8.0"},"dependencies":{"@vueuse/core":"^10.5.0"},"_id":"@amitkhare/layer-vue@1.0.0","gitHead":"bee0e155295914088870c499c6dfc8e71d58fa81","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-H4fgsa/MhiIWg/fwLl/MvRqM19dwTI5Q/ySK6/FZyHgW+GXJEXHFbzp3gJ3bRZM9vJ6PLMIkaJLJungINnNoPQ==","shasum":"d6c334d4dc503ce71fb8630960eb967eb2ae1aaa","tarball":"https://registry.npmjs.org/@amitkhare/layer-vue/-/layer-vue-1.0.0.tgz","fileCount":11,"unpackedSize":73373,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDNWalZ7GXQFmOg0WYuq6xnmZgyr4NjiPLYhG38YJQiCAiAyZbLqB27TxM7kfyPtGfhGZaPYZDrt9YWwT0OwG2aYPg=="}]},"_npmUser":{"name":"amitkhare","email":"amit@khare.co.in","actor":{"name":"amitkhare","email":"amit@khare.co.in","type":"user"}},"directories":{},"maintainers":[{"name":"amitkhare","email":"amit@khare.co.in"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/layer-vue_1.0.0_1750356440952_0.782783435091305"},"_hasShrinkwrap":false}},"time":{"created":"2025-06-19T18:07:20.842Z","1.0.0":"2025-06-19T18:07:21.165Z","modified":"2025-06-19T18:07:21.479Z"},"maintainers":[{"name":"amitkhare","email":"amit@khare.co.in"}],"description":"A Vue 3 library for creating draggable/sortable list items with hierarchical structure support.","homepage":"https://github.com/amitkhare/layer-vue#readme","keywords":["vue","vue3","draggable","sortable","layers","list","components","drag-drop","hierarchical","nested","tree","layer-panel","typescript"],"repository":{"type":"git","url":"git+https://github.com/amitkhare/layer-vue.git"},"author":{"name":"Amit Kumar Khare"},"bugs":{"url":"https://github.com/amitkhare/layer-vue/issues"},"license":"MIT","readme":"# Layer Vue\r\n\r\nA Vue 3 library for creating draggable/sortable list items with hierarchical structure support. \r\nPerfect for building complex UI with nested hierarchies, drag & drop functionality, and rich interactions.\r\n\r\n## Features\r\n\r\n- 🎯 **Drag & Drop Reordering**: Intuitive drag and drop to reorder items\r\n- 🗂️ **Layer Groups/Nesting**: Create hierarchical structures with unlimited nesting\r\n- 🔄 **Reverse Order Display**: Display items in reverse order (bottom-to-top)\r\n- 🔄 **Reverse Order Groups**: Optionally reverse order within groups independently\r\n- 🖱️ **Context Menus**: Right-click context menus with customizable actions\r\n- 🔘 **Multi-Select**: Select multiple items with Ctrl/Cmd + click or Shift + click\r\n- 🎨 **Template Slots**: Fully customizable item appearance using Vue slots\r\n- 📍 **Item Positioning**: Access to both current and original item indices\r\n- 🎛️ **Custom Expand/Collapse**: Customizable expand/collapse controls\r\n- 👁️ **Visibility Toggle**: Show/hide items with visual indicators\r\n- 🔒 **Lock/Unlock**: Prevent modifications to specific items\r\n- ⚡ **Vue 3 + TypeScript**: Built with modern Vue 3 Composition API and full TypeScript support\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @amitkhare/layer-vue\r\n```\r\n\r\n## Basic Usage\r\n\r\n```vue\r\n<template>\r\n  <LayerPanel\r\n    v-model:items=\"layers\"\r\n    :allow-nesting=\"true\"\r\n    :allow-multi-select=\"true\"\r\n    :show-context-menu=\"true\"\r\n    @item-select=\"handleItemSelect\"\r\n    @item-reorder=\"handleReorder\"\r\n  />\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref } from 'vue'\r\nimport { LayerPanel, type LayerItemType } from '@amitkhare/layer-vue'\r\n\r\nconst layers = ref<LayerItemType[]>([\r\n  {\r\n    id: 'layer1',\r\n    title: 'Background',\r\n    visible: true,\r\n    locked: false,\r\n    selected: false\r\n  },\r\n  {\r\n    id: 'group1',\r\n    title: 'UI Group',\r\n    visible: true,\r\n    locked: false,\r\n    selected: false,\r\n    collapsed: false,\r\n    children: [\r\n      {\r\n        id: 'layer2',\r\n        title: 'Header',\r\n        visible: true,\r\n        locked: false,\r\n        selected: false,\r\n        parent: 'group1'\r\n      }\r\n    ]\r\n  }\r\n])\r\n\r\nfunction handleItemSelect(item: LayerItemType, selectedItems: LayerItemType[]) {\r\n  console.log('Selected:', item.title, 'Total selected:', selectedItems.length)\r\n}\r\n\r\nfunction handleReorder(reorderedItems: LayerItemType[]) {\r\n  console.log('Items reordered:', reorderedItems)\r\n}\r\n</script>\r\n```\r\n\r\n## Reverse Order Display\r\n\r\nThe `reverseOrder` prop allows you to control the display order of layers, and `reverseOrderGroups` controls whether children within groups are also reversed:\r\n\r\n```vue\r\n<template>\r\n  <!-- Traditional order: first item at top -->\r\n  <LayerPanel\r\n    v-model:items=\"layers\"\r\n    :reverse-order=\"false\"\r\n    :reverse-order-groups=\"false\"\r\n  />\r\n  \r\n  <!-- Design software order: first item at bottom -->\r\n  <LayerPanel\r\n    v-model:items=\"layers\"\r\n    :reverse-order=\"true\"\r\n    :reverse-order-groups=\"false\"\r\n  />\r\n  \r\n  <!-- Both top-level and groups reversed -->\r\n  <LayerPanel\r\n    v-model:items=\"layers\"\r\n    :reverse-order=\"true\"\r\n    :reverse-order-groups=\"true\"\r\n  />\r\n  \r\n  <!-- Dynamic controls -->\r\n  <div>\r\n    <label>\r\n      <input type=\"checkbox\" v-model=\"reverseOrder\" />\r\n      Reverse Order (Top Level)\r\n    </label>\r\n    <label>\r\n      <input type=\"checkbox\" v-model=\"reverseOrderGroups\" />\r\n      Reverse Order Groups (Children)\r\n    </label>\r\n    <LayerPanel\r\n      v-model:items=\"layers\"\r\n      :reverse-order=\"reverseOrder\"\r\n      :reverse-order-groups=\"reverseOrderGroups\"\r\n    />\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref } from 'vue'\r\n\r\nconst reverseOrder = ref(false)\r\nconst reverseOrderGroups = ref(false)\r\n\r\n// Given this layer data:\r\nconst layers = ref([\r\n  { id: 1, title: 'Background' },   // Index 0, Original Index 0\r\n  { id: 2, title: 'Content' },     // Index 1, Original Index 1  \r\n  { id: 3, title: 'Overlay' }      // Index 2, Original Index 2\r\n])\r\n\r\n// reverseOrder: false displays: Background, Content, Overlay\r\n// reverseOrder: true displays:  Overlay, Content, Background\r\n// Original indices remain constant regardless of display order\r\n</script>\r\n```\r\n\r\n## Custom Item Template\r\n\r\n```vue\r\n<template>\r\n  <LayerPanel v-model:items=\"layers\">\r\n    <!-- Custom content with index information -->\r\n    <template #item-content=\"{ item, level, index, originalIndex }\">\r\n      <div class=\"custom-layer\" :style=\"{ paddingLeft: (level * 20) + 'px' }\">\r\n        <div class=\"layer-icon\">\r\n          <i :class=\"getIconClass(item)\"></i>\r\n        </div>\r\n        <span class=\"layer-name\">{{ item.title }}</span>\r\n        <div class=\"layer-info\">\r\n          <span class=\"index-info\">{{ index }} ({{ originalIndex }})</span>\r\n          <span v-if=\"item.data?.opacity\" class=\"opacity\">\r\n            {{ item.data.opacity }}%\r\n          </span>\r\n        </div>\r\n      </div>\r\n    </template>\r\n    \r\n    <!-- Custom expand/collapse controls -->\r\n    <template #item-expand=\"{ hasChildren, collapsed, toggleCollapse }\">\r\n      <div v-if=\"hasChildren\">\r\n        <button @click.stop=\"toggleCollapse\" class=\"custom-expand\">\r\n          {{ collapsed ? '📁' : '📂' }}\r\n        </button>\r\n      </div>\r\n      <div v-else class=\"expand-spacer\"></div>\r\n    </template>\r\n    \r\n    <!-- Custom controls -->\r\n    <template #item-controls=\"{ item }\">\r\n      <div class=\"custom-controls\">\r\n        <button @click=\"duplicateItem(item)\">📋</button>\r\n        <button @click=\"deleteItem(item)\">🗑️</button>\r\n      </div>\r\n    </template>\r\n  </LayerPanel>\r\n</template>\r\n```\r\n\r\n## Props\r\n\r\n### LayerPanel Props\r\n\r\n| Prop | Type | Default | Description |\r\n|------|------|---------|-------------|\r\n| `items` | `LayerItem[]` | `[]` | Array of layer items |\r\n| `allowNesting` | `boolean` | `true` | Enable drag & drop nesting |\r\n| `allowMultiSelect` | `boolean` | `true` | Enable multi-selection |\r\n| `showContextMenu` | `boolean` | `true` | Show right-click context menu |\r\n| `maxNestingLevel` | `number` | `10` | Maximum nesting depth |\r\n| `reverseOrder` | `boolean` | `false` | Reverse the display order of top-level items |\r\n| `reverseOrderGroups` | `boolean` | `false` | Reverse the display order within groups/children |\r\n\r\n### LayerItem Interface\r\n\r\n```typescript\r\ninterface LayerItem {\r\n  id: string | number\r\n  title: string\r\n  visible?: boolean\r\n  locked?: boolean\r\n  selected?: boolean\r\n  collapsed?: boolean\r\n  children?: LayerItem[]\r\n  parent?: string | number | null\r\n  data?: any\r\n}\r\n```\r\n\r\n## Events\r\n\r\n| Event | Payload | Description |\r\n|-------|---------|-------------|\r\n| `update:items` | `LayerItem[]` | Emitted when items array changes |\r\n| `item-select` | `(item: LayerItem, selectedItems: LayerItem[])` | Item selection changed |\r\n| `item-toggle-visibility` | `LayerItem` | Item visibility toggled |\r\n| `item-toggle-lock` | `LayerItem` | Item lock state toggled |\r\n| `item-reorder` | `LayerItem[]` | Items reordered via drag & drop |\r\n| `item-group` | `LayerItem[]` | Items grouped together |\r\n| `item-ungroup` | `LayerItem` | Group ungrouped |\r\n| `item-duplicate` | `LayerItem` | Item duplicated |\r\n| `item-delete` | `LayerItem[]` | Items deleted |\r\n| `context-menu` | `(event: MouseEvent, item: LayerItem)` | Context menu opened |\r\n\r\n## Slots\r\n\r\n### `item-content`\r\n\r\nCustomize the main content area of each item.\r\n\r\n**Slot Props:**\r\n- `item: LayerItem` - The layer item data\r\n- `level: number` - Nesting level (0-based)\r\n- `index: number` - Current display index (affected by reverse order)\r\n- `originalIndex: number` - Original index in the array (unaffected by reverse order)\r\n\r\n### `item-expand`\r\n\r\nCustomize the expand/collapse button for items with children.\r\n\r\n**Slot Props:**\r\n- `item: LayerItem` - The layer item data\r\n- `level: number` - Nesting level (0-based) \r\n- `hasChildren: boolean` - Whether the item has children\r\n- `collapsed: boolean` - Whether the item is collapsed\r\n- `toggleCollapse: () => void` - Function to toggle collapse state\r\n\r\n### `item-controls`\r\n\r\nCustomize the controls area (right side) of each item.\r\n\r\n**Slot Props:**\r\n- `item: LayerItem` - The layer item data\r\n\r\n### `context-menu`\r\n\r\nCustomize the context menu content.\r\n\r\n**Slot Props:**\r\n- `item: LayerItem` - The clicked item\r\n- `selectedItems: LayerItem[]` - All selected items\r\n\r\n## Keyboard Shortcuts\r\n\r\n- **Ctrl/Cmd + Click**: Multi-select items\r\n- **Shift + Click**: Range select (simplified)\r\n- **Right Click**: Open context menu\r\n- **Drag**: Reorder items\r\n- **Drag to Group**: Nest items inside groups\r\n\r\n## Styling\r\n\r\nThe component uses scoped styles and CSS custom properties for theming. You can override the default styles by targeting the component classes:\r\n\r\n```css\r\n.layer-panel {\r\n  --layer-bg: #2d2d2d;\r\n  --layer-text: #ffffff;\r\n  --layer-selected: #007acc;\r\n  --layer-hover: rgba(255, 255, 255, 0.05);\r\n}\r\n\r\n.layer-item.selected {\r\n  background: var(--layer-selected);\r\n}\r\n\r\n.layer-item:hover {\r\n  background: var(--layer-hover);\r\n}\r\n```\r\n\r\n## Development\r\n\r\n```bash\r\n# Install dependencies\r\nnpm install\r\n\r\n# Start development server\r\nnpm run dev\r\n\r\n# Build library\r\nnpm run build-lib\r\n\r\n# Build demo\r\nnpm run build\r\n```\r\n\r\n## Publishing\r\n\r\nTo publish to NPM:\r\n\r\n```bash\r\n# 1. Build the library\r\nnpm run build-lib\r\n\r\n# 2. Login to NPM (if not already logged in)\r\nnpm login\r\n\r\n# 3. Publish to NPM\r\nnpm publish\r\n```\r\n\r\nThe `prepublishOnly` script will automatically build the library before publishing.\r\n\r\n### Demo Structure\r\n\r\nThe project includes comprehensive demos showcasing all features:\r\n\r\n**Available Demos:**\r\n\r\n**Demo Files:**\r\n- `src/demo/Demo.vue` - Feature-rich demo component\r\n- `src/demo/SimpleDemo.vue` - Minimal demo component  \r\n- `src/demo/demo.ts` - Entry point for full demo\r\n- `src/demo/simple-demo.ts` - Entry point for simple demo\r\n\r\n**Running Demos:**\r\n- Demo: `http://localhost:5173/` (default)\r\n\r\nAll demo files are organized in the `src/demo/` directory for better project structure.\r\n\r\n## License\r\n\r\nMIT License\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please feel free to submit a Pull Request.\r\n","readmeFilename":"README.md","_rev":"1-5b8983be059374ebc2fe95e8db872b52"}