@thefittingroom/shop-ui 3.0.0-alpha-4 → 3.0.0-alpha-6
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/dist/esm/components/SizeRec.d.ts +1 -1
- package/dist/esm/components/Vto.d.ts +2 -0
- package/dist/esm/components/slider.d.ts +1 -1
- package/dist/esm/index.js +85 -18
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +3 -3
- package/dist/esm/tfr-size-rec.d.ts +1 -1
- package/dist/esm/tfr.d.ts +1 -1
- package/package.json +1 -1
|
@@ -38,7 +38,7 @@ export declare class SizeRecComponent {
|
|
|
38
38
|
private tfrToggleClosedElements;
|
|
39
39
|
private isCollapsed;
|
|
40
40
|
private redraw;
|
|
41
|
-
constructor(sizeRecMainDivId: string, onSignInClick: () => void, onSignOutClick: () => void, onFitInfoClick: () => void, onTryOnClick: (styleId: number, sizeId: number) => void);
|
|
41
|
+
constructor(sizeRecMainDivId: string, onSignInClick: () => void, onSignOutClick: () => void, onFitInfoClick: () => void, onTryOnClick: (styleId: number, sizeId: number, shouldDisplay: boolean) => Promise<void>);
|
|
42
42
|
get sku(): string;
|
|
43
43
|
setSku(sku: string): void;
|
|
44
44
|
get styleId(): number;
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* thefittingroom v3.0.0-alpha-
|
|
2
|
+
* thefittingroom v3.0.0-alpha-6 (2025-04-18T16:48:31.249Z)
|
|
3
3
|
* Copyright 2022-present, TheFittingRoom, Inc. All rights reserved.
|
|
4
4
|
*/
|
|
5
5
|
function loadImageRecursive(imageURL, imageURLs) {
|
|
@@ -23,13 +23,13 @@ const InitImageSlider = (sliderID, onChange) => {
|
|
|
23
23
|
throw new Error(`Slider with id ${sliderID} not found`);
|
|
24
24
|
}
|
|
25
25
|
return {
|
|
26
|
-
Load(imageURLs) {
|
|
26
|
+
Load(imageURLs, initialValue) {
|
|
27
27
|
if (!Array.isArray(imageURLs) || !imageURLs.length) {
|
|
28
28
|
console.debug('slider has no images to load');
|
|
29
29
|
return new Error('slider has no images to load');
|
|
30
30
|
}
|
|
31
31
|
loadImages(imageURLs);
|
|
32
|
-
const defaultScrollValue = 0;
|
|
32
|
+
const defaultScrollValue = initialValue !== undefined ? initialValue : 0;
|
|
33
33
|
slider.value = defaultScrollValue.toString();
|
|
34
34
|
slider.max = (imageURLs.length - 1).toString();
|
|
35
35
|
const handleSliderChange = () => {
|
|
@@ -26591,6 +26591,8 @@ class VtoComponent {
|
|
|
26591
26591
|
constructor(vtoMainDivId) {
|
|
26592
26592
|
this.vtoMainDivId = vtoMainDivId;
|
|
26593
26593
|
this.isInit = false;
|
|
26594
|
+
this.currentSliderValue = 0;
|
|
26595
|
+
this.slider = null;
|
|
26594
26596
|
}
|
|
26595
26597
|
init() {
|
|
26596
26598
|
if (this.isInit)
|
|
@@ -26604,21 +26606,34 @@ class VtoComponent {
|
|
|
26604
26606
|
<input type="range" id="tfr-slider" />
|
|
26605
26607
|
</div>
|
|
26606
26608
|
`;
|
|
26607
|
-
this.isInit = true;
|
|
26608
|
-
}
|
|
26609
|
-
onNewFramesReady(frames) {
|
|
26610
26609
|
const tryOnImage = document.getElementById('tfr-tryon-image');
|
|
26611
26610
|
const onChange = (slider, imageUrl) => {
|
|
26612
26611
|
console.debug('slider change', slider, imageUrl);
|
|
26613
26612
|
tryOnImage.src = imageUrl;
|
|
26613
|
+
this.currentSliderValue = parseInt(slider.value);
|
|
26614
26614
|
};
|
|
26615
|
-
|
|
26615
|
+
this.slider = InitImageSlider('tfr-slider', onChange);
|
|
26616
|
+
this.isInit = true;
|
|
26617
|
+
}
|
|
26618
|
+
onNewFramesReady(frames) {
|
|
26619
|
+
if (!this.isInit) {
|
|
26620
|
+
this.init();
|
|
26621
|
+
}
|
|
26616
26622
|
if (Array.isArray(frames) && frames.length > 0) {
|
|
26617
|
-
|
|
26623
|
+
// Ensure the current slider value is within bounds of the new frames array
|
|
26624
|
+
const boundedValue = Math.min(this.currentSliderValue, frames.length - 1);
|
|
26625
|
+
const e = this.slider.Load(frames, boundedValue);
|
|
26618
26626
|
if (e instanceof Error) {
|
|
26619
26627
|
console.error(e);
|
|
26620
26628
|
return;
|
|
26621
26629
|
}
|
|
26630
|
+
// Restore previous slider position if it's within bounds
|
|
26631
|
+
const sliderElement = document.getElementById('tfr-slider');
|
|
26632
|
+
if (sliderElement && this.currentSliderValue < frames.length) {
|
|
26633
|
+
sliderElement.value = this.currentSliderValue.toString();
|
|
26634
|
+
const tryOnImage = document.getElementById('tfr-tryon-image');
|
|
26635
|
+
tryOnImage.src = frames[this.currentSliderValue];
|
|
26636
|
+
}
|
|
26622
26637
|
}
|
|
26623
26638
|
}
|
|
26624
26639
|
}
|
|
@@ -26697,7 +26712,7 @@ n(css$6,{});
|
|
|
26697
26712
|
var css$5 = "@media screen and (max-width:702px){.tfr-modal-title-logo-container{display:flex;flex-direction:column}}@media screen and (min-width:600px){.tfr-modal-content-container{border-radius:10px;height:auto;margin:auto;width:100%}}@media screen and (max-width:599px){#tfr-size-recommendations{width:calc(100vw - 30px)!important}.tfr-mobile-small-text{font-size:12px}.tfr-mobile-hidden{display:none}.tfr-modal-content{overflow:hidden}.tfr-modal-content-container{max-height:none;max-width:100vw;min-height:100vh;min-width:100vw}.trf-logo-title{margin-bottom:10px}.tfr-modal-content-flex{overflow:auto}}@media screen and (max-width:500px){.tfr-fieldset{width:90%}.tfr-how-it-works-item{flex-direction:column}.tfr-try-on-content{margin-left:0;margin-top:20px}}@media screen and (max-height:800px){.tfr-video-responsive{height:280px!important}}";
|
|
26698
26713
|
n(css$5,{});
|
|
26699
26714
|
|
|
26700
|
-
var css$4 = "#tfr-size-recommendations{align-items:center;background-color:var(--tfr-main-bg-color);border:var(--tfr-main-border-width) solid var(--tfr-main-border-color);border-radius:var(--tfr-main-border-radius);color:var(--tfr-dark);display:flex;flex-direction:column;font-family:var(--tfr-main-font);justify-content:center;padding:var(--tfr-main-v-padding) var(--tfr-main-h-padding);width:var(--tfr-main-width)}#tfr-size-recommendations-container{align-items:center;display:none;flex-direction:column;justify-content:center;position:relative;width:100%}#tfr-size-rec-select-container{align-items:center;display:none;flex-direction:column;font-size:13px;width:100%}#tfr-size-rec-title{align-items:center;display:flex;font-family:var(--tfr-title-font);margin-bottom:8px}#tfr-size-rec-title-toggle{color:var(--tfr-grey);cursor:pointer;position:absolute;right:0;top:0;transition:all .3s ease}.tfr-chevron-up{transform:rotate(180deg) scaleY(.6)}.tfr-chevron-down{transform:rotate(0deg) scaleY(.6)}#tfr-info-icon{cursor:pointer}#tfr-size-rec-subtitle{border-bottom:2px solid #000;font-size:18px;font-weight:700;text-align:center;width:100%}#tfr-size-rec-title{font-size:14px}#tfr-size-rec-table{display:flex;flex-direction:column;font-size:12px;padding:0 10px;width:100%}.tfr-size-rec-table-row:first-of-type{border-top-width:0}.tfr-size-rec-table-row{align-items:center;border-top:var(--tfr-main-border-width) solid var(--tfr-main-border-color);display:flex;font-family:var(--tfr-row-font);justify-content:center;min-height:40px}.tfr-size-rec-table-cell-left,.tfr-size-rec-table-cell-right{flex:1 1 0px}.tfr-size-rec-table-cell-left{flex-grow:1;padding-left:8px;text-align:right}.tfr-size-rec-table-cell-right{
|
|
26715
|
+
var css$4 = "#tfr-size-recommendations{align-items:center;background-color:var(--tfr-main-bg-color);border:var(--tfr-main-border-width) solid var(--tfr-main-border-color);border-radius:var(--tfr-main-border-radius);color:var(--tfr-dark);display:flex;flex-direction:column;font-family:var(--tfr-main-font);justify-content:center;padding:var(--tfr-main-v-padding) var(--tfr-main-h-padding);width:var(--tfr-main-width)}#tfr-size-recommendations-container{align-items:center;display:none;flex-direction:column;justify-content:center;position:relative;width:100%}#tfr-size-rec-select-container{align-items:center;display:none;flex-direction:column;font-size:13px;width:100%}#tfr-size-rec-title{align-items:center;display:flex;font-family:var(--tfr-title-font);margin-bottom:8px}#tfr-size-rec-title-toggle{color:var(--tfr-grey);cursor:pointer;position:absolute;right:0;top:0;transition:all .3s ease}.tfr-chevron-up{transform:rotate(180deg) scaleY(.6)}.tfr-chevron-down{transform:rotate(0deg) scaleY(.6)}#tfr-info-icon{cursor:pointer}#tfr-size-rec-subtitle{border-bottom:2px solid #000;font-size:18px;font-weight:700;text-align:center;width:100%}#tfr-size-rec-title{font-size:14px}#tfr-size-rec-table{display:flex;flex-direction:column;font-size:12px;padding:0 10px;width:100%}.tfr-size-rec-table-row:first-of-type{border-top-width:0}.tfr-size-rec-table-row{align-items:center;border-top:var(--tfr-main-border-width) solid var(--tfr-main-border-color);display:flex;font-family:var(--tfr-row-font);justify-content:center;min-height:40px}.tfr-size-rec-table-cell-left,.tfr-size-rec-table-cell-right{flex:1 1 0px}.tfr-size-rec-table-cell-left{flex-grow:1;padding-left:8px;padding-right:8px;text-align:right}.tfr-size-rec-table-cell-right{flex-grow:1;padding-left:8px;padding-right:8px;text-align:left}.tfr-size-rec-table-cell-right.perfect{color:var(--tfr-brand-color)}#tfr-size-rec-size{display:inline-block}#tfr-size-rec-size>.tfr-size-rec-login-cta{font-weight:500;margin-left:10px}.tfr-size-rec-login-cta,.tfr-size-rec-table-cell-right{font-size:12px}.tfr-size-rec-login-cta{color:var(--tfr-muted);display:flex;width:150px}#tfr-size-rec-action-login,#tfr-size-rec-action-logout{display:none;font-family:var(--tfr-cta-font)}#tfr-size-rec-action{cursor:pointer;font-size:16px;text-decoration:underline}#tfr-size-rec-select{background-color:var(--tfr-size-selector-bg-color);border-color:var(--tfr-size-selector-border-color);border-radius:var(--tfr-size-selector-button-radius);border-style:solid;border-width:var(--tfr-size-selector-border-width);box-shadow:var(--tfr-size-selector-button-shadow);color:var(--tfr-size-selector-text-color);display:none;font-size:var(--tfr-size-selector-font-size);font-weight:var(--tfr-size-selector-font-weight);margin-bottom:20px;margin-top:10px}#tfr-size-rec-select,.tfr-size-rec-select-button{align-items:center;height:var(--tfr-size-selector-button-height);justify-content:center}.tfr-size-rec-select-button{cursor:pointer;display:flex;transition:all .15s ease-in;width:80px}.tfr-size-rec-select-button:hover:not(.active):not(.tfr-disabled){background-color:var(--tfr-size-selector-bg-color-hover);opacity:.7}.tfr-size-rec-select-button.active{background-color:var(--tfr-size-selector-bg-color-active);border-color:var(--tfr-size-selector-button-active-border-color);border-style:solid;border-width:var(--tfr-size-selector-button-active-border-width);height:var(--tfr-size-selector-button-active-height)}.tfr-size-rec-select-button.active,.tfr-size-rec-select-button:first-of-type{border-bottom-left-radius:var(--tfr-size-selector-button-radius);border-top-left-radius:var(--tfr-size-selector-button-radius)}.tfr-size-rec-select-button.active,.tfr-size-rec-select-button:last-of-type{border-bottom-right-radius:var(--tfr-size-selector-button-radius);border-top-right-radius:var(--tfr-size-selector-button-radius)}.tfr-powered-by{align-items:center;display:flex;font-size:10px;margin-top:10px}.tfr-powered-by-logo{margin:0 4px}.tfr-powered-by-logo,.tfr-powered-by-logo img,.tfr-powered-by-logo svg{height:24px;width:12px}.tfr-powered-by-text-bold{font-weight:700}#tfr-size-recommendation-error{color:#8d0000;display:none}#tfr-sign-in-nav{margin-bottom:80px}.tfr-disabled{cursor:default}#tfr-login-to-view{cursor:pointer}.tfr-try-on-button{align-items:center;background-color:var(--tfr-size-selector-bg-color-active);border-color:var(--tfr-size-selector-border-color);border-radius:var(--tfr-size-selector-button-radius);border-style:solid;border-width:var(--tfr-size-selector-border-width);box-shadow:var(--tfr-size-selector-button-shadow);color:var(--tfr-size-selector-text-color);cursor:pointer;display:flex;font-size:var(--tfr-size-selector-font-size);font-weight:var(--tfr-size-selector-font-weight);height:var(--tfr-size-selector-button-height);justify-content:center;margin-bottom:10px;margin-top:20px;max-width:200px;position:relative;transition:all .15s ease-in;width:100%}.tfr-try-on-button.loading,.tfr-try-on-button:disabled{cursor:not-allowed;opacity:.7}.tfr-try-on-button.loading:after{animation:spin 1s linear infinite;border:2px solid var(--tfr-size-selector-text-color);border-radius:50%;border-top:2px solid transparent;content:\"\";height:16px;margin-left:8px;position:absolute;width:16px}@keyframes spin{to{transform:rotate(1turn)}}";
|
|
26701
26716
|
n(css$4,{});
|
|
26702
26717
|
|
|
26703
26718
|
var css$3 = ".tfr-mt-10{margin-top:10px}.tfr-mt-20{margin-top:20px}.tfr-mt-15{margin-top:15px}.tfr-mt-30{margin-top:30px}.mt-40{margin-top:40px}.tfr-mb-40{margin-bottom:40px}.tfr-mb-20{margin-bottom:20px}.tfr-mr-10{margin-right:10px}.tfr-mr-15{margin-right:15px}.tfr-mt-50{margin-top:50px}.tfr-mt-60{margin-top:60px}.tfr-mb-60{margin-bottom:60px}.tfr-mr-20{margin-right:20px}.tfr-mt-15-p{margin-top:15%}.tfr-mb-13-p{margin-bottom:13%}.tfr-m-h-auto{margin-left:auto;margin-right:auto}.tfr-pt-20{padding-top:20px}.tfr-pb-50{padding-bottom:50px}.tfr-p-20{padding:20px 10px}.tfr-pr-20{padding-right:20px}.tfr-pl-20{padding-left:20px}.tfr-pb-7-p{padding-bottom:7%}";
|
|
@@ -27501,6 +27516,9 @@ class SizeRecComponent {
|
|
|
27501
27516
|
this.isCollapsed = false;
|
|
27502
27517
|
this.tfrSizeRecTitleToggle.classList.add('tfr-chevron-up');
|
|
27503
27518
|
this.tfrSizeRecTitleToggle.classList.remove('tfr-chevron-down');
|
|
27519
|
+
// Ensure the container is visible
|
|
27520
|
+
this.tfrSizeRecSelectContainer.style.display = 'flex';
|
|
27521
|
+
this.tfrSizeRecSelectContainer.style.opacity = '1';
|
|
27504
27522
|
}
|
|
27505
27523
|
else {
|
|
27506
27524
|
this.tfrSizeHowItFits.style.opacity = '0.4';
|
|
@@ -27577,6 +27595,48 @@ class SizeRecComponent {
|
|
|
27577
27595
|
this.tfrSizeRecTitleToggle.addEventListener('click', this.toggletSizeRecSelectContainer.bind(this));
|
|
27578
27596
|
this.tfrInfoIcon.addEventListener('click', this.onFitInfoClick);
|
|
27579
27597
|
this.tfrLoginToView.addEventListener('click', this.onSignInClick);
|
|
27598
|
+
const tryOnButton = document.getElementById('tfr-try-on-button');
|
|
27599
|
+
if (!tryOnButton)
|
|
27600
|
+
return;
|
|
27601
|
+
tryOnButton.addEventListener('click', async () => {
|
|
27602
|
+
// Prevent multiple clicks while loading
|
|
27603
|
+
if (tryOnButton.classList.contains('loading')) {
|
|
27604
|
+
return;
|
|
27605
|
+
}
|
|
27606
|
+
const activeButton = document.querySelector('.tfr-size-rec-select-button.active');
|
|
27607
|
+
if (!activeButton)
|
|
27608
|
+
return;
|
|
27609
|
+
const selectedSizeId = Number(activeButton.getAttribute('data-size-id'));
|
|
27610
|
+
if (Number.isNaN(selectedSizeId))
|
|
27611
|
+
return;
|
|
27612
|
+
// Set loading state
|
|
27613
|
+
tryOnButton.classList.add('loading');
|
|
27614
|
+
const originalText = tryOnButton.textContent;
|
|
27615
|
+
tryOnButton.textContent = ' ';
|
|
27616
|
+
tryOnButton.setAttribute('disabled', 'true');
|
|
27617
|
+
try {
|
|
27618
|
+
// Get all size buttons
|
|
27619
|
+
const allSizeButtons = Array.from(document.querySelectorAll('.tfr-size-rec-select-button'));
|
|
27620
|
+
// Request frames for all sizes concurrently
|
|
27621
|
+
await Promise.all(allSizeButtons.map(async (button) => {
|
|
27622
|
+
const sizeId = Number(button.getAttribute('data-size-id'));
|
|
27623
|
+
if (Number.isNaN(sizeId))
|
|
27624
|
+
return;
|
|
27625
|
+
// Only display the active size, others are just requested
|
|
27626
|
+
const shouldDisplay = button === activeButton;
|
|
27627
|
+
await this.onTryOnClick(this.styleId, sizeId, shouldDisplay);
|
|
27628
|
+
}));
|
|
27629
|
+
}
|
|
27630
|
+
catch (error) {
|
|
27631
|
+
console.error('Error during try-on:', error);
|
|
27632
|
+
}
|
|
27633
|
+
finally {
|
|
27634
|
+
// Reset loading state
|
|
27635
|
+
tryOnButton.classList.remove('loading');
|
|
27636
|
+
tryOnButton.textContent = originalText;
|
|
27637
|
+
tryOnButton.removeAttribute('disabled');
|
|
27638
|
+
}
|
|
27639
|
+
});
|
|
27580
27640
|
}
|
|
27581
27641
|
onSizeRecSelectClick(e) {
|
|
27582
27642
|
const target = e.target;
|
|
@@ -27593,7 +27653,7 @@ class SizeRecComponent {
|
|
|
27593
27653
|
const selectedSizeId = Number(target.getAttribute('data-size-id'));
|
|
27594
27654
|
if (Number.isNaN(selectedSizeId))
|
|
27595
27655
|
return;
|
|
27596
|
-
this.onTryOnClick(this.styleId, selectedSizeId);
|
|
27656
|
+
this.onTryOnClick(this.styleId, selectedSizeId, true);
|
|
27597
27657
|
}
|
|
27598
27658
|
renderSizeRec(recommended, sizes) {
|
|
27599
27659
|
this.tfrSizeRecSize.innerHTML = ` ${recommended}`;
|
|
@@ -27601,8 +27661,6 @@ class SizeRecComponent {
|
|
|
27601
27661
|
this.redraw = (index) => this.renderSizeRecTable(sizes, index);
|
|
27602
27662
|
this.redraw(selectedSizeIndex);
|
|
27603
27663
|
this.renderSizeRecSelect(sizes, selectedSizeIndex);
|
|
27604
|
-
const selectedSizeId = sizes[selectedSizeIndex].size_id;
|
|
27605
|
-
this.onTryOnClick(this.styleId, selectedSizeId);
|
|
27606
27664
|
}
|
|
27607
27665
|
renderSizeRecTable(sizes, index) {
|
|
27608
27666
|
const { locations } = sizes[index];
|
|
@@ -27724,6 +27782,8 @@ class SizeRecComponent {
|
|
|
27724
27782
|
</div>
|
|
27725
27783
|
|
|
27726
27784
|
<div id="tfr-size-rec-table"></div>
|
|
27785
|
+
|
|
27786
|
+
<div id="tfr-try-on-button" class="tfr-try-on-button">Try On</div>
|
|
27727
27787
|
</div>
|
|
27728
27788
|
</div>
|
|
27729
27789
|
|
|
@@ -27955,10 +28015,8 @@ class FittingRoom {
|
|
|
27955
28015
|
this.tfrModal = new TfrModal(modalDivId, this.signIn.bind(this), this.forgotPassword.bind(this), this.submitTel.bind(this));
|
|
27956
28016
|
this.tfrShop = initShop(Number(this.shopId), env);
|
|
27957
28017
|
this.tfrSizeRec = new TfrSizeRec(sizeRecMainDivId, cssVariables, this.tfrShop, this.onSignInClick.bind(this), this.signOut.bind(this), this.onFitInfoClick.bind(this), this.onTryOnClick.bind(this));
|
|
27958
|
-
|
|
28018
|
+
if (vtoMainDivId)
|
|
27959
28019
|
this.vtoComponent = new VtoComponent(vtoMainDivId);
|
|
27960
|
-
}
|
|
27961
|
-
catch (_a) { }
|
|
27962
28020
|
}
|
|
27963
28021
|
get shop() {
|
|
27964
28022
|
return this.tfrShop;
|
|
@@ -28057,10 +28115,19 @@ class FittingRoom {
|
|
|
28057
28115
|
onFitInfoClick() {
|
|
28058
28116
|
this.tfrModal.toFitInfo();
|
|
28059
28117
|
}
|
|
28060
|
-
async onTryOnClick(styleId, sizeId) {
|
|
28118
|
+
async onTryOnClick(styleId, sizeId, shouldDisplay = true) {
|
|
28119
|
+
if (!this.vtoComponent)
|
|
28120
|
+
return console.error('VtoComponent is not initialized');
|
|
28061
28121
|
const frames = await this.shop.tryOn(styleId, sizeId);
|
|
28062
|
-
|
|
28063
|
-
|
|
28122
|
+
if (shouldDisplay) {
|
|
28123
|
+
try {
|
|
28124
|
+
this.vtoComponent.init();
|
|
28125
|
+
this.vtoComponent.onNewFramesReady(frames);
|
|
28126
|
+
}
|
|
28127
|
+
catch (e) {
|
|
28128
|
+
console.error(e);
|
|
28129
|
+
}
|
|
28130
|
+
}
|
|
28064
28131
|
}
|
|
28065
28132
|
onUserProfileChange(userProfile) {
|
|
28066
28133
|
var _a, _b, _c, _d;
|