@gem-sdk/components 2.1.34 → 2.1.36
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/image/helpers/getSrcSet.js +2 -1
- package/dist/cjs/product/components/Product.liquid.js +3 -2
- package/dist/cjs/product/components/ProductVariants/index.liquid.js +11 -18
- package/dist/cjs/product/components/ProductVariants/variants/Base.liquid.js +1 -0
- package/dist/cjs/product/components/ProductVariants/variants/Dropdown.liquid.js +26 -12
- package/dist/cjs/product/components/ProductVariants/variants/DropdownGroup.liquid.js +4 -37
- package/dist/cjs/product/components/ProductVariants/variants/combine/index.js +47 -0
- package/dist/esm/image/helpers/getSrcSet.js +2 -1
- package/dist/esm/product/components/Product.liquid.js +3 -2
- package/dist/esm/product/components/ProductVariants/index.liquid.js +12 -19
- package/dist/esm/product/components/ProductVariants/variants/Base.liquid.js +1 -0
- package/dist/esm/product/components/ProductVariants/variants/Dropdown.liquid.js +26 -12
- package/dist/esm/product/components/ProductVariants/variants/DropdownGroup.liquid.js +4 -37
- package/dist/esm/product/components/ProductVariants/variants/combine/index.js +44 -0
- package/dist/types/index.d.ts +12 -0
- package/package.json +2 -2
|
@@ -30,7 +30,8 @@ const getSrcSetLiquid = (liquid, storage)=>{
|
|
|
30
30
|
return `{{ '${liquid}' | asset_img_url: '768x' }} 768w, {{ '${liquid}' | asset_img_url: '1024x' }} 1024w, {{ '${liquid}' | asset_img_url: 'master' }} 1440w`;
|
|
31
31
|
};
|
|
32
32
|
const getSrcSetLink = (link)=>{
|
|
33
|
-
return
|
|
33
|
+
return link; // Since image src didn't change in size so this line of code is pointless
|
|
34
|
+
// return `${link} 768w,${link} 1024w,${link} 1440w`;
|
|
34
35
|
};
|
|
35
36
|
const getImageSrc = (image, currentDevice)=>{
|
|
36
37
|
let src = image?.backupFilePath;
|
|
@@ -9,6 +9,7 @@ var helpers = require('../../helpers.js');
|
|
|
9
9
|
const PRODUCT_ID_LATEST = 'latest';
|
|
10
10
|
const PREFIX_PRODUCT_ID = 'gid://shopify/Product/';
|
|
11
11
|
const PREFIX_PRODUCT_VARIANT_ID = 'gid://shopify/ProductVariant/';
|
|
12
|
+
const PREFIX_PRODUCT_OPTION_VALUE_ID = 'gid://shopify/ProductOptionValue/';
|
|
12
13
|
const STATIC_PRODUCT_STATUS = 'static';
|
|
13
14
|
const DYNAMIC_PRODUCT_STATUS = 'dynamic';
|
|
14
15
|
const Product = ({ children, setting, styles, style, builderProps, rawChildren, advanced })=>{
|
|
@@ -24,8 +25,8 @@ const Product = ({ children, setting, styles, style, builderProps, rawChildren,
|
|
|
24
25
|
const formatProductId = productSetting?.productId?.replace(PREFIX_PRODUCT_ID, '').toLowerCase() || PRODUCT_ID_LATEST;
|
|
25
26
|
const formatVariantId = initVariantId?.replace(PREFIX_PRODUCT_VARIANT_ID, '') || '';
|
|
26
27
|
const productStatus = productSetting?.productStatus ?? STATIC_PRODUCT_STATUS;
|
|
28
|
+
const preSelectedOptionIds = productSetting?.selectedOptions?.map((option)=>option?.valueBaseID?.replace(PREFIX_PRODUCT_OPTION_VALUE_ID, ''));
|
|
27
29
|
return core.template /* liquid */ `
|
|
28
|
-
|
|
29
30
|
{%- assign gpBkProduct = product -%}
|
|
30
31
|
${productStatus !== DYNAMIC_PRODUCT_STATUS ? `
|
|
31
32
|
{%- liquid
|
|
@@ -100,7 +101,7 @@ const Product = ({ children, setting, styles, style, builderProps, rawChildren,
|
|
|
100
101
|
{%- endif -%}
|
|
101
102
|
<gp-product data-uid="${builderProps?.uid}" data-id="${builderProps?.uid}" style="${{
|
|
102
103
|
...advancedStyle
|
|
103
|
-
}}" class="${advanced?.cssClass}" gp-context='{"productId": {{ product.id }}, "isSyncProduct": "${isSyncProduct}", "variantSelected": {{ variant | json | escape }}, "inventoryQuantity": {{ variant.inventory_quantity }}, "quantity": 1, "formId": "{{ product_form_id }}" }'
|
|
104
|
+
}}" class="${advanced?.cssClass}" gp-context='{"productId": {{ product.id }}, "preSelectedOptionIds": [${preSelectedOptionIds}], "isSyncProduct": "${isSyncProduct}", "variantSelected": {{ variant | json | escape }}, "inventoryQuantity": {{ variant.inventory_quantity }}, "quantity": 1, "formId": "{{ product_form_id }}" }'
|
|
104
105
|
gp-data='{"variantSelected": {{ variant | json | escape }}, "quantity": 1, "productUrl":{{ product.url | json | escape }}, "productHandle":{{ product.handle | json | escape }}, "collectionUrl": {{ collection.url | json | escape }}, "collectionHandle": {{ collection.handle | json | escape }}}'>
|
|
105
106
|
<product-form class="product-form">
|
|
106
107
|
{%- form 'product', product, id: product_form_id, class: 'form contents', data-type: 'add-to-cart-form', autocomplete: 'off' -%}
|
|
@@ -97,15 +97,9 @@ const ProductVariants = ({ builderProps, style, styles, setting, advanced })=>{
|
|
|
97
97
|
<div
|
|
98
98
|
option-name="{{option.name | escape}}"
|
|
99
99
|
class="${core.cls('gp-flex variant-inside', {
|
|
100
|
-
|
|
101
|
-
'gp-flex-row': layout?.desktop === 'horizontal',
|
|
102
|
-
'tablet:gp-flex-row': layout?.tablet === 'horizontal',
|
|
103
|
-
'tablet:gp-flex-col': layout?.tablet === 'vertical',
|
|
104
|
-
'mobile:gp-flex-row': layout?.mobile === 'horizontal',
|
|
105
|
-
'mobile:gp-flex-col': layout?.mobile === 'vertical'
|
|
106
|
-
}, {
|
|
100
|
+
...core.getLayoutClasses(layout),
|
|
107
101
|
..._function.getAlignClasses(layout, align)
|
|
108
|
-
})}
|
|
102
|
+
})}"
|
|
109
103
|
|
|
110
104
|
>
|
|
111
105
|
{% assign showVariantClass = 'variant-display' %}
|
|
@@ -137,15 +131,7 @@ const ProductVariants = ({ builderProps, style, styles, setting, advanced })=>{
|
|
|
137
131
|
<div
|
|
138
132
|
variant-option-name="{{option.name | escape}}"
|
|
139
133
|
class="${core.cls({
|
|
140
|
-
|
|
141
|
-
'gp-justify-center': align?.desktop === 'center',
|
|
142
|
-
'gp-justify-end': align?.desktop === 'right',
|
|
143
|
-
'tablet:gp-justify-start': align?.tablet === 'left',
|
|
144
|
-
'tablet:gp-justify-center': align?.tablet === 'center',
|
|
145
|
-
'tablet:gp-justify-end': align?.tablet === 'right',
|
|
146
|
-
'mobile:gp-justify-start': align?.mobile === 'left',
|
|
147
|
-
'mobile:gp-justify-center': align?.mobile === 'center',
|
|
148
|
-
'mobile:gp-justify-end': align?.mobile === 'right'
|
|
134
|
+
...core.getAlignmentClasses(align)
|
|
149
135
|
}, 'gp-flex gp-w-full gp-flex-wrap gp-items-center variant-option-group')}"
|
|
150
136
|
style="${{
|
|
151
137
|
...core.makeStyle({
|
|
@@ -328,6 +314,10 @@ const ProductVariants = ({ builderProps, style, styles, setting, advanced })=>{
|
|
|
328
314
|
`;
|
|
329
315
|
};
|
|
330
316
|
return core.template`
|
|
317
|
+
{%- assign total_combinations = 1 -%}
|
|
318
|
+
{%- for option in product.options_with_values -%}
|
|
319
|
+
{%- assign total_combinations = total_combinations | times: option.values.size -%}
|
|
320
|
+
{%- endfor -%}
|
|
331
321
|
<gp-product-variants
|
|
332
322
|
data-id="${uid}"
|
|
333
323
|
class="${advanced?.cssClass}"
|
|
@@ -343,7 +333,10 @@ const ProductVariants = ({ builderProps, style, styles, setting, advanced })=>{
|
|
|
343
333
|
"moneyFormat": {{shop.money_format | json | escape}},
|
|
344
334
|
"productId": {{product.id | json | escape}},
|
|
345
335
|
"productUrl": {{product.url | json | escape}},
|
|
346
|
-
"
|
|
336
|
+
"productHandle": {{product.handle | json | escape}},
|
|
337
|
+
"displayState": ${JSON.stringify(advancedDisplay)},
|
|
338
|
+
"totalVariantCombinations": {{total_combinations}},
|
|
339
|
+
"firstAvailableVariant": {{product.selected_or_first_available_variant | json | escape}}
|
|
347
340
|
}
|
|
348
341
|
'>
|
|
349
342
|
{%- assign options = product.options_with_values -%}
|
|
@@ -156,6 +156,7 @@ const BaseVariant = ({ optionTransform, optionTypography, optionBgColor, optionT
|
|
|
156
156
|
option-data="{{option.name | escape}}"
|
|
157
157
|
option-value="{{value | escape}}"
|
|
158
158
|
option-position="{{option.position}}"
|
|
159
|
+
data-gp-option-available="{{value.available}}"
|
|
159
160
|
option-type="${type || 'rectangle_list'}"
|
|
160
161
|
data-disabled="{%- if option_disabled == true -%} disabled {%- endif -%}"
|
|
161
162
|
data-hidden='true'
|
|
@@ -18,6 +18,15 @@ const DropdownVariant = ({ variantGroup, blankText, swatchAutoWidth, swatchHeigh
|
|
|
18
18
|
};
|
|
19
19
|
const appendTypoClass = core.composeTypographyClassName(optionTypo, optionTypography);
|
|
20
20
|
const appendTypoStyle = core.composeTypographyStyle(optionTypo, optionTypography);
|
|
21
|
+
const composeSelectOptionAttrs = `
|
|
22
|
+
option-data="{{option.name | escape}}"
|
|
23
|
+
option-value="{{value | escape}}"
|
|
24
|
+
data-gp-option-value-id="{{value.id}}"
|
|
25
|
+
data-gp-option-available="{{value.available}}"
|
|
26
|
+
value="{{value | escape}}"
|
|
27
|
+
class="option-value-wrapper"
|
|
28
|
+
key="{{value | escape}}"
|
|
29
|
+
`;
|
|
21
30
|
return core.template /* liquid */ `
|
|
22
31
|
<select
|
|
23
32
|
aria-label={{option.name | escape}}
|
|
@@ -73,37 +82,42 @@ const DropdownVariant = ({ variantGroup, blankText, swatchAutoWidth, swatchHeigh
|
|
|
73
82
|
-%}
|
|
74
83
|
${isSoldOutMark ? `{%- if option_disabled == true -%}
|
|
75
84
|
{%- if value == selectedValue -%}
|
|
76
|
-
<option disabled ${!hasPreSelected ? '' : 'selected'}
|
|
85
|
+
<option disabled ${!hasPreSelected ? '' : 'selected'}
|
|
77
86
|
option-position="{{option.position}}"
|
|
78
|
-
|
|
87
|
+
${composeSelectOptionAttrs}>
|
|
79
88
|
{{value}}
|
|
80
89
|
</option>
|
|
81
90
|
{% else %}
|
|
82
|
-
<option
|
|
83
|
-
|
|
91
|
+
<option
|
|
92
|
+
disabled
|
|
93
|
+
${composeSelectOptionAttrs}>
|
|
84
94
|
{{value}}
|
|
85
95
|
</option>
|
|
86
96
|
{%- endif -%}
|
|
87
97
|
{%- else -%}
|
|
88
98
|
{%- if value == selectedValue -%}
|
|
89
|
-
<option ${!hasPreSelected ? '' : 'selected'}
|
|
90
|
-
option-
|
|
99
|
+
<option ${!hasPreSelected ? '' : 'selected'}
|
|
100
|
+
option-position="{{option.position}}"
|
|
101
|
+
${composeSelectOptionAttrs}>
|
|
91
102
|
{{value}}
|
|
92
103
|
</option>
|
|
93
104
|
{% else %}
|
|
94
|
-
<option
|
|
95
|
-
|
|
105
|
+
<option
|
|
106
|
+
${composeSelectOptionAttrs}
|
|
107
|
+
option-position="{{option.position}}">
|
|
96
108
|
{{value}}
|
|
97
109
|
</option>
|
|
98
110
|
{%- endif -%}
|
|
99
111
|
{%- endif -%}` : `{%- if value == selectedValue -%}
|
|
100
|
-
<option ${!hasPreSelected ? '' : 'selected'}
|
|
101
|
-
|
|
112
|
+
<option ${!hasPreSelected ? '' : 'selected'}
|
|
113
|
+
${composeSelectOptionAttrs}
|
|
114
|
+
option-position="{{option.position}}">
|
|
102
115
|
{{value}}
|
|
103
116
|
</option>
|
|
104
117
|
{% else %}
|
|
105
|
-
<option
|
|
106
|
-
|
|
118
|
+
<option
|
|
119
|
+
${composeSelectOptionAttrs}
|
|
120
|
+
option-position="{{option.position}}">
|
|
107
121
|
{{value}}
|
|
108
122
|
</option>
|
|
109
123
|
{%- endif -%}`}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var core = require('@gem-sdk/core');
|
|
6
|
-
var
|
|
6
|
+
var index = require('./combine/index.js');
|
|
7
7
|
|
|
8
|
-
const DropdownVariant = ({ price, blankText, optionTypography, optionBgColor, optionTextColor, optionRounded, optionShadow, optionHasShadow, optionBorder, optionTransform, hasPreSelected, optionTypo, combineWidth, combineHeight, soldOutStyle })=>{
|
|
8
|
+
const DropdownVariant = ({ price: hasPrice, blankText, optionTypography, optionBgColor, optionTextColor, optionRounded, optionShadow, optionHasShadow, optionBorder, optionTransform, hasPreSelected, optionTypo, combineWidth, combineHeight, soldOutStyle })=>{
|
|
9
9
|
const swatchWidthResponsive = core.makeStyleResponsive('w', core.makeWidth(combineWidth));
|
|
10
10
|
const getCustomCSSActiveState = ()=>{
|
|
11
11
|
return core.makeStyle({
|
|
@@ -27,7 +27,6 @@ const DropdownVariant = ({ price, blankText, optionTypography, optionBgColor, op
|
|
|
27
27
|
option-data="{{option.name}}"
|
|
28
28
|
option-type="{{optionType}}"
|
|
29
29
|
class="${core.cls('gp-truncate gp-bg-auto gp-pl-4 gp-pr-6 gp-outline-none dropdown-option-item', core.handleConvertClassColor(optionBorder), appendTypoClass, core.getGlobalColorStateClass('text', optionTextColor), core.getGlobalColorStateClass('bg', optionBgColor), 'gp-outline-none', 'gp-shadow-none')}"
|
|
30
|
-
|
|
31
30
|
style="${{
|
|
32
31
|
...core.getStyleShadowState(optionShadow, 'box-shadow', optionHasShadow),
|
|
33
32
|
...getCustomCSSActiveState(),
|
|
@@ -49,40 +48,8 @@ const DropdownVariant = ({ price, blankText, optionTypography, optionBgColor, op
|
|
|
49
48
|
'background-position': 'right 16px center'
|
|
50
49
|
}}"
|
|
51
50
|
>
|
|
52
|
-
${
|
|
53
|
-
${
|
|
54
|
-
${isSoldOutMark ? `{%- if variantItem.available == false -%}
|
|
55
|
-
{%- if variantItem.id == variant.id -%}
|
|
56
|
-
<option origin-price="{{variantItem.price}}" disabled ${!hasPreSelected ? '' : 'selected'} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
57
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
58
|
-
</option>
|
|
59
|
-
{% else %}
|
|
60
|
-
<option origin-price="{{variantItem.price}}" disabled value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
61
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
62
|
-
</option>
|
|
63
|
-
{%- endif -%}
|
|
64
|
-
{%- else -%}
|
|
65
|
-
{%- if variantItem.id == variant.id -%}
|
|
66
|
-
<option origin-price="{{variantItem.price}}" ${!hasPreSelected ? '' : 'selected'} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
67
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
68
|
-
</option>
|
|
69
|
-
{% else %}
|
|
70
|
-
<option origin-price="{{variantItem.price}}" value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
71
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
72
|
-
</option>
|
|
73
|
-
{%- endif -%}
|
|
74
|
-
{%- endif -%}` : `{%- if variantItem.id == variant.id -%}
|
|
75
|
-
<option origin-price="{{variantItem.price}}" ${!hasPreSelected ? '' : 'selected'} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
76
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
77
|
-
</option>
|
|
78
|
-
{% else %}
|
|
79
|
-
<option origin-price="{{variantItem.price}}" value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
80
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
81
|
-
</option>
|
|
82
|
-
{%- endif -%}`}
|
|
83
|
-
|
|
84
|
-
{%- endfor -%}
|
|
85
|
-
`}
|
|
51
|
+
${index.renderBlankOption(hasPreSelected, blankText)}
|
|
52
|
+
${index.renderCombineVariants(isSoldOutMark, hasPreSelected, hasPrice)}
|
|
86
53
|
</select>
|
|
87
54
|
`;
|
|
88
55
|
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var helpers = require('../../../../../helpers.js');
|
|
4
|
+
|
|
5
|
+
const renderCombineVariants = (isSoldOutMark, hasPreSelected, enablePrice)=>{
|
|
6
|
+
const hasPrice = enablePrice ? '- {{variantItem.price | money}}' : '';
|
|
7
|
+
const optionAttrs = 'origin-price="{{variantItem.price}}" value="{{variantItem.id}}" key="{{variantItem.id}}"';
|
|
8
|
+
return `${`{%- for variantItem in variants -%}
|
|
9
|
+
${isSoldOutMark ? `{%- if variantItem.available == false -%}
|
|
10
|
+
{%- if variantItem.id == variant.id -%}
|
|
11
|
+
<option origin-price="{{variantItem.price}}" disabled ${hasPreSelected ? 'selected' : ''} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
12
|
+
{{variantItem.title}} ${hasPrice} : ''}
|
|
13
|
+
</option>
|
|
14
|
+
{% else %}
|
|
15
|
+
<option ${optionAttrs} disabled>
|
|
16
|
+
{{variantItem.title}} ${hasPrice}
|
|
17
|
+
</option>
|
|
18
|
+
{%- endif -%}
|
|
19
|
+
{%- else -%}
|
|
20
|
+
{%- if variantItem.id == variant.id -%}
|
|
21
|
+
<option origin-price="{{variantItem.price}}" ${hasPreSelected ? 'selected' : ''} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
22
|
+
{{variantItem.title}} ${hasPrice}
|
|
23
|
+
</option>
|
|
24
|
+
{% else %}
|
|
25
|
+
<option ${optionAttrs}>
|
|
26
|
+
{{variantItem.title}} ${hasPrice}
|
|
27
|
+
</option>
|
|
28
|
+
{%- endif -%}
|
|
29
|
+
{%- endif -%}` : `{%- if variantItem.id == variant.id -%}
|
|
30
|
+
<option origin-price="{{variantItem.price}}" ${hasPreSelected ? 'selected' : ''} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
31
|
+
{{variantItem.title}} ${hasPrice}
|
|
32
|
+
</option>
|
|
33
|
+
{% else %}
|
|
34
|
+
<option ${optionAttrs}>
|
|
35
|
+
{{variantItem.title}} ${hasPrice}
|
|
36
|
+
</option>
|
|
37
|
+
{%- endif -%}`}
|
|
38
|
+
|
|
39
|
+
{%- endfor -%}
|
|
40
|
+
`}`;
|
|
41
|
+
};
|
|
42
|
+
const renderBlankOption = (hasPreSelected, blankText)=>{
|
|
43
|
+
return !hasPreSelected ? `<option value="blank" selected>${blankText ?? helpers.getStaticLocale('ProductVariants', 'please_select')}</option>` : '';
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
exports.renderBlankOption = renderBlankOption;
|
|
47
|
+
exports.renderCombineVariants = renderCombineVariants;
|
|
@@ -28,7 +28,8 @@ const getSrcSetLiquid = (liquid, storage)=>{
|
|
|
28
28
|
return `{{ '${liquid}' | asset_img_url: '768x' }} 768w, {{ '${liquid}' | asset_img_url: '1024x' }} 1024w, {{ '${liquid}' | asset_img_url: 'master' }} 1440w`;
|
|
29
29
|
};
|
|
30
30
|
const getSrcSetLink = (link)=>{
|
|
31
|
-
return
|
|
31
|
+
return link; // Since image src didn't change in size so this line of code is pointless
|
|
32
|
+
// return `${link} 768w,${link} 1024w,${link} 1440w`;
|
|
32
33
|
};
|
|
33
34
|
const getImageSrc = (image, currentDevice)=>{
|
|
34
35
|
let src = image?.backupFilePath;
|
|
@@ -5,6 +5,7 @@ import { getStaticLocale, getSettingPreloadData } from '../../helpers.js';
|
|
|
5
5
|
const PRODUCT_ID_LATEST = 'latest';
|
|
6
6
|
const PREFIX_PRODUCT_ID = 'gid://shopify/Product/';
|
|
7
7
|
const PREFIX_PRODUCT_VARIANT_ID = 'gid://shopify/ProductVariant/';
|
|
8
|
+
const PREFIX_PRODUCT_OPTION_VALUE_ID = 'gid://shopify/ProductOptionValue/';
|
|
8
9
|
const STATIC_PRODUCT_STATUS = 'static';
|
|
9
10
|
const DYNAMIC_PRODUCT_STATUS = 'dynamic';
|
|
10
11
|
const Product = ({ children, setting, styles, style, builderProps, rawChildren, advanced })=>{
|
|
@@ -20,8 +21,8 @@ const Product = ({ children, setting, styles, style, builderProps, rawChildren,
|
|
|
20
21
|
const formatProductId = productSetting?.productId?.replace(PREFIX_PRODUCT_ID, '').toLowerCase() || PRODUCT_ID_LATEST;
|
|
21
22
|
const formatVariantId = initVariantId?.replace(PREFIX_PRODUCT_VARIANT_ID, '') || '';
|
|
22
23
|
const productStatus = productSetting?.productStatus ?? STATIC_PRODUCT_STATUS;
|
|
24
|
+
const preSelectedOptionIds = productSetting?.selectedOptions?.map((option)=>option?.valueBaseID?.replace(PREFIX_PRODUCT_OPTION_VALUE_ID, ''));
|
|
23
25
|
return template /* liquid */ `
|
|
24
|
-
|
|
25
26
|
{%- assign gpBkProduct = product -%}
|
|
26
27
|
${productStatus !== DYNAMIC_PRODUCT_STATUS ? `
|
|
27
28
|
{%- liquid
|
|
@@ -96,7 +97,7 @@ const Product = ({ children, setting, styles, style, builderProps, rawChildren,
|
|
|
96
97
|
{%- endif -%}
|
|
97
98
|
<gp-product data-uid="${builderProps?.uid}" data-id="${builderProps?.uid}" style="${{
|
|
98
99
|
...advancedStyle
|
|
99
|
-
}}" class="${advanced?.cssClass}" gp-context='{"productId": {{ product.id }}, "isSyncProduct": "${isSyncProduct}", "variantSelected": {{ variant | json | escape }}, "inventoryQuantity": {{ variant.inventory_quantity }}, "quantity": 1, "formId": "{{ product_form_id }}" }'
|
|
100
|
+
}}" class="${advanced?.cssClass}" gp-context='{"productId": {{ product.id }}, "preSelectedOptionIds": [${preSelectedOptionIds}], "isSyncProduct": "${isSyncProduct}", "variantSelected": {{ variant | json | escape }}, "inventoryQuantity": {{ variant.inventory_quantity }}, "quantity": 1, "formId": "{{ product_form_id }}" }'
|
|
100
101
|
gp-data='{"variantSelected": {{ variant | json | escape }}, "quantity": 1, "productUrl":{{ product.url | json | escape }}, "productHandle":{{ product.handle | json | escape }}, "collectionUrl": {{ collection.url | json | escape }}, "collectionHandle": {{ collection.handle | json | escape }}}'>
|
|
101
102
|
<product-form class="product-form">
|
|
102
103
|
{%- form 'product', product, id: product_form_id, class: 'form contents', data-type: 'add-to-cart-form', autocomplete: 'off' -%}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { makeStyleResponsive, makeWidth, composeMemo, composeTypographyClassName, template, optionLayoutStyle, RenderIf, isLocalEnv, baseAssetURL, cls, makeStyle, getResponsiveValueByScreen } from '@gem-sdk/core';
|
|
1
|
+
import { makeStyleResponsive, makeWidth, composeMemo, composeTypographyClassName, template, optionLayoutStyle, RenderIf, isLocalEnv, baseAssetURL, cls, getLayoutClasses, getAlignmentClasses, makeStyle, getResponsiveValueByScreen } from '@gem-sdk/core';
|
|
2
2
|
import Text from '../../../text/components/Text.liquid.js';
|
|
3
3
|
import VariantItem from './variants/index.liquid.js';
|
|
4
4
|
import DropdownVariant from './variants/Dropdown.liquid.js';
|
|
@@ -93,15 +93,9 @@ const ProductVariants = ({ builderProps, style, styles, setting, advanced })=>{
|
|
|
93
93
|
<div
|
|
94
94
|
option-name="{{option.name | escape}}"
|
|
95
95
|
class="${cls('gp-flex variant-inside', {
|
|
96
|
-
|
|
97
|
-
'gp-flex-row': layout?.desktop === 'horizontal',
|
|
98
|
-
'tablet:gp-flex-row': layout?.tablet === 'horizontal',
|
|
99
|
-
'tablet:gp-flex-col': layout?.tablet === 'vertical',
|
|
100
|
-
'mobile:gp-flex-row': layout?.mobile === 'horizontal',
|
|
101
|
-
'mobile:gp-flex-col': layout?.mobile === 'vertical'
|
|
102
|
-
}, {
|
|
96
|
+
...getLayoutClasses(layout),
|
|
103
97
|
...getAlignClasses(layout, align)
|
|
104
|
-
})}
|
|
98
|
+
})}"
|
|
105
99
|
|
|
106
100
|
>
|
|
107
101
|
{% assign showVariantClass = 'variant-display' %}
|
|
@@ -133,15 +127,7 @@ const ProductVariants = ({ builderProps, style, styles, setting, advanced })=>{
|
|
|
133
127
|
<div
|
|
134
128
|
variant-option-name="{{option.name | escape}}"
|
|
135
129
|
class="${cls({
|
|
136
|
-
|
|
137
|
-
'gp-justify-center': align?.desktop === 'center',
|
|
138
|
-
'gp-justify-end': align?.desktop === 'right',
|
|
139
|
-
'tablet:gp-justify-start': align?.tablet === 'left',
|
|
140
|
-
'tablet:gp-justify-center': align?.tablet === 'center',
|
|
141
|
-
'tablet:gp-justify-end': align?.tablet === 'right',
|
|
142
|
-
'mobile:gp-justify-start': align?.mobile === 'left',
|
|
143
|
-
'mobile:gp-justify-center': align?.mobile === 'center',
|
|
144
|
-
'mobile:gp-justify-end': align?.mobile === 'right'
|
|
130
|
+
...getAlignmentClasses(align)
|
|
145
131
|
}, 'gp-flex gp-w-full gp-flex-wrap gp-items-center variant-option-group')}"
|
|
146
132
|
style="${{
|
|
147
133
|
...makeStyle({
|
|
@@ -324,6 +310,10 @@ const ProductVariants = ({ builderProps, style, styles, setting, advanced })=>{
|
|
|
324
310
|
`;
|
|
325
311
|
};
|
|
326
312
|
return template`
|
|
313
|
+
{%- assign total_combinations = 1 -%}
|
|
314
|
+
{%- for option in product.options_with_values -%}
|
|
315
|
+
{%- assign total_combinations = total_combinations | times: option.values.size -%}
|
|
316
|
+
{%- endfor -%}
|
|
327
317
|
<gp-product-variants
|
|
328
318
|
data-id="${uid}"
|
|
329
319
|
class="${advanced?.cssClass}"
|
|
@@ -339,7 +329,10 @@ const ProductVariants = ({ builderProps, style, styles, setting, advanced })=>{
|
|
|
339
329
|
"moneyFormat": {{shop.money_format | json | escape}},
|
|
340
330
|
"productId": {{product.id | json | escape}},
|
|
341
331
|
"productUrl": {{product.url | json | escape}},
|
|
342
|
-
"
|
|
332
|
+
"productHandle": {{product.handle | json | escape}},
|
|
333
|
+
"displayState": ${JSON.stringify(advancedDisplay)},
|
|
334
|
+
"totalVariantCombinations": {{total_combinations}},
|
|
335
|
+
"firstAvailableVariant": {{product.selected_or_first_available_variant | json | escape}}
|
|
343
336
|
}
|
|
344
337
|
'>
|
|
345
338
|
{%- assign options = product.options_with_values -%}
|
|
@@ -152,6 +152,7 @@ const BaseVariant = ({ optionTransform, optionTypography, optionBgColor, optionT
|
|
|
152
152
|
option-data="{{option.name | escape}}"
|
|
153
153
|
option-value="{{value | escape}}"
|
|
154
154
|
option-position="{{option.position}}"
|
|
155
|
+
data-gp-option-available="{{value.available}}"
|
|
155
156
|
option-type="${type || 'rectangle_list'}"
|
|
156
157
|
data-disabled="{%- if option_disabled == true -%} disabled {%- endif -%}"
|
|
157
158
|
data-hidden='true'
|
|
@@ -14,6 +14,15 @@ const DropdownVariant = ({ variantGroup, blankText, swatchAutoWidth, swatchHeigh
|
|
|
14
14
|
};
|
|
15
15
|
const appendTypoClass = composeTypographyClassName(optionTypo, optionTypography);
|
|
16
16
|
const appendTypoStyle = composeTypographyStyle(optionTypo, optionTypography);
|
|
17
|
+
const composeSelectOptionAttrs = `
|
|
18
|
+
option-data="{{option.name | escape}}"
|
|
19
|
+
option-value="{{value | escape}}"
|
|
20
|
+
data-gp-option-value-id="{{value.id}}"
|
|
21
|
+
data-gp-option-available="{{value.available}}"
|
|
22
|
+
value="{{value | escape}}"
|
|
23
|
+
class="option-value-wrapper"
|
|
24
|
+
key="{{value | escape}}"
|
|
25
|
+
`;
|
|
17
26
|
return template /* liquid */ `
|
|
18
27
|
<select
|
|
19
28
|
aria-label={{option.name | escape}}
|
|
@@ -69,37 +78,42 @@ const DropdownVariant = ({ variantGroup, blankText, swatchAutoWidth, swatchHeigh
|
|
|
69
78
|
-%}
|
|
70
79
|
${isSoldOutMark ? `{%- if option_disabled == true -%}
|
|
71
80
|
{%- if value == selectedValue -%}
|
|
72
|
-
<option disabled ${!hasPreSelected ? '' : 'selected'}
|
|
81
|
+
<option disabled ${!hasPreSelected ? '' : 'selected'}
|
|
73
82
|
option-position="{{option.position}}"
|
|
74
|
-
|
|
83
|
+
${composeSelectOptionAttrs}>
|
|
75
84
|
{{value}}
|
|
76
85
|
</option>
|
|
77
86
|
{% else %}
|
|
78
|
-
<option
|
|
79
|
-
|
|
87
|
+
<option
|
|
88
|
+
disabled
|
|
89
|
+
${composeSelectOptionAttrs}>
|
|
80
90
|
{{value}}
|
|
81
91
|
</option>
|
|
82
92
|
{%- endif -%}
|
|
83
93
|
{%- else -%}
|
|
84
94
|
{%- if value == selectedValue -%}
|
|
85
|
-
<option ${!hasPreSelected ? '' : 'selected'}
|
|
86
|
-
option-
|
|
95
|
+
<option ${!hasPreSelected ? '' : 'selected'}
|
|
96
|
+
option-position="{{option.position}}"
|
|
97
|
+
${composeSelectOptionAttrs}>
|
|
87
98
|
{{value}}
|
|
88
99
|
</option>
|
|
89
100
|
{% else %}
|
|
90
|
-
<option
|
|
91
|
-
|
|
101
|
+
<option
|
|
102
|
+
${composeSelectOptionAttrs}
|
|
103
|
+
option-position="{{option.position}}">
|
|
92
104
|
{{value}}
|
|
93
105
|
</option>
|
|
94
106
|
{%- endif -%}
|
|
95
107
|
{%- endif -%}` : `{%- if value == selectedValue -%}
|
|
96
|
-
<option ${!hasPreSelected ? '' : 'selected'}
|
|
97
|
-
|
|
108
|
+
<option ${!hasPreSelected ? '' : 'selected'}
|
|
109
|
+
${composeSelectOptionAttrs}
|
|
110
|
+
option-position="{{option.position}}">
|
|
98
111
|
{{value}}
|
|
99
112
|
</option>
|
|
100
113
|
{% else %}
|
|
101
|
-
<option
|
|
102
|
-
|
|
114
|
+
<option
|
|
115
|
+
${composeSelectOptionAttrs}
|
|
116
|
+
option-position="{{option.position}}">
|
|
103
117
|
{{value}}
|
|
104
118
|
</option>
|
|
105
119
|
{%- endif -%}`}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { makeStyleResponsive, makeWidth, composeTypographyClassName, composeTypographyStyle, template, cls, handleConvertClassColor, getGlobalColorStateClass, getStyleShadowState, makeStyle, getGlobalColorStateStyle, handleConvertBorderStyle, handleConvertBorderWidth, handleConvertBorderColor, composeRadius, getSingleColorVariable } from '@gem-sdk/core';
|
|
2
|
-
import {
|
|
2
|
+
import { renderBlankOption, renderCombineVariants } from './combine/index.js';
|
|
3
3
|
|
|
4
|
-
const DropdownVariant = ({ price, blankText, optionTypography, optionBgColor, optionTextColor, optionRounded, optionShadow, optionHasShadow, optionBorder, optionTransform, hasPreSelected, optionTypo, combineWidth, combineHeight, soldOutStyle })=>{
|
|
4
|
+
const DropdownVariant = ({ price: hasPrice, blankText, optionTypography, optionBgColor, optionTextColor, optionRounded, optionShadow, optionHasShadow, optionBorder, optionTransform, hasPreSelected, optionTypo, combineWidth, combineHeight, soldOutStyle })=>{
|
|
5
5
|
const swatchWidthResponsive = makeStyleResponsive('w', makeWidth(combineWidth));
|
|
6
6
|
const getCustomCSSActiveState = ()=>{
|
|
7
7
|
return makeStyle({
|
|
@@ -23,7 +23,6 @@ const DropdownVariant = ({ price, blankText, optionTypography, optionBgColor, op
|
|
|
23
23
|
option-data="{{option.name}}"
|
|
24
24
|
option-type="{{optionType}}"
|
|
25
25
|
class="${cls('gp-truncate gp-bg-auto gp-pl-4 gp-pr-6 gp-outline-none dropdown-option-item', handleConvertClassColor(optionBorder), appendTypoClass, getGlobalColorStateClass('text', optionTextColor), getGlobalColorStateClass('bg', optionBgColor), 'gp-outline-none', 'gp-shadow-none')}"
|
|
26
|
-
|
|
27
26
|
style="${{
|
|
28
27
|
...getStyleShadowState(optionShadow, 'box-shadow', optionHasShadow),
|
|
29
28
|
...getCustomCSSActiveState(),
|
|
@@ -45,40 +44,8 @@ const DropdownVariant = ({ price, blankText, optionTypography, optionBgColor, op
|
|
|
45
44
|
'background-position': 'right 16px center'
|
|
46
45
|
}}"
|
|
47
46
|
>
|
|
48
|
-
${
|
|
49
|
-
${
|
|
50
|
-
${isSoldOutMark ? `{%- if variantItem.available == false -%}
|
|
51
|
-
{%- if variantItem.id == variant.id -%}
|
|
52
|
-
<option origin-price="{{variantItem.price}}" disabled ${!hasPreSelected ? '' : 'selected'} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
53
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
54
|
-
</option>
|
|
55
|
-
{% else %}
|
|
56
|
-
<option origin-price="{{variantItem.price}}" disabled value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
57
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
58
|
-
</option>
|
|
59
|
-
{%- endif -%}
|
|
60
|
-
{%- else -%}
|
|
61
|
-
{%- if variantItem.id == variant.id -%}
|
|
62
|
-
<option origin-price="{{variantItem.price}}" ${!hasPreSelected ? '' : 'selected'} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
63
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
64
|
-
</option>
|
|
65
|
-
{% else %}
|
|
66
|
-
<option origin-price="{{variantItem.price}}" value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
67
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
68
|
-
</option>
|
|
69
|
-
{%- endif -%}
|
|
70
|
-
{%- endif -%}` : `{%- if variantItem.id == variant.id -%}
|
|
71
|
-
<option origin-price="{{variantItem.price}}" ${!hasPreSelected ? '' : 'selected'} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
72
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
73
|
-
</option>
|
|
74
|
-
{% else %}
|
|
75
|
-
<option origin-price="{{variantItem.price}}" value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
76
|
-
{{variantItem.title}} ${price ? '- {{variantItem.price | money}}' : ''}
|
|
77
|
-
</option>
|
|
78
|
-
{%- endif -%}`}
|
|
79
|
-
|
|
80
|
-
{%- endfor -%}
|
|
81
|
-
`}
|
|
47
|
+
${renderBlankOption(hasPreSelected, blankText)}
|
|
48
|
+
${renderCombineVariants(isSoldOutMark, hasPreSelected, hasPrice)}
|
|
82
49
|
</select>
|
|
83
50
|
`;
|
|
84
51
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { getStaticLocale } from '../../../../../helpers.js';
|
|
2
|
+
|
|
3
|
+
const renderCombineVariants = (isSoldOutMark, hasPreSelected, enablePrice)=>{
|
|
4
|
+
const hasPrice = enablePrice ? '- {{variantItem.price | money}}' : '';
|
|
5
|
+
const optionAttrs = 'origin-price="{{variantItem.price}}" value="{{variantItem.id}}" key="{{variantItem.id}}"';
|
|
6
|
+
return `${`{%- for variantItem in variants -%}
|
|
7
|
+
${isSoldOutMark ? `{%- if variantItem.available == false -%}
|
|
8
|
+
{%- if variantItem.id == variant.id -%}
|
|
9
|
+
<option origin-price="{{variantItem.price}}" disabled ${hasPreSelected ? 'selected' : ''} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
10
|
+
{{variantItem.title}} ${hasPrice} : ''}
|
|
11
|
+
</option>
|
|
12
|
+
{% else %}
|
|
13
|
+
<option ${optionAttrs} disabled>
|
|
14
|
+
{{variantItem.title}} ${hasPrice}
|
|
15
|
+
</option>
|
|
16
|
+
{%- endif -%}
|
|
17
|
+
{%- else -%}
|
|
18
|
+
{%- if variantItem.id == variant.id -%}
|
|
19
|
+
<option origin-price="{{variantItem.price}}" ${hasPreSelected ? 'selected' : ''} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
20
|
+
{{variantItem.title}} ${hasPrice}
|
|
21
|
+
</option>
|
|
22
|
+
{% else %}
|
|
23
|
+
<option ${optionAttrs}>
|
|
24
|
+
{{variantItem.title}} ${hasPrice}
|
|
25
|
+
</option>
|
|
26
|
+
{%- endif -%}
|
|
27
|
+
{%- endif -%}` : `{%- if variantItem.id == variant.id -%}
|
|
28
|
+
<option origin-price="{{variantItem.price}}" ${hasPreSelected ? 'selected' : ''} value="{{variantItem.id}}" key="{{variantItem.id}}">
|
|
29
|
+
{{variantItem.title}} ${hasPrice}
|
|
30
|
+
</option>
|
|
31
|
+
{% else %}
|
|
32
|
+
<option ${optionAttrs}>
|
|
33
|
+
{{variantItem.title}} ${hasPrice}
|
|
34
|
+
</option>
|
|
35
|
+
{%- endif -%}`}
|
|
36
|
+
|
|
37
|
+
{%- endfor -%}
|
|
38
|
+
`}`;
|
|
39
|
+
};
|
|
40
|
+
const renderBlankOption = (hasPreSelected, blankText)=>{
|
|
41
|
+
return !hasPreSelected ? `<option value="blank" selected>${blankText ?? getStaticLocale('ProductVariants', 'please_select')}</option>` : '';
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export { renderBlankOption, renderCombineVariants };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1361,6 +1361,12 @@ type ProductSetting = {
|
|
|
1361
1361
|
initialVariantId?: string;
|
|
1362
1362
|
initialVariantBaseId?: string;
|
|
1363
1363
|
productHandle?: string;
|
|
1364
|
+
selectedOptions?: {
|
|
1365
|
+
name: string;
|
|
1366
|
+
value: string;
|
|
1367
|
+
optionType: string;
|
|
1368
|
+
valueBaseID: string;
|
|
1369
|
+
}[];
|
|
1364
1370
|
};
|
|
1365
1371
|
discountType?: 'PERCENTAGE' | 'FIXED_AMOUNT';
|
|
1366
1372
|
discountValue?: number;
|
|
@@ -5592,6 +5598,12 @@ declare const Product: ({ children, setting, styles, style, builderProps, rawChi
|
|
|
5592
5598
|
initialVariantId?: string | undefined;
|
|
5593
5599
|
initialVariantBaseId?: string | undefined;
|
|
5594
5600
|
productHandle?: string | undefined;
|
|
5601
|
+
selectedOptions?: {
|
|
5602
|
+
name: string;
|
|
5603
|
+
value: string;
|
|
5604
|
+
optionType: string;
|
|
5605
|
+
valueBaseID: string;
|
|
5606
|
+
}[] | undefined;
|
|
5595
5607
|
} | undefined;
|
|
5596
5608
|
discountType?: "FIXED_AMOUNT" | "PERCENTAGE" | undefined;
|
|
5597
5609
|
discountValue?: number | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gem-sdk/components",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.36",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"format": "prettier --write \"./src/**/*.{ts,tsx}\""
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@gem-sdk/core": "2.1.
|
|
24
|
+
"@gem-sdk/core": "2.1.36",
|
|
25
25
|
"@gem-sdk/styles": "2.1.31",
|
|
26
26
|
"@types/react-transition-group": "^4.4.5"
|
|
27
27
|
},
|