@mcp-elements/angular 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/index.d.ts +506 -0
  2. package/dist/index.js +2714 -0
  3. package/dist/index.js.map +1 -0
  4. package/package.json +28 -11
  5. package/src/accordion.component.ts +0 -74
  6. package/src/ai-badge.component.ts +0 -26
  7. package/src/alert.component.ts +0 -25
  8. package/src/avatar.component.ts +0 -24
  9. package/src/badge.component.ts +0 -17
  10. package/src/button.component.ts +0 -27
  11. package/src/card.component.ts +0 -46
  12. package/src/chat-bubble.component.ts +0 -53
  13. package/src/chips.component.ts +0 -33
  14. package/src/counter.component.ts +0 -48
  15. package/src/dialog.component.ts +0 -42
  16. package/src/drawer.component.ts +0 -48
  17. package/src/dropdown-menu.component.ts +0 -62
  18. package/src/feedback.component.ts +0 -71
  19. package/src/index.ts +0 -86
  20. package/src/input.component.ts +0 -46
  21. package/src/loader.component.ts +0 -12
  22. package/src/mcp/index.ts +0 -9
  23. package/src/mcp/mcp-app-frame.component.ts +0 -60
  24. package/src/mcp/mcp-consent-dialog.component.ts +0 -63
  25. package/src/mcp/mcp-resource-browser.component.ts +0 -86
  26. package/src/mcp/mcp-scope-inspector.component.ts +0 -81
  27. package/src/mcp/mcp-server-status.component.ts +0 -44
  28. package/src/mcp/mcp-tool-call.component.ts +0 -105
  29. package/src/mcp/mcp-tool-form.component.ts +0 -127
  30. package/src/password-input.component.ts +0 -35
  31. package/src/popover.component.ts +0 -40
  32. package/src/progress.component.ts +0 -20
  33. package/src/prompt-input.component.ts +0 -70
  34. package/src/select.component.ts +0 -106
  35. package/src/separator.component.ts +0 -15
  36. package/src/skeleton.component.ts +0 -11
  37. package/src/source-card.component.ts +0 -34
  38. package/src/streaming-text.component.ts +0 -43
  39. package/src/suggestion-chips.component.ts +0 -23
  40. package/src/switch.component.ts +0 -32
  41. package/src/tabs.component.ts +0 -95
  42. package/src/textarea.component.ts +0 -22
  43. package/src/toast.component.ts +0 -62
  44. package/src/tooltip.directive.ts +0 -63
