vviinn-widgets 2.221.0 → 2.223.0
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/cjs/{index-sL3iGA57.js → index-DZw3p4dq.js} +1 -1
- package/dist/cjs/{search.store-C-fS-eJR.js → search.store-Bh2_GSpU.js} +2 -1
- package/dist/cjs/vviinn-button_6.cjs.entry.js +1 -1
- package/dist/cjs/vviinn-camera_12.cjs.entry.js +259 -107
- package/dist/cjs/vviinn-carousel_10.cjs.entry.js +2 -53
- package/dist/cjs/vviinn-shop-the-look.cjs.entry.js +1 -1
- package/dist/cjs/vviinn-text-search.cjs.entry.js +1 -1
- package/dist/collection/components/vviinn-cropper/helpers/cropperOcrGate.js +36 -0
- package/dist/collection/components/vviinn-cropper/helpers/hasSelectedOcrFilter.js +4 -0
- package/dist/collection/components/vviinn-cropper/vviinn-cropper.js +108 -38
- package/dist/collection/components/vviinn-filters/vviinn-extended-filters.js +2 -2
- package/dist/collection/components/vviinn-results/vviinn-results.js +78 -3
- package/dist/collection/components/vviinn-suggestions/helpers.js +27 -10
- package/dist/collection/components/vviinn-suggestions/render-helpers.js +42 -15
- package/dist/esm/{index-D5yWioO8.js → index-DQQYIioG.js} +1 -1
- package/dist/esm/{search.store-C8LIDQfX.js → search.store-lTerE9Yh.js} +2 -2
- package/dist/esm/vviinn-button_6.entry.js +1 -1
- package/dist/esm/vviinn-camera_12.entry.js +259 -107
- package/dist/esm/vviinn-carousel_10.entry.js +2 -53
- package/dist/esm/vviinn-shop-the-look.entry.js +1 -1
- package/dist/esm/vviinn-text-search.entry.js +1 -1
- package/dist/storybook/helpers/industryToken.js +6 -8
- package/dist/types/components/vviinn-cropper/helpers/cropperOcrGate.d.ts +19 -0
- package/dist/types/components/vviinn-cropper/helpers/hasSelectedOcrFilter.d.ts +2 -0
- package/dist/types/components/vviinn-cropper/vviinn-cropper.d.ts +14 -0
- package/dist/types/components/vviinn-filters/vviinn-extended-filters.d.ts +51 -0
- package/dist/types/components/vviinn-results/vviinn-results.d.ts +1 -1
- package/dist/types/components/vviinn-suggestions/helpers.d.ts +1 -0
- package/dist/vviinn-widgets/p-08d39cc9.entry.js +1 -0
- package/dist/vviinn-widgets/{p-07211a51.entry.js → p-1e2f9b9f.entry.js} +1 -1
- package/dist/vviinn-widgets/{p-95423f25.entry.js → p-3daed25b.entry.js} +1 -1
- package/dist/vviinn-widgets/{p-DTASrq1W.js → p-CJAxBbhA.js} +1 -1
- package/dist/vviinn-widgets/{p-BpHXy3Gg.js → p-DhCqK4d8.js} +1 -1
- package/dist/vviinn-widgets/{p-f46ad1fd.entry.js → p-eb579723.entry.js} +1 -1
- package/{www/build/p-f48452fd.entry.js → dist/vviinn-widgets/p-f9f4e909.entry.js} +1 -1
- package/dist/vviinn-widgets/vviinn-widgets.esm.js +1 -1
- package/package.json +1 -1
- package/www/build/p-08d39cc9.entry.js +1 -0
- package/www/build/{p-07211a51.entry.js → p-1e2f9b9f.entry.js} +1 -1
- package/www/build/{p-95423f25.entry.js → p-3daed25b.entry.js} +1 -1
- package/www/build/{p-2d5777fa.js → p-4f556dc3.js} +1 -1
- package/www/build/{p-DTASrq1W.js → p-CJAxBbhA.js} +1 -1
- package/www/build/{p-BpHXy3Gg.js → p-DhCqK4d8.js} +1 -1
- package/www/build/{p-f46ad1fd.entry.js → p-eb579723.entry.js} +1 -1
- package/{dist/vviinn-widgets/p-f48452fd.entry.js → www/build/p-f9f4e909.entry.js} +1 -1
- package/www/build/vviinn-widgets.esm.js +1 -1
- package/www/index.html +1 -1
- package/dist/vviinn-widgets/p-e7b0a5b9.entry.js +0 -1
- package/www/build/p-e7b0a5b9.entry.js +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var index = require('./index-BU8FMTXn.js');
|
|
4
|
-
var search_store = require('./search.store-
|
|
4
|
+
var search_store = require('./search.store-Bh2_GSpU.js');
|
|
5
5
|
var Rectangle = require('./Rectangle-7dF6_xf3.js');
|
|
6
6
|
var store = require('./store-jPZ4ROqV.js');
|
|
7
|
-
var index$1 = require('./index-
|
|
7
|
+
var index$1 = require('./index-DZw3p4dq.js');
|
|
8
8
|
var constants = require('./constants-BlwqMvns.js');
|
|
9
9
|
var index$2 = require('./index-CP1QUrJT.js');
|
|
10
10
|
var index$3 = require('./index-BF9aENF8.js');
|
|
@@ -656,57 +656,6 @@ const filterOptionsBySearch = (filterOptions, searchTerm) => {
|
|
|
656
656
|
|
|
657
657
|
const vviinnFiltersCss$2 = ":host{--font-family-base:Inter, system-ui, sans-serif;--font-family-mono:monospace;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--font-size-display:32px;--font-size-title:24px;--font-size-headline:18px;--font-size-label-large:16px;--font-size-label:14px;--font-size-body-large:16px;--font-size-body:14px;--font-size-caption:12px;--line-height-display:40px;--line-height-title:32px;--line-height-headline:24px;--line-height-label-large:24px;--line-height-label:20px;--line-height-body-large:24px;--line-height-body:20px;--line-height-caption:16px;--letter-spacing-title:0px;--letter-spacing-headline:0px;--letter-spacing-label-large:0px;--letter-spacing-label:0px;--letter-spacing-body-large:0px;--letter-spacing-body:0px;--letter-spacing-caption:0px;--font-weight-400:400;--font-weight-500:500;--font-weight-600:600;--font-weight-700:700;--spacing-none:0px;--spacing-25:2px;--spacing-50:4px;--spacing-75:6px;--spacing-100:8px;--spacing-125:10px;--spacing-150:12px;--spacing-200:16px;--spacing-250:20px;--spacing-300:24px;--spacing-400:32px;--spacing-500:40px;--spacing-600:48px;--border-radius-none:0px;--border-radius-25:2px;--border-radius-50:4px;--border-radius-100:8px;--border-radius-150:12px;--border-radius-200:16px;--border-radius-300:24px;--border-radius-400:32px;--border-radius-full:9999px;--stroke-width-none:0px;--stroke-width-25:1px;--stroke-width-50:2px;--stroke-width-75:3px;--stroke-width-100:4px;--stroke-width-150:6px;--stroke-width-200:8px;--stroke-width-300:12px;--product-card-widget-min-width:135px;--product-card-results-min-width:250px;--image-set-mode-min-width:155px;--source-card-set-mode-max-width:500px;--filter-blur-none:0px;--filter-blur-100:8px;--filter-blur-150:12px;--filter-blur-200:16px;--color-bg-base:#ffffff;--color-bg-inverse:#161616;--color-border-00:#ffffff;--color-border-01:#f4f4f4;--color-border-02:#e0e0e0;--color-border-03:#c6c6c6;--color-border-inverse-00:#161616;--color-border-inverse-01:#393939;--color-field-01:#ffffff;--color-field-02:#f4f4f4;--color-icon-primary:#161616;--color-icon-secondary:#525252;--color-icon-helper:#8d8d8d;--color-icon-on-color:#ffffff;--color-icon-inverse:#ffffff;--color-icon-disabled:#16161640;--color-text-primary:#161616;--color-text-secondary:#707070;--color-text-helper:#8d8d8d;--color-text-placeholder:#a8a8a8;--color-text-on-color:#ffffff;--color-text-inverse:#ffffff;--color-text-disabled:#16161640;--button-bg-color-primary:#000000;--button-bg-color-primary-hover:#161616;--button-bg-color-primary-active:#1e1e1e;--button-bg-color-secondary:#f4f4f4;--button-bg-color-secondary-hover:#e0e0e0;--button-bg-color-secondary-active:#c6c6c6;--button-bg-color-ghost-hover:#f4f4f4;--button-bg-color-ghost-active:#eaeaea;--button-bg-color-frosted:#6f6f6f66;--button-bg-color-frosted-hover:#6f6f6f80;--button-bg-color-frosted-active:#6f6f6f99;--button-bg-color-disabled:#e0e0e0;--button-bg-color-positive:#dcfce7;--surface-bg-color-01:#f4f4f4;--surface-bg-color-01-hover:#eaeaea;--surface-bg-color-01-active:#e0e0e0;--surface-bg-color-02:#ffffff;--surface-bg-color-inverse:#262626;--surface-bg-color-inverse-hover:#303030;--surface-bg-color-inverse-active:#393939;--surface-bg-color-disabled:#e0e0e0;--surface-bg-color-shadow-01:#dddddd;--surface-bg-color-shadow-02:#c6c6c6;--chip-bg-color-primary:#161616;--chip-bg-color-primary-hover:#1e1e1e;--chip-bg-color-primary-active:#262626;--chip-bg-color-subtle:#f4f4f4;--chip-bg-color-subtle-hover:#eaeaea;--chip-bg-color-subtle-active:#e0e0e0;--chip-bg-color-outline-hover:#f4f4f4;--chip-bg-color-outline-active:#eaeaea;--label-bg-color-accent:#ff3944;--sidebar-animation-duration-default:0.5s;--search-modal-animation-duration-default:0.25s;--search-modal-animation-duration-mobile-default:0.35s;}:host{display:block;font-family:var(--font-family, var(--font-family-base));font-style:normal;display:contents;}.filters-modal-list,.sub-filters-wrapper,.main-filters-list,.filters-modal-sub-list,.selected-filters-wrapper{list-style:none;margin:0;padding:0}.main-filters-list{padding:var(--spacing-25);gap:var(--spacing-25);border-radius:8px;background:var(--surface-bg-color-01);display:inline-flex}vviinn-range-filter{width:100%;max-width:500px;padding-bottom:var(--spacing-150)}.filters-search-input-container{position:relative;box-sizing:border-box;width:100%;display:flex;align-items:center}.filters-search-icon{position:absolute;left:var(--spacing-100);color:var(--color-icon-helper);z-index:1;pointer-events:none;display:flex;align-items:center;justify-content:center}.filters-search-input{width:100%;padding:var(--spacing-100) var(--spacing-100) var(--spacing-100)\n var(--spacing-500);border:none;background:var(--color-bg-base);font-family:var(--font-family, var(--font-family-base));font-size:var(--font-size-body);font-weight:var(--font-weight-400);line-height:var(--line-height-body);color:var(--color-text-primary);box-sizing:border-box;outline:none}.filters-search-input::-moz-placeholder{color:var(--color-text-placeholder)}.filters-search-input::placeholder{color:var(--color-text-placeholder)}.filters-modal-main-button,.filters-sub-button,.filters-main-button,.filters-modal-close,.filters-sub-button-selected{font-family:var(--font-family, var(--font-family-base));cursor:pointer;border:none}.filters-sub-button,.filters-main-button{font-size:var(--font-size-body);font-weight:var(--font-weight-400);line-height:var(--line-height-body);letter-spacing:var(--letter-spacing-body);display:flex;justify-content:center;align-items:center;border-radius:6px}.filters-main-button{padding:var(--spacing-100);color:var(--color-text-secondary);background:none;transition:background 0.15s,\n color 0.15s}.filters-main-button.active,.filters-main-button:hover{background:var(--surface-bg-color-02);color:var(--color-text-primary)}.sub-filters-wrapper,.selected-filters-wrapper{gap:var(--spacing-100);display:flex;flex-direction:row;overflow-x:auto;scrollbar-width:thin}.sub-filters-wrapper{align-items:center;gap:var(--spacing-100);margin:16px -2px 0}.sub-filters-wrapper>li{padding:2px}.selected-filters-wrapper{align-items:center;gap:var(--spacing-100);flex-wrap:wrap}.filters-sub-button{color:var(--color-text-primary);background:var(--surface-bg-color-01);padding:var(--spacing-100);gap:var(--spacing-25);height:100%}.filters-sub-button>span,.filters-sub-button-selected>span{display:inline-flex;justify-content:center;align-items:center;gap:var(--spacing-25);white-space:nowrap}.filters-sub-button>span>span,.filters-sub-button-selected>span>span{padding:var(--spacing-25)}.filters-sub-button:hover{background:var(--surface-bg-color-01-hover)}.filters-sub-button:disabled{cursor:not-allowed;background:var(--surface-bg-color-disabled);color:var(--color-text-disabled)}.filters-more-button{display:flex;padding:var(--spacing-100);gap:var(--spacing-50);border-radius:var(--border-radius-100);align-items:flex-start;background-color:var(--button-bg-color-secondary);transition:background-color 0.1s;border:none;cursor:pointer}.filters-more-button:hover{background-color:var(--button-bg-color-secondary-hover)}.filters-modal-wrapper{display:flex;flex-direction:column;background:#ffffff}.filters-modal.button,.filters-modal.modal{display:none;position:fixed;top:0;bottom:0;right:0;left:0;z-index:99999;background-color:rgba(0, 0, 0, 0.5)}.filters-modal.button .filters-modal-wrapper{position:fixed;top:0;bottom:0;right:0;width:420px;z-index:99999;border-radius:var(--border-radius-400) var(--border-radius-none)\n var(--border-radius-none) var(--border-radius-400)}.filters-modal.preview{display:block}.filters-modal.open{display:block}.filters-modal-header{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;color:var(--color-text-primary);text-align:center;border-bottom:1px solid var(--color-border-01)}.filters-modal-header.show-header-content{min-height:64px}.filters-modal-title{margin:0;padding:0;font-size:var(--font-size-headline);font-weight:var(--font-weight-500);line-height:var(--line-height-headline);letter-spacing:var(--letter-spacing-headline)}.filters-modal-no-filters-message{font-size:var(--font-size-caption);color:var(--color-text-secondary);font-weight:var(--font-weight-500);line-height:var(--line-height-caption);letter-spacing:var(--letter-spacing-caption);text-align:center;padding:var(--spacing-300) var(--spacing-200);display:flex;align-items:center;justify-content:center}.filters-modal-main{overflow-y:auto;scrolbar-width:thin}.filters-modal-list{margin:var(--spacing-50) 0 0 var(--spacing-300)}.filters-modal-list>li{padding-right:var(--spacing-300)}.filters-modal:not(.preview-inline) .filters-modal-list>li:not(:last-child) .filters-modal-main-button-wrapper{border-bottom:1px solid var(--color-border-01)}.filters-modal-main-button{position:relative;width:100%;background:none;text-align:left;padding:var(--spacing-200) 0;color:var(--color-text-primary);font-size:var(--font-size-label-large);font-weight:var(--font-weight-500);line-height:var(--line-height-label-large);letter-spacing:var(--letter-spacing-label-large)}.filters-modal-main-button>svg{position:absolute;right:0;top:var(--spacing-200);color:var(--color-icon-helper);transform:rotate(90deg)}.filters-modal-main-button:hover>svg{color:var(--color-icon-primary);transition:color 0.2s}.filters-modal-main-button-wrapper.open .filters-modal-main-button>svg{transform:rotate(-90deg);color:var(--color-icon-primary)}.filters-modal-sub-list{display:none}.filters-modal-main-button-wrapper.open .filters-modal-sub-list{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding-bottom:var(--spacing-150)}.filters-modal-sub-list>li{display:contents}.filters-modal-close{position:absolute;color:#6f6f6f;right:var(--spacing-100);top:var(--spacing-200);cursor:pointer;background:none}.filters-modal-close:hover{color:#000}.filters-modal.preview .filters-modal-close{display:none}.filters-more-modal-button{background:none;border:none;cursor:pointer;display:flex;align-items:center;height:36px;padding:var(--spacing-75);gap:var(--spacing-50);border-radius:var(--border-radius-100);background-color:var(--surface-bg-color-01);transition:background-color 0.1s;font-family:var(--font-family, var(--font-family-base));font-size:var(--font-size-label);color:var(--color-text-primary)}.filters-more-modal-button.custom:not(.clickable){cursor:default}.filters-more-modal-button:hover{background-color:var(--surface-bg-color-01-hover)}.filters-more-modal-button.active{background:var(--surface-bg-color-inverse);color:var(--color-text-inverse)}.filters-more-modal-button.active .filters-option-icon-wrapper{border-color:var(--color-bg-base);background-color:var(--color-bg-base);color:var(--color-icon-primary)}.filters-more-modal-button>span{white-space:nowrap;padding:var(--spacing-25)}.filters-more-modal-button:disabled{cursor:not-allowed;opacity:0.5}.filters-more-modal-button img{box-sizing:border-box;-o-object-fit:cover;object-fit:cover;-o-object-position:center;object-position:center;border-radius:var(--border-radius-full);border:1px solid var(--color-border-01)}.filters-modal-actions{border-top:1px solid var(--color-border-01);padding:var(--spacing-125);z-index:10;border-radius:0px 0px 0px 32px}.filters-modal-apply,.filters-modal-reset{font-family:var(--font-family, var(--font-family-base))}.filters-modal-apply{cursor:pointer;width:100%;border:none;margin-bottom:20px;display:flex;padding:var(--spacing-150);justify-content:center;align-items:center;gap:var(--spacing-50);align-self:stretch;color:var(--color-text-inverse);text-align:center;border-radius:var(--border-radius-150);background:var(--button-bg-color-primary);font-size:var(--font-size-label-large);font-weight:var(--font-weight-500);line-height:var(--line-height-label-large);letter-spacing:var(--letter-spacing-label-large)}.filters-modal-apply:disabled{background:var(--button-bg-color-disabled);color:var(--color-text-disabled)}.filters-modal-reset{background:none;border:none;cursor:pointer;display:block;text-align:center;width:100%;padding:var(--spacing-125) 0;color:var(--color-text-secondary);text-align:center;font-size:var(--font-size-label);font-weight:var(--font-weight-500);line-height:var(--line-height-label);letter-spacing:var(--letter-spacing-label)}.filters-modal-reset:hover{color:var(--color-text-primary)}.selected-filters-wrapper>li .filters-sub-button-selected{border-radius:var(--border-radius-100);background:var(--surface-bg-color-inverse);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:var(--spacing-100)}.selected-filters-wrapper>li.hidden{display:none}.filters-sub-button-selected{display:flex;align-items:center;gap:var(--spacing-25);background:var(--surface-bg-color-inverse);border-radius:var(--border-radius-100);color:var(--color-text-inverse);text-overflow:ellipsis;font-size:var(--font-size-body);font-weight:var(--font-weight-400);line-height:var(--line-height-body);letter-spacing:var(--letter-spacing-body);padding:var(--spacing-100)}.filters-sub-button-color-dot{box-sizing:border-box;width:24px;height:24px;border-radius:var(--border-radius-full);border:var(--stroke-width-50) solid var(--color-border-01)}.selected-filters-wrapper .filters-sub-button-selected{width:24px;height:24px;border:none}.filters-option-icon-wrapper{display:flex;box-sizing:border-box;align-items:center;justify-content:center;border-radius:4px;border:2px solid #e0e0e0;background:#fff;width:20px;height:20px}.filters-modal-main-button-added-options{color:var(--color-text-secondary);text-overflow:ellipsis;padding-right:var(--spacing-100);font-size:var(--font-size-body);font-weight:var(--font-weight-400);line-height:var(--line-height-body);letter-spacing:var(--letter-spacing-body)}.filters-modal-main-button-added-options>span::after{content:\", \"}.filters-modal-main-button-added-options>span:last-child::after{content:\"\"}.filters-modal.preview-inline,.filters-modal.preview-inline .filters-modal-wrapper,.filters-modal.preview-inline .filters-modal-main{overflow:visible}.filters-modal.preview-inline .filters-modal-header,.filters-modal.preview-inline .filters-modal-actions{display:none}.filters-modal.preview-inline .filters-modal-list{margin:0;flex-direction:row;gap:var(--spacing-100);display:flex;flex-wrap:wrap}.filters-modal.preview-inline .extended-filters-row{box-sizing:border-box;padding-right:0;border-radius:var(--border-radius-100);background:var(--surface-bg-color-01)}.filters-modal.preview-inline .filters-modal-main-button{width:100%;display:flex;align-items:center;padding:var(--spacing-75);gap:var(--spacing-25);justify-content:space-between;font-size:var(--font-size-body);font-weight:var(--font-weight-400)}.filters-modal.preview-inline .filters-modal-main-button>svg{position:static}.filters-modal.preview-inline .extended-filters-row{position:relative}.filters-modal.preview-inline .filters-search-container{max-height:225px;width:-moz-max-content;width:max-content;min-width:140px;height:-moz-fit-content;height:fit-content;overflow:hidden;position:absolute;display:flex;flex-direction:column;flex-wrap:nowrap;align-items:stretch;padding:0;top:calc(100% + var(--spacing-75));left:0;right:0;z-index:1000;border-radius:var(--border-radius-150);border:1px solid var(--color-border-01);background-color:var(--color-bg-base);box-shadow:0 4px 8px 0 rgba(0, 0, 0, 0.1);box-sizing:border-box}.filters-modal.preview-inline .filters-search-input-container{position:sticky;top:0;background-color:var(--color-bg-base);padding:var(--spacing-50);border-bottom:1px solid var(--color-border-01);z-index:1}.filters-modal.preview-inline .filters-modal-sub-list{position:static;border:none;background:none;box-shadow:none;padding:var(--spacing-50);margin:0;max-height:165px;width:100%;box-sizing:border-box;display:flex;flex-direction:column;flex-wrap:nowrap;align-items:flex-start;gap:8px;overflow-y:auto;scrollbar-width:thin}.filters-modal.preview-inline .align-right .filters-search-container{left:auto;right:0}.filters-modal.preview-inline .filters-more-modal-button{width:100%;gap:var(--spacing-150);background-color:var(--color-bg-base)}.filters-modal.preview-inline .filters-option-icon-wrapper{margin-left:auto}.filters-modal.preview-inline .filters-more-modal-button:hover{background-color:var(--surface-bg-color-01-hover)}.filters-modal.preview-inline .filters-more-modal-button.active{color:var(--color-text-primary)}.filters-modal.preview-inline .filters-more-modal-button.active .filters-option-icon-wrapper{border-color:var(--color-bg-inverse);background-color:var(--color-bg-inverse);color:var(--color-icon-inverse)}.filters-modal.preview-inline .filters-modal-sub-list:has(vviinn-range-filter){padding:0 var(--spacing-75);width:220px;max-height:unset}.filters-modal.preview-inline vviinn-range-filter{width:100%}@media (max-width: 768px){.sub-filters-wrapper,.selected-filters-wrapper{flex-wrap:unset;overflow-x:auto;scrollbar-width:none;padding-bottom:0}.sub-filters-wrapper,.selected-filters-wrapper{-webkit-overflow-scrolling:touch;scrollbar-width:none;-ms-overflow-style:none}.sub-filters-wrapper::-webkit-scrollbar,.selected-filters-wrapper::-webkit-scrollbar{display:none}:host(.show-in-widget) .selected-filters-container{overflow-x:auto;width:100%}:host(.show-in-widget) .selected-filters-wrapper{padding:0 var(--spacing-300)}.filters-modal.button .filters-modal-wrapper,.filters-modal.modal .filters-modal-wrapper{width:100%;border-radius:24px 24px 0px 0px}.filters-modal.button .filters-modal-wrapper{top:10%}.filters-modal.modal .filters-modal-wrapper{position:fixed;width:100%;height:calc(100% - 64px);bottom:0;transform:translateY(-64px)}.filters-modal.modal .filters-modal-header{font-size:var(--font-size-body-large)}.filters-modal.modal .filters-modal-main{padding-bottom:120px}vviinn-range-filter{max-width:unset}:host(.show-in-widget.primary-filters) vviinn-range-filter{max-width:calc(100% - 48px);transform:translateX(24px)}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}";
|
|
658
658
|
|
|
659
|
-
/**
|
|
660
|
-
* @slot vviinn-extended-filters-title - Text on widget's header.
|
|
661
|
-
* @slot vviinn-extended-filters-apply - Title of Apply Button.
|
|
662
|
-
* @slot vviinn-extended-filters-reset - Title of Reset Button.
|
|
663
|
-
* @slot vviinn-extended-filters-no-filters - Message shown when no filters are available.
|
|
664
|
-
* @slot vviinn-filters-search-icon - Custom icon for the search input.
|
|
665
|
-
* @slot vviinn-range-filter-from-label - Label text for the "From" input field in range filters.
|
|
666
|
-
* @slot vviinn-range-filter-to-label - Label text for the "To" input field in range filters.
|
|
667
|
-
*
|
|
668
|
-
* @part extended-filters-modal - Modal itself.
|
|
669
|
-
* @part extended-filters-modal-wrapper - Wrapper for the modal.
|
|
670
|
-
* @part extended-filters-header - Header of the modal.
|
|
671
|
-
* @part extended-filters-title - Title heading (h2) of the modal.
|
|
672
|
-
* @part extended-filters-modal-close - Close button of the modal.
|
|
673
|
-
* @part extended-filters-no-filters - No filters message container.
|
|
674
|
-
* @part extended-filters-main - Wrapper for the main modal content.
|
|
675
|
-
* @part extended-filters-list - List of filters.
|
|
676
|
-
* @part extended-filters-row - Row of the filters.
|
|
677
|
-
* @part extended-filters-row-wrapper - Wrapper for the row.
|
|
678
|
-
* @part extended-filters-main-button - Main button of the row.
|
|
679
|
-
* @part extended-filters-selected-wrapper - Wrapper for the selected options.
|
|
680
|
-
* @part extended-filters-sub-list - List of sub filters.
|
|
681
|
-
* @part extended-filters-actions - Wrapper for the actions.
|
|
682
|
-
* @part extended-filters-apply - Apply button.
|
|
683
|
-
* @part extended-filters-reset - Reset button.
|
|
684
|
-
*
|
|
685
|
-
* @part filters-search-container - Container wrapping search input and filter list.
|
|
686
|
-
* @part filters-search-input-container - Container for the search input with icon.
|
|
687
|
-
* @part filters-search-icon - Icon wrapper for the search input.
|
|
688
|
-
* @part filters-search-input - Search input field.
|
|
689
|
-
*
|
|
690
|
-
* @part filters-sub-row - Row of the sub filters.
|
|
691
|
-
* @part filters-option-button - Button of the sub filter.
|
|
692
|
-
* @part filters-option-image - Image of the sub filter.
|
|
693
|
-
* @part filters-option-color-dot - Color Dot of the sub filter.
|
|
694
|
-
* @part filters-option-text - Text of the sub filter.
|
|
695
|
-
* @part filters-option-icon-wrapper - Icon Wrapper of the sub filter.
|
|
696
|
-
*
|
|
697
|
-
* @part histogram - Wrapper itself.
|
|
698
|
-
* @part histogram-bar - Bar of the histogram.
|
|
699
|
-
* @part histogram-range-container - Container for the range sliders.
|
|
700
|
-
* @part histogram-sliders-control - Container for the range sliders control.
|
|
701
|
-
* @part histogram-from-slider - Slider for the minimum value.
|
|
702
|
-
* @part histogram-to-slider - Slider for the maximum value.
|
|
703
|
-
* @part histogram-label-wrapper - Wrapper for the labels/inputs.
|
|
704
|
-
* @part histogram-label - Label for the histogram (when showIntervalInputs is false).
|
|
705
|
-
* @part histogram-input-container - Container for the input field (when showIntervalInputs is true).
|
|
706
|
-
* @part histogram-input-label - Label text for the input (From/Till).
|
|
707
|
-
* @part histogram-from-input - Input field for the minimum value.
|
|
708
|
-
* @part histogram-to-input - Input field for the maximum value.
|
|
709
|
-
*/
|
|
710
659
|
const FILTER_OPTIONS_INITIAL_COUNT = 8;
|
|
711
660
|
const FILTER_OPTIONS_STEP_COUNT = 5;
|
|
712
661
|
const VviinnExtendedFilters = class {
|
|
@@ -4,7 +4,7 @@ var index = require('./index-BU8FMTXn.js');
|
|
|
4
4
|
var Rectangle = require('./Rectangle-7dF6_xf3.js');
|
|
5
5
|
var cropperUtils = require('./cropperUtils-DCDOLeBS.js');
|
|
6
6
|
var swiperElement = require('./swiper-element-DjtzojCR.js');
|
|
7
|
-
var search_store = require('./search.store-
|
|
7
|
+
var search_store = require('./search.store-Bh2_GSpU.js');
|
|
8
8
|
var SecondaryActionIcon = require('./SecondaryActionIcon-CuNEBTWD.js');
|
|
9
9
|
var index$1 = require('./index-BF9aENF8.js');
|
|
10
10
|
var store = require('./store-jPZ4ROqV.js');
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var index = require('./index-BU8FMTXn.js');
|
|
4
4
|
var Rectangle = require('./Rectangle-7dF6_xf3.js');
|
|
5
|
-
var search_store = require('./search.store-
|
|
5
|
+
var search_store = require('./search.store-Bh2_GSpU.js');
|
|
6
6
|
var index$2 = require('./index-CP1QUrJT.js');
|
|
7
7
|
var store = require('./store-jPZ4ROqV.js');
|
|
8
8
|
var index$1 = require('./index-BF9aENF8.js');
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { hasSelectedOcrFilter } from "./hasSelectedOcrFilter";
|
|
2
|
+
/**
|
|
3
|
+
* Decides whether the cropper must be hidden because an OCR filter is active.
|
|
4
|
+
* Once the user adjusts the crop box the cropper stays regardless of OCR.
|
|
5
|
+
* Engagement resets whenever a different image is loaded.
|
|
6
|
+
*/
|
|
7
|
+
export class CropperOcrGate {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.engaged = false;
|
|
10
|
+
this.lastImage = null;
|
|
11
|
+
this.awaitingFilters = false;
|
|
12
|
+
}
|
|
13
|
+
/** Re-arm OCR gating for a freshly loaded image. */
|
|
14
|
+
onImage(image) {
|
|
15
|
+
if (image === this.lastImage)
|
|
16
|
+
return;
|
|
17
|
+
this.lastImage = image;
|
|
18
|
+
this.engaged = false;
|
|
19
|
+
this.awaitingFilters = true;
|
|
20
|
+
}
|
|
21
|
+
/** Fresh dynamicFilters for the current image have arrived. */
|
|
22
|
+
onFreshFilters() {
|
|
23
|
+
this.awaitingFilters = false;
|
|
24
|
+
}
|
|
25
|
+
/** Mark that the user started working with the cropper. */
|
|
26
|
+
onUserAdjust() {
|
|
27
|
+
this.engaged = true;
|
|
28
|
+
}
|
|
29
|
+
/** True when the cropper should be hidden. */
|
|
30
|
+
isGated(dynamicFilters, isSearchLoading = false) {
|
|
31
|
+
// Defer while the image's search is still resolving, to avoid a flash.
|
|
32
|
+
if (this.awaitingFilters && isSearchLoading)
|
|
33
|
+
return true;
|
|
34
|
+
return !this.engaged && hasSelectedOcrFilter(dynamicFilters);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { extractSelectedFilters } from "../../vviinn-filters/helpers";
|
|
2
|
+
const MODALITY_COLUMN = "modality";
|
|
3
|
+
const OCR_VALUE = "OCR";
|
|
4
|
+
export const hasSelectedOcrFilter = (dynamicFilters) => extractSelectedFilters(dynamicFilters !== null && dynamicFilters !== void 0 ? dynamicFilters : []).some((filter) => filter.column === MODALITY_COLUMN && filter.values.includes(OCR_VALUE));
|
|
@@ -12,6 +12,7 @@ import { makeVisualSearchRequest, useSearchStore, } from "../../store/search.sto
|
|
|
12
12
|
import { getImageSizes } from "../../Image/sizing";
|
|
13
13
|
import { isCropBoxChangeMinimal } from "./helpers/isCropBoxDataSimilar";
|
|
14
14
|
import { getCropBoxData } from "./helpers/cropperUtils";
|
|
15
|
+
import { CropperOcrGate } from "./helpers/cropperOcrGate";
|
|
15
16
|
import { cleanLocalStorage, getLocalStorageItems } from "../../localStorage";
|
|
16
17
|
import { addEventListenersWithSignal } from "../../dom";
|
|
17
18
|
import { renderExternalCSS } from "../../utils/cssUrl/cssUrlHelper";
|
|
@@ -30,6 +31,45 @@ export class VviinnCropper {
|
|
|
30
31
|
this.showInWidget = false;
|
|
31
32
|
this.cropper = null;
|
|
32
33
|
this.selectedDetectedObject = null;
|
|
34
|
+
this.imageElement = null;
|
|
35
|
+
this.gate = new CropperOcrGate();
|
|
36
|
+
this.destroyCropper = () => {
|
|
37
|
+
var _a;
|
|
38
|
+
(_a = this.cropper) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
39
|
+
this.cropper = null;
|
|
40
|
+
};
|
|
41
|
+
this.clearCropSelection = () => {
|
|
42
|
+
this.state.searchArea = null;
|
|
43
|
+
this.state.croppedImageUrl = null;
|
|
44
|
+
this.selectedDetectedObject = null;
|
|
45
|
+
};
|
|
46
|
+
/** Tear down the cropper and drop any applied crop. */
|
|
47
|
+
this.discardCrop = () => {
|
|
48
|
+
this.destroyCropper();
|
|
49
|
+
this.clearCropSelection();
|
|
50
|
+
};
|
|
51
|
+
this.resetCropperState = () => {
|
|
52
|
+
this.discardCrop();
|
|
53
|
+
this.state.image = null;
|
|
54
|
+
};
|
|
55
|
+
/** Show or hide the cropper to match the current OCR gate decision. */
|
|
56
|
+
this.reconcileCropper = () => {
|
|
57
|
+
// Trust the fresh filters even before the image DOM is ready.
|
|
58
|
+
this.gate.onFreshFilters();
|
|
59
|
+
if (!this.state.image || !this.imageElement || !this.state.imageBounds)
|
|
60
|
+
return;
|
|
61
|
+
if (this.gate.isGated(this.state.dynamicFilters)) {
|
|
62
|
+
// Drop only the frame, keep the region/object so OCR searches within it.
|
|
63
|
+
this.destroyCropper();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// Guard geometry here so initCropper doesn't re-emit the aspect-ratio error on every filter change.
|
|
67
|
+
if (!this.cropper &&
|
|
68
|
+
this.hasSupportedAspectRatio() &&
|
|
69
|
+
this.hasSupportedSize()) {
|
|
70
|
+
this.initCropper(this.imageElement);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
33
73
|
this.initPreloadedImage = () => {
|
|
34
74
|
var _a;
|
|
35
75
|
if (this.showInWidget && this.state.image) {
|
|
@@ -53,14 +93,12 @@ export class VviinnCropper {
|
|
|
53
93
|
cleanLocalStorage();
|
|
54
94
|
};
|
|
55
95
|
this.resetStateHandler = ({ detail, }) => {
|
|
56
|
-
var _a
|
|
96
|
+
var _a;
|
|
57
97
|
if (this.skipStateChanges(detail.isTriggeredByVpsWidget))
|
|
58
98
|
return;
|
|
59
|
-
this.selectedDetectedObject = null;
|
|
60
99
|
(_a = this.state.image) === null || _a === void 0 ? void 0 : _a.setAttribute("src", "");
|
|
61
100
|
this.state.detectedObjects = [];
|
|
62
|
-
this.
|
|
63
|
-
(_b = this.cropper) === null || _b === void 0 ? void 0 : _b.destroy();
|
|
101
|
+
this.resetCropperState();
|
|
64
102
|
cleanLocalStorage();
|
|
65
103
|
};
|
|
66
104
|
this.resetCropAreaHandler = ({ detail, }) => {
|
|
@@ -68,9 +106,7 @@ export class VviinnCropper {
|
|
|
68
106
|
if (this.skipStateChanges(detail.isTriggeredByVpsWidget))
|
|
69
107
|
return;
|
|
70
108
|
(_a = this.cropper) === null || _a === void 0 ? void 0 : _a.reset();
|
|
71
|
-
this.
|
|
72
|
-
this.state.croppedImageUrl = null;
|
|
73
|
-
this.selectedDetectedObject = null;
|
|
109
|
+
this.clearCropSelection();
|
|
74
110
|
this.vviinnImageCrop.emit({
|
|
75
111
|
isTriggeredByVpsWidget: this.showInWidget,
|
|
76
112
|
});
|
|
@@ -98,32 +134,62 @@ export class VviinnCropper {
|
|
|
98
134
|
this.cropper.replace(this.state.image.src);
|
|
99
135
|
};
|
|
100
136
|
this.loadImage = () => {
|
|
101
|
-
|
|
102
|
-
if (this.state.image)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
this.
|
|
137
|
+
var _a;
|
|
138
|
+
if (!this.state.image)
|
|
139
|
+
return;
|
|
140
|
+
const renderedImageElement = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector("img");
|
|
141
|
+
if (!renderedImageElement)
|
|
142
|
+
return;
|
|
143
|
+
this.imageElement = renderedImageElement;
|
|
144
|
+
this.gate.onImage(this.state.image);
|
|
145
|
+
let data = {};
|
|
146
|
+
if (this.cropper) {
|
|
147
|
+
data = this.cropper.getData(true);
|
|
148
|
+
this.destroyCropper();
|
|
149
|
+
}
|
|
150
|
+
const imageBounds = fromImage(renderedImageElement);
|
|
151
|
+
this.vviinnCropperLoadImage.emit({
|
|
152
|
+
imageBounds,
|
|
153
|
+
});
|
|
154
|
+
this.state.imageBounds = imageBounds;
|
|
155
|
+
const isSearchLoading = this.state.searchStatus === "loading";
|
|
156
|
+
if (this.gate.isGated(this.state.dynamicFilters, isSearchLoading)) {
|
|
157
|
+
this.discardCrop();
|
|
158
|
+
// Still surface aspect-ratio errors while hidden — geometry matters regardless.
|
|
159
|
+
this.checkAspectRatio();
|
|
160
|
+
return;
|
|
124
161
|
}
|
|
162
|
+
this.initCropper(renderedImageElement, data);
|
|
163
|
+
};
|
|
164
|
+
this.hasSupportedAspectRatio = () => {
|
|
165
|
+
if (!this.state.imageBounds)
|
|
166
|
+
return false;
|
|
167
|
+
const { width, height } = this.state.imageBounds;
|
|
168
|
+
return (width / height >= SUPPORTED_ASPECT_RATIO &&
|
|
169
|
+
height / width >= SUPPORTED_ASPECT_RATIO);
|
|
170
|
+
};
|
|
171
|
+
this.hasSupportedSize = () => {
|
|
172
|
+
if (!this.state.imageBounds)
|
|
173
|
+
return false;
|
|
174
|
+
const { width, height } = this.state.imageBounds;
|
|
175
|
+
return (width >= MIN_IMAGE_SIDE_FOR_CROPPER &&
|
|
176
|
+
height >= MIN_IMAGE_SIDE_FOR_CROPPER);
|
|
177
|
+
};
|
|
178
|
+
this.checkAspectRatio = () => {
|
|
179
|
+
if (this.hasSupportedAspectRatio())
|
|
180
|
+
return true;
|
|
181
|
+
this.vviinnCropperAspectRatioError.emit(true);
|
|
182
|
+
return false;
|
|
183
|
+
};
|
|
184
|
+
this.initCropper = (imageElement, data = {}) => {
|
|
185
|
+
if (!imageElement)
|
|
186
|
+
return;
|
|
187
|
+
if (!this.checkAspectRatio() || !this.hasSupportedSize())
|
|
188
|
+
return;
|
|
189
|
+
this.cropper = new Cropper(imageElement, Object.assign(Object.assign({}, cropperOptions), { cropstart: this.cropStart, cropend: this.cropEnd, ready: () => { var _a; return (_a = this.cropper) === null || _a === void 0 ? void 0 : _a.reset(); }, data }));
|
|
125
190
|
};
|
|
126
191
|
this.cropStart = () => {
|
|
192
|
+
this.gate.onUserAdjust();
|
|
127
193
|
this.startEndCropBoxData = getCropBoxData(this.cropper);
|
|
128
194
|
};
|
|
129
195
|
this.cropEnd = () => {
|
|
@@ -149,9 +215,10 @@ export class VviinnCropper {
|
|
|
149
215
|
!this.showAspectRatioError;
|
|
150
216
|
}
|
|
151
217
|
connectedCallback() {
|
|
152
|
-
const { state, storeName } = useSearchStore(this.showInWidget);
|
|
218
|
+
const { state, storeName, onChange } = useSearchStore(this.showInWidget);
|
|
153
219
|
this.state = state;
|
|
154
220
|
this.storeName = storeName;
|
|
221
|
+
this.disposeStoreListener = onChange("dynamicFilters", this.reconcileCropper);
|
|
155
222
|
this.initPreloadedImage();
|
|
156
223
|
this.eventAbortController = new AbortController();
|
|
157
224
|
const { signal } = this.eventAbortController;
|
|
@@ -162,10 +229,13 @@ export class VviinnCropper {
|
|
|
162
229
|
], signal);
|
|
163
230
|
}
|
|
164
231
|
disconnectedCallback() {
|
|
165
|
-
var _a, _b
|
|
232
|
+
var _a, _b;
|
|
166
233
|
(_a = this.eventAbortController) === null || _a === void 0 ? void 0 : _a.abort();
|
|
167
|
-
(
|
|
168
|
-
this.
|
|
234
|
+
(_b = this.disposeStoreListener) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
235
|
+
this.destroyCropper();
|
|
236
|
+
// "never" keeps no image across mounts, so clear it from the shared store.
|
|
237
|
+
if (this.saveImageMode === "never")
|
|
238
|
+
this.state.image = null;
|
|
169
239
|
}
|
|
170
240
|
selectDetectedObject({ detail }) {
|
|
171
241
|
this.selectedDetectedObject = detail.detectedObject;
|
|
@@ -198,14 +268,14 @@ export class VviinnCropper {
|
|
|
198
268
|
}
|
|
199
269
|
render() {
|
|
200
270
|
var _a;
|
|
201
|
-
return (h(Host, { key: '
|
|
271
|
+
return (h(Host, { key: 'b50ccb5595b27ef6673ff9d9350fc30359a6f7ce', class: {
|
|
202
272
|
"show-in-widget": this.showInWidget,
|
|
203
273
|
active: !!this.state.image,
|
|
204
|
-
} }, renderExternalCSS(this.cssUrl), h("div", { key: '
|
|
274
|
+
} }, renderExternalCSS(this.cssUrl), h("div", { key: 'efd816ed4e19082091567714fee4ef40efe9a6c4', class: "container" }, this.state.image && (h("div", { key: '13f35758ba243eb73513e17375daca8431538383', class: "image-container", style: {
|
|
205
275
|
width: `${this.width.toString()}px`,
|
|
206
276
|
overflow: "hidden",
|
|
207
|
-
} }, h("img", { key: '
|
|
208
|
-
_a.map((object) => (h("vviinn-detected-object", { detectedObject: object, selectedDetectedObject: this.selectedDetectedObject, basicEventData: this.basicEventData, imageBounds: this.state.imageBounds, showInWidget: this.showInWidget }))))), this.showPreloader() && (h("div", { key: '
|
|
277
|
+
} }, h("img", { key: '7525aae0654325fb25c88106a9ee1fface11a62e', decoding: "async", width: this.width, height: this.height, src: this.state.image.src, draggable: false, onLoad: this.loadImage, alt: i18next.t("a11y.cropperImage") }), (_a = this.state.detectedObjects) === null || _a === void 0 ? void 0 :
|
|
278
|
+
_a.map((object) => (h("vviinn-detected-object", { detectedObject: object, selectedDetectedObject: this.selectedDetectedObject, basicEventData: this.basicEventData, imageBounds: this.state.imageBounds, showInWidget: this.showInWidget }))))), this.showPreloader() && (h("div", { key: 'b89ad46bda5279b77f4fe258f7a6d4af08f81c29', class: "image-preloader" }, h("vviinn-preloader", { key: '34f55578c05321480d7e3d8141a4638df8aad08b' }))))));
|
|
209
279
|
}
|
|
210
280
|
static get is() { return "vviinn-cropper"; }
|
|
211
281
|
static get encapsulation() { return "shadow"; }
|
|
@@ -12,6 +12,8 @@ import { useSearchStore } from "../../store/search.store";
|
|
|
12
12
|
import { defaultConfig } from "../../store/store";
|
|
13
13
|
import { addEventListenersWithSignal, isElementInSelector } from "../../dom";
|
|
14
14
|
import { extendedFiltersParts } from "../../cssParts";
|
|
15
|
+
const FILTER_OPTIONS_INITIAL_COUNT = 8;
|
|
16
|
+
const FILTER_OPTIONS_STEP_COUNT = 5;
|
|
15
17
|
/**
|
|
16
18
|
* @slot vviinn-extended-filters-title - Text on widget's header.
|
|
17
19
|
* @slot vviinn-extended-filters-apply - Title of Apply Button.
|
|
@@ -63,8 +65,6 @@ import { extendedFiltersParts } from "../../cssParts";
|
|
|
63
65
|
* @part histogram-from-input - Input field for the minimum value.
|
|
64
66
|
* @part histogram-to-input - Input field for the maximum value.
|
|
65
67
|
*/
|
|
66
|
-
const FILTER_OPTIONS_INITIAL_COUNT = 8;
|
|
67
|
-
const FILTER_OPTIONS_STEP_COUNT = 5;
|
|
68
68
|
export class VviinnExtendedFilters {
|
|
69
69
|
constructor() {
|
|
70
70
|
this.mode = "button";
|
|
@@ -32,6 +32,81 @@ import { addIfNotEmpty } from "../../utils/collections/collectionsUtils";
|
|
|
32
32
|
import { RESULTS_CALCULATED_COLUMNS_CSS_VAR } from "../vviinn-carousel/constants";
|
|
33
33
|
import { renderExternalCSS } from "../../utils/cssUrl/cssUrlHelper";
|
|
34
34
|
import { openProductLink } from "../../helpers/navigation/openProductLink";
|
|
35
|
+
/**
|
|
36
|
+
* @part products - Products container.
|
|
37
|
+
* @part product-card - Product Card itself.
|
|
38
|
+
* @part image-container - Product Card's image container.
|
|
39
|
+
* @part content-container - Product Card's content container.
|
|
40
|
+
* @part basket-button-container - Product Card's basket button container.
|
|
41
|
+
* @part brand - Brand inside Product Card.
|
|
42
|
+
* @part product-type - Product Type inside Product Card.
|
|
43
|
+
* @part currency - Currency related to price.
|
|
44
|
+
* @part deeplink - Anchor element around product title. Rendered only if "deeplink" property is filled.
|
|
45
|
+
* @part image - Product Card image.
|
|
46
|
+
* @part image-link - Anchor element around product image. Rendered only if "deeplink" property is filled.
|
|
47
|
+
* @part image-picture - Picture element for image.
|
|
48
|
+
* @part image-placeholder - Placeholder shown when no image is available.
|
|
49
|
+
* @part price-amount-regular - Numeric part of the price.
|
|
50
|
+
* @part price-amount-sale - Numeric part of the price.
|
|
51
|
+
* @part price-amount-outdated - Numeric part of the price.
|
|
52
|
+
* @part price-amount-base-sale - Numeric part of the base price.
|
|
53
|
+
* @part price-amount-base-outdated - Numeric part of the base price.
|
|
54
|
+
* @part price-amount-base-regular - Numeric part of the base price.
|
|
55
|
+
* @part price-outdated - Block for outdated price. Rendered when the product contains the sale price.
|
|
56
|
+
* @part price-regular - Block for a price if no sale price is presented.
|
|
57
|
+
* @part price-sale - Block for sale price. Rendered only if the sale price is presented.
|
|
58
|
+
* @part price-prefix - Block rendered before each price element (for ex. "from").
|
|
59
|
+
* @part title - Title inside Product Card.
|
|
60
|
+
* @part basket-button - Add to Basket button.
|
|
61
|
+
* @part basket-button-container - Product Card's basket button container.
|
|
62
|
+
* @part favorite-button - Favorite button.
|
|
63
|
+
* @part product-card-actions - Product Card actions wrapper.
|
|
64
|
+
* @part product-card-actions-top - Product Card top actions wrapper.
|
|
65
|
+
* @part energy-label-container - Energy label container.
|
|
66
|
+
* @part energy-label-icon - Icon with an energy class.
|
|
67
|
+
* @part energy-label-product-type - Product type.
|
|
68
|
+
* @part energy-label-data-sheet-link - Data sheet link.
|
|
69
|
+
* @part product-images-pagination - Container for product images pagination dots (mobile only).
|
|
70
|
+
* @part product-images-pagination-bullet - Individual pagination dot.
|
|
71
|
+
* @part product-images-pagination-bullet-active - Active pagination dot.
|
|
72
|
+
*
|
|
73
|
+
* @part custom-label-0 - Custom label with index 0.
|
|
74
|
+
* @part custom-label-1 - Custom label with index 1.
|
|
75
|
+
* @part custom-label-2 - Custom label with index 2.
|
|
76
|
+
* @part custom-label-3 - Custom label with index 3.
|
|
77
|
+
* @part custom-label-4 - Custom label with index 4.
|
|
78
|
+
*
|
|
79
|
+
* @part list-card - List card container (for entity-type="list").
|
|
80
|
+
* @part list-card-content-container - List card's content container.
|
|
81
|
+
* @part list-label - List card's label (e.g., "Category").
|
|
82
|
+
* @part list-title - List card's title.
|
|
83
|
+
* @part list-card-image-container - List card's image container.
|
|
84
|
+
* @part list-card-image - List card's image element.
|
|
85
|
+
* @part list-card-image-picture - List card's image picture element.
|
|
86
|
+
*
|
|
87
|
+
* @part content-card - Content card container (for entity-type="content").
|
|
88
|
+
* @part content-card-content-container - Content card's content container.
|
|
89
|
+
* @part content-label - Content card's label.
|
|
90
|
+
* @part content-title - Content card's title.
|
|
91
|
+
* @part content-link - Content card's link.
|
|
92
|
+
* @part content-card-image - Content card's image element.
|
|
93
|
+
* @part content-card-image-container - Content card's image container.
|
|
94
|
+
* @part content-card-image-picture - Content card's image picture element.
|
|
95
|
+
*
|
|
96
|
+
* @slot vviinn-results-vpr-icon - One-Click Discovery icon.
|
|
97
|
+
* @slot vviinn-favorite-icon - Icon of Favorite button.
|
|
98
|
+
* @slot vviinn-favorite-icon-pressed - Icon of pressed Favorite button.
|
|
99
|
+
* @slot vviinn-basket-button-text - Text of Add to Basket button.
|
|
100
|
+
* @slot vviinn-basket-button-icon - Text of Add to Basket icon.
|
|
101
|
+
* @slot vviinn-basket-button-text-pressed - Text of pressed Add to Basket button.
|
|
102
|
+
* @slot vviinn-basket-button-icon-pressed - Icon of pressed Add to Basket button.
|
|
103
|
+
* @slot vviinn-custom-label-0 - Custom label with index 0.
|
|
104
|
+
* @slot vviinn-custom-label-1 - Custom label with index 1.
|
|
105
|
+
* @slot vviinn-custom-label-2 - Custom label with index 2.
|
|
106
|
+
* @slot vviinn-custom-label-3 - Custom label with index 3.
|
|
107
|
+
* @slot vviinn-custom-label-4 - Custom label with index 4.
|
|
108
|
+
* @slot vviinn-image-placeholder-icon - Icon or content for the image placeholder.
|
|
109
|
+
*/
|
|
35
110
|
export class VviinnResults {
|
|
36
111
|
constructor() {
|
|
37
112
|
/** Campaign ID used for Text Search */
|
|
@@ -432,13 +507,13 @@ export class VviinnResults {
|
|
|
432
507
|
render() {
|
|
433
508
|
var _a;
|
|
434
509
|
const resultsLength = this.getResults().length;
|
|
435
|
-
return (h(Host, { key: '
|
|
510
|
+
return (h(Host, { key: 'd62957bb1294f3a62e14fa9a3eb97c7ef6007eae', id: "results-block", class: {
|
|
436
511
|
"show-in-widget": this.showInWidget,
|
|
437
512
|
"matching-discovery": this.oneClickDiscoveryMode === "append-slider",
|
|
438
|
-
}, exportparts: `${productCardParts}, ${listCardParts}, ${contentCardParts}, ${productCardsGridPart}` }, renderExternalCSS(this.cssUrl), h("div", { key: '
|
|
513
|
+
}, exportparts: `${productCardParts}, ${listCardParts}, ${contentCardParts}, ${productCardsGridPart}` }, renderExternalCSS(this.cssUrl), h("div", { key: '69f7a38dc02f42c357dbae8cf154ecb78380f270', class: "nothing-found" }, this.getCurrentErrorType() && (h("vviinn-error", { key: 'd78ed9f6d777d7ec1686b10b709deee018c4391e', errorType: this.getCurrentErrorType(), handler: this.resetWidgetState, hasBackground: this.showInWidget, searchType: this.state.searchType }))), h("div", { key: 'be3db62dcfd508b6f60036454d3c825d6c27f5ae', class: {
|
|
439
514
|
hidden: this.showAspectRatioError || resultsLength === 0,
|
|
440
515
|
products: true,
|
|
441
|
-
}, part: productCardsGridPart, id: "vviinn-results-products" }, resultsLength > 0 && this.renderResults(), h("div", { key: '
|
|
516
|
+
}, part: productCardsGridPart, id: "vviinn-results-products" }, resultsLength > 0 && this.renderResults(), h("div", { key: '88d3d2d5880806b9e24799694cc540de676d17f8', id: "one-click-discovery-append", style: {
|
|
442
517
|
order: ((_a = this.oneClickDiscoveryAppendIndex) !== null && _a !== void 0 ? _a : resultsLength).toString(),
|
|
443
518
|
} }))));
|
|
444
519
|
}
|
|
@@ -8,12 +8,21 @@ export const toggleFilterInSet = (appliedFilters, suggestionText) => {
|
|
|
8
8
|
}
|
|
9
9
|
return newAppliedFilters;
|
|
10
10
|
};
|
|
11
|
+
export const formatIntervalKey = (column, start, end) => `${column}:${start}-${end}`;
|
|
11
12
|
export const extractActiveFilterValues = (activeFilters) => {
|
|
12
13
|
const activeValues = new Set();
|
|
13
14
|
activeFilters.forEach((filter) => {
|
|
14
|
-
if (Array.isArray(filter.values))
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
if (!Array.isArray(filter.values))
|
|
16
|
+
return;
|
|
17
|
+
filter.values.forEach((v) => {
|
|
18
|
+
// Interval values are `{start, end}` objects; categorical values are strings.
|
|
19
|
+
if (v !== null && typeof v === "object" && "start" in v) {
|
|
20
|
+
activeValues.add(formatIntervalKey(filter.column, v.start, v.end));
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
activeValues.add(`${filter.column}:${String(v)}`);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
17
26
|
});
|
|
18
27
|
return activeValues;
|
|
19
28
|
};
|
|
@@ -33,13 +42,21 @@ export const syncSuggestionFilters = (activeFilters, stream) => {
|
|
|
33
42
|
if (!((_c = (_b = annotation.interactions) === null || _b === void 0 ? void 0 : _b.dynamicFilters) === null || _c === void 0 ? void 0 : _c.length))
|
|
34
43
|
continue;
|
|
35
44
|
for (const filter of annotation.interactions.dynamicFilters) {
|
|
36
|
-
if (filter.type
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
}
|
|
45
|
+
if (filter.type === "categorical" && "values" in filter) {
|
|
46
|
+
filter.values.forEach((value) => {
|
|
47
|
+
if (activeValues.has(`${filter.column}:${String(value.value)}`)) {
|
|
48
|
+
updatedAppliedFilters.add(`${filter.column}:${value.value}`);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else if (filter.type === "interval" && "selectedValues" in filter) {
|
|
53
|
+
filter.selectedValues.forEach((interval) => {
|
|
54
|
+
const key = formatIntervalKey(filter.column, interval.start, interval.end);
|
|
55
|
+
if (activeValues.has(key)) {
|
|
56
|
+
updatedAppliedFilters.add(key);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
43
60
|
}
|
|
44
61
|
}
|
|
45
62
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { h } from "@stencil/core";
|
|
2
2
|
import { marked } from "marked";
|
|
3
3
|
import { triggerFilter } from "../vviinn-filters/helpers/triggerFilter";
|
|
4
|
+
import { formatIntervalKey } from "./helpers";
|
|
4
5
|
export const extractDataItems = (annotation) => annotation.data.items;
|
|
5
6
|
export const findMatchingFilterValue = (item, filter) => {
|
|
6
7
|
if (filter.type !== "categorical" ||
|
|
@@ -21,18 +22,38 @@ export const applyFiltersForItems = (dataItems, interactions, currentRequestFilt
|
|
|
21
22
|
let updatedFilters = currentRequestFilters;
|
|
22
23
|
if (dataItems.length === 0) {
|
|
23
24
|
for (const filter of filters) {
|
|
24
|
-
if (filter.type
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
25
|
+
if (filter.type === "categorical" && "values" in filter) {
|
|
26
|
+
for (const filterValue of filter.values) {
|
|
27
|
+
updatedFilters = triggerFilter({
|
|
28
|
+
filterValue: filterValue,
|
|
29
|
+
selectedFilter: filter,
|
|
30
|
+
requestFilters: updatedFilters,
|
|
31
|
+
vviinnFilterTriggered: handlers.vviinnFilterTriggered,
|
|
32
|
+
vviinnFiltersChanged: handlers.vviinnFiltersChanged,
|
|
33
|
+
el: handlers.el,
|
|
34
|
+
isTriggeredByVpsWidget: handlers.isTriggeredByVpsWidget,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (filter.type === "interval" && "selectedValues" in filter) {
|
|
39
|
+
// A suggestion chip represents one specific range to toggle, not a slider.
|
|
40
|
+
// The backend emits `full === selectedValues[0]`, which would make
|
|
41
|
+
// `isFullRangeInterval` read every click as "cleared to the full range"
|
|
42
|
+
// (deselect-only). Neutralize `full` so the shared toggle logic selects /
|
|
43
|
+
// deselects this exact interval by value match. Only the object passed to
|
|
44
|
+
// `triggerFilter` is affected; `value` still carries the real interval.
|
|
45
|
+
const chipFilter = Object.assign(Object.assign({}, filter), { full: { start: undefined, end: undefined } });
|
|
46
|
+
for (const interval of filter.selectedValues) {
|
|
47
|
+
updatedFilters = triggerFilter({
|
|
48
|
+
filterValue: { interval },
|
|
49
|
+
selectedFilter: chipFilter,
|
|
50
|
+
requestFilters: updatedFilters,
|
|
51
|
+
vviinnFilterTriggered: handlers.vviinnFilterTriggered,
|
|
52
|
+
vviinnFiltersChanged: handlers.vviinnFiltersChanged,
|
|
53
|
+
el: handlers.el,
|
|
54
|
+
isTriggeredByVpsWidget: handlers.isTriggeredByVpsWidget,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
36
57
|
}
|
|
37
58
|
}
|
|
38
59
|
return updatedFilters;
|
|
@@ -81,9 +102,15 @@ export const splitContentByLocators = (content, annotations) => {
|
|
|
81
102
|
};
|
|
82
103
|
export const getAnnotationFilterKeys = (annotation) => {
|
|
83
104
|
var _a, _b, _c;
|
|
84
|
-
return (_c = (_b = (_a = annotation.interactions) === null || _a === void 0 ? void 0 : _a.dynamicFilters) === null || _b === void 0 ? void 0 : _b.flatMap((filter) =>
|
|
85
|
-
|
|
86
|
-
|
|
105
|
+
return (_c = (_b = (_a = annotation.interactions) === null || _a === void 0 ? void 0 : _a.dynamicFilters) === null || _b === void 0 ? void 0 : _b.flatMap((filter) => {
|
|
106
|
+
if (filter.type === "categorical" && "values" in filter) {
|
|
107
|
+
return filter.values.map((v) => `${filter.column}:${v.value}`);
|
|
108
|
+
}
|
|
109
|
+
if (filter.type === "interval" && "selectedValues" in filter) {
|
|
110
|
+
return filter.selectedValues.map((interval) => formatIntervalKey(filter.column, interval.start, interval.end));
|
|
111
|
+
}
|
|
112
|
+
return [];
|
|
113
|
+
})) !== null && _c !== void 0 ? _c : [];
|
|
87
114
|
};
|
|
88
115
|
const getAnnotationDeeplink = (annotation) => {
|
|
89
116
|
for (const item of annotation.data.items) {
|