@thinkersteps_labs/3d-viewer-angular 0.0.0-stage → 1.0.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
@@ -1,3 +1,107 @@
1
- # Temporary Holding Version
1
+ # @thinkersteps_labs/3d-viewer-angular
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Official Angular component wrapper for `@thinkersteps_labs/3d-viewer-core`. Renders photorealistic 3D jewelry and customizer canvases in Angular 18+ applications (including standalone components and legacy `NgModule` architectures).
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pnpm add @thinkersteps_labs/3d-viewer-angular @thinkersteps_labs/3d-viewer-core three
11
+ # or with npm
12
+ npm install @thinkersteps_labs/3d-viewer-angular @thinkersteps_labs/3d-viewer-core three
13
+ ```
14
+
15
+ > **Peer Dependencies**: Requires `@angular/core >= 18.0.0` and `three >= 0.150.0`.
16
+
17
+ ---
18
+
19
+ ## 1. Turnkey Customizer (`<td-jewelry-customizer>`)
20
+
21
+ ```typescript
22
+ import { Component } from '@angular/core'
23
+ import { JewelryCustomizerComponent } from '@thinkersteps_labs/3d-viewer-angular'
24
+
25
+ @Component({
26
+ selector: 'app-product-page',
27
+ standalone: true,
28
+ imports: [JewelryCustomizerComponent],
29
+ template: `
30
+ <td-jewelry-customizer
31
+ [src]="'https://cdn.example.com/models/solitaire-ring.glb'"
32
+ [(metal)]="activeMetal"
33
+ [(stone)]="activeStone"
34
+ [height]="520"
35
+ [autoRotate]="true"
36
+ ></td-jewelry-customizer>
37
+ `
38
+ })
39
+ export class ProductPageComponent {
40
+ activeMetal = 'yellow-gold-18k'
41
+ activeStone = 'diamond-d'
42
+ }
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 2. Composable Primitives (`<td-viewer>` + Swatches)
48
+
49
+ ```typescript
50
+ import { Component } from '@angular/core'
51
+ import {
52
+ ViewerComponent,
53
+ MetalSwatchesComponent,
54
+ StoneSwatchesComponent,
55
+ type MetalColorProp,
56
+ type StoneColorProp,
57
+ } from '@thinkersteps_labs/3d-viewer-angular'
58
+
59
+ @Component({
60
+ selector: 'app-product-detail',
61
+ standalone: true,
62
+ imports: [ViewerComponent, MetalSwatchesComponent, StoneSwatchesComponent],
63
+ template: `
64
+ <div style="max-width: 840px; margin: 0 auto;">
65
+ <td-viewer
66
+ [src]="modelUrl"
67
+ [metalColor]="activeMetal"
68
+ [stoneColor]="activeStone"
69
+ [height]="500"
70
+ [autoRotate]="true"
71
+ ></td-viewer>
72
+
73
+ <div style="margin-top: 16px; display: flex; flex-direction: column; gap: 14px;">
74
+ <td-metal-swatches [(value)]="activeMetal" [variant]="'pills'"></td-metal-swatches>
75
+ <td-stone-swatches [(value)]="activeStone" [variant]="'pills'"></td-stone-swatches>
76
+ </div>
77
+ </div>
78
+ `
79
+ })
80
+ export class ProductDetailComponent {
81
+ modelUrl = 'https://cdn.example.com/models/solitaire-ring.glb'
82
+ activeMetal: MetalColorProp = 'yellow-gold-18k'
83
+ activeStone: StoneColorProp = 'diamond-d'
84
+ }
85
+ ```
86
+
87
+ ---
88
+
89
+ ## 3. NgModule Apps (e.g. Angular ERP)
90
+
91
+ Import `ViewerModule` in your feature module to get access to `<td-viewer>`, `<td-metal-swatches>`, `<td-stone-swatches>`, and `<td-jewelry-customizer>`:
92
+
93
+ ```typescript
94
+ import { NgModule } from '@angular/core'
95
+ import { ViewerModule } from '@thinkersteps_labs/3d-viewer-angular'
96
+
97
+ @NgModule({
98
+ imports: [ViewerModule],
99
+ })
100
+ export class ProductModule {}
101
+ ```
102
+
103
+ ---
104
+
105
+ ## License
106
+
107
+ MIT
@@ -0,0 +1,8 @@
1
+ export { ViewerComponent } from './viewer.component';
2
+ export { ViewerModule } from './viewer.module';
3
+ export { MetalSwatchesComponent, MetalSelectComponent, } from './swatches/metal-swatches.component';
4
+ export { StoneSwatchesComponent, StoneSelectComponent, } from './swatches/stone-swatches.component';
5
+ export { JewelryCustomizerComponent, } from './swatches/jewelry-customizer.component';
6
+ export { CANONICAL_METAL_PRESETS, CANONICAL_STONE_PRESETS, METAL_PRESETS, STONE_PRESETS, PHYSICALLY_BASED_METAL_PRESETS, DIAMOND_PRESETS, GEMSTONE_PRESETS, ALL_METAL_PRESETS, ALL_STONE_PRESETS, getMetalPreset, getStonePreset, normalizeModelSource, inferFormatFromUrl, } from '@thinkersteps_labs/3d-viewer-core';
7
+ export type { MetalPreset, StonePreset, StandardMetalId, StandardStoneId, MetalColorProp, StoneColorProp, ModelSource, ViewerSourceInput, ViewerOptions, ViewerState, PartInfo, PartType, MaterialSlotInfo, MeshMaterialSlot, StateRestoreResult, Viewer, } from '@thinkersteps_labs/3d-viewer-core';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,EACL,0BAA0B,GAC3B,MAAM,yCAAyC,CAAA;AAGhD,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,aAAa,EACb,aAAa,EACb,8BAA8B,EAC9B,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,mCAAmC,CAAA;AAE1C,YAAY,EACV,WAAW,EACX,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,GACP,MAAM,mCAAmC,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { ViewerComponent } from './viewer.component';
2
+ export { ViewerModule } from './viewer.module';
3
+ export { MetalSwatchesComponent, MetalSelectComponent, } from './swatches/metal-swatches.component';
4
+ export { StoneSwatchesComponent, StoneSelectComponent, } from './swatches/stone-swatches.component';
5
+ export { JewelryCustomizerComponent, } from './swatches/jewelry-customizer.component';
6
+ // Convenience re-exports — Angular consumers can import everything from one place.
7
+ export { CANONICAL_METAL_PRESETS, CANONICAL_STONE_PRESETS, METAL_PRESETS, STONE_PRESETS, PHYSICALLY_BASED_METAL_PRESETS, DIAMOND_PRESETS, GEMSTONE_PRESETS, ALL_METAL_PRESETS, ALL_STONE_PRESETS, getMetalPreset, getStonePreset, normalizeModelSource, inferFormatFromUrl, } from '@thinkersteps_labs/3d-viewer-core';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,EACL,0BAA0B,GAC3B,MAAM,yCAAyC,CAAA;AAEhD,mFAAmF;AACnF,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,aAAa,EACb,aAAa,EACb,8BAA8B,EAC9B,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,mCAAmC,CAAA"}
@@ -0,0 +1,29 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { type MetalPreset, type StonePreset, type MetalColorProp, type StoneColorProp, type ViewerSourceInput, type PartInfo, type PartType } from '@thinkersteps_labs/3d-viewer-core';
3
+ import * as i0 from "@angular/core";
4
+ export declare class JewelryCustomizerComponent {
5
+ src?: string;
6
+ source?: ViewerSourceInput;
7
+ metal: MetalColorProp;
8
+ metalChange: EventEmitter<string>;
9
+ stone: StoneColorProp;
10
+ stoneChange: EventEmitter<string>;
11
+ height: number | string;
12
+ autoRotate: boolean;
13
+ quality: 'low' | 'medium' | 'high';
14
+ controlsVariant: 'pills' | 'dots' | 'select' | 'none';
15
+ metalOptions: MetalPreset[];
16
+ stoneOptions: StonePreset[];
17
+ loaded: EventEmitter<PartInfo[]>;
18
+ partSelected: EventEmitter<{
19
+ meshId: string;
20
+ type: PartType;
21
+ }>;
22
+ get buttonVariant(): 'pills' | 'dots';
23
+ get formattedHeight(): string;
24
+ onMetalChange(val: string): void;
25
+ onStoneChange(val: string): void;
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<JewelryCustomizerComponent, never>;
27
+ static ɵcmp: i0.ɵɵComponentDeclaration<JewelryCustomizerComponent, "td-jewelry-customizer", never, { "src": { "alias": "src"; "required": false; }; "source": { "alias": "source"; "required": false; }; "metal": { "alias": "metal"; "required": false; }; "stone": { "alias": "stone"; "required": false; }; "height": { "alias": "height"; "required": false; }; "autoRotate": { "alias": "autoRotate"; "required": false; }; "quality": { "alias": "quality"; "required": false; }; "controlsVariant": { "alias": "controlsVariant"; "required": false; }; "metalOptions": { "alias": "metalOptions"; "required": false; }; "stoneOptions": { "alias": "stoneOptions"; "required": false; }; }, { "metalChange": "metalChange"; "stoneChange": "stoneChange"; "loaded": "loaded"; "partSelected": "partSelected"; }, never, never, true, never>;
28
+ }
29
+ //# sourceMappingURL=jewelry-customizer.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jewelry-customizer.component.d.ts","sourceRoot":"","sources":["../../src/swatches/jewelry-customizer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EAEb,MAAM,eAAe,CAAA;AAEtB,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,mCAAmC,CAAA;;AAkC1C,qBA4Da,0BAA0B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,KAAK,EAAE,cAAc,CAAoB;IACxC,WAAW,uBAA6B;IAEzC,KAAK,EAAE,cAAc,CAAc;IAClC,WAAW,uBAA6B;IAEzC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAM;IAC7B,UAAU,UAAO;IACjB,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAS;IAC3C,eAAe,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAU;IAE/D,YAAY,EAAE,WAAW,EAAE,CAA0B;IACrD,YAAY,EAAE,WAAW,EAAE,CAA0B;IAEpD,MAAM,2BAAiC;IACvC,YAAY;gBAA8B,MAAM;cAAQ,QAAQ;OAAK;IAE/E,IAAI,aAAa,IAAI,OAAO,GAAG,MAAM,CAEpC;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKhC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;yCAjCrB,0BAA0B;2CAA1B,0BAA0B;CAqCtC"}
@@ -0,0 +1,198 @@
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { CANONICAL_METAL_PRESETS, CANONICAL_STONE_PRESETS, } from '@thinkersteps_labs/3d-viewer-core';
4
+ import { ViewerComponent } from '../viewer.component';
5
+ import { MetalSwatchesComponent, MetalSelectComponent } from './metal-swatches.component';
6
+ import { StoneSwatchesComponent, StoneSelectComponent } from './stone-swatches.component';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@angular/common";
9
+ const CUSTOMIZER_STYLES = `
10
+ :host {
11
+ display: block;
12
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
13
+ }
14
+ .td-customizer-card {
15
+ display: flex;
16
+ flex-direction: column;
17
+ gap: 16px;
18
+ background: #ffffff;
19
+ border-radius: 16px;
20
+ border: 1px solid #e2e8f0;
21
+ padding: 16px;
22
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
23
+ }
24
+ .td-customizer-viewport {
25
+ position: relative;
26
+ width: 100%;
27
+ border-radius: 12px;
28
+ overflow: hidden;
29
+ background: #f8fafc;
30
+ }
31
+ .td-customizer-controls {
32
+ display: flex;
33
+ flex-direction: column;
34
+ gap: 14px;
35
+ }
36
+ `;
37
+ export class JewelryCustomizerComponent {
38
+ constructor() {
39
+ this.metal = 'yellow-gold-18k';
40
+ this.metalChange = new EventEmitter();
41
+ this.stone = 'diamond-d';
42
+ this.stoneChange = new EventEmitter();
43
+ this.height = 520;
44
+ this.autoRotate = true;
45
+ this.quality = 'high';
46
+ this.controlsVariant = 'pills';
47
+ this.metalOptions = CANONICAL_METAL_PRESETS;
48
+ this.stoneOptions = CANONICAL_STONE_PRESETS;
49
+ this.loaded = new EventEmitter();
50
+ this.partSelected = new EventEmitter();
51
+ }
52
+ get buttonVariant() {
53
+ return this.controlsVariant === 'dots' ? 'dots' : 'pills';
54
+ }
55
+ get formattedHeight() {
56
+ return typeof this.height === 'number' ? `${this.height}px` : this.height;
57
+ }
58
+ onMetalChange(val) {
59
+ this.metal = val;
60
+ this.metalChange.emit(val);
61
+ }
62
+ onStoneChange(val) {
63
+ this.stone = val;
64
+ this.stoneChange.emit(val);
65
+ }
66
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: JewelryCustomizerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
67
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: JewelryCustomizerComponent, isStandalone: true, selector: "td-jewelry-customizer", inputs: { src: "src", source: "source", metal: "metal", stone: "stone", height: "height", autoRotate: "autoRotate", quality: "quality", controlsVariant: "controlsVariant", metalOptions: "metalOptions", stoneOptions: "stoneOptions" }, outputs: { metalChange: "metalChange", stoneChange: "stoneChange", loaded: "loaded", partSelected: "partSelected" }, ngImport: i0, template: `
68
+ <div class="td-customizer-card">
69
+ <div class="td-customizer-viewport" [style.height]="formattedHeight">
70
+ <td-viewer
71
+ [src]="src"
72
+ [source]="source"
73
+ [metalColor]="metal"
74
+ [stoneColor]="stone"
75
+ [autoRotate]="autoRotate"
76
+ [quality]="quality"
77
+ (loaded)="loaded.emit($event)"
78
+ (partSelected)="partSelected.emit($event)"
79
+ ></td-viewer>
80
+ </div>
81
+
82
+ <div class="td-customizer-controls" *ngIf="controlsVariant !== 'none'">
83
+ <ng-container *ngIf="controlsVariant === 'select'; else buttonSwatches">
84
+ <td-metal-select
85
+ [value]="metal"
86
+ (valueChange)="onMetalChange($event)"
87
+ [options]="metalOptions"
88
+ ></td-metal-select>
89
+ <td-stone-select
90
+ [value]="stone"
91
+ (valueChange)="onStoneChange($event)"
92
+ [options]="stoneOptions"
93
+ ></td-stone-select>
94
+ </ng-container>
95
+
96
+ <ng-template #buttonSwatches>
97
+ <td-metal-swatches
98
+ [value]="metal"
99
+ (valueChange)="onMetalChange($event)"
100
+ [options]="metalOptions"
101
+ [variant]="buttonVariant"
102
+ ></td-metal-swatches>
103
+ <td-stone-swatches
104
+ [value]="stone"
105
+ (valueChange)="onStoneChange($event)"
106
+ [options]="stoneOptions"
107
+ [variant]="buttonVariant"
108
+ ></td-stone-swatches>
109
+ </ng-template>
110
+ </div>
111
+ </div>
112
+ `, isInline: true, styles: ["\n :host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n .td-customizer-card {\n display: flex;\n flex-direction: column;\n gap: 16px;\n background: #ffffff;\n border-radius: 16px;\n border: 1px solid #e2e8f0;\n padding: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);\n }\n .td-customizer-viewport {\n position: relative;\n width: 100%;\n border-radius: 12px;\n overflow: hidden;\n background: #f8fafc;\n }\n .td-customizer-controls {\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ViewerComponent, selector: "td-viewer", inputs: ["src", "source", "metalColor", "stoneColor", "materialColors", "partColors", "height", "minHeight", "background", "metalEnvUrl", "gemEnvUrl", "fov", "shadows", "options", "autoRotate", "quality", "state"], outputs: ["loaded", "modelLoaded", "progress", "partSelected", "error", "change"] }, { kind: "component", type: MetalSwatchesComponent, selector: "td-metal-swatches", inputs: ["value", "options", "category", "variant", "showLabel"], outputs: ["valueChange"] }, { kind: "component", type: MetalSelectComponent, selector: "td-metal-select", inputs: ["value", "options", "label"], outputs: ["valueChange"] }, { kind: "component", type: StoneSwatchesComponent, selector: "td-stone-swatches", inputs: ["value", "options", "category", "variant", "showLabel"], outputs: ["valueChange"] }, { kind: "component", type: StoneSelectComponent, selector: "td-stone-select", inputs: ["value", "options", "label"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
113
+ }
114
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: JewelryCustomizerComponent, decorators: [{
115
+ type: Component,
116
+ args: [{ selector: 'td-jewelry-customizer', standalone: true, imports: [
117
+ CommonModule,
118
+ ViewerComponent,
119
+ MetalSwatchesComponent,
120
+ MetalSelectComponent,
121
+ StoneSwatchesComponent,
122
+ StoneSelectComponent,
123
+ ], template: `
124
+ <div class="td-customizer-card">
125
+ <div class="td-customizer-viewport" [style.height]="formattedHeight">
126
+ <td-viewer
127
+ [src]="src"
128
+ [source]="source"
129
+ [metalColor]="metal"
130
+ [stoneColor]="stone"
131
+ [autoRotate]="autoRotate"
132
+ [quality]="quality"
133
+ (loaded)="loaded.emit($event)"
134
+ (partSelected)="partSelected.emit($event)"
135
+ ></td-viewer>
136
+ </div>
137
+
138
+ <div class="td-customizer-controls" *ngIf="controlsVariant !== 'none'">
139
+ <ng-container *ngIf="controlsVariant === 'select'; else buttonSwatches">
140
+ <td-metal-select
141
+ [value]="metal"
142
+ (valueChange)="onMetalChange($event)"
143
+ [options]="metalOptions"
144
+ ></td-metal-select>
145
+ <td-stone-select
146
+ [value]="stone"
147
+ (valueChange)="onStoneChange($event)"
148
+ [options]="stoneOptions"
149
+ ></td-stone-select>
150
+ </ng-container>
151
+
152
+ <ng-template #buttonSwatches>
153
+ <td-metal-swatches
154
+ [value]="metal"
155
+ (valueChange)="onMetalChange($event)"
156
+ [options]="metalOptions"
157
+ [variant]="buttonVariant"
158
+ ></td-metal-swatches>
159
+ <td-stone-swatches
160
+ [value]="stone"
161
+ (valueChange)="onStoneChange($event)"
162
+ [options]="stoneOptions"
163
+ [variant]="buttonVariant"
164
+ ></td-stone-swatches>
165
+ </ng-template>
166
+ </div>
167
+ </div>
168
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["\n :host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n .td-customizer-card {\n display: flex;\n flex-direction: column;\n gap: 16px;\n background: #ffffff;\n border-radius: 16px;\n border: 1px solid #e2e8f0;\n padding: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);\n }\n .td-customizer-viewport {\n position: relative;\n width: 100%;\n border-radius: 12px;\n overflow: hidden;\n background: #f8fafc;\n }\n .td-customizer-controls {\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n"] }]
169
+ }], propDecorators: { src: [{
170
+ type: Input
171
+ }], source: [{
172
+ type: Input
173
+ }], metal: [{
174
+ type: Input
175
+ }], metalChange: [{
176
+ type: Output
177
+ }], stone: [{
178
+ type: Input
179
+ }], stoneChange: [{
180
+ type: Output
181
+ }], height: [{
182
+ type: Input
183
+ }], autoRotate: [{
184
+ type: Input
185
+ }], quality: [{
186
+ type: Input
187
+ }], controlsVariant: [{
188
+ type: Input
189
+ }], metalOptions: [{
190
+ type: Input
191
+ }], stoneOptions: [{
192
+ type: Input
193
+ }], loaded: [{
194
+ type: Output
195
+ }], partSelected: [{
196
+ type: Output
197
+ }] } });
198
+ //# sourceMappingURL=jewelry-customizer.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jewelry-customizer.component.js","sourceRoot":"","sources":["../../src/swatches/jewelry-customizer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,EACL,MAAM,EACN,YAAY,EACZ,uBAAuB,GACxB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EACL,uBAAuB,EACvB,uBAAuB,GAQxB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AACzF,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;;;AAEzF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BzB,CAAA;AA8DD,MAAM,OAAO,0BAA0B;IA5DvC;QA+DW,UAAK,GAAmB,iBAAiB,CAAA;QACxC,gBAAW,GAAG,IAAI,YAAY,EAAU,CAAA;QAEzC,UAAK,GAAmB,WAAW,CAAA;QAClC,gBAAW,GAAG,IAAI,YAAY,EAAU,CAAA;QAEzC,WAAM,GAAoB,GAAG,CAAA;QAC7B,eAAU,GAAG,IAAI,CAAA;QACjB,YAAO,GAA8B,MAAM,CAAA;QAC3C,oBAAe,GAAyC,OAAO,CAAA;QAE/D,iBAAY,GAAkB,uBAAuB,CAAA;QACrD,iBAAY,GAAkB,uBAAuB,CAAA;QAEpD,WAAM,GAAG,IAAI,YAAY,EAAc,CAAA;QACvC,iBAAY,GAAG,IAAI,YAAY,EAAsC,CAAA;KAmBhF;IAjBC,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,eAAe,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;IAC3D,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAA;IAC3E,CAAC;IAED,aAAa,CAAC,GAAW;QACvB,IAAI,CAAC,KAAK,GAAG,GAAG,CAAA;QAChB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAED,aAAa,CAAC,GAAW;QACvB,IAAI,CAAC,KAAK,GAAG,GAAG,CAAA;QAChB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;+GApCU,0BAA0B;mGAA1B,0BAA0B,gbAjD3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CT,svBApDC,YAAY,mIACZ,eAAe,gWACf,sBAAsB,0JACtB,oBAAoB,6HACpB,sBAAsB,0JACtB,oBAAoB;;4FAmDX,0BAA0B;kBA5DtC,SAAS;+BACE,uBAAuB,cACrB,IAAI,WACP;wBACP,YAAY;wBACZ,eAAe;wBACf,sBAAsB;wBACtB,oBAAoB;wBACpB,sBAAsB;wBACtB,oBAAoB;qBACrB,YACS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CT,mBAEgB,uBAAuB,CAAC,MAAM;8BAGtC,GAAG;sBAAX,KAAK;gBACG,MAAM;sBAAd,KAAK;gBACG,KAAK;sBAAb,KAAK;gBACI,WAAW;sBAApB,MAAM;gBAEE,KAAK;sBAAb,KAAK;gBACI,WAAW;sBAApB,MAAM;gBAEE,MAAM;sBAAd,KAAK;gBACG,UAAU;sBAAlB,KAAK;gBACG,OAAO;sBAAf,KAAK;gBACG,eAAe;sBAAvB,KAAK;gBAEG,YAAY;sBAApB,KAAK;gBACG,YAAY;sBAApB,KAAK;gBAEI,MAAM;sBAAf,MAAM;gBACG,YAAY;sBAArB,MAAM"}
@@ -0,0 +1,28 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { type MetalPreset, type MetalColorProp } from '@thinkersteps_labs/3d-viewer-core';
3
+ import * as i0 from "@angular/core";
4
+ export declare class MetalSwatchesComponent {
5
+ value?: MetalColorProp;
6
+ valueChange: EventEmitter<string>;
7
+ options: MetalPreset[];
8
+ category: 'all' | 'gold' | 'platinum-silver' | 'alternative';
9
+ variant: 'pills' | 'dots';
10
+ showLabel: boolean;
11
+ get visibleOptions(): MetalPreset[];
12
+ get activePreset(): MetalPreset | undefined;
13
+ isSelected(m: MetalPreset): boolean;
14
+ selectMetal(m: MetalPreset): void;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<MetalSwatchesComponent, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<MetalSwatchesComponent, "td-metal-swatches", never, { "value": { "alias": "value"; "required": false; }; "options": { "alias": "options"; "required": false; }; "category": { "alias": "category"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "showLabel": { "alias": "showLabel"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
17
+ }
18
+ export declare class MetalSelectComponent {
19
+ value?: MetalColorProp;
20
+ valueChange: EventEmitter<string>;
21
+ options: MetalPreset[];
22
+ label: string;
23
+ get activeValue(): string;
24
+ onSelectChange(event: Event): void;
25
+ static ɵfac: i0.ɵɵFactoryDeclaration<MetalSelectComponent, never>;
26
+ static ɵcmp: i0.ɵɵComponentDeclaration<MetalSelectComponent, "td-metal-select", never, { "value": { "alias": "value"; "required": false; }; "options": { "alias": "options"; "required": false; }; "label": { "alias": "label"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
27
+ }
28
+ //# sourceMappingURL=metal-swatches.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metal-swatches.component.d.ts","sourceRoot":"","sources":["../../src/swatches/metal-swatches.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EAEb,MAAM,eAAe,CAAA;AAEtB,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,mCAAmC,CAAA;;AAyH1C,qBAgCa,sBAAsB;IACxB,KAAK,CAAC,EAAE,cAAc,CAAA;IACrB,WAAW,uBAA6B;IAEzC,OAAO,EAAE,WAAW,EAAE,CAA0B;IAChD,QAAQ,EAAE,KAAK,GAAG,MAAM,GAAG,iBAAiB,GAAG,aAAa,CAAQ;IACpE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAU;IACnC,SAAS,UAAO;IAEzB,IAAI,cAAc,IAAI,WAAW,EAAE,CAGlC;IAED,IAAI,YAAY,IAAI,WAAW,GAAG,SAAS,CAE1C;IAED,UAAU,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO;IAMnC,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI;yCAxBtB,sBAAsB;2CAAtB,sBAAsB;CA4BlC;AAED,qBAiBa,oBAAoB;IACtB,KAAK,CAAC,EAAE,cAAc,CAAA;IACrB,WAAW,uBAA6B;IACzC,OAAO,EAAE,WAAW,EAAE,CAA0B;IAChD,KAAK,SAAiB;IAE/B,IAAI,WAAW,IAAI,MAAM,CAGxB;IAED,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;yCAXvB,oBAAoB;2CAApB,oBAAoB;CAgBhC"}