[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6JB09TVRM19MSTR7MSVC4T3":3,"skill-same:01M6JB09TVRM19MSTR7MSVC4T3":67},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":35,"linkOnly":36,"markdownContent":37,"markdownBody":38,"frontMatter":39,"refName":40,"commitSha":41,"skillDirectory":42,"forksCount":13,"repositoryHtmlUrl":43,"repositoryHomepageUrl":6,"ownerHtmlUrl":44,"ownerBlogUrl":6,"ownerDescription":45,"updatedAt":46,"install":47,"resources":60},"01M6JB09TVRM19MSTR7MSVC4T3","angular-cdk-integration",null,"Create components using Angular CDK utilities including drag-drop, overlay, portal, scrolling, a11y, clipboard, and platform detection for ng-events project","superhealth\u002Fskills-hub","superhealth","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6292112?v=4","01M6JA6E7F21BYK5W3E4P270TT","01M6JA6EC0W8MPHKDJVBZDSEZ0",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub\u002Fblob\u002Fmaster\u002Fskills\u002F7spade\u002Fangular-cdk-integration\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"integration","angular","angular cdk integration","cdk","project","for","ng","Utilities","drag","events","platform","components","drop","clipboard","detection","create","platform detection","2026-11-10 10:12:30",false,"---\nname: angular-cdk-integration\ndescription: Create components using Angular CDK utilities including drag-drop, overlay, portal, scrolling, a11y, clipboard, and platform detection for ng-events project\nlicense: MIT\n---\n\n# Angular CDK Integration Skill\n\nThis skill guides the creation of components and features using Angular CDK (@angular\u002Fcdk) utilities in the ng-events construction site management system.\n\n## When to Use This Skill\n\n**Triggers**: \"Angular CDK\", \"drag and drop\", \"overlay\", \"portal\", \"virtual scroll\", \"accessibility\", \"clipboard\", \"platform detection\", \"CDK utilities\"\n\nUse this skill when:\n- Implementing drag-and-drop functionality\n- Creating overlays, tooltips, or popovers\n- Building virtual scrolling lists\n- Managing focus and accessibility\n- Detecting platform\u002Fbrowser capabilities\n- Working with clipboard operations\n- Managing scrolling behavior\n\n## Core CDK Modules\n\n### 1. Drag and Drop (@angular\u002Fcdk\u002Fdrag-drop)\n\n**Purpose**: Create draggable elements and drop zones\n\n```typescript\nimport { Component } from '@angular\u002Fcore';\nimport { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular\u002Fcdk\u002Fdrag-drop';\nimport { CommonModule } from '@angular\u002Fcommon';\nimport { CdkDropList, CdkDrag } from '@angular\u002Fcdk\u002Fdrag-drop';\n\n@Component({\n  selector: 'app-task-board',\n  standalone: true,\n  imports: [CommonModule, CdkDropList, CdkDrag],\n  template: `\n    \u003Cdiv class=\"task-board\">\n      \u003Cdiv class=\"column\" cdkDropList #todoList=\"cdkDropList\"\n           [cdkDropListData]=\"todo\"\n           [cdkDropListConnectedTo]=\"[inProgressList, doneList]\"\n           (cdkDropListDropped)=\"drop($event)\">\n        \u003Ch3>To Do\u003C\u002Fh3>\n        @for (task of todo; track task.id) {\n          \u003Cdiv cdkDrag class=\"task-card\">\n            {{ task.title }}\n            \u003Cdiv *cdkDragPlaceholder class=\"drag-placeholder\">\u003C\u002Fdiv>\n          \u003C\u002Fdiv>\n        }\n      \u003C\u002Fdiv>\n      \n      \u003Cdiv class=\"column\" cdkDropList #inProgressList=\"cdkDropList\"\n           [cdkDropListData]=\"inProgress\"\n           [cdkDropListConnectedTo]=\"[todoList, doneList]\"\n           (cdkDropListDropped)=\"drop($event)\">\n        \u003Ch3>In Progress\u003C\u002Fh3>\n        @for (task of inProgress; track task.id) {\n          \u003Cdiv cdkDrag class=\"task-card\">{{ task.title }}\u003C\u002Fdiv>\n        }\n      \u003C\u002Fdiv>\n      \n      \u003Cdiv class=\"column\" cdkDropList #doneList=\"cdkDropList\"\n           [cdkDropListData]=\"done\"\n           [cdkDropListConnectedTo]=\"[todoList, inProgressList]\"\n           (cdkDropListDropped)=\"drop($event)\">\n        \u003Ch3>Done\u003C\u002Fh3>\n        @for (task of done; track task.id) {\n          \u003Cdiv cdkDrag class=\"task-card\">{{ task.title }}\u003C\u002Fdiv>\n        }\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  `,\n  styles: [`\n    .task-board {\n      display: flex;\n      gap: 20px;\n    }\n    \n    .column {\n      flex: 1;\n      min-height: 400px;\n      background: #f5f5f5;\n      padding: 16px;\n      border-radius: 4px;\n    }\n    \n    .task-card {\n      background: white;\n      padding: 12px;\n      margin-bottom: 8px;\n      border-radius: 4px;\n      cursor: move;\n    }\n    \n    .task-card:active {\n      box-shadow: 0 5px 5px -3px rgba(0,0,0,.2);\n    }\n    \n    .drag-placeholder {\n      background: #ccc;\n      border: dotted 2px #999;\n      height: 40px;\n      transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n    }\n  `]\n})\nexport class TaskBoardComponent {\n  todo = [\n    { id: '1', title: 'Task 1' },\n    { id: '2', title: 'Task 2' }\n  ];\n  \n  inProgress = [\n    { id: '3', title: 'Task 3' }\n  ];\n  \n  done = [\n    { id: '4', title: 'Task 4' }\n  ];\n  \n  drop(event: CdkDragDrop\u003CTask[]>) {\n    if (event.previousContainer === event.container) {\n      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);\n    } else {\n      transferArrayItem(\n        event.previousContainer.data,\n        event.container.data,\n        event.previousIndex,\n        event.currentIndex\n      );\n    }\n  }\n}\n```\n\n### 2. Overlay (@angular\u002Fcdk\u002Foverlay)\n\n**Purpose**: Create floating panels and popups\n\n```typescript\nimport { Component, inject } from '@angular\u002Fcore';\nimport { Overlay, OverlayRef } from '@angular\u002Fcdk\u002Foverlay';\nimport { ComponentPortal } from '@angular\u002Fcdk\u002Fportal';\n\n@Component({\n  selector: 'app-menu-trigger',\n  standalone: true,\n  template: `\n    \u003Cbutton (click)=\"openMenu()\">Open Menu\u003C\u002Fbutton>\n  `\n})\nexport class MenuTriggerComponent {\n  private overlay = inject(Overlay);\n  private overlayRef: OverlayRef | null = null;\n  \n  openMenu(): void {\n    if (this.overlayRef) {\n      this.overlayRef.dispose();\n      this.overlayRef = null;\n      return;\n    }\n    \n    const positionStrategy = this.overlay\n      .position()\n      .flexibleConnectedTo(this.elementRef)\n      .withPositions([\n        {\n          originX: 'start',\n          originY: 'bottom',\n          overlayX: 'start',\n          overlayY: 'top'\n        }\n      ]);\n    \n    this.overlayRef = this.overlay.create({\n      positionStrategy,\n      scrollStrategy: this.overlay.scrollStrategies.reposition(),\n      hasBackdrop: true,\n      backdropClass: 'cdk-overlay-transparent-backdrop'\n    });\n    \n    const menuPortal = new ComponentPortal(MenuComponent);\n    this.overlayRef.attach(menuPortal);\n    \n    \u002F\u002F Close on backdrop click\n    this.overlayRef.backdropClick().subscribe(() => {\n      this.overlayRef?.dispose();\n      this.overlayRef = null;\n    });\n  }\n}\n```\n\n### 3. Virtual Scrolling (@angular\u002Fcdk\u002Fscrolling)\n\n**Purpose**: Efficiently render large lists\n\n```typescript\nimport { Component, signal } from '@angular\u002Fcore';\nimport { ScrollingModule } from '@angular\u002Fcdk\u002Fscrolling';\nimport { CommonModule } from '@angular\u002Fcommon';\n\n@Component({\n  selector: 'app-task-list-virtual',\n  standalone: true,\n  imports: [CommonModule, ScrollingModule],\n  template: `\n    \u003Ccdk-virtual-scroll-viewport itemSize=\"50\" class=\"viewport\">\n      \u003Cdiv *cdkVirtualFor=\"let task of tasks()\" class=\"task-item\">\n        \u003Ch4>{{ task.title }}\u003C\u002Fh4>\n        \u003Cp>{{ task.description }}\u003C\u002Fp>\n      \u003C\u002Fdiv>\n    \u003C\u002Fcdk-virtual-scroll-viewport>\n  `,\n  styles: [`\n    .viewport {\n      height: 400px;\n      width: 100%;\n      border: 1px solid #ccc;\n    }\n    \n    .task-item {\n      height: 50px;\n      padding: 10px;\n      border-bottom: 1px solid #eee;\n    }\n  `]\n})\nexport class TaskListVirtualComponent {\n  tasks = signal(Array.from({ length: 10000 }, (_, i) => ({\n    id: `task-${i}`,\n    title: `Task ${i}`,\n    description: `Description for task ${i}`\n  })));\n}\n```\n\n### 4. Clipboard (@angular\u002Fcdk\u002Fclipboard)\n\n**Purpose**: Copy text to clipboard\n\n```typescript\nimport { Component, inject } from '@angular\u002Fcore';\nimport { Clipboard, ClipboardModule } from '@angular\u002Fcdk\u002Fclipboard';\n\n@Component({\n  selector: 'app-share-link',\n  standalone: true,\n  imports: [ClipboardModule],\n  template: `\n    \u003Cdiv class=\"share-container\">\n      \u003Cinput [value]=\"shareLink\" readonly #linkInput \u002F>\n      \u003Cbutton \n        [cdkCopyToClipboard]=\"shareLink\"\n        (cdkCopyToClipboardCopied)=\"onCopied($event)\">\n        Copy Link\n      \u003C\u002Fbutton>\n      @if (copied) {\n        \u003Cspan class=\"success\">Copied!\u003C\u002Fspan>\n      }\n    \u003C\u002Fdiv>\n  `\n})\nexport class ShareLinkComponent {\n  private clipboard = inject(Clipboard);\n  shareLink = 'https:\u002F\u002Fng-events.com\u002Fblueprints\u002F123';\n  copied = false;\n  \n  onCopied(success: boolean): void {\n    if (success) {\n      this.copied = true;\n      setTimeout(() => this.copied = false, 2000);\n    }\n  }\n}\n```\n\n### 5. Platform Detection (@angular\u002Fcdk\u002Fplatform)\n\n**Purpose**: Detect browser and platform capabilities\n\n```typescript\nimport { Component, inject, OnInit } from '@angular\u002Fcore';\nimport { Platform } from '@angular\u002Fcdk\u002Fplatform';\n\n@Component({\n  selector: 'app-platform-aware',\n  standalone: true,\n  template: `\n    \u003Cdiv class=\"platform-info\">\n      \u003Ch3>Platform Information\u003C\u002Fh3>\n      \u003Cul>\n        \u003Cli>Browser: {{ browser }}\u003C\u002Fli>\n        \u003Cli>Mobile: {{ isMobile }}\u003C\u002Fli>\n        \u003Cli>iOS: {{ isIOS }}\u003C\u002Fli>\n        \u003Cli>Android: {{ isAndroid }}\u003C\u002Fli>\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n  `\n})\nexport class PlatformAwareComponent implements OnInit {\n  private platform = inject(Platform);\n  \n  browser = '';\n  isMobile = false;\n  isIOS = false;\n  isAndroid = false;\n  \n  ngOnInit(): void {\n    this.isMobile = this.platform.IOS || this.platform.ANDROID;\n    this.isIOS = this.platform.IOS;\n    this.isAndroid = this.platform.ANDROID;\n    \n    if (this.platform.FIREFOX) this.browser = 'Firefox';\n    else if (this.platform.EDGE) this.browser = 'Edge';\n    else if (this.platform.SAFARI) this.browser = 'Safari';\n    else if (this.platform.WEBKIT) this.browser = 'WebKit';\n    else this.browser = 'Unknown';\n  }\n}\n```\n\n## Integration Checklist\n\nWhen using Angular CDK:\n- [ ] Import specific CDK modules (not full @angular\u002Fcdk)\n- [ ] Use standalone components with CDK directives\n- [ ] Implement proper cleanup (subscriptions, overlays)\n- [ ] Test accessibility with screen readers\n- [ ] Handle mobile\u002Ftouch interactions\n- [ ] Consider performance (virtual scrolling for lists >100 items)\n- [ ] Integrate with Blueprint multi-tenancy when needed\n- [ ] Follow three-layer architecture (CDK in UI layer only)\n\n## Best Practices\n\n### DO ✅\n- Use CDK for complex UI interactions\n- Leverage virtual scrolling for large datasets\n- Use overlay service for tooltips\u002Fmenus\n- Detect platform for feature support\n- Clean up overlays and portals on destroy\n\n### DON'T ❌\n- Use CDK in services or repositories (UI layer only)\n- Create overlays without disposal logic\n- Skip accessibility considerations\n- Ignore mobile touch events\n\n## References\n\n- [Angular CDK Documentation](https:\u002F\u002Fmaterial.angular.io\u002Fcdk\u002Fcategories)\n- [Drag and Drop Guide](https:\u002F\u002Fmaterial.angular.io\u002Fcdk\u002Fdrag-drop\u002Foverview)\n- [Virtual Scrolling Guide](https:\u002F\u002Fmaterial.angular.io\u002Fcdk\u002Fscrolling\u002Foverview)\n\n---\n\n**Version**: 1.0.0  \n**Compatible with**: @angular\u002Fcdk 20.x, Angular 20.3.x  \n**Last Updated**: 2025-12-25\n","# Angular CDK Integration Skill\n\nThis skill guides the creation of components and features using Angular CDK (@angular\u002Fcdk) utilities in the ng-events construction site management system.\n\n## When to Use This Skill\n\n**Triggers**: \"Angular CDK\", \"drag and drop\", \"overlay\", \"portal\", \"virtual scroll\", \"accessibility\", \"clipboard\", \"platform detection\", \"CDK utilities\"\n\nUse this skill when:\n- Implementing drag-and-drop functionality\n- Creating overlays, tooltips, or popovers\n- Building virtual scrolling lists\n- Managing focus and accessibility\n- Detecting platform\u002Fbrowser capabilities\n- Working with clipboard operations\n- Managing scrolling behavior\n\n## Core CDK Modules\n\n### 1. Drag and Drop (@angular\u002Fcdk\u002Fdrag-drop)\n\n**Purpose**: Create draggable elements and drop zones\n\n```typescript\nimport { Component } from '@angular\u002Fcore';\nimport { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular\u002Fcdk\u002Fdrag-drop';\nimport { CommonModule } from '@angular\u002Fcommon';\nimport { CdkDropList, CdkDrag } from '@angular\u002Fcdk\u002Fdrag-drop';\n\n@Component({\n  selector: 'app-task-board',\n  standalone: true,\n  imports: [CommonModule, CdkDropList, CdkDrag],\n  template: `\n    \u003Cdiv class=\"task-board\">\n      \u003Cdiv class=\"column\" cdkDropList #todoList=\"cdkDropList\"\n           [cdkDropListData]=\"todo\"\n           [cdkDropListConnectedTo]=\"[inProgressList, doneList]\"\n           (cdkDropListDropped)=\"drop($event)\">\n        \u003Ch3>To Do\u003C\u002Fh3>\n        @for (task of todo; track task.id) {\n          \u003Cdiv cdkDrag class=\"task-card\">\n            {{ task.title }}\n            \u003Cdiv *cdkDragPlaceholder class=\"drag-placeholder\">\u003C\u002Fdiv>\n          \u003C\u002Fdiv>\n        }\n      \u003C\u002Fdiv>\n      \n      \u003Cdiv class=\"column\" cdkDropList #inProgressList=\"cdkDropList\"\n           [cdkDropListData]=\"inProgress\"\n           [cdkDropListConnectedTo]=\"[todoList, doneList]\"\n           (cdkDropListDropped)=\"drop($event)\">\n        \u003Ch3>In Progress\u003C\u002Fh3>\n        @for (task of inProgress; track task.id) {\n          \u003Cdiv cdkDrag class=\"task-card\">{{ task.title }}\u003C\u002Fdiv>\n        }\n      \u003C\u002Fdiv>\n      \n      \u003Cdiv class=\"column\" cdkDropList #doneList=\"cdkDropList\"\n           [cdkDropListData]=\"done\"\n           [cdkDropListConnectedTo]=\"[todoList, inProgressList]\"\n           (cdkDropListDropped)=\"drop($event)\">\n        \u003Ch3>Done\u003C\u002Fh3>\n        @for (task of done; track task.id) {\n          \u003Cdiv cdkDrag class=\"task-card\">{{ task.title }}\u003C\u002Fdiv>\n        }\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  `,\n  styles: [`\n    .task-board {\n      display: flex;\n      gap: 20px;\n    }\n    \n    .column {\n      flex: 1;\n      min-height: 400px;\n      background: #f5f5f5;\n      padding: 16px;\n      border-radius: 4px;\n    }\n    \n    .task-card {\n      background: white;\n      padding: 12px;\n      margin-bottom: 8px;\n      border-radius: 4px;\n      cursor: move;\n    }\n    \n    .task-card:active {\n      box-shadow: 0 5px 5px -3px rgba(0,0,0,.2);\n    }\n    \n    .drag-placeholder {\n      background: #ccc;\n      border: dotted 2px #999;\n      height: 40px;\n      transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n    }\n  `]\n})\nexport class TaskBoardComponent {\n  todo = [\n    { id: '1', title: 'Task 1' },\n    { id: '2', title: 'Task 2' }\n  ];\n  \n  inProgress = [\n    { id: '3', title: 'Task 3' }\n  ];\n  \n  done = [\n    { id: '4', title: 'Task 4' }\n  ];\n  \n  drop(event: CdkDragDrop\u003CTask[]>) {\n    if (event.previousContainer === event.container) {\n      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);\n    } else {\n      transferArrayItem(\n        event.previousContainer.data,\n        event.container.data,\n        event.previousIndex,\n        event.currentIndex\n      );\n    }\n  }\n}\n```\n\n### 2. Overlay (@angular\u002Fcdk\u002Foverlay)\n\n**Purpose**: Create floating panels and popups\n\n```typescript\nimport { Component, inject } from '@angular\u002Fcore';\nimport { Overlay, OverlayRef } from '@angular\u002Fcdk\u002Foverlay';\nimport { ComponentPortal } from '@angular\u002Fcdk\u002Fportal';\n\n@Component({\n  selector: 'app-menu-trigger',\n  standalone: true,\n  template: `\n    \u003Cbutton (click)=\"openMenu()\">Open Menu\u003C\u002Fbutton>\n  `\n})\nexport class MenuTriggerComponent {\n  private overlay = inject(Overlay);\n  private overlayRef: OverlayRef | null = null;\n  \n  openMenu(): void {\n    if (this.overlayRef) {\n      this.overlayRef.dispose();\n      this.overlayRef = null;\n      return;\n    }\n    \n    const positionStrategy = this.overlay\n      .position()\n      .flexibleConnectedTo(this.elementRef)\n      .withPositions([\n        {\n          originX: 'start',\n          originY: 'bottom',\n          overlayX: 'start',\n          overlayY: 'top'\n        }\n      ]);\n    \n    this.overlayRef = this.overlay.create({\n      positionStrategy,\n      scrollStrategy: this.overlay.scrollStrategies.reposition(),\n      hasBackdrop: true,\n      backdropClass: 'cdk-overlay-transparent-backdrop'\n    });\n    \n    const menuPortal = new ComponentPortal(MenuComponent);\n    this.overlayRef.attach(menuPortal);\n    \n    \u002F\u002F Close on backdrop click\n    this.overlayRef.backdropClick().subscribe(() => {\n      this.overlayRef?.dispose();\n      this.overlayRef = null;\n    });\n  }\n}\n```\n\n### 3. Virtual Scrolling (@angular\u002Fcdk\u002Fscrolling)\n\n**Purpose**: Efficiently render large lists\n\n```typescript\nimport { Component, signal } from '@angular\u002Fcore';\nimport { ScrollingModule } from '@angular\u002Fcdk\u002Fscrolling';\nimport { CommonModule } from '@angular\u002Fcommon';\n\n@Component({\n  selector: 'app-task-list-virtual',\n  standalone: true,\n  imports: [CommonModule, ScrollingModule],\n  template: `\n    \u003Ccdk-virtual-scroll-viewport itemSize=\"50\" class=\"viewport\">\n      \u003Cdiv *cdkVirtualFor=\"let task of tasks()\" class=\"task-item\">\n        \u003Ch4>{{ task.title }}\u003C\u002Fh4>\n        \u003Cp>{{ task.description }}\u003C\u002Fp>\n      \u003C\u002Fdiv>\n    \u003C\u002Fcdk-virtual-scroll-viewport>\n  `,\n  styles: [`\n    .viewport {\n      height: 400px;\n      width: 100%;\n      border: 1px solid #ccc;\n    }\n    \n    .task-item {\n      height: 50px;\n      padding: 10px;\n      border-bottom: 1px solid #eee;\n    }\n  `]\n})\nexport class TaskListVirtualComponent {\n  tasks = signal(Array.from({ length: 10000 }, (_, i) => ({\n    id: `task-${i}`,\n    title: `Task ${i}`,\n    description: `Description for task ${i}`\n  })));\n}\n```\n\n### 4. Clipboard (@angular\u002Fcdk\u002Fclipboard)\n\n**Purpose**: Copy text to clipboard\n\n```typescript\nimport { Component, inject } from '@angular\u002Fcore';\nimport { Clipboard, ClipboardModule } from '@angular\u002Fcdk\u002Fclipboard';\n\n@Component({\n  selector: 'app-share-link',\n  standalone: true,\n  imports: [ClipboardModule],\n  template: `\n    \u003Cdiv class=\"share-container\">\n      \u003Cinput [value]=\"shareLink\" readonly #linkInput \u002F>\n      \u003Cbutton \n        [cdkCopyToClipboard]=\"shareLink\"\n        (cdkCopyToClipboardCopied)=\"onCopied($event)\">\n        Copy Link\n      \u003C\u002Fbutton>\n      @if (copied) {\n        \u003Cspan class=\"success\">Copied!\u003C\u002Fspan>\n      }\n    \u003C\u002Fdiv>\n  `\n})\nexport class ShareLinkComponent {\n  private clipboard = inject(Clipboard);\n  shareLink = 'https:\u002F\u002Fng-events.com\u002Fblueprints\u002F123';\n  copied = false;\n  \n  onCopied(success: boolean): void {\n    if (success) {\n      this.copied = true;\n      setTimeout(() => this.copied = false, 2000);\n    }\n  }\n}\n```\n\n### 5. Platform Detection (@angular\u002Fcdk\u002Fplatform)\n\n**Purpose**: Detect browser and platform capabilities\n\n```typescript\nimport { Component, inject, OnInit } from '@angular\u002Fcore';\nimport { Platform } from '@angular\u002Fcdk\u002Fplatform';\n\n@Component({\n  selector: 'app-platform-aware',\n  standalone: true,\n  template: `\n    \u003Cdiv class=\"platform-info\">\n      \u003Ch3>Platform Information\u003C\u002Fh3>\n      \u003Cul>\n        \u003Cli>Browser: {{ browser }}\u003C\u002Fli>\n        \u003Cli>Mobile: {{ isMobile }}\u003C\u002Fli>\n        \u003Cli>iOS: {{ isIOS }}\u003C\u002Fli>\n        \u003Cli>Android: {{ isAndroid }}\u003C\u002Fli>\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n  `\n})\nexport class PlatformAwareComponent implements OnInit {\n  private platform = inject(Platform);\n  \n  browser = '';\n  isMobile = false;\n  isIOS = false;\n  isAndroid = false;\n  \n  ngOnInit(): void {\n    this.isMobile = this.platform.IOS || this.platform.ANDROID;\n    this.isIOS = this.platform.IOS;\n    this.isAndroid = this.platform.ANDROID;\n    \n    if (this.platform.FIREFOX) this.browser = 'Firefox';\n    else if (this.platform.EDGE) this.browser = 'Edge';\n    else if (this.platform.SAFARI) this.browser = 'Safari';\n    else if (this.platform.WEBKIT) this.browser = 'WebKit';\n    else this.browser = 'Unknown';\n  }\n}\n```\n\n## Integration Checklist\n\nWhen using Angular CDK:\n- [ ] Import specific CDK modules (not full @angular\u002Fcdk)\n- [ ] Use standalone components with CDK directives\n- [ ] Implement proper cleanup (subscriptions, overlays)\n- [ ] Test accessibility with screen readers\n- [ ] Handle mobile\u002Ftouch interactions\n- [ ] Consider performance (virtual scrolling for lists >100 items)\n- [ ] Integrate with Blueprint multi-tenancy when needed\n- [ ] Follow three-layer architecture (CDK in UI layer only)\n\n## Best Practices\n\n### DO ✅\n- Use CDK for complex UI interactions\n- Leverage virtual scrolling for large datasets\n- Use overlay service for tooltips\u002Fmenus\n- Detect platform for feature support\n- Clean up overlays and portals on destroy\n\n### DON'T ❌\n- Use CDK in services or repositories (UI layer only)\n- Create overlays without disposal logic\n- Skip accessibility considerations\n- Ignore mobile touch events\n\n## References\n\n- [Angular CDK Documentation](https:\u002F\u002Fmaterial.angular.io\u002Fcdk\u002Fcategories)\n- [Drag and Drop Guide](https:\u002F\u002Fmaterial.angular.io\u002Fcdk\u002Fdrag-drop\u002Foverview)\n- [Virtual Scrolling Guide](https:\u002F\u002Fmaterial.angular.io\u002Fcdk\u002Fscrolling\u002Foverview)\n\n---\n\n**Version**: 1.0.0  \n**Compatible with**: @angular\u002Fcdk 20.x, Angular 20.3.x  \n**Last Updated**: 2025-12-25\n",{"name":5,"license":14,"description":7},"master","08cc2532077058aa50e6e18f54695bc256c88152","skills\u002F7spade\u002Fangular-cdk-integration","https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub","https:\u002F\u002Fgithub.com\u002Fsuperhealth","java engineer","2026-04-06 22:07:23",{"source":8,"skillName":5,"commands":48,"prompt":58,"zipAvailable":59},[49,52,55],{"tool":50,"command":51},"npx","npx skills add superhealth\u002Fskills-hub --skill angular-cdk-integration",{"tool":53,"command":54},"bunx","bunx skills add superhealth\u002Fskills-hub --skill angular-cdk-integration",{"tool":56,"command":57},"pnpm","pnpm dlx skills add superhealth\u002Fskills-hub --skill angular-cdk-integration","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub\u002Fblob\u002Fmaster\u002Fskills\u002F7spade\u002Fangular-cdk-integration\u002FSKILL.md",true,[61],{"path":62,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":65,"sourceHtmlUrl":66},"skill-report.json","REFERENCE","参考文档",11048,"https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub\u002Fblob\u002Fmaster\u002Fskills\u002F7spade\u002Fangular-cdk-integration\u002Fskill-report.json",[68,99,126,139,155,179],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":79,"publishedAt":35},"01M6MC9F3WHV8S8FZ2W4TRB0FE","vercel-react-best-practices","React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React\u002FNext.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.","https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub\u002Fblob\u002Fmaster\u002Fskills\u002Fzhanlincui\u002Fvercel-react-best-practices\u002FSKILL.md",[74],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,29,97,98],"react","vercel react best practices","best practices","vercel","react best practices","data fetching","code","triggers","pages","next","patterns","refactoring","data","Optimization","tasks","guidelines","react components","performance","writing",{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":109,"publishedAt":35},"01M6MB8KWE1Q5A5KERR7RFTQWP","vue-testing-best-practices","Use for Vue.js testing. Covers Vitest, Vue Test Utils, component testing, mocking, testing patterns, and Playwright for E2E testing.","https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub\u002Fblob\u002Fmaster\u002Fskills\u002Fvuejs-ai\u002Fvue-testing-best-practices\u002FSKILL.md",[105,108],{"categoryNo":106,"categoryName":107,"taxonomyType":77,"taxonomyTypeDesc":78},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},[110,111,112,82,113,114,115,116,117,118,119,90,120,121,23,122,123,124,125],"vue testing best practices","testing best practices","vue","testing","testing patterns","js","e2e","vitest","use","component","test","mocking","utils","e2e testing","github","playwright",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":133,"publishedAt":35},"01M6MB8GK06M6GA4KVYNDV1BZP","vue-router-best-practices","Vue Router 4 patterns, navigation guards, route params, and route-component lifecycle interactions.","https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub\u002Fblob\u002Fmaster\u002Fskills\u002Fvuejs-ai\u002Fvue-router-best-practices\u002FSKILL.md",[132],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},[82,112,134,135,136,90,137,138,119,124],"router","vue router best practices","route","navigation","lifecycle",{"skillNo":140,"name":141,"nameZh":6,"description":142,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":143,"categories":144,"keywords":146,"publishedAt":35},"01M6MB8DQF21TZMQ9XC3745ERW","vue-pinia-best-practices","Pinia stores, state management patterns, store setup, and reactivity with stores.","https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub\u002Fblob\u002Fmaster\u002Fskills\u002Fvuejs-ai\u002Fvue-pinia-best-practices\u002FSKILL.md",[145],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},[147,148,112,82,149,150,90,151,152,153,154,124],"vue pinia best practices","pinia","with","store","management","state","state management","setup",{"skillNo":156,"name":157,"nameZh":6,"description":158,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":159,"categories":160,"keywords":170,"publishedAt":35},"01M6MB8A7MC08747J9TV4GWQ9A","vue-options-api-best-practices","Vue 3 Options API style (data(), methods, this context). Each reference shows Options API solution only.","https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub\u002Fblob\u002Fmaster\u002Fskills\u002Fvuejs-ai\u002Fvue-options-api-best-practices\u002FSKILL.md",[161,162,165],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},{"categoryNo":163,"categoryName":164,"taxonomyType":77,"taxonomyTypeDesc":78},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":166,"categoryName":167,"taxonomyType":168,"taxonomyTypeDesc":169},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[112,171,172,173,82,174,175,176,177,92,124,178],"options","vue options api best practices","api","methods","reference","only","context","style",{"skillNo":180,"name":181,"nameZh":6,"description":182,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":183,"categories":184,"keywords":186,"publishedAt":35},"01M6MB85ZTQC24Q04X49MM4YXN","vue-development-guides","A collection of best practices and tips for developing applications using Vue.js. This skill MUST be apply when developing, refactoring or reviewing Vue.js or Nuxt projects.","https:\u002F\u002Fgithub.com\u002Fsuperhealth\u002Fskills-hub\u002Fblob\u002Fmaster\u002Fskills\u002Fvuejs-ai\u002Fvue-development-guides\u002FSKILL.md",[185],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},[187,112,188,189,124,190,191,23,22,192,193,115,91,194,195,82],"development","guides","vue development guides","tips","apply","nuxt","projects","collection","applications"]