@@ -1,106 +0,0 @@
1
- import { Component, input, output, signal, computed, ElementRef, viewChild, HostListener } from '@angular/core'
2
- import { createSelect, type SelectOption } from '@mcp-elements/core'
3
-
4
- @Component({
5
- selector: 'mcpe-select',
6
- standalone: true,
7
- template: `
8
- <div class="relative" #container>
9
- <button
10
- class="mcpe-select-trigger"
11
- [attr.aria-expanded]="isOpen()"
12
- aria-haspopup="listbox"
13
- (click)="toggle()"
14
- (keydown)="onKeyDown($event)"
15
- >
16
- <span>{{ selectedLabel() || placeholder() }}</span>
17
- <svg class="h-4 w-4 opacity-50" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
18
- <path d="m6 9 6 6 6-6" />
19
- </svg>
20
- </button>
21
- @if (isOpen()) {
22
- <div class="mcpe-select-content absolute top-full mt-1 w-full">
23
- <div class="mcpe-select-viewport" role="listbox">
24
- @for (option of options(); track option.value; let i = $index) {
25
- <div
26
- role="option"
27
- [attr.aria-selected]="option.value === selectedValue()"
28
- [attr.aria-disabled]="option.disabled"
29
- [class]="getItemClasses(option, i)"
30
- (click)="selectOption(option)"
31
- (mouseenter)="highlightedIndex.set(i)"
32
- >
33
- {{ option.label }}
34
- </div>
35
- }
36
- </div>
37
- </div>
38
- }
39
- </div>
40
- `,
41
- host: {
42
- '(document:click)': 'onDocumentClick($event)',
43
- },
44
- })
45
- export class SnxSelectComponent {
46
- options = input<SelectOption[]>([])
47
- placeholder = input('Select...')
48
- valueChange = output<string>()
49
-
50
- isOpen = signal(false)
51
- selectedValue = signal<string | null>(null)
52
- highlightedIndex = signal(0)
53
-
54
- container = viewChild<ElementRef>('container')
55
-
56
- selectedLabel = computed(() => {
57
- const val = this.selectedValue()
58
- return this.options().find(o => o.value === val)?.label ?? ''
59
- })
60
-
61
- toggle() { this.isOpen.update(v => !v) }
62
-
63
- selectOption(option: SelectOption) {
64
- if (option.disabled) return
65
- this.selectedValue.set(option.value)
66
- this.valueChange.emit(option.value)
67
- this.isOpen.set(false)
68
- }
69
-
70
- getItemClasses(option: SelectOption, index: number): string {
71
- return [
72
- 'mcpe-select-item',
73
- index === this.highlightedIndex() ? 'mcpe-select-item-active' : '',
74
- option.value === this.selectedValue() ? 'mcpe-select-item-selected' : '',
75
- ].filter(Boolean).join(' ')
76
- }
77
-
78
- onKeyDown(event: KeyboardEvent) {
79
- const opts = this.options().filter(o => !o.disabled)
80
- if (event.key === 'ArrowDown') {
81
- event.preventDefault()
82
- if (!this.isOpen()) { this.isOpen.set(true); return }
83
- this.highlightedIndex.update(i => (i + 1) % opts.length)
84
- } else if (event.key === 'ArrowUp') {
85
- event.preventDefault()
86
- this.highlightedIndex.update(i => (i - 1 + opts.length) % opts.length)
87
- } else if (event.key === 'Enter' || event.key === ' ') {
88
- event.preventDefault()
89
- if (this.isOpen()) {
90
- const opt = opts[this.highlightedIndex()]
91
- if (opt) this.selectOption(opt)
92
- } else {
93
- this.isOpen.set(true)
94
- }
95
- } else if (event.key === 'Escape') {
96
- this.isOpen.set(false)
97
- }
98
- }
99
-
100
- onDocumentClick(event: MouseEvent) {
101
- const el = this.container()?.nativeElement
102
- if (el && !el.contains(event.target as Node)) {
103
- this.isOpen.set(false)
104
- }
105
- }
106
- }
@@ -1,15 +0,0 @@
1
- import { Component, input, computed } from '@angular/core'
2
-
3
- @Component({
4
- selector: 'mcpe-separator',
5
- standalone: true,
6
- template: `<div [class]="classes()" role="separator" [attr.aria-orientation]="orientation()"></div>`,
7
- })
8
- export class SnxSeparatorComponent {
9
- orientation = input<'horizontal' | 'vertical'>('horizontal')
10
- class = input('')
11
-
12
- classes = computed(() =>
13
- ['mcpe-separator', `mcpe-separator-${this.orientation()}`, this.class()].filter(Boolean).join(' ')
14
- )
15
- }
@@ -1,11 +0,0 @@
1
- import { Component, input, computed } from '@angular/core'
2
-
3
- @Component({
4
- selector: 'mcpe-skeleton',
5
- standalone: true,
6
- template: `<div [class]="classes()"></div>`,
7
- })
8
- export class SnxSkeletonComponent {
9
- class = input('')
10
- classes = computed(() => ['mcpe-skeleton', this.class()].filter(Boolean).join(' '))
11
- }
@@ -1,34 +0,0 @@
1
- import { Component, input } from '@angular/core'
2
-
3
- @Component({
4
- selector: 'mcpe-source-cards',
5
- standalone: true,
6
- template: `<div class="mcpe-source-cards"><ng-content /></div>`,
7
- })
8
- export class SnxSourceCardsComponent {}
9
-
10
- @Component({
11
- selector: 'mcpe-source-card',
12
- standalone: true,
13
- template: `
14
- <a [href]="href()" class="mcpe-source-card" target="_blank" rel="noopener noreferrer">
15
- @if (favicon()) {
16
- <img class="mcpe-source-card-favicon" [src]="favicon()" [alt]="domain()" />
17
- }
18
- <div class="mcpe-source-card-body">
19
- <p class="mcpe-source-card-title">{{ title() }}</p>
20
- <p class="mcpe-source-card-domain">{{ domain() }}</p>
21
- </div>
22
- @if (index()) {
23
- <span class="mcpe-source-card-index">{{ index() }}</span>
24
- }
25
- </a>
26
- `,
27
- })
28
- export class SnxSourceCardComponent {
29
- href = input.required<string>()
30
- favicon = input('')
31
- title = input('')
32
- domain = input('')
33
- index = input<number | undefined>(undefined)
34
- }
@@ -1,43 +0,0 @@
1
- import { Component } from '@angular/core'
2
-
3
- @Component({
4
- selector: 'mcpe-streaming-text',
5
- standalone: true,
6
- template: `<div class="mcpe-streaming-text-cursor"><ng-content /></div>`,
7
- })
8
- export class SnxStreamingTextComponent {}
9
-
10
- @Component({
11
- selector: 'mcpe-streaming-text-fade-in',
12
- standalone: true,
13
- template: `<span class="mcpe-streaming-text-fade-in"><ng-content /></span>`,
14
- })
15
- export class SnxStreamingTextFadeInComponent {}
16
-
17
- @Component({
18
- selector: 'mcpe-streaming-text-word',
19
- standalone: true,
20
- template: `<span class="mcpe-streaming-text-word"><ng-content /></span>`,
21
- })
22
- export class SnxStreamingTextWordComponent {}
23
-
24
- @Component({
25
- selector: 'mcpe-streaming-text-line',
26
- standalone: true,
27
- template: `<div class="mcpe-streaming-text-line"><ng-content /></div>`,
28
- })
29
- export class SnxStreamingTextLineComponent {}
30
-
31
- @Component({
32
- selector: 'mcpe-streaming-text-skeleton',
33
- standalone: true,
34
- template: `<div class="mcpe-streaming-text-skeleton"><ng-content /></div>`,
35
- })
36
- export class SnxStreamingTextSkeletonComponent {}
37
-
38
- @Component({
39
- selector: 'mcpe-streaming-text-skeleton-line',
40
- standalone: true,
41
- template: `<div class="mcpe-streaming-text-skeleton-line"></div>`,
42
- })
43
- export class SnxStreamingTextSkeletonLineComponent {}
@@ -1,23 +0,0 @@
1
- import { Component, input, computed } from '@angular/core'
2
-
3
- type SuggestionChipVariant = 'default' | 'primary' | 'outline'
4
-
5
- @Component({
6
- selector: 'mcpe-suggestion-chips',
7
- standalone: true,
8
- template: `<div class="mcpe-suggestion-chips"><ng-content /></div>`,
9
- })
10
- export class SnxSuggestionChipsComponent {}
11
-
12
- @Component({
13
- selector: 'mcpe-suggestion-chip',
14
- standalone: true,
15
- template: `<button [class]="classes()" type="button"><ng-content /></button>`,
16
- })
17
- export class SnxSuggestionChipComponent {
18
- variant = input<SuggestionChipVariant>('default')
19
- class = input('')
20
- classes = computed(() =>
21
- ['mcpe-suggestion-chip', `mcpe-suggestion-chip-${this.variant()}`, this.class()].filter(Boolean).join(' ')
22
- )
23
- }
@@ -1,32 +0,0 @@
1
- import { Component, input, output, signal, computed } from '@angular/core'
2
-
3
- @Component({
4
- selector: 'mcpe-switch',
5
- standalone: true,
6
- template: `
7
- <button
8
- type="button"
9
- role="switch"
10
- [attr.aria-checked]="checked()"
11
- [attr.aria-disabled]="disabled()"
12
- [disabled]="disabled()"
13
- [class]="'mcpe-switch'"
14
- (click)="toggle()"
15
- (keydown.space)="$event.preventDefault(); toggle()"
16
- (keydown.enter)="$event.preventDefault(); toggle()"
17
- >
18
- <span class="mcpe-switch-thumb"></span>
19
- </button>
20
- `,
21
- })
22
- export class SnxSwitchComponent {
23
- checked = signal(false)
24
- disabled = input(false)
25
- checkedChange = output<boolean>()
26
-
27
- toggle() {
28
- if (this.disabled()) return
29
- this.checked.update(v => !v)
30
- this.checkedChange.emit(this.checked())
31
- }
32
- }
@@ -1,95 +0,0 @@
1
- import { Component, input, output, signal, computed, effect, contentChildren, ElementRef } from '@angular/core'
2
- import { createTabs, type TabItem } from '@mcp-elements/core'
3
-
4
- @Component({
5
- selector: 'mcpe-tabs',
6
- standalone: true,
7
- template: `<div><ng-content /></div>`,
8
- })
9
- export class SnxTabsComponent {
10
- items = input<TabItem[]>([])
11
- defaultValue = input<string>('')
12
- activeValue = signal('')
13
-
14
- private api = computed(() =>
15
- createTabs(this.items(), {
16
- defaultValue: this.defaultValue(),
17
- onValueChange: (v) => this.activeValue.set(v),
18
- })
19
- )
20
-
21
- constructor() {
22
- effect(() => {
23
- const def = this.defaultValue()
24
- const items = this.items()
25
- if (def) {
26
- this.activeValue.set(def)
27
- } else if (items.length > 0) {
28
- this.activeValue.set(items[0].value)
29
- }
30
- })
31
- }
32
-
33
- getTabProps(value: string) {
34
- return this.api().getTriggerProps(value, this.activeValue())
35
- }
36
-
37
- getPanelProps(value: string) {
38
- return this.api().getPanelProps(value, this.activeValue())
39
- }
40
-
41
- isActive(value: string): boolean {
42
- return this.activeValue() === value
43
- }
44
-
45
- select(value: string) {
46
- this.activeValue.set(value)
47
- }
48
- }
49
-
50
- @Component({
51
- selector: 'mcpe-tabs-list',
52
- standalone: true,
53
- template: `<div role="tablist" class="mcpe-tabs-list"><ng-content /></div>`,
54
- })
55
- export class SnxTabsListComponent {}
56
-
57
- @Component({
58
- selector: 'mcpe-tabs-trigger',
59
- standalone: true,
60
- template: `
61
- <button
62
- role="tab"
63
- [class]="classes()"
64
- [attr.aria-selected]="isActive()"
65
- [attr.tabindex]="isActive() ? 0 : -1"
66
- (click)="onClick.emit()"
67
- >
68
- <ng-content />
69
- </button>
70
- `,
71
- })
72
- export class SnxTabsTriggerComponent {
73
- isActive = input(false)
74
- onClick = output<void>()
75
- class = input('')
76
-
77
- classes = computed(() =>
78
- ['mcpe-tabs-trigger', this.isActive() ? 'mcpe-tabs-trigger-active' : '', this.class()]
79
- .filter(Boolean)
80
- .join(' ')
81
- )
82
- }
83
-
84
- @Component({
85
- selector: 'mcpe-tabs-content',
86
- standalone: true,
87
- template: `
88
- @if (isActive()) {
89
- <div role="tabpanel" class="mcpe-tabs-content"><ng-content /></div>
90
- }
91
- `,
92
- })
93
- export class SnxTabsContentComponent {
94
- isActive = input(false)
95
- }
@@ -1,22 +0,0 @@
1
- import { Component, input, computed } from '@angular/core'
2
-
3
- @Component({
4
- selector: 'mcpe-textarea',
5
- standalone: true,
6
- template: `
7
- <textarea
8
- [class]="classes()"
9
- [placeholder]="placeholder()"
10
- [disabled]="disabled()"
11
- [rows]="rows()"
12
- ><ng-content /></textarea>
13
- `,
14
- })
15
- export class SnxTextareaComponent {
16
- placeholder = input('')
17
- disabled = input(false)
18
- rows = input(3)
19
- class = input('')
20
-
21
- classes = computed(() => ['mcpe-textarea', this.class()].filter(Boolean).join(' '))
22
- }
@@ -1,62 +0,0 @@
1
- import { Component, Injectable, signal } from '@angular/core'
2
-
3
- export interface ToastData {
4
- id: string
5
- title?: string
6
- description?: string
7
- variant?: 'default' | 'destructive' | 'success'
8
- }
9
-
10
- @Injectable({ providedIn: 'root' })
11
- export class SnxToastService {
12
- toasts = signal<ToastData[]>([])
13
- private counter = 0
14
-
15
- show(toast: Omit<ToastData, 'id'>, duration = 5000): string {
16
- const id = `toast-${++this.counter}`
17
- this.toasts.update(t => [...t, { id, ...toast }])
18
- if (duration > 0) {
19
- setTimeout(() => this.dismiss(id), duration)
20
- }
21
- return id
22
- }
23
-
24
- success(title: string, description?: string) {
25
- return this.show({ title, description, variant: 'success' })
26
- }
27
-
28
- error(title: string, description?: string) {
29
- return this.show({ title, description, variant: 'destructive' })
30
- }
31
-
32
- dismiss(id: string) {
33
- this.toasts.update(t => t.filter(x => x.id !== id))
34
- }
35
- }
36
-
37
- @Component({
38
- selector: 'mcpe-toaster',
39
- standalone: true,
40
- template: `
41
- <div class="mcpe-toaster mcpe-toaster-bottom-right">
42
- @for (t of toastService.toasts(); track t.id) {
43
- <div
44
- [class]="'mcpe-toast group' + (t.variant === 'destructive' ? ' mcpe-toast-destructive' : '') + (t.variant === 'success' ? ' mcpe-toast-success' : '')"
45
- >
46
- <div class="flex-1">
47
- @if (t.title) { <div class="mcpe-toast-title">{{ t.title }}</div> }
48
- @if (t.description) { <div class="mcpe-toast-description">{{ t.description }}</div> }
49
- </div>
50
- <button class="mcpe-toast-close" (click)="toastService.dismiss(t.id)" aria-label="Close">
51
- <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
52
- <path d="M18 6 6 18" /><path d="m6 6 12 12" />
53
- </svg>
54
- </button>
55
- </div>
56
- }
57
- </div>
58
- `,
59
- })
60
- export class SnxToasterComponent {
61
- constructor(public toastService: SnxToastService) {}
62
- }
@@ -1,63 +0,0 @@
1
- import { Directive, input, HostListener, ElementRef, Renderer2, OnDestroy } from '@angular/core'
2
-
3
- @Directive({
4
- selector: '[mcpeTooltip]',
5
- standalone: true,
6
- })
7
- export class SnxTooltipDirective implements OnDestroy {
8
- mcpeTooltip = input<string>('')
9
- tooltipDelay = input(700)
10
-
11
- private tooltipEl: HTMLElement | null = null
12
- private timeoutId: ReturnType<typeof setTimeout> | null = null
13
-
14
- constructor(private el: ElementRef, private renderer: Renderer2) {}
15
-
16
- @HostListener('mouseenter')
17
- @HostListener('focus')
18
- onShow() {
19
- this.clearDelay()
20
- this.timeoutId = setTimeout(() => this.show(), this.tooltipDelay())
21
- }
22
-
23
- @HostListener('mouseleave')
24
- @HostListener('blur')
25
- onHide() {
26
- this.clearDelay()
27
- this.hide()
28
- }
29
-
30
- private show() {
31
- if (this.tooltipEl) return
32
- this.tooltipEl = this.renderer.createElement('div')
33
- this.renderer.addClass(this.tooltipEl, 'mcpe-tooltip-content')
34
- this.renderer.setStyle(this.tooltipEl, 'position', 'absolute')
35
- this.renderer.setStyle(this.tooltipEl, 'bottom', '100%')
36
- this.renderer.setStyle(this.tooltipEl, 'left', '50%')
37
- this.renderer.setStyle(this.tooltipEl, 'transform', 'translateX(-50%)')
38
- this.renderer.setStyle(this.tooltipEl, 'margin-bottom', '0.5rem')
39
- const text = this.renderer.createText(this.mcpeTooltip())
40
- this.renderer.appendChild(this.tooltipEl, text)
41
- this.renderer.setStyle(this.el.nativeElement, 'position', 'relative')
42
- this.renderer.appendChild(this.el.nativeElement, this.tooltipEl)
43
- }
44
-
45
- private hide() {
46
- if (this.tooltipEl) {
47
- this.renderer.removeChild(this.el.nativeElement, this.tooltipEl)
48
- this.tooltipEl = null
49
- }
50
- }
51
-
52
- private clearDelay() {
53
- if (this.timeoutId !== null) {
54
- clearTimeout(this.timeoutId)
55
- this.timeoutId = null
56
- }
57
- }
58
-
59
- ngOnDestroy() {
60
- this.clearDelay()
61
- this.hide()
62
- }
63
- }