{"_id":"@daflow-ui/block-album-list","_rev":"3-5d0757d390ca842ab1d92a1297d8d60b","name":"@daflow-ui/block-album-list","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@daflow-ui/block-album-list","version":"0.1.0","keywords":["vue","ui","component","daflow","album-list"],"license":"MIT","_id":"@daflow-ui/block-album-list@0.1.0","maintainers":[{"name":"cuiguojie","email":"cuiguojie@me.com"},{"name":"charicexxuan","email":"xiaoxuan.chang@kanjian.com"}],"dist":{"shasum":"d01de85ad7e82f43d25c661b387c4f83ad1f2c16","tarball":"https://registry.npmjs.org/@daflow-ui/block-album-list/-/block-album-list-0.1.0.tgz","fileCount":10,"integrity":"sha512-sXfeNksIKtEVxKKMc+l4krZAz1gI5f2OTMH7OnpCwN2JcX7DKE2M7wNTrk3xpRdBdVXuf53ui/0YagTVGmvyiQ==","signatures":[{"sig":"MEYCIQDMMMx2S77TXxD/SCoxj2jXRPE5ZvpuVY0iE+hntuK4VgIhAKtZypJXbuaEQH/bHp5pcOBQzM/up3IMd/tpeYghVHE1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":168056},"main":"./dist/index.js","type":"module","_from":"file:daflow-ui-block-album-list-0.1.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./style.css":"./dist/style.css"},"scripts":{"lint":"eslint .","build":"vite build && vue-tsc -p tsconfig.build.json --emitDeclarationOnly","lint:fix":"eslint . --fix","typecheck":"vue-tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"charicexxuan","email":"xiaoxuan.chang@kanjian.com"},"_resolved":"/private/var/folders/pc/vbwk747s1mn2dnbr__fbrfrc0000gn/T/8d4dc485ea82e8fdd8cbb897bd46ca17/daflow-ui-block-album-list-0.1.0.tgz","_integrity":"sha512-sXfeNksIKtEVxKKMc+l4krZAz1gI5f2OTMH7OnpCwN2JcX7DKE2M7wNTrk3xpRdBdVXuf53ui/0YagTVGmvyiQ==","_npmVersion":"10.9.2","description":"Album list component for DaFlow UI","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"22.17.0","dependencies":{"@ark-ui/vue":"5.30.0","@daflow-ui/ui-table":"0.1.1","@daflow-ui/ui-loading":"0.1.0","@daflow-ui/ui-pagination":"0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.27","vite":"^7.3.1","eslint":"^9.39.2","vue-tsc":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.5","sass-embedded":"^1.97.3","@vue/compiler-sfc":"^3.5.27","@vitejs/plugin-vue":"^6.0.3","vite-plugin-vue-devtools":"^8.0.5","@seemusic/eslint-config-vue3":"^2.0.0"},"peerDependencies":{"vue":"^3.5.0"},"_npmOperationalInternal":{"tmp":"tmp/block-album-list_0.1.0_1776758557403_0.9244115788981708","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@daflow-ui/block-album-list","version":"0.1.1","keywords":["vue","ui","component","daflow","album-list"],"license":"MIT","_id":"@daflow-ui/block-album-list@0.1.1","maintainers":[{"name":"cuiguojie","email":"cuiguojie@me.com"},{"name":"charicexxuan","email":"xiaoxuan.chang@kanjian.com"}],"dist":{"shasum":"ca1f66ebcdc6fa5a55aa65cdf0e35e7a6609ca00","tarball":"https://registry.npmjs.org/@daflow-ui/block-album-list/-/block-album-list-0.1.1.tgz","fileCount":10,"integrity":"sha512-iXI4ATGFUDf08NyqoecOqQzTbuOWrF7ccAhOXweNMzhQDSSOaLTh7JQnK+9gNWIR27Tv2tyM9UB3IRvkTfg5Dw==","signatures":[{"sig":"MEUCIQCLlhJL088+Io8UIKTDxdMDXLTPoQEUd0ECZiZrAFHmZgIgdW7ygirF8DF61fBwCH1XFqrrqKX0ntZyOMR8tlnEbVw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":171769},"main":"./dist/index.js","type":"module","_from":"file:daflow-ui-block-album-list-0.1.1.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./style.css":"./dist/style.css"},"scripts":{"lint":"eslint .","build":"vite build && vue-tsc -p tsconfig.build.json --emitDeclarationOnly","lint:fix":"eslint . --fix","typecheck":"vue-tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"charicexxuan","email":"xiaoxuan.chang@kanjian.com"},"_resolved":"/private/var/folders/pc/vbwk747s1mn2dnbr__fbrfrc0000gn/T/64376657939f94939ca6111254f21b82/daflow-ui-block-album-list-0.1.1.tgz","_integrity":"sha512-iXI4ATGFUDf08NyqoecOqQzTbuOWrF7ccAhOXweNMzhQDSSOaLTh7JQnK+9gNWIR27Tv2tyM9UB3IRvkTfg5Dw==","_npmVersion":"10.9.2","description":"Album list component for DaFlow UI","directories":{},"sideEffects":["**/*.css"],"_nodeVersion":"22.17.0","dependencies":{"@ark-ui/vue":"5.30.0","@daflow-ui/ui-table":"0.1.1","@daflow-ui/ui-loading":"0.1.0","@daflow-ui/ui-pagination":"0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.27","vite":"^7.3.1","eslint":"^9.39.2","vue-tsc":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.5","sass-embedded":"^1.97.3","@vue/compiler-sfc":"^3.5.27","@vitejs/plugin-vue":"^6.0.3","vite-plugin-vue-devtools":"^8.0.5","@seemusic/eslint-config-vue3":"^2.0.0"},"peerDependencies":{"vue":"^3.5.0"},"_npmOperationalInternal":{"tmp":"tmp/block-album-list_0.1.1_1776853193886_0.708565633992303","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@daflow-ui/block-album-list","version":"0.1.2","description":"Album list component for DaFlow UI","type":"module","license":"MIT","sideEffects":["**/*.css"],"publishConfig":{"access":"public"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./style.css":"./dist/style.css"},"dependencies":{"@ark-ui/vue":"5.30.0","@daflow-ui/ui-loading":"0.1.0","@daflow-ui/ui-table":"0.1.1","@daflow-ui/ui-pagination":"0.1.0"},"peerDependencies":{"vue":"^3.5.0"},"devDependencies":{"@seemusic/eslint-config-vue3":"^2.0.0","@types/node":"^22.10.5","@vitejs/plugin-vue":"^6.0.3","@vue/compiler-sfc":"^3.5.27","eslint":"^9.39.2","sass-embedded":"^1.97.3","typescript":"^5.9.3","vite":"^7.3.1","vite-plugin-vue-devtools":"^8.0.5","vue":"^3.5.27","vue-tsc":"^3.2.4"},"keywords":["vue","ui","component","daflow","album-list"],"scripts":{"build":"vite build && vue-tsc -p tsconfig.build.json --emitDeclarationOnly","lint":"eslint .","lint:fix":"eslint . --fix","typecheck":"vue-tsc -p tsconfig.json --noEmit"},"_id":"@daflow-ui/block-album-list@0.1.2","_integrity":"sha512-aTJAwzu7SuFmwAK1aWtcIn6cX8LXaERIAdISerdDektAf4B4hz/8rCDMgAKZ6h0us3YpTyAeUmmpOz9tr8h+wQ==","_resolved":"/private/var/folders/pc/vbwk747s1mn2dnbr__fbrfrc0000gn/T/6ab09405e9be3a36d73db4c515888881/daflow-ui-block-album-list-0.1.2.tgz","_from":"file:daflow-ui-block-album-list-0.1.2.tgz","_nodeVersion":"22.17.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-aTJAwzu7SuFmwAK1aWtcIn6cX8LXaERIAdISerdDektAf4B4hz/8rCDMgAKZ6h0us3YpTyAeUmmpOz9tr8h+wQ==","shasum":"f5639f5d485c41282e8fff92b3b792b2e8717da1","tarball":"https://registry.npmjs.org/@daflow-ui/block-album-list/-/block-album-list-0.1.2.tgz","fileCount":10,"unpackedSize":175045,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGsmSjFIaF3yl+nhJE4DjyD6xRfb5pSifIXQy1a2yxN+AiB5uxCWqpzQZZasUgDLMxJ/v7J2vSmxtbKUUPZbKqWrkA=="}]},"_npmUser":{"name":"charicexxuan","email":"xiaoxuan.chang@kanjian.com"},"directories":{},"maintainers":[{"name":"cuiguojie","email":"cuiguojie@me.com"},{"name":"charicexxuan","email":"xiaoxuan.chang@kanjian.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/block-album-list_0.1.2_1776917984876_0.7042706574406994"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-21T08:02:37.301Z","modified":"2026-04-23T04:19:45.163Z","0.1.0":"2026-04-21T08:02:37.556Z","0.1.1":"2026-04-22T10:19:54.064Z","0.1.2":"2026-04-23T04:19:45.011Z"},"license":"MIT","keywords":["vue","ui","component","daflow","album-list"],"description":"Album list component for DaFlow UI","maintainers":[{"name":"cuiguojie","email":"cuiguojie@me.com"},{"name":"charicexxuan","email":"xiaoxuan.chang@kanjian.com"}],"readme":"# @daflow-ui/block-album-list\n\nAlbum list component for DaFlow UI component library.\n\n## Installation\n\n```bash\npnpm add @daflow-ui/block-album-list\n```\n\n## Usage\n\n全局引入样式（在 `main.ts` 中）：\n\n```ts\nimport '@daflow-ui/block-album-list/style.css';\n```\n\n在组件中使用：\n\n```vue\n<script setup lang=\"ts\">\nimport { DfAlbumList, CONTROL_ACTIONS } from '@daflow-ui/block-album-list';\nimport type { AlbumListItem, AlbumListPagination, AlbumListActionDef } from '@daflow-ui/block-album-list';\n</script>\n\n<template>\n  <DfAlbumList\n    :items=\"items\"\n    :pagination=\"{ currentPage: 1, pageSize: 10, total: 100 }\"\n  />\n</template>\n```\n\n## API\n\n### Props\n\n| 属性 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `items` | `AlbumListItem[]` | `[]` | 列表数据 |\n| `pagination` | `AlbumListPagination` | `{ currentPage: 1, pageSize: 10, total: 0 }` | 分页参数 |\n| `loading` | `boolean` | `false` | 加载状态 |\n| `variant` | `'detailed' \\| 'compact' \\| 'control'` | `'detailed'` | 展示变体 |\n| `controlActions` | `AlbumListActionDef[]` | `[]` | control 变体追加的自定义操作 |\n| `defaultControlActionVisible` | `Partial<Record<DefaultControlActionKey, boolean>>` | - | control 变体默认 4 个操作的显示状态 |\n| `controlActionDisabled` | `Partial<Record<AlbumListActionDef['key'], boolean>> \\| (row: AlbumListItem) => Partial<Record<AlbumListActionDef['key'], boolean>>` | - | control 变体各操作的禁用状态（平面对象或每行函数） |\n| `showSelection` | `boolean` | `false` | 是否显示复选框（仅 control 变体） |\n| `selectedIds` | `string[]` | - | 受控选中的专辑 ID 列表 |\n\n### Events\n\n| 事件名 | 参数 | 说明 |\n|--------|------|------|\n| `page-change` | `(page: number) => void` | 分页变化 |\n| `album-detail-click` | `(id: string) => void` | 专辑详情点击 |\n| `track-list-click` | `(id: string) => void` | 歌曲列表点击 |\n| `release-status-click` | `(id: string) => void` | 发行状态点击 |\n| `authorization-contract-click` | `(id: string) => void` | 授权合同点击 |\n| `control-action-click` | `(key: AlbumListActionDef['key'], row: AlbumListItem) => void` | control 变体操作点击 |\n| `batch-action` | `(actionKey: BatchActionKey, selectedIds: string[]) => void` | 批量操作点击 |\n| `update:selectedIds` | `(ids: string[]) => void` | 选中状态变化 |\n\n### Exports\n\n```ts\nexport type DefaultControlActionKey = 'detail' | 'track-list' | 'release' | 'contract'\nexport type AlbumListBuiltInActionIcon = 'eye' | 'list' | 'clock' | 'file'\nexport type AlbumListActionIcon = AlbumListBuiltInActionIcon | Component\nexport type AlbumListActionIconResolver = (row: AlbumListItem) => AlbumListActionIcon\n\n// 操作项定义\nexport interface AlbumListActionDef {\n  key: string\n  label: string | ((row: AlbumListItem) => string)\n  icon: AlbumListActionIcon\n  iconResolver?: AlbumListActionIconResolver\n}\n\nexport interface DefaultControlActionDef extends AlbumListActionDef {\n  key: DefaultControlActionKey\n  icon: AlbumListBuiltInActionIcon\n}\n\n// control 变体支持的操作列表\nexport const CONTROL_ACTIONS: DefaultControlActionDef[]\n\n// 批量操作定义\nexport interface BatchActionDef {\n  key: BatchActionKey\n  label: string\n  icon: string\n}\n\nexport type BatchActionKey = 'publish' | 'take-down' | 'delete'\n\n// 批量操作列表\nexport const BATCH_ACTIONS: BatchActionDef[]\n```\n\n## Variants\n\n### detailed (默认)\n\n信息优先，需要浏览完整专辑信息。\n\n```\n┌─────────────────────────────────────────────────────────────────────────┐\n│ 专辑信息 │ 附加信息 │ 授权状态 │ 发行状态 │ 操作                        │\n└─────────────────────────────────────────────────────────────────────────┘\n```\n\n### compact\n\n单行高密度展示，适合快速浏览。\n\n```\n┌─────────────────────────────────────────────────────────────────────────┐\n│ 封面 │ 专辑名 │ 艺人 │ UPC │ 歌曲数量 │ 操作                           │\n└─────────────────────────────────────────────────────────────────────────┘\n```\n\n### control\n\n操作优先展示，仅保留专辑信息（封面 + 标题）和操作列，支持隐藏默认操作并追加自定义操作。\n\n```\n┌─────────────────────────────────────────────────────────────────────────┐\n│ 专辑信息                              │ 操作                            │\n│ [封面] 专辑名称 (2 行)                   │ [icon] [icon] [icon] [icon]    │\n└─────────────────────────────────────────────────────────────────────────┘\n```\n\n## Operation Permission Control\n\n组件采用「哑组件」设计原则：\n\n- **默认操作可配置显示/隐藏**：通过 `defaultControlActionVisible` 全局控制 4 个内置操作\n- **支持追加自定义操作**：通过 `controlActions` 在默认操作后追加业务按钮\n- **无权限时禁用**：通过 `disabled` 状态表示当前不可用\n- **判断逻辑外置**：组件只负责展示，权限判断由外部业务层处理\n\n### 使用示例\n\n```vue\n<script setup lang=\"ts\">\nimport { defineComponent, h } from 'vue'\nimport { DfAlbumList, CONTROL_ACTIONS } from '@daflow-ui/block-album-list'\nimport type { AlbumListActionDef, AlbumListItem } from '@daflow-ui/block-album-list'\n\nconst defaultControlActionVisible = {\n  detail: true,\n  'track-list': true,\n  release: false,\n  contract: true\n}\n\nconst AnalyticsIcon = defineComponent({\n  name: 'AnalyticsIcon',\n  setup() {\n    return () => h(\n      'svg',\n      { viewBox: '0 0 24 24', 'aria-hidden': 'true', focusable: 'false' },\n      [h('path', { fill: 'currentColor', d: 'M4 19h16v2H2V3h2v16Zm2-2V9h3v8H6Zm5 0V5h3v12h-3Zm5 0v-6h3v6h-3Z' })]\n    )\n  }\n})\n\nconst customActions: AlbumListActionDef[] = [\n  { key: 'analytics', label: '数据概览', icon: AnalyticsIcon }\n]\n\n// 方式一：平面对象（所有行共用状态）\nconst actionDisabled = {\n  detail: false,\n  'track-list': false,\n  release: true,\n  contract: true,\n  analytics: false\n}\n\n// 方式二：函数（每行独立状态）\nconst getActionDisabled = (row: AlbumListItem) => ({\n  detail: false,\n  'track-list': row.authorizationStatus?.label !== '已授权',\n  release: row.authorizationStatus?.label !== '已授权',\n  contract: false,\n  analytics: false\n})\n\nconst handleActionClick = (key: AlbumListActionDef['key'], row: AlbumListItem) => {\n  console.log('action clicked:', key, row.id)\n}\n</script>\n\n<template>\n  <!-- 方式一：平面对象 -->\n  <DfAlbumList\n    :items=\"items\"\n    variant=\"control\"\n    :default-control-action-visible=\"defaultControlActionVisible\"\n    :control-actions=\"customActions\"\n    :control-action-disabled=\"actionDisabled\"\n    @control-action-click=\"handleActionClick\"\n  />\n  \n  <!-- 方式二：每行函数 -->\n  <DfAlbumList\n    :items=\"items\"\n    variant=\"control\"\n    :default-control-action-visible=\"defaultControlActionVisible\"\n    :control-actions=\"customActions\"\n    :control-action-disabled=\"getActionDisabled\"\n    @control-action-click=\"handleActionClick\"\n  />\n</template>\n```\n\n### `iconResolver` 示例\n\n当同一个操作需要根据当前行的 `releaseStatuses` 切换图标和文案时，建议保持 `key` 和点击事件不变，只通过 `label` 和 `iconResolver` 返回不同结果：\n\n```vue\n<script setup lang=\"ts\">\nimport { defineComponent, h } from 'vue'\nimport { DfAlbumList } from '@daflow-ui/block-album-list'\nimport type { AlbumListActionDef, AlbumListItem } from '@daflow-ui/block-album-list'\n\nconst PublishIcon = defineComponent({\n  name: 'PublishIcon',\n  setup() {\n    return () => h(\n      'svg',\n      { viewBox: '0 0 24 24', 'aria-hidden': 'true', focusable: 'false' },\n      [h('path', { fill: 'currentColor', d: 'M12 21a1 1 0 0 1-1-1v-8.59l-2.3 2.3a1 1 0 1 1-1.4-1.42l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 1 1-1.4 1.42L13 11.41V20a1 1 0 0 1-1 1Zm-8-15a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1Z' })]\n    )\n  }\n})\n\nconst TakeDownIcon = defineComponent({\n  name: 'TakeDownIcon',\n  setup() {\n    return () => h(\n      'svg',\n      { viewBox: '0 0 24 24', 'aria-hidden': 'true', focusable: 'false' },\n      [h('path', { fill: 'currentColor', d: 'M12 3a1 1 0 0 1 1 1v8.59l2.3-2.3a1 1 0 1 1 1.4 1.42l-4 4a1 1 0 0 1-1.4 0l-4-4a1 1 0 1 1 1.4-1.42l2.3 2.3V4a1 1 0 0 1 1-1Zm-8 11a1 1 0 0 1 1 1v3h14v-3a1 1 0 1 1 2 0v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3a1 1 0 0 1 1-1Z' })]\n    )\n  }\n})\n\nconst hasReleaseStatus = (row: AlbumListItem, label: string) =>\n  row.releaseStatuses?.some((status) => status.label === label) ?? false\n\nconst controlActions: AlbumListActionDef[] = [\n  {\n    key: 'release-toggle',\n    label: (row) => hasReleaseStatus(row, '已上架') ? '下架专辑' : '上架专辑',\n    icon: PublishIcon,\n    iconResolver: (row) => hasReleaseStatus(row, '已上架') ? TakeDownIcon : PublishIcon\n  }\n]\n\nconst handleControlActionClick = (key: AlbumListActionDef['key'], row: AlbumListItem) => {\n  if (key === 'release-toggle') {\n    // 基于 releaseStatuses 判断当前是执行上架还是下架\n    console.log('toggle publish status', row.id)\n  }\n}\n</script>\n\n<template>\n  <DfAlbumList\n    :items=\"items\"\n    variant=\"control\"\n    :control-actions=\"controlActions\"\n    @control-action-click=\"handleControlActionClick\"\n  />\n</template>\n```\n\n## Batch Actions (多选批量操作)\n\n当启用 `showSelection` 时，会显示复选框列和底部批量操作栏。\n\n### 批量操作\n\n| 操作 | key | 说明 |\n|------|-----|------|\n| 批量上架 | `publish` | 触发批量上架事件 |\n| 批量下架 | `take-down` | 触发批量下架事件 |\n| 删除 | `delete` | 触发删除事件 |\n\n### 使用示例\n\n```vue\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { DfAlbumList } from '@daflow-ui/block-album-list'\nimport type { AlbumListItem, AlbumListPagination, BatchActionKey } from '@daflow-ui/block-album-list'\n\nconst selectedIds = ref<string[]>([])\n\n// 外部判断哪些记录可以执行操作\nconst canExecuteAction = (id: string, actionKey: BatchActionKey) => {\n  // 根据业务逻辑判断\n  return true\n}\n\nconst handleBatchAction = (actionKey: BatchActionKey, ids: string[]) => {\n  // 过滤出可以执行的记录\n  const validIds = ids.filter(id => canExecuteAction(id, actionKey))\n  \n  switch (actionKey) {\n    case 'publish':\n      batchPublish(validIds)\n      break\n    case 'take-down':\n      batchRemove(validIds)\n      break\n    case 'delete':\n      batchDelete(ids)  // 删除不需要判断状态\n      break\n  }\n}\n</script>\n\n<template>\n  <DfAlbumList\n    v-model:selected-ids=\"selectedIds\"\n    :show-selection=\"true\"\n    @batch-action=\"handleBatchAction\"\n  />\n</template>\n```\n\n## Development\n\n### Install dependencies\n\n```bash\npnpm install\n```\n\n### Start playground (at monorepo root)\n\n```bash\ncd ../..  # 回到 monorepo 根目录\npnpm dev  # 启动统一 playground，自动发现组件\n```\n\n组件会自动出现在 playground 导航中（通过 `dev/index.vue`）。\n\n### Build\n\n```bash\npnpm build\n```\n\n### Type check\n\n```bash\npnpm typecheck\n```\n\n### Lint\n\n```bash\npnpm lint\npnpm lint:fix\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}