fontdue-js 2.24.0 → 2.25.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/CHANGELOG.md +5 -0
- package/dist/components/CartButton/index.js +6 -2
- package/dist/components/ConfigContext.d.ts +2 -0
- package/dist/components/ConfigContext.js +3 -2
- package/dist/components/StoreModal/StoreModalContainer.js +22 -10
- package/dist/components/StoreModal/types.d.ts +1 -0
- package/dist/components/elements/EmptyCart/index.js +22 -8
- package/dist/fontdue.css +63 -17
- package/dist/reducer.js +9 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 2.25.0
|
|
2
|
+
|
|
3
|
+
- Added `storeModal.hideAllCollections` config option (default `false`). When `true`, the store modal skips the "All collections" landing page — the modal opens directly to the cart route, the cart button always opens the cart regardless of item count, the empty-cart "Continue shopping" button closes the modal, and the product/checkout back button becomes "Close" when there's no history. Useful for stores that drive purchases from "Add to Cart" buttons on product pages.
|
|
4
|
+
- Improved the empty-cart layout: added a "Your cart is empty." message and the modal now collapses to its default 800px width when empty (instead of staying at the wider cart width).
|
|
5
|
+
|
|
1
6
|
## 2.24.0
|
|
2
7
|
|
|
3
8
|
- The cart's licensee picker now reads its button labels and per-option descriptions from tenant settings, so admins can rename "Yourself" / "Your client" and add explainer text without a code change.
|
|
@@ -12,6 +12,7 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
12
12
|
var _reactRedux = require("react-redux");
|
|
13
13
|
var _reactRelay = require("react-relay");
|
|
14
14
|
var _ComponentsContext = _interopRequireDefault(require("../ComponentsContext"));
|
|
15
|
+
var _ConfigContext = _interopRequireDefault(require("../ConfigContext"));
|
|
15
16
|
var _Icons = require("../Icons");
|
|
16
17
|
var _useSerializablePreloadedQuery = _interopRequireDefault(require("../../relay/useSerializablePreloadedQuery"));
|
|
17
18
|
var _Price = _interopRequireWildcard(require("../Price"));
|
|
@@ -40,6 +41,9 @@ function CartButtonComponent(_ref) {
|
|
|
40
41
|
const orderData = (0, _reactRelay.useFragment)((_CartButton_order2.default.hash && _CartButton_order2.default.hash !== "26a092d7efb579c98adda18413349b3b" && console.error("The definition of 'CartButton_order' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _CartButton_order2.default), orderKey);
|
|
41
42
|
const [count, setCount] = (0, _react.useState)(0);
|
|
42
43
|
const dispatch = (0, _reactRedux.useDispatch)();
|
|
44
|
+
const {
|
|
45
|
+
storeModal: storeModalConfig
|
|
46
|
+
} = (0, _react.useContext)(_ConfigContext.default);
|
|
43
47
|
const formatSuffix = (0, _react.useCallback)(() => {
|
|
44
48
|
if (!suffix) return null;
|
|
45
49
|
|
|
@@ -77,14 +81,14 @@ function CartButtonComponent(_ref) {
|
|
|
77
81
|
return nodes.length > 0 ? nodes : null;
|
|
78
82
|
}, [suffix, count, orderData === null || orderData === void 0 ? void 0 : orderData.subtotal]);
|
|
79
83
|
const handleClick = (0, _react.useCallback)(() => {
|
|
80
|
-
if (count > 0) {
|
|
84
|
+
if (count > 0 || storeModalConfig.hideAllCollections) {
|
|
81
85
|
dispatch({
|
|
82
86
|
type: 'STORE_MODAL_REPLACE',
|
|
83
87
|
route: 'cart'
|
|
84
88
|
});
|
|
85
89
|
}
|
|
86
90
|
dispatch(openCart());
|
|
87
|
-
}, [count, dispatch]);
|
|
91
|
+
}, [count, dispatch, storeModalConfig.hideAllCollections]);
|
|
88
92
|
(0, _react.useEffect)(() => {
|
|
89
93
|
// set count only on the client, because on the server it's always gonna be zero
|
|
90
94
|
setCount(cartButtonCount(orderData));
|
|
@@ -90,6 +90,7 @@ export declare const makeConfig: (config?: Config) => {
|
|
|
90
90
|
indexLayout: "styled-aa" | "styled-font-names";
|
|
91
91
|
indexExcludeTags: string[] | undefined;
|
|
92
92
|
productLicensesPosition: "top" | "bottom";
|
|
93
|
+
hideAllCollections: boolean;
|
|
93
94
|
};
|
|
94
95
|
stripe: {
|
|
95
96
|
appearance: Appearance | null;
|
|
@@ -161,6 +162,7 @@ declare const _default: React.Context<{
|
|
|
161
162
|
indexLayout: "styled-aa" | "styled-font-names";
|
|
162
163
|
indexExcludeTags: string[] | undefined;
|
|
163
164
|
productLicensesPosition: "top" | "bottom";
|
|
165
|
+
hideAllCollections: boolean;
|
|
164
166
|
};
|
|
165
167
|
stripe: {
|
|
166
168
|
appearance: Appearance | null;
|
|
@@ -59,7 +59,7 @@ const makeTypeTesterConfig = config => {
|
|
|
59
59
|
};
|
|
60
60
|
};
|
|
61
61
|
const makeConfig = config => {
|
|
62
|
-
var _config$form, _config$storeModal, _config$storeModal2, _config$storeModal3, _config$stripe, _config$tracking, _config$tracking2, _config$tracking3, _config$tracking4;
|
|
62
|
+
var _config$form, _config$storeModal, _config$storeModal2, _config$storeModal3, _config$storeModal4, _config$stripe, _config$tracking, _config$tracking2, _config$tracking3, _config$tracking4;
|
|
63
63
|
return {
|
|
64
64
|
typeTester: makeTypeTesterConfig(config === null || config === void 0 ? void 0 : config.typeTester),
|
|
65
65
|
form: {
|
|
@@ -68,7 +68,8 @@ const makeConfig = config => {
|
|
|
68
68
|
storeModal: {
|
|
69
69
|
indexLayout: (config === null || config === void 0 ? void 0 : (_config$storeModal = config.storeModal) === null || _config$storeModal === void 0 ? void 0 : _config$storeModal.indexLayout) ?? 'styled-aa',
|
|
70
70
|
indexExcludeTags: config === null || config === void 0 ? void 0 : (_config$storeModal2 = config.storeModal) === null || _config$storeModal2 === void 0 ? void 0 : _config$storeModal2.indexExcludeTags,
|
|
71
|
-
productLicensesPosition: (config === null || config === void 0 ? void 0 : (_config$storeModal3 = config.storeModal) === null || _config$storeModal3 === void 0 ? void 0 : _config$storeModal3.productLicensesPosition) ?? 'top'
|
|
71
|
+
productLicensesPosition: (config === null || config === void 0 ? void 0 : (_config$storeModal3 = config.storeModal) === null || _config$storeModal3 === void 0 ? void 0 : _config$storeModal3.productLicensesPosition) ?? 'top',
|
|
72
|
+
hideAllCollections: (config === null || config === void 0 ? void 0 : (_config$storeModal4 = config.storeModal) === null || _config$storeModal4 === void 0 ? void 0 : _config$storeModal4.hideAllCollections) ?? false
|
|
72
73
|
},
|
|
73
74
|
stripe: {
|
|
74
75
|
appearance: (config === null || config === void 0 ? void 0 : (_config$stripe = config.stripe) === null || _config$stripe === void 0 ? void 0 : _config$stripe.appearance) ?? null
|
|
@@ -31,8 +31,14 @@ const getPageTitle = name => {
|
|
|
31
31
|
return 'Review';
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
|
-
const getBackLink = (history, currentRoute) => {
|
|
35
|
-
if (
|
|
34
|
+
const getBackLink = (history, currentRoute, hideAllCollections) => {
|
|
35
|
+
if (history.length === 0) {
|
|
36
|
+
if (hideAllCollections) {
|
|
37
|
+
return currentRoute === 'cart' ? null : 'Close';
|
|
38
|
+
}
|
|
39
|
+
if (currentRoute !== 'index') return 'All collections';
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
36
42
|
const previous = history[history.length - 1];
|
|
37
43
|
if (!previous) return null;
|
|
38
44
|
return getPageTitle(previous.name);
|
|
@@ -61,17 +67,23 @@ const StoreModalContainer = _ref => {
|
|
|
61
67
|
}, [dispatch]);
|
|
62
68
|
const currentRoute = (0, _reactRedux.useSelector)(state => state.storeModalRoute.name);
|
|
63
69
|
const history = (0, _reactRedux.useSelector)(state => state.storeModalHistory);
|
|
64
|
-
const link = getBackLink(history, currentRoute);
|
|
65
70
|
const config = (0, _react.useContext)(_ConfigContext.default);
|
|
71
|
+
const link = getBackLink(history, currentRoute, config.storeModal.hideAllCollections);
|
|
66
72
|
const handleBack = () => {
|
|
67
73
|
if (history.length === 0) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
if (config.storeModal.hideAllCollections) {
|
|
75
|
+
dispatch({
|
|
76
|
+
type: 'CLOSE_CART'
|
|
77
|
+
});
|
|
78
|
+
} else {
|
|
79
|
+
dispatch({
|
|
80
|
+
type: 'STORE_MODAL_REPLACE',
|
|
81
|
+
route: 'index',
|
|
82
|
+
variables: {
|
|
83
|
+
excludeTags: config.storeModal.indexExcludeTags
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
75
87
|
} else {
|
|
76
88
|
dispatch({
|
|
77
89
|
type: 'STORE_MODAL_BACK'
|
|
@@ -14,16 +14,30 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
14
14
|
const EmptyCart = () => {
|
|
15
15
|
const dispatch = (0, _reactRedux.useDispatch)();
|
|
16
16
|
const config = (0, _react.useContext)(_ConfigContext.default);
|
|
17
|
+
const {
|
|
18
|
+
hideAllCollections
|
|
19
|
+
} = config.storeModal;
|
|
20
|
+
const handleContinueShopping = () => {
|
|
21
|
+
if (hideAllCollections) {
|
|
22
|
+
dispatch({
|
|
23
|
+
type: 'CLOSE_CART'
|
|
24
|
+
});
|
|
25
|
+
} else {
|
|
26
|
+
dispatch({
|
|
27
|
+
type: 'STORE_MODAL_NAVIGATE',
|
|
28
|
+
route: 'index',
|
|
29
|
+
variables: {
|
|
30
|
+
excludeTags: config.storeModal.indexExcludeTags
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
};
|
|
17
35
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
18
36
|
className: "empty-cart__container"
|
|
19
|
-
}, /*#__PURE__*/_react.default.createElement(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
variables: {
|
|
24
|
-
excludeTags: config.storeModal.indexExcludeTags
|
|
25
|
-
}
|
|
26
|
-
})
|
|
37
|
+
}, /*#__PURE__*/_react.default.createElement("p", {
|
|
38
|
+
className: "empty-cart__message"
|
|
39
|
+
}, "Your cart is empty."), /*#__PURE__*/_react.default.createElement(_Button.default, {
|
|
40
|
+
onClick: handleContinueShopping
|
|
27
41
|
}, "Continue shopping"));
|
|
28
42
|
};
|
|
29
43
|
var _default = EmptyCart;
|
package/dist/fontdue.css
CHANGED
|
@@ -1272,6 +1272,17 @@ body[data-fontdue-store-modal=open] {
|
|
|
1272
1272
|
grid-column: 1/span 2;
|
|
1273
1273
|
}
|
|
1274
1274
|
|
|
1275
|
+
.store-modal__cart__items {
|
|
1276
|
+
--gutter: 20px;
|
|
1277
|
+
}
|
|
1278
|
+
@media (min-width: 900px) {
|
|
1279
|
+
.store-modal__cart__items {
|
|
1280
|
+
display: grid;
|
|
1281
|
+
grid-template-columns: [name] 300fr [licenses] 700fr [price] minmax(80px, auto) [end];
|
|
1282
|
+
column-gap: var(--gutter);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1275
1286
|
.store-modal__cart__button {
|
|
1276
1287
|
background: none;
|
|
1277
1288
|
color: inherit;
|
|
@@ -1780,6 +1791,12 @@ body[data-fontdue-store-modal=open] {
|
|
|
1780
1791
|
font-size: 20px;
|
|
1781
1792
|
}
|
|
1782
1793
|
|
|
1794
|
+
.store-modal__page__body:has(> .store-modal__index-item__button) {
|
|
1795
|
+
display: grid;
|
|
1796
|
+
grid-template-columns: auto 1fr auto;
|
|
1797
|
+
column-gap: 16px;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1783
1800
|
.store-modal__index-item__button {
|
|
1784
1801
|
background: none;
|
|
1785
1802
|
color: inherit;
|
|
@@ -1803,24 +1820,19 @@ body[data-fontdue-store-modal=open] {
|
|
|
1803
1820
|
width: 100%;
|
|
1804
1821
|
border: 1px solid var(--secondary_text_color);
|
|
1805
1822
|
padding: 20px;
|
|
1806
|
-
display:
|
|
1823
|
+
display: grid;
|
|
1824
|
+
grid-template-columns: subgrid;
|
|
1825
|
+
grid-column: 1/-1;
|
|
1807
1826
|
align-items: center;
|
|
1808
1827
|
margin-bottom: 20px;
|
|
1809
1828
|
}
|
|
1810
1829
|
|
|
1811
1830
|
.store-modal__index-item__text-container {
|
|
1812
|
-
display:
|
|
1813
|
-
vertical-align: baseline;
|
|
1831
|
+
display: contents;
|
|
1814
1832
|
}
|
|
1815
1833
|
|
|
1816
1834
|
.store-modal__index-item__aa {
|
|
1817
1835
|
font-size: 60px;
|
|
1818
|
-
margin-right: 16px;
|
|
1819
|
-
display: inline-block;
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
.store-modal__index-item__description {
|
|
1823
|
-
display: inline-block;
|
|
1824
1836
|
}
|
|
1825
1837
|
|
|
1826
1838
|
.store-modal__index-item__name {
|
|
@@ -1828,10 +1840,23 @@ body[data-fontdue-store-modal=open] {
|
|
|
1828
1840
|
line-height: 30px;
|
|
1829
1841
|
}
|
|
1830
1842
|
|
|
1831
|
-
|
|
1832
|
-
|
|
1843
|
+
@media (max-width: 899px) {
|
|
1844
|
+
.store-modal__page__body:has(> .store-modal__index-item__button) {
|
|
1845
|
+
display: block;
|
|
1846
|
+
}
|
|
1847
|
+
.store-modal__index-item__button {
|
|
1848
|
+
display: flex;
|
|
1849
|
+
align-items: last baseline;
|
|
1850
|
+
}
|
|
1851
|
+
.store-modal__index-item__text-container,
|
|
1852
|
+
.store-modal__index-item__aa,
|
|
1853
|
+
.store-modal__index-item__description {
|
|
1854
|
+
display: block;
|
|
1855
|
+
}
|
|
1856
|
+
.store-modal__index-item__buy {
|
|
1857
|
+
margin-left: auto;
|
|
1858
|
+
}
|
|
1833
1859
|
}
|
|
1834
|
-
|
|
1835
1860
|
.store-modal__license-selection__container[data-disabled=true] {
|
|
1836
1861
|
opacity: 0.2;
|
|
1837
1862
|
pointer-events: none;
|
|
@@ -2347,9 +2372,32 @@ body[data-fontdue-store-modal=open] {
|
|
|
2347
2372
|
font-size: 20px;
|
|
2348
2373
|
}
|
|
2349
2374
|
|
|
2375
|
+
@media (max-width: 899px) {
|
|
2376
|
+
.store-modal__family__bundle-button .store-modal__style-button__container {
|
|
2377
|
+
flex-wrap: wrap;
|
|
2378
|
+
}
|
|
2379
|
+
.store-modal__family__bundle-button .store-modal__style-button__feature-glyphs {
|
|
2380
|
+
flex: 0 0 100%;
|
|
2381
|
+
}
|
|
2382
|
+
.store-modal__family__bundle-button .store-modal__style-button__style-name {
|
|
2383
|
+
flex: 1 1 0;
|
|
2384
|
+
min-width: 0;
|
|
2385
|
+
}
|
|
2386
|
+
.store-modal__family__bundle-button .store-modal__style-button__price {
|
|
2387
|
+
align-self: flex-end;
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
.empty-cart__container {
|
|
2391
|
+
padding: 40px 0;
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2350
2394
|
.empty-cart__message {
|
|
2351
2395
|
font-size: 20px;
|
|
2352
|
-
margin
|
|
2396
|
+
margin: 0 0 32px;
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
[data-route=cart]:has(.empty-cart__container) .store-modal__container__container {
|
|
2400
|
+
max-width: 800px;
|
|
2353
2401
|
}
|
|
2354
2402
|
|
|
2355
2403
|
.cart-additions__form {
|
|
@@ -2496,7 +2544,6 @@ body[data-fontdue-store-modal=open] {
|
|
|
2496
2544
|
padding-right: var(--StoreModalPageContainer-padding);
|
|
2497
2545
|
padding-bottom: 40px;
|
|
2498
2546
|
line-height: 20px;
|
|
2499
|
-
--gutter: 20px;
|
|
2500
2547
|
}
|
|
2501
2548
|
.cart-item + .cart-item {
|
|
2502
2549
|
border-top: 1px solid var(--horizontal_rule_color);
|
|
@@ -2519,9 +2566,8 @@ body[data-fontdue-store-modal=open] {
|
|
|
2519
2566
|
.cart-item {
|
|
2520
2567
|
display: grid;
|
|
2521
2568
|
align-items: baseline;
|
|
2522
|
-
grid-template-columns:
|
|
2523
|
-
grid-
|
|
2524
|
-
grid-column-gap: var(--gutter);
|
|
2569
|
+
grid-template-columns: subgrid;
|
|
2570
|
+
grid-column: 1/-1;
|
|
2525
2571
|
padding-bottom: 30px;
|
|
2526
2572
|
margin-bottom: 0;
|
|
2527
2573
|
}
|
package/dist/reducer.js
CHANGED
|
@@ -269,6 +269,14 @@ const reducer = (state, action) => {
|
|
|
269
269
|
};
|
|
270
270
|
function createDefaultStore(config) {
|
|
271
271
|
const configValue = (0, _ConfigContext.makeConfig)(config);
|
|
272
|
+
const initialRoute = configValue.storeModal.hideAllCollections ? {
|
|
273
|
+
name: 'cart'
|
|
274
|
+
} : {
|
|
275
|
+
name: 'index',
|
|
276
|
+
variables: {
|
|
277
|
+
excludeTags: configValue.storeModal.indexExcludeTags
|
|
278
|
+
}
|
|
279
|
+
};
|
|
272
280
|
return (0, _redux.createStore)(reducer, {
|
|
273
281
|
selectedSkuIds: {},
|
|
274
282
|
// { [skuId]: Boolean }
|
|
@@ -279,12 +287,7 @@ function createDefaultStore(config) {
|
|
|
279
287
|
skuPrices: {},
|
|
280
288
|
collectionSkus: {},
|
|
281
289
|
fetchedCollectionIds: [],
|
|
282
|
-
storeModalRoute:
|
|
283
|
-
name: 'index',
|
|
284
|
-
variables: {
|
|
285
|
-
excludeTags: configValue.storeModal.indexExcludeTags
|
|
286
|
-
}
|
|
287
|
-
},
|
|
290
|
+
storeModalRoute: initialRoute,
|
|
288
291
|
storeModalHistory: [],
|
|
289
292
|
orderVariableSelections: [],
|
|
290
293
|
licenseeIsBillingIdentity: null
|