@inlaylab/opaline-angular 1.1.0 → 1.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.
package/README.md
CHANGED
|
@@ -23,7 +23,13 @@ export class UserAvatar {
|
|
|
23
23
|
}
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Inputs: `seed`, `look`, `size`, `src`, `alt`, `palette`, `finish`, `expression`, `mood`, `face`, `family`, `backdrop`, `shape`, `body` and `
|
|
26
|
+
Inputs: `seed`, `look`, `size`, `src`, `alt`, `palette`, `finish`, `expression`, `mood`, `face`, `family`, `backdrop`, `shape`, `body`, `ears` and `text`. Works with Angular 22 and inside Ivorie's `<iv-avatar-fallback>`.
|
|
27
|
+
|
|
28
|
+
Groups: `OpalineAvatarGroup` (`<op-avatar-group>`) overlaps avatars and adds a `+N` chip past `max`. Inputs: `members` (seeds or `{ seed, src, alt }`), `look`, `max`, `size`, `alt`, `palette`, `shape` and `finish`.
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<op-avatar-group [members]="people" [look]="clay" max="4" alt="Project members" />
|
|
32
|
+
```
|
|
27
33
|
|
|
28
34
|
Same seed, same avatar: from 1.0, the same seed and options give a byte-identical SVG in every 1.x release.
|
|
29
35
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { ChangeDetectionStrategy, Component, Injectable, afterNextRender, computed, effect, inject, input, signal, untracked, viewChild } from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, Injectable, afterNextRender, computed, effect, inject, input, numberAttribute, signal, untracked, viewChild } from "@angular/core";
|
|
3
3
|
import { DomSanitizer } from "@angular/platform-browser";
|
|
4
|
-
import { createAvatar } from "@inlaylab/opaline";
|
|
4
|
+
import { avatarGroup, createAvatar } from "@inlaylab/opaline";
|
|
5
5
|
var OpalineIds = class OpalineIds {
|
|
6
6
|
count = 0;
|
|
7
7
|
next() {
|
|
@@ -447,6 +447,282 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
447
447
|
}]
|
|
448
448
|
}
|
|
449
449
|
});
|
|
450
|
-
|
|
450
|
+
var OpalineAvatarGroup = class OpalineAvatarGroup {
|
|
451
|
+
members = input.required(...ngDevMode ? [{ debugName: "members" }] : /* istanbul ignore next */ []);
|
|
452
|
+
look = input.required(...ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []);
|
|
453
|
+
max = input(void 0, {
|
|
454
|
+
...ngDevMode ? { debugName: "max" } : /* istanbul ignore next */ {},
|
|
455
|
+
transform: (v) => v == null || v === "" ? void 0 : numberAttribute(v)
|
|
456
|
+
});
|
|
457
|
+
size = input(40, {
|
|
458
|
+
...ngDevMode ? { debugName: "size" } : /* istanbul ignore next */ {},
|
|
459
|
+
transform: numberAttribute
|
|
460
|
+
});
|
|
461
|
+
alt = input(...ngDevMode ? [void 0, { debugName: "alt" }] : /* istanbul ignore next */ []);
|
|
462
|
+
palette = input(...ngDevMode ? [void 0, { debugName: "palette" }] : /* istanbul ignore next */ []);
|
|
463
|
+
shape = input(...ngDevMode ? [void 0, { debugName: "shape" }] : /* istanbul ignore next */ []);
|
|
464
|
+
finish = input(...ngDevMode ? [void 0, { debugName: "finish" }] : /* istanbul ignore next */ []);
|
|
465
|
+
g = computed(() => avatarGroup(this.members(), {
|
|
466
|
+
max: this.max(),
|
|
467
|
+
size: this.size(),
|
|
468
|
+
shape: this.shape()
|
|
469
|
+
}), ...ngDevMode ? [{ debugName: "g" }] : /* istanbul ignore next */ []);
|
|
470
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
471
|
+
minVersion: "12.0.0",
|
|
472
|
+
version: "22.2.4",
|
|
473
|
+
ngImport: i0,
|
|
474
|
+
type: OpalineAvatarGroup,
|
|
475
|
+
deps: [],
|
|
476
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
477
|
+
});
|
|
478
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
479
|
+
minVersion: "17.0.0",
|
|
480
|
+
version: "22.2.4",
|
|
481
|
+
type: OpalineAvatarGroup,
|
|
482
|
+
isStandalone: true,
|
|
483
|
+
selector: "op-avatar-group",
|
|
484
|
+
inputs: {
|
|
485
|
+
members: {
|
|
486
|
+
classPropertyName: "members",
|
|
487
|
+
publicName: "members",
|
|
488
|
+
isSignal: true,
|
|
489
|
+
isRequired: true,
|
|
490
|
+
transformFunction: null
|
|
491
|
+
},
|
|
492
|
+
look: {
|
|
493
|
+
classPropertyName: "look",
|
|
494
|
+
publicName: "look",
|
|
495
|
+
isSignal: true,
|
|
496
|
+
isRequired: true,
|
|
497
|
+
transformFunction: null
|
|
498
|
+
},
|
|
499
|
+
max: {
|
|
500
|
+
classPropertyName: "max",
|
|
501
|
+
publicName: "max",
|
|
502
|
+
isSignal: true,
|
|
503
|
+
isRequired: false,
|
|
504
|
+
transformFunction: null
|
|
505
|
+
},
|
|
506
|
+
size: {
|
|
507
|
+
classPropertyName: "size",
|
|
508
|
+
publicName: "size",
|
|
509
|
+
isSignal: true,
|
|
510
|
+
isRequired: false,
|
|
511
|
+
transformFunction: null
|
|
512
|
+
},
|
|
513
|
+
alt: {
|
|
514
|
+
classPropertyName: "alt",
|
|
515
|
+
publicName: "alt",
|
|
516
|
+
isSignal: true,
|
|
517
|
+
isRequired: false,
|
|
518
|
+
transformFunction: null
|
|
519
|
+
},
|
|
520
|
+
palette: {
|
|
521
|
+
classPropertyName: "palette",
|
|
522
|
+
publicName: "palette",
|
|
523
|
+
isSignal: true,
|
|
524
|
+
isRequired: false,
|
|
525
|
+
transformFunction: null
|
|
526
|
+
},
|
|
527
|
+
shape: {
|
|
528
|
+
classPropertyName: "shape",
|
|
529
|
+
publicName: "shape",
|
|
530
|
+
isSignal: true,
|
|
531
|
+
isRequired: false,
|
|
532
|
+
transformFunction: null
|
|
533
|
+
},
|
|
534
|
+
finish: {
|
|
535
|
+
classPropertyName: "finish",
|
|
536
|
+
publicName: "finish",
|
|
537
|
+
isSignal: true,
|
|
538
|
+
isRequired: false,
|
|
539
|
+
transformFunction: null
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
host: {
|
|
543
|
+
attributes: {
|
|
544
|
+
"data-opaline-group": "",
|
|
545
|
+
"role": "group"
|
|
546
|
+
},
|
|
547
|
+
properties: {
|
|
548
|
+
"style": "g().css.root",
|
|
549
|
+
"attr.aria-label": "alt() || null",
|
|
550
|
+
"attr.alt": "null",
|
|
551
|
+
"attr.look": "null",
|
|
552
|
+
"attr.max": "null",
|
|
553
|
+
"attr.size": "null",
|
|
554
|
+
"attr.palette": "null",
|
|
555
|
+
"attr.shape": "null",
|
|
556
|
+
"attr.finish": "null"
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
ngImport: i0,
|
|
560
|
+
template: `@for (m of g().shown; track $index) {
|
|
561
|
+
<span data-opaline-member [style]="$index ? g().css.member : g().css.first">
|
|
562
|
+
<op-avatar
|
|
563
|
+
[seed]="m.seed"
|
|
564
|
+
[src]="m.src"
|
|
565
|
+
[alt]="m.alt"
|
|
566
|
+
[look]="look()"
|
|
567
|
+
[size]="size()"
|
|
568
|
+
[palette]="palette()"
|
|
569
|
+
[shape]="shape()"
|
|
570
|
+
[finish]="finish()"
|
|
571
|
+
/>
|
|
572
|
+
</span>
|
|
573
|
+
}
|
|
574
|
+
@if (g().rest) {
|
|
575
|
+
<span
|
|
576
|
+
data-opaline-more
|
|
577
|
+
role="img"
|
|
578
|
+
[attr.aria-label]="g().rest + ' more'"
|
|
579
|
+
[style]="g().css.more"
|
|
580
|
+
>+{{ g().rest }}</span
|
|
581
|
+
>
|
|
582
|
+
}`,
|
|
583
|
+
isInline: true,
|
|
584
|
+
dependencies: [{
|
|
585
|
+
kind: "component",
|
|
586
|
+
type: OpalineAvatar,
|
|
587
|
+
selector: "op-avatar",
|
|
588
|
+
inputs: [
|
|
589
|
+
"seed",
|
|
590
|
+
"look",
|
|
591
|
+
"size",
|
|
592
|
+
"src",
|
|
593
|
+
"alt",
|
|
594
|
+
"palette",
|
|
595
|
+
"family",
|
|
596
|
+
"face",
|
|
597
|
+
"mood",
|
|
598
|
+
"expression",
|
|
599
|
+
"backdrop",
|
|
600
|
+
"shape",
|
|
601
|
+
"finish",
|
|
602
|
+
"body",
|
|
603
|
+
"ears",
|
|
604
|
+
"text"
|
|
605
|
+
]
|
|
606
|
+
}],
|
|
607
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
608
|
+
});
|
|
609
|
+
};
|
|
610
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
611
|
+
minVersion: "12.0.0",
|
|
612
|
+
version: "22.2.4",
|
|
613
|
+
ngImport: i0,
|
|
614
|
+
type: OpalineAvatarGroup,
|
|
615
|
+
decorators: [{
|
|
616
|
+
type: Component,
|
|
617
|
+
args: [{
|
|
618
|
+
selector: "op-avatar-group",
|
|
619
|
+
imports: [OpalineAvatar],
|
|
620
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
621
|
+
host: {
|
|
622
|
+
"data-opaline-group": "",
|
|
623
|
+
role: "group",
|
|
624
|
+
"[style]": "g().css.root",
|
|
625
|
+
"[attr.aria-label]": "alt() || null",
|
|
626
|
+
"[attr.alt]": "null",
|
|
627
|
+
"[attr.look]": "null",
|
|
628
|
+
"[attr.max]": "null",
|
|
629
|
+
"[attr.size]": "null",
|
|
630
|
+
"[attr.palette]": "null",
|
|
631
|
+
"[attr.shape]": "null",
|
|
632
|
+
"[attr.finish]": "null"
|
|
633
|
+
},
|
|
634
|
+
template: `@for (m of g().shown; track $index) {
|
|
635
|
+
<span data-opaline-member [style]="$index ? g().css.member : g().css.first">
|
|
636
|
+
<op-avatar
|
|
637
|
+
[seed]="m.seed"
|
|
638
|
+
[src]="m.src"
|
|
639
|
+
[alt]="m.alt"
|
|
640
|
+
[look]="look()"
|
|
641
|
+
[size]="size()"
|
|
642
|
+
[palette]="palette()"
|
|
643
|
+
[shape]="shape()"
|
|
644
|
+
[finish]="finish()"
|
|
645
|
+
/>
|
|
646
|
+
</span>
|
|
647
|
+
}
|
|
648
|
+
@if (g().rest) {
|
|
649
|
+
<span
|
|
650
|
+
data-opaline-more
|
|
651
|
+
role="img"
|
|
652
|
+
[attr.aria-label]="g().rest + ' more'"
|
|
653
|
+
[style]="g().css.more"
|
|
654
|
+
>+{{ g().rest }}</span
|
|
655
|
+
>
|
|
656
|
+
}`
|
|
657
|
+
}]
|
|
658
|
+
}],
|
|
659
|
+
propDecorators: {
|
|
660
|
+
members: [{
|
|
661
|
+
type: i0.Input,
|
|
662
|
+
args: [{
|
|
663
|
+
isSignal: true,
|
|
664
|
+
alias: "members",
|
|
665
|
+
required: true
|
|
666
|
+
}]
|
|
667
|
+
}],
|
|
668
|
+
look: [{
|
|
669
|
+
type: i0.Input,
|
|
670
|
+
args: [{
|
|
671
|
+
isSignal: true,
|
|
672
|
+
alias: "look",
|
|
673
|
+
required: true
|
|
674
|
+
}]
|
|
675
|
+
}],
|
|
676
|
+
max: [{
|
|
677
|
+
type: i0.Input,
|
|
678
|
+
args: [{
|
|
679
|
+
isSignal: true,
|
|
680
|
+
alias: "max",
|
|
681
|
+
required: false
|
|
682
|
+
}]
|
|
683
|
+
}],
|
|
684
|
+
size: [{
|
|
685
|
+
type: i0.Input,
|
|
686
|
+
args: [{
|
|
687
|
+
isSignal: true,
|
|
688
|
+
alias: "size",
|
|
689
|
+
required: false
|
|
690
|
+
}]
|
|
691
|
+
}],
|
|
692
|
+
alt: [{
|
|
693
|
+
type: i0.Input,
|
|
694
|
+
args: [{
|
|
695
|
+
isSignal: true,
|
|
696
|
+
alias: "alt",
|
|
697
|
+
required: false
|
|
698
|
+
}]
|
|
699
|
+
}],
|
|
700
|
+
palette: [{
|
|
701
|
+
type: i0.Input,
|
|
702
|
+
args: [{
|
|
703
|
+
isSignal: true,
|
|
704
|
+
alias: "palette",
|
|
705
|
+
required: false
|
|
706
|
+
}]
|
|
707
|
+
}],
|
|
708
|
+
shape: [{
|
|
709
|
+
type: i0.Input,
|
|
710
|
+
args: [{
|
|
711
|
+
isSignal: true,
|
|
712
|
+
alias: "shape",
|
|
713
|
+
required: false
|
|
714
|
+
}]
|
|
715
|
+
}],
|
|
716
|
+
finish: [{
|
|
717
|
+
type: i0.Input,
|
|
718
|
+
args: [{
|
|
719
|
+
isSignal: true,
|
|
720
|
+
alias: "finish",
|
|
721
|
+
required: false
|
|
722
|
+
}]
|
|
723
|
+
}]
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
export { OpalineAvatar, OpalineAvatarGroup, OpalineIds };
|
|
451
727
|
|
|
452
728
|
//# sourceMappingURL=inlaylab-opaline-angular.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inlaylab-opaline-angular.mjs","names":[],"sources":["../../src/ids.ts","../../src/avatar.ts"],"sourcesContent":["import { Injectable } from '@angular/core'\n\n/** Per-app counter. Server and client render in the same order, so IDs match on hydration. */\n@Injectable({ providedIn: 'root' })\nexport class OpalineIds {\n private count = 0\n\n next(): string {\n return `n${++this.count}`\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core'\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser'\nimport {\n createAvatar,\n type BlobOptions,\n type ClayOptions,\n type Finish,\n type Expression,\n type Family,\n type Mood,\n type PaletteName,\n type Shape,\n type Style,\n} from '@inlaylab/opaline'\nimport { OpalineIds } from './ids'\n\ntype ImageState = 'loading' | 'loaded' | 'error'\n\n/** `<op-avatar seed=\"ada@inlay.dev\" [look]=\"morph\" />`: a seeded avatar with an optional photo. */\n@Component({\n selector: 'op-avatar',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'data-opaline': '',\n style: 'display:inline-block;position:relative',\n '[style.width.px]': 'size()',\n '[style.height.px]': 'size()',\n '[attr.role]': 'alt() ? \"img\" : null',\n '[attr.aria-label]': 'alt() || null',\n '[attr.aria-hidden]': 'alt() ? null : \"true\"',\n // Static template attributes (`seed=\"ada@inlay.dev\"`) stay on the host; the seed is often an\n // email. Clear them so the root carries only the markup contract, on the server too.\n '[attr.seed]': 'null',\n '[attr.look]': 'null',\n '[attr.size]': 'null',\n '[attr.src]': 'null',\n '[attr.alt]': 'null',\n '[attr.palette]': 'null',\n '[attr.family]': 'null',\n '[attr.face]': 'null',\n '[attr.mood]': 'null',\n '[attr.expression]': 'null',\n '[attr.backdrop]': 'null',\n '[attr.shape]': 'null',\n '[attr.text]': 'null',\n '[attr.finish]': 'null',\n '[attr.body]': 'null',\n '[attr.ears]': 'null',\n },\n template: `<span style=\"display:contents\" [innerHTML]=\"svg()\"></span>\n @if (src() && state() !== 'error') {\n <img\n #img\n [src]=\"src()\"\n alt=\"\"\n style=\"position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:inherit\"\n [hidden]=\"state() !== 'loaded'\"\n (load)=\"state.set('loaded')\"\n (error)=\"state.set('error')\"\n />\n }`,\n})\nexport class OpalineAvatar {\n private readonly sanitizer = inject(DomSanitizer)\n // Unique per instance, so the same avatar twice on a page never shares gradient IDs.\n private readonly instance = inject(OpalineIds).next()\n private readonly img = viewChild<ElementRef<HTMLImageElement>>('img')\n\n readonly seed = input<string | number | null | undefined>()\n readonly look = input.required<Style<any>>()\n readonly size = input(64)\n readonly src = input<string>()\n readonly alt = input<string>()\n readonly palette = input<PaletteName>()\n readonly family = input<Family>()\n readonly face = input<boolean>()\n readonly mood = input<Mood>()\n readonly expression = input<Expression>()\n readonly backdrop = input<BlobOptions['backdrop']>()\n readonly shape = input<Shape>()\n readonly finish = input<Finish>()\n readonly body = input<ClayOptions['body']>()\n readonly ears = input<ClayOptions['ears']>()\n /** Initials only: letters to show instead of the ones from the seed. */\n readonly text = input<string>()\n\n protected readonly state = signal<ImageState>('loading')\n\n protected readonly svg = computed<SafeHtml>(() => {\n const svg = createAvatar(this.look(), {\n seed: this.seed(),\n size: this.size(),\n instance: this.instance,\n palette: this.palette(),\n family: this.family(),\n face: this.face(),\n mood: this.mood(),\n expression: this.expression(),\n backdrop: this.backdrop(),\n shape: this.shape(),\n finish: this.finish(),\n body: this.body(),\n ears: this.ears(),\n text: this.text(),\n }).svg\n // Safe: the core escapes every input that reaches the SVG, and the default sanitizer strips SVG.\n return this.sanitizer.bypassSecurityTrustHtml(svg)\n })\n\n constructor() {\n // A new src is a new image: hide it until it loads.\n effect(() => {\n this.src()\n untracked(() => this.state.set('loading'))\n })\n // With SSR the image can finish before hydration, so its load event is missed. Read it once.\n afterNextRender(() => {\n const img = this.img()?.nativeElement\n if (img?.complete) this.state.set(img.naturalWidth > 0 ? 'loaded' : 'error')\n })\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"inlaylab-opaline-angular.mjs","names":[],"sources":["../../src/ids.ts","../../src/avatar.ts","../../src/group.ts"],"sourcesContent":["import { Injectable } from '@angular/core'\n\n/** Per-app counter. Server and client render in the same order, so IDs match on hydration. */\n@Injectable({ providedIn: 'root' })\nexport class OpalineIds {\n private count = 0\n\n next(): string {\n return `n${++this.count}`\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core'\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser'\nimport {\n createAvatar,\n type BlobOptions,\n type ClayOptions,\n type Finish,\n type Expression,\n type Family,\n type Mood,\n type PaletteName,\n type Shape,\n type Style,\n} from '@inlaylab/opaline'\nimport { OpalineIds } from './ids'\n\ntype ImageState = 'loading' | 'loaded' | 'error'\n\n/** `<op-avatar seed=\"ada@inlay.dev\" [look]=\"morph\" />`: a seeded avatar with an optional photo. */\n@Component({\n selector: 'op-avatar',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'data-opaline': '',\n style: 'display:inline-block;position:relative',\n '[style.width.px]': 'size()',\n '[style.height.px]': 'size()',\n '[attr.role]': 'alt() ? \"img\" : null',\n '[attr.aria-label]': 'alt() || null',\n '[attr.aria-hidden]': 'alt() ? null : \"true\"',\n // Static template attributes (`seed=\"ada@inlay.dev\"`) stay on the host; the seed is often an\n // email. Clear them so the root carries only the markup contract, on the server too.\n '[attr.seed]': 'null',\n '[attr.look]': 'null',\n '[attr.size]': 'null',\n '[attr.src]': 'null',\n '[attr.alt]': 'null',\n '[attr.palette]': 'null',\n '[attr.family]': 'null',\n '[attr.face]': 'null',\n '[attr.mood]': 'null',\n '[attr.expression]': 'null',\n '[attr.backdrop]': 'null',\n '[attr.shape]': 'null',\n '[attr.text]': 'null',\n '[attr.finish]': 'null',\n '[attr.body]': 'null',\n '[attr.ears]': 'null',\n },\n template: `<span style=\"display:contents\" [innerHTML]=\"svg()\"></span>\n @if (src() && state() !== 'error') {\n <img\n #img\n [src]=\"src()\"\n alt=\"\"\n style=\"position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:inherit\"\n [hidden]=\"state() !== 'loaded'\"\n (load)=\"state.set('loaded')\"\n (error)=\"state.set('error')\"\n />\n }`,\n})\nexport class OpalineAvatar {\n private readonly sanitizer = inject(DomSanitizer)\n // Unique per instance, so the same avatar twice on a page never shares gradient IDs.\n private readonly instance = inject(OpalineIds).next()\n private readonly img = viewChild<ElementRef<HTMLImageElement>>('img')\n\n readonly seed = input<string | number | null | undefined>()\n readonly look = input.required<Style<any>>()\n readonly size = input(64)\n readonly src = input<string>()\n readonly alt = input<string>()\n readonly palette = input<PaletteName>()\n readonly family = input<Family>()\n readonly face = input<boolean>()\n readonly mood = input<Mood>()\n readonly expression = input<Expression>()\n readonly backdrop = input<BlobOptions['backdrop']>()\n readonly shape = input<Shape>()\n readonly finish = input<Finish>()\n readonly body = input<ClayOptions['body']>()\n readonly ears = input<ClayOptions['ears']>()\n /** Initials only: letters to show instead of the ones from the seed. */\n readonly text = input<string>()\n\n protected readonly state = signal<ImageState>('loading')\n\n protected readonly svg = computed<SafeHtml>(() => {\n const svg = createAvatar(this.look(), {\n seed: this.seed(),\n size: this.size(),\n instance: this.instance,\n palette: this.palette(),\n family: this.family(),\n face: this.face(),\n mood: this.mood(),\n expression: this.expression(),\n backdrop: this.backdrop(),\n shape: this.shape(),\n finish: this.finish(),\n body: this.body(),\n ears: this.ears(),\n text: this.text(),\n }).svg\n // Safe: the core escapes every input that reaches the SVG, and the default sanitizer strips SVG.\n return this.sanitizer.bypassSecurityTrustHtml(svg)\n })\n\n constructor() {\n // A new src is a new image: hide it until it loads.\n effect(() => {\n this.src()\n untracked(() => this.state.set('loading'))\n })\n // With SSR the image can finish before hydration, so its load event is missed. Read it once.\n afterNextRender(() => {\n const img = this.img()?.nativeElement\n if (img?.complete) this.state.set(img.naturalWidth > 0 ? 'loaded' : 'error')\n })\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, input, numberAttribute } from '@angular/core'\nimport {\n avatarGroup,\n type Finish,\n type GroupMember,\n type PaletteName,\n type Shape,\n type Style,\n} from '@inlaylab/opaline'\nimport { OpalineAvatar } from './avatar'\n\n/**\n * `<op-avatar-group [members]=\"people\" [look]=\"clay\" [max]=\"3\" />`: overlapping avatars with a\n * `+N` chip for everyone past `max`.\n */\n@Component({\n selector: 'op-avatar-group',\n imports: [OpalineAvatar],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'data-opaline-group': '',\n role: 'group',\n '[style]': 'g().css.root',\n '[attr.aria-label]': 'alt() || null',\n // Like <op-avatar>: static template attributes do not stay on the host.\n '[attr.alt]': 'null',\n '[attr.look]': 'null',\n '[attr.max]': 'null',\n '[attr.size]': 'null',\n '[attr.palette]': 'null',\n '[attr.shape]': 'null',\n '[attr.finish]': 'null',\n },\n template: `@for (m of g().shown; track $index) {\n <span data-opaline-member [style]=\"$index ? g().css.member : g().css.first\">\n <op-avatar\n [seed]=\"m.seed\"\n [src]=\"m.src\"\n [alt]=\"m.alt\"\n [look]=\"look()\"\n [size]=\"size()\"\n [palette]=\"palette()\"\n [shape]=\"shape()\"\n [finish]=\"finish()\"\n />\n </span>\n }\n @if (g().rest) {\n <span\n data-opaline-more\n role=\"img\"\n [attr.aria-label]=\"g().rest + ' more'\"\n [style]=\"g().css.more\"\n >+{{ g().rest }}</span\n >\n }`,\n})\nexport class OpalineAvatarGroup {\n /** Seeds, or `{ seed, src, alt }` for a photo and an accessible name. */\n readonly members = input.required<readonly GroupMember[]>()\n readonly look = input.required<Style<any>>()\n /** Show at most this many avatars, then a `+N` chip. Shows everyone when unset. */\n readonly max = input(undefined, {\n transform: (v: unknown) => (v == null || v === '' ? undefined : numberAttribute(v)),\n })\n /** Pixel size of each avatar. Takes a number or a static attribute such as `size=\"32\"`. */\n readonly size = input(40, { transform: numberAttribute })\n /** Accessible name for the whole group, e.g. \"Project members\". */\n readonly alt = input<string>()\n readonly palette = input<PaletteName>()\n readonly shape = input<Shape>()\n readonly finish = input<Finish>()\n\n protected readonly g = computed(() =>\n avatarGroup(this.members(), { max: this.max(), size: this.size(), shape: this.shape() }),\n )\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inlaylab/opaline-angular",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Seeded avatars for Angular: a standalone, zoneless, SSR-safe component.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"avatar",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@angular/platform-browser": ">=22.0.0 <23.0.0"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@inlaylab/opaline": "1.1.
|
|
39
|
+
"@inlaylab/opaline": "1.1.1",
|
|
40
40
|
"tslib": "^2.3.0"
|
|
41
41
|
},
|
|
42
42
|
"module": "fesm2022/inlaylab-opaline-angular.mjs",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SafeHtml } from "@angular/platform-browser";
|
|
2
|
-
import { Expression, Family, Finish, Mood, PaletteName, Shape, Style } from "@inlaylab/opaline";
|
|
2
|
+
import { Expression, Family, Finish, GroupMember, Mood, PaletteName, Shape, Style } from "@inlaylab/opaline";
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
type ImageState = 'loading' | 'loaded' | 'error';
|
|
5
5
|
/** `<op-avatar seed="ada@inlay.dev" [look]="morph" />`: a seeded avatar with an optional photo. */
|
|
@@ -111,6 +111,68 @@ export declare class OpalineAvatar {
|
|
|
111
111
|
};
|
|
112
112
|
}, {}, never, never, true, never>;
|
|
113
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* `<op-avatar-group [members]="people" [look]="clay" [max]="3" />`: overlapping avatars with a
|
|
116
|
+
* `+N` chip for everyone past `max`.
|
|
117
|
+
*/
|
|
118
|
+
export declare class OpalineAvatarGroup {
|
|
119
|
+
/** Seeds, or `{ seed, src, alt }` for a photo and an accessible name. */
|
|
120
|
+
readonly members: import("@angular/core").InputSignal<readonly GroupMember[]>;
|
|
121
|
+
readonly look: import("@angular/core").InputSignal<Style<any>>;
|
|
122
|
+
/** Show at most this many avatars, then a `+N` chip. Shows everyone when unset. */
|
|
123
|
+
readonly max: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
|
|
124
|
+
/** Pixel size of each avatar. Takes a number or a static attribute such as `size="32"`. */
|
|
125
|
+
readonly size: import("@angular/core").InputSignalWithTransform<number, unknown>;
|
|
126
|
+
/** Accessible name for the whole group, e.g. "Project members". */
|
|
127
|
+
readonly alt: import("@angular/core").InputSignal<string | undefined>;
|
|
128
|
+
readonly palette: import("@angular/core").InputSignal<PaletteName | undefined>;
|
|
129
|
+
readonly shape: import("@angular/core").InputSignal<Shape | undefined>;
|
|
130
|
+
readonly finish: import("@angular/core").InputSignal<Finish | undefined>;
|
|
131
|
+
protected readonly g: import("@angular/core").Signal<import("@inlaylab/opaline").GroupLayout>;
|
|
132
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<OpalineAvatarGroup, never>;
|
|
133
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<OpalineAvatarGroup, "op-avatar-group", never, {
|
|
134
|
+
"members": {
|
|
135
|
+
"alias": "members";
|
|
136
|
+
"required": true;
|
|
137
|
+
"isSignal": true;
|
|
138
|
+
};
|
|
139
|
+
"look": {
|
|
140
|
+
"alias": "look";
|
|
141
|
+
"required": true;
|
|
142
|
+
"isSignal": true;
|
|
143
|
+
};
|
|
144
|
+
"max": {
|
|
145
|
+
"alias": "max";
|
|
146
|
+
"required": false;
|
|
147
|
+
"isSignal": true;
|
|
148
|
+
};
|
|
149
|
+
"size": {
|
|
150
|
+
"alias": "size";
|
|
151
|
+
"required": false;
|
|
152
|
+
"isSignal": true;
|
|
153
|
+
};
|
|
154
|
+
"alt": {
|
|
155
|
+
"alias": "alt";
|
|
156
|
+
"required": false;
|
|
157
|
+
"isSignal": true;
|
|
158
|
+
};
|
|
159
|
+
"palette": {
|
|
160
|
+
"alias": "palette";
|
|
161
|
+
"required": false;
|
|
162
|
+
"isSignal": true;
|
|
163
|
+
};
|
|
164
|
+
"shape": {
|
|
165
|
+
"alias": "shape";
|
|
166
|
+
"required": false;
|
|
167
|
+
"isSignal": true;
|
|
168
|
+
};
|
|
169
|
+
"finish": {
|
|
170
|
+
"alias": "finish";
|
|
171
|
+
"required": false;
|
|
172
|
+
"isSignal": true;
|
|
173
|
+
};
|
|
174
|
+
}, {}, never, never, true, never>;
|
|
175
|
+
}
|
|
114
176
|
/** Per-app counter. Server and client render in the same order, so IDs match on hydration. */
|
|
115
177
|
export declare class OpalineIds {
|
|
116
178
|
private count;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inlaylab-opaline-angular.d.ts","names":[],"sources":["../../src/avatar.ts","../../src/ids.ts"],"mappings":";;;KA4BK;;qBA8CQ;mBACM;mBAEA;mBACA;WAER,8BAAI;WACJ,8BAAI,YAAA;WACJ,8BAAI;WACJ,6BAAG;WACH,6BAAG;WACH,iCAAO,YAAA;WACP,gCAAM,YAAA;WACN,8BAAI;WACJ,8BAAI,YAAA;WACJ,oCAAU,YAAA;WACV,kCAAQ;WACR,+BAAK,YAAA;WACL,gCAAM,YAAA;WACN,8BAAI;WACJ,8BAAI;;WAEJ,8BAAI;qBAEM,+BAAK,eAAA;qBAEL,6BAAG,OAAA;;SA1BX,MAAA,GAAA,qBAAA;SAAA,MAAA,GAAA,uBAAA;IAAa;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;;;;
|
|
1
|
+
{"version":3,"file":"inlaylab-opaline-angular.d.ts","names":[],"sources":["../../src/avatar.ts","../../src/group.ts","../../src/ids.ts"],"mappings":";;;KA4BK;;qBA8CQ;mBACM;mBAEA;mBACA;WAER,8BAAI;WACJ,8BAAI,YAAA;WACJ,8BAAI;WACJ,6BAAG;WACH,6BAAG;WACH,iCAAO,YAAA;WACP,gCAAM,YAAA;WACN,8BAAI;WACJ,8BAAI,YAAA;WACJ,oCAAU,YAAA;WACV,kCAAQ;WACR,+BAAK,YAAA;WACL,gCAAM,YAAA;WACN,8BAAI;WACJ,8BAAI;;WAEJ,8BAAI;qBAEM,+BAAK,eAAA;qBAEL,6BAAG,OAAA;;SA1BX,MAAA,GAAA,qBAAA;SAAA,MAAA,GAAA,uBAAA;IAAa;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;;;;;;;qBCjBb;;WAEF,iCAAO,qBAAA;WACP,8BAAI,YAAA;;WAEJ,6BAAG;;WAIH,8BAAI;;WAEJ,6BAAG;WACH,iCAAO,YAAA;WACP,+BAAK,YAAA;WACL,gCAAM,YAAA;qBAEI,2BAAC,mCAAA;SAhBT,MAAA,GAAA,qBAAA;SAAA,MAAA,GAAA,uBAAA;IAAkB;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;IAAA;MAAA;MAAA;MAAA;;;;;qBCrDlB;UACH;EAER;SAHW,MAAA,GAAA,qBAAA"}
|