@depict-ai/react-ui 0.0.10 → 0.0.11

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.
Files changed (35) hide show
  1. package/dist/main.js +19 -20
  2. package/dist/module.js +19 -20
  3. package/dist/styles/components/PLP/Buttons.scss +124 -0
  4. package/dist/styles/components/PLP/MorphingSign.scss +31 -0
  5. package/dist/styles/components/PLP/PLPResults.scss +20 -0
  6. package/dist/styles/components/PLP/ProductListingPage.scss +142 -0
  7. package/dist/styles/components/PLP/ScrollStatus.scss +24 -0
  8. package/dist/styles/components/PLP/SelectedFilters.scss +74 -0
  9. package/dist/styles/components/PLP/SlidableItems.scss +99 -0
  10. package/dist/styles/components/PLP/SortAndFilter/FloatingButtons.scss +75 -0
  11. package/dist/styles/components/PLP/SortAndFilter/SortAndFilter.scss +728 -0
  12. package/dist/styles/components/PLP/SortAndFilter/SortAndFilterModal.scss +160 -0
  13. package/dist/styles/components/PLP/SortAndFilter/WhiteSortAndFilter.scss +148 -0
  14. package/dist/styles/components/PLP/Toast.scss +54 -0
  15. package/dist/styles/components/PLP/index.scss +45 -0
  16. package/dist/styles/components/category/BreadCrumbs.scss +23 -0
  17. package/dist/styles/components/category/CategoryTitle.scss +28 -0
  18. package/dist/styles/components/category/QuickLinks.scss +71 -0
  19. package/dist/styles/components/category/index.scss +23 -0
  20. package/dist/styles/components/search/Autocomplete.scss +117 -0
  21. package/dist/styles/components/search/CategorySuggestions.scss +74 -0
  22. package/dist/styles/components/search/InstantCard.scss +94 -0
  23. package/dist/styles/components/search/InstantResults.scss +10 -0
  24. package/dist/styles/components/search/PreviousSearches.scss +77 -0
  25. package/dist/styles/components/search/QueryInput.scss +167 -0
  26. package/dist/styles/components/search/SearchModal.scss +90 -0
  27. package/dist/styles/components/search/SearchRecommendations.scss +25 -0
  28. package/dist/styles/components/search/ShowingResultsFor.scss +10 -0
  29. package/dist/styles/components/search/index.scss +40 -0
  30. package/dist/{styling → styles}/default.css +0 -0
  31. package/dist/styles/helpers/custom_input.scss +162 -0
  32. package/dist/styles/helpers/supports-hover.scss +5 -0
  33. package/dist/styles/helpers/utils.scss +82 -0
  34. package/dist/styles/variables.scss +10 -0
  35. package/package.json +8 -8
package/dist/main.js CHANGED
@@ -3,8 +3,8 @@ var $1pn1h$depictaireactsolidbridge = require("@depict-ai/react-solid-bridge");
3
3
  var $1pn1h$react = require("react");
4
4
  var $1pn1h$depictaiui = require("@depict-ai/ui");
5
5
  var $1pn1h$reactjsxruntime = require("react/jsx-runtime");
6
- var $1pn1h$depictaiutilishared = require("@depict-ai/utilishared");
7
6
  var $1pn1h$solidjs = require("solid-js");
7
+ var $1pn1h$depictaiutilishared = require("@depict-ai/utilishared");
8
8
 
9
9
  function $parcel$export(e, n, v, s) {
10
10
  Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
@@ -19,7 +19,6 @@ $parcel$export(module.exports, "DepictSearchHeader", () => $20bf907adee775ba$exp
19
19
 
20
20
 
21
21
 
22
-
23
22
  const $e589c49931886c97$export$8e769ad4338a911e = {
24
23
  search: null,
25
24
  header_alignment: null
@@ -38,6 +37,14 @@ function $b4d0d98857ed9934$export$5cae361ad82dce8b(value) {
38
37
  ]);
39
38
  return ref.current;
40
39
  }
40
+ let $b4d0d98857ed9934$var$run_on_href_change;
41
+ function $b4d0d98857ed9934$export$74f3924c5027fe1d(cb) {
42
+ $b4d0d98857ed9934$var$run_on_href_change = cb;
43
+ }
44
+ (async ()=>{
45
+ for await (const href of (0, $1pn1h$depictaiutilishared.href_change_ipns))$b4d0d98857ed9934$var$run_on_href_change?.(href);
46
+ })();
47
+
41
48
 
42
49
 
43
50
 
@@ -116,20 +123,13 @@ const $7b6eabbde6829606$export$99ae278b8f3607a0 = (opts)=>{
116
123
 
117
124
 
118
125
  function $18b830ef84ac138a$export$9fac37a9c21c2f3b(props) {
119
- const { children: children , merchant: merchant , market: market , search_page_path: search_page_path } = props;
120
- const previous_props = (0, $b4d0d98857ed9934$export$5cae361ad82dce8b)(props);
121
- if (!(0, $e589c49931886c97$export$8e769ad4338a911e).search) // Todo: use search_page_path for navigation
126
+ const { children: children , search_page_path: search_page_path , ...assignable_options } = props;
127
+ const { search: search } = (0, $e589c49931886c97$export$8e769ad4338a911e);
128
+ if (!search) // Todo: use search_page_path for navigation
122
129
  (0, $e589c49931886c97$export$8e769ad4338a911e).search = (0, $7b6eabbde6829606$export$99ae278b8f3607a0)({
123
- merchant: merchant,
124
- market: market
130
+ ...assignable_options
125
131
  });
126
- else if (previous_props) {
127
- const { prev_merchant: prev_merchant , prev_market: prev_market , search_page_path: search_page_path1 } = previous_props;
128
- // Todo: here we can check if our search config changed and react to it.
129
- // Do we need to know if it changed specifically, or could we just always set the values regardless if they changed or not?
130
- // Should changing merchant log an error? Is it ever not a bug?
131
- }
132
- console.log("DepictProvider render", props, previous_props);
132
+ else Object.assign(search, assignable_options);
133
133
  return children;
134
134
  }
135
135
 
@@ -222,8 +222,13 @@ function $7c7f5a6b750dca70$var$DepictSearchPageContent(opts) {
222
222
  const solidBridge = (0, $1pn1h$reactjsxruntime.jsx)((0, $1pn1h$depictaireactsolidbridge.ReactToSolidBridge), {
223
223
  solidComponent: ()=>{
224
224
  const [el, dispose] = (0, $1pn1h$solidjs.createRoot)((dispose)=>{
225
+ (0, $b4d0d98857ed9934$export$74f3924c5027fe1d)((href)=>{
226
+ // TODO: Will be user specified
227
+ if (!new URL(href).pathname.startsWith("/search")) dispose();
228
+ });
225
229
  const el = (0, $1pn1h$depictaiui.SearchPage)({
226
230
  depict_search: (0, $e589c49931886c97$export$8e769ad4338a911e).search,
231
+ include_input_field: true,
227
232
  cols_at_size: [
228
233
  [
229
234
  4
@@ -248,7 +253,6 @@ function $7c7f5a6b750dca70$var$DepictSearchPageContent(opts) {
248
253
  ];
249
254
  });
250
255
  (0, $1pn1h$solidjs.onCleanup)(dispose);
251
- $7c7f5a6b750dca70$var$dispose_on_href_change(dispose);
252
256
  return el;
253
257
  },
254
258
  key: Math.random()
@@ -266,10 +270,5 @@ function $7c7f5a6b750dca70$export$210723f5a54a7028(opts) {
266
270
  children: (0, $1pn1h$reactjsxruntime.jsx)($7c7f5a6b750dca70$var$DepictSearchPageContent, opts)
267
271
  });
268
272
  }
269
- async function $7c7f5a6b750dca70$var$dispose_on_href_change(dispose) {
270
- const [exit_ipns, href_ipns] = (0, $1pn1h$depictaiutilishared.make_asyncIterable_exiter)((0, $1pn1h$depictaiutilishared.href_change_ipns));
271
- (0, $1pn1h$solidjs.onCleanup)(exit_ipns);
272
- for await (const href of href_ipns)if (!new URL(href).pathname.startsWith("/search")) dispose();
273
- }
274
273
 
275
274
 
package/dist/module.js CHANGED
@@ -3,9 +3,8 @@ import {ReactToSolidBridge as $9xHCU$ReactToSolidBridge, ReactToSolidBridgeProvi
3
3
  import {useState as $9xHCU$useState, useEffect as $9xHCU$useEffect, ReactPortal as $9xHCU$ReactPortal, createElement as $9xHCU$createElement, useRef as $9xHCU$useRef} from "react";
4
4
  import {SearchPage as $9xHCU$SearchPage, DepictSearch as $9xHCU$DepictSearch, swedish_search_translation as $9xHCU$swedish_search_translation} from "@depict-ai/ui";
5
5
  import {jsx as $9xHCU$jsx} from "react/jsx-runtime";
6
- import {make_asyncIterable_exiter as $9xHCU$make_asyncIterable_exiter, href_change_ipns as $9xHCU$href_change_ipns, observer as $9xHCU$observer, history_replacer as $9xHCU$history_replacer, queueMacroTask as $9xHCU$queueMacroTask} from "@depict-ai/utilishared";
7
6
  import {onCleanup as $9xHCU$onCleanup, createRoot as $9xHCU$createRoot, createSignal as $9xHCU$createSignal, createMemo as $9xHCU$createMemo} from "solid-js";
8
-
7
+ import {href_change_ipns as $9xHCU$href_change_ipns, observer as $9xHCU$observer, history_replacer as $9xHCU$history_replacer, queueMacroTask as $9xHCU$queueMacroTask} from "@depict-ai/utilishared";
9
8
 
10
9
 
11
10
 
@@ -30,6 +29,14 @@ function $c83ba9ab79386687$export$5cae361ad82dce8b(value) {
30
29
  ]);
31
30
  return ref.current;
32
31
  }
32
+ let $c83ba9ab79386687$var$run_on_href_change;
33
+ function $c83ba9ab79386687$export$74f3924c5027fe1d(cb) {
34
+ $c83ba9ab79386687$var$run_on_href_change = cb;
35
+ }
36
+ (async ()=>{
37
+ for await (const href of (0, $9xHCU$href_change_ipns))$c83ba9ab79386687$var$run_on_href_change?.(href);
38
+ })();
39
+
33
40
 
34
41
 
35
42
 
@@ -108,20 +115,13 @@ const $cd2077d7481df27e$export$99ae278b8f3607a0 = (opts)=>{
108
115
 
109
116
 
110
117
  function $faf794495ff8b304$export$9fac37a9c21c2f3b(props) {
111
- const { children: children , merchant: merchant , market: market , search_page_path: search_page_path } = props;
112
- const previous_props = (0, $c83ba9ab79386687$export$5cae361ad82dce8b)(props);
113
- if (!(0, $9ce874af9a04465f$export$8e769ad4338a911e).search) // Todo: use search_page_path for navigation
118
+ const { children: children , search_page_path: search_page_path , ...assignable_options } = props;
119
+ const { search: search } = (0, $9ce874af9a04465f$export$8e769ad4338a911e);
120
+ if (!search) // Todo: use search_page_path for navigation
114
121
  (0, $9ce874af9a04465f$export$8e769ad4338a911e).search = (0, $cd2077d7481df27e$export$99ae278b8f3607a0)({
115
- merchant: merchant,
116
- market: market
122
+ ...assignable_options
117
123
  });
118
- else if (previous_props) {
119
- const { prev_merchant: prev_merchant , prev_market: prev_market , search_page_path: search_page_path1 } = previous_props;
120
- // Todo: here we can check if our search config changed and react to it.
121
- // Do we need to know if it changed specifically, or could we just always set the values regardless if they changed or not?
122
- // Should changing merchant log an error? Is it ever not a bug?
123
- }
124
- console.log("DepictProvider render", props, previous_props);
124
+ else Object.assign(search, assignable_options);
125
125
  return children;
126
126
  }
127
127
 
@@ -214,8 +214,13 @@ function $a854d2a2f2059f57$var$DepictSearchPageContent(opts) {
214
214
  const solidBridge = (0, $9xHCU$jsx)((0, $9xHCU$ReactToSolidBridge), {
215
215
  solidComponent: ()=>{
216
216
  const [el, dispose] = (0, $9xHCU$createRoot)((dispose)=>{
217
+ (0, $c83ba9ab79386687$export$74f3924c5027fe1d)((href)=>{
218
+ // TODO: Will be user specified
219
+ if (!new URL(href).pathname.startsWith("/search")) dispose();
220
+ });
217
221
  const el = (0, $9xHCU$SearchPage)({
218
222
  depict_search: (0, $9ce874af9a04465f$export$8e769ad4338a911e).search,
223
+ include_input_field: true,
219
224
  cols_at_size: [
220
225
  [
221
226
  4
@@ -240,7 +245,6 @@ function $a854d2a2f2059f57$var$DepictSearchPageContent(opts) {
240
245
  ];
241
246
  });
242
247
  (0, $9xHCU$onCleanup)(dispose);
243
- $a854d2a2f2059f57$var$dispose_on_href_change(dispose);
244
248
  return el;
245
249
  },
246
250
  key: Math.random()
@@ -258,11 +262,6 @@ function $a854d2a2f2059f57$export$210723f5a54a7028(opts) {
258
262
  children: (0, $9xHCU$jsx)($a854d2a2f2059f57$var$DepictSearchPageContent, opts)
259
263
  });
260
264
  }
261
- async function $a854d2a2f2059f57$var$dispose_on_href_change(dispose) {
262
- const [exit_ipns, href_ipns] = (0, $9xHCU$make_asyncIterable_exiter)((0, $9xHCU$href_change_ipns));
263
- (0, $9xHCU$onCleanup)(exit_ipns);
264
- for await (const href of href_ipns)if (!new URL(href).pathname.startsWith("/search")) dispose();
265
- }
266
265
 
267
266
 
268
267
  export {$a854d2a2f2059f57$export$210723f5a54a7028 as DepictSearchPage, $faf794495ff8b304$export$9fac37a9c21c2f3b as DepictProvider, $f41a371216eff80b$export$a7f6cffb6b8ba11c as openModal, $f41a371216eff80b$export$cbcd1ecdb41b1d0a as DepictSearchHeader};
@@ -0,0 +1,124 @@
1
+ @use "../../variables";
2
+ @use "../../helpers/supports-hover";
3
+ @use "../../helpers/utils";
4
+ @use "sass:color";
5
+
6
+ $primary-button-background: variables.$brand-black;
7
+ $primary-button-color: #fff;
8
+ $primary-button-border: 1px solid transparent; // so that the page doesn't jump when there's half a border when switching between having sort and filters open (the buttons switch between pimary and secondary)
9
+ $primary-button-border-radius: variables.$border-radius;
10
+ $primary-button-hover-filter: drop-shadow(-2px -2px 4px rgba(255, 255, 255, 0.25))
11
+ drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.15));
12
+ $primary-button-active-filter: drop-shadow(2px 2px 4px rgba(255, 255, 255, 0.25))
13
+ drop-shadow(-2px -2px 4px rgba(0, 0, 0, 0.15));
14
+ $primary-button-focus-visible-filter: drop-shadow(2px 2px 4px rgba(65, 143, 195, 0.8))
15
+ drop-shadow(-2px -2px 4px rgba(65, 143, 195, 0.8));
16
+
17
+ $secondary-button-background: variables.$brand-lightest-grey;
18
+ $secondary-button-color: variables.$brand-dark-grey;
19
+ $secondary-button-border: 1px solid variables.$brand-black;
20
+ $secondary-button-border-radius: variables.$border-radius;
21
+ $secondary-button-hover-filter: drop-shadow(-2px -2px 4px rgba(255, 255, 255, 0.25))
22
+ drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.15));
23
+ $secondary-button-active-filter: drop-shadow(2px 2px 4px rgba(255, 255, 255, 0.25))
24
+ drop-shadow(-2px -2px 4px rgba(0, 0, 0, 0.15));
25
+ $secondary-button-focus-visible-filter: drop-shadow(-2px -2px 4px rgba(65, 143, 195, 0.8))
26
+ drop-shadow(2px 2px 4px rgba(65, 143, 195, 0.8));
27
+
28
+ @mixin PrimaryButton(
29
+ $background: $primary-button-background,
30
+ $color: $primary-button-color,
31
+ $border: $primary-button-border,
32
+ $border-radius: $primary-button-border-radius,
33
+ $hover-filter: $primary-button-hover-filter,
34
+ $active-filter: $primary-button-active-filter,
35
+ $focus-visible-filter: $primary-button-focus-visible-filter
36
+ ) {
37
+ // not using .primary since that's 100% going to conflict with existing declarations on sites
38
+ button.major {
39
+ @include Button(
40
+ $background,
41
+ $color,
42
+ $border,
43
+ $border-radius,
44
+ $hover-filter,
45
+ $active-filter,
46
+ $focus-visible-filter
47
+ ) {
48
+ @content;
49
+ }
50
+ }
51
+ }
52
+
53
+ @mixin SecondaryButton(
54
+ $background: $secondary-button-background,
55
+ $color: $secondary-button-color,
56
+ $border: $secondary-button-border,
57
+ $border-radius: $secondary-button-border-radius,
58
+ $hover-filter: $secondary-button-hover-filter,
59
+ $active-filter: $secondary-button-active-filter,
60
+ $focus-visible-filter: $secondary-button-focus-visible-filter
61
+ ) {
62
+ // not using .secondary since that's 100% going to conflict with existing declarations on sites
63
+ button.minor {
64
+ @include Button(
65
+ $background,
66
+ $color,
67
+ $border,
68
+ $border-radius,
69
+ $hover-filter,
70
+ $active-filter,
71
+ $focus-visible-filter
72
+ ) {
73
+ @content;
74
+ }
75
+ }
76
+ }
77
+
78
+ @mixin Button(
79
+ $background,
80
+ $color,
81
+ $border,
82
+ $border-radius,
83
+ $hover-filter,
84
+ $active-filter,
85
+ $focus-visible-filter,
86
+ $padding: 10px 20px
87
+ ) {
88
+ background: $background;
89
+ color: $color;
90
+ border: $border;
91
+ border-radius: $border-radius;
92
+ @if $padding {
93
+ padding: $padding;
94
+ }
95
+ display: flex;
96
+ white-space: pre-wrap; // can't have spaces otherwise
97
+ justify-content: center;
98
+ align-items: center;
99
+ cursor: pointer;
100
+ transition: filter 150ms ease-in-out, background 100ms ease-in-out;
101
+
102
+ svg path {
103
+ fill: $color; // treat icons the same as text
104
+ }
105
+
106
+ @include supports-hover.supports-hover() {
107
+ &:hover {
108
+ filter: $hover-filter;
109
+ @include utils.highlight-background($normal-background: $background);
110
+ }
111
+ }
112
+ &:active {
113
+ filter: $active-filter;
114
+ @include utils.highlight-background($normal-background: $background, $darken-factor: 10%, $lighten-factor: 20%);
115
+ }
116
+ &:focus {
117
+ outline-style: none;
118
+ }
119
+ &:focus-visible {
120
+ filter: $focus-visible-filter;
121
+ @include utils.highlight-background($normal-background: $background);
122
+ }
123
+ @content;
124
+ }
@@ -0,0 +1,31 @@
1
+ @mixin MorphingSign($color: #fff) {
2
+ .morphing-sign {
3
+ /* https://stackoverflow.com/a/38136283 */
4
+ border: 0;
5
+ font-size: 1.5em;
6
+ position: relative;
7
+ width: 1em;
8
+ height: 1em;
9
+
10
+ span {
11
+ position: absolute;
12
+ background: $color;
13
+ border-radius: 2px;
14
+ }
15
+
16
+ /* Create the "+" shape by positioning the spans absolutely */
17
+ span:first-child {
18
+ top: 25%;
19
+ bottom: 25%;
20
+ width: 10%;
21
+ left: 45%;
22
+ }
23
+
24
+ span:last-child {
25
+ left: 25%;
26
+ right: 25%;
27
+ height: 10%;
28
+ top: 45%;
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,20 @@
1
+ @use "../../variables";
2
+ @use "../../helpers/utils";
3
+
4
+ @mixin PLPResults() {
5
+ .listing-page {
6
+ .no-results {
7
+ background: white;
8
+ padding: 40px;
9
+ display: flex;
10
+ justify-content: flex-start;
11
+ align-items: center;
12
+ flex-direction: column;
13
+ flex-grow: 2;
14
+ .hint {
15
+ text-decoration: underline;
16
+ cursor: pointer;
17
+ }
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,142 @@
1
+ @use "../../helpers/utils";
2
+
3
+ @mixin ProductListingPage($spacing-to-filters: 12px, $desktop-item-gap: 20px, $mobile-item-gap: 16px) {
4
+ .listing-page {
5
+ display: flex;
6
+ flex-direction: column;
7
+ padding: $desktop-item-gap calc(#{$desktop-item-gap} / 2);
8
+ @include mobile_sizes() {
9
+ padding: $mobile-item-gap calc(#{$mobile-item-gap} / 2);
10
+ }
11
+
12
+ &,
13
+ & * {
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ & > .filter-results-for-one-row,
18
+ & > .results-for {
19
+ margin-bottom: calc(#{$desktop-item-gap} / 2);
20
+ @include mobile_sizes() {
21
+ margin-bottom: calc(#{$mobile-item-gap} / 2);
22
+ }
23
+ }
24
+
25
+ & > .sort-and-filter-buttons {
26
+ margin-top: calc(#{$desktop-item-gap} / 2);
27
+ margin-bottom: calc(#{$desktop-item-gap} / 2);
28
+ @include mobile_sizes() {
29
+ margin-top: calc(#{$mobile-item-gap} / 2);
30
+ margin-bottom: calc(#{$mobile-item-gap} / 2);
31
+ }
32
+ }
33
+ .PLP-results {
34
+ margin-top: calc(#{$desktop-item-gap} / 2);
35
+ @include mobile_sizes() {
36
+ margin-top: calc(#{$mobile-item-gap} / 2);
37
+ }
38
+ display: flex;
39
+ & > {
40
+ .filters,
41
+ .sorting {
42
+ margin-left: $spacing-to-filters;
43
+ }
44
+ }
45
+ }
46
+ .cards {
47
+ // this is for all product lists, meaning PLPResults (category + search product lists) and SearchRecommendations
48
+ flex-wrap: wrap;
49
+ display: flex;
50
+ flex-direction: row;
51
+ flex-grow: 1;
52
+ overflow: hidden;
53
+ }
54
+ }
55
+ }
56
+
57
+ @mixin SearchPage(
58
+ $spacing-to-filters: 12px,
59
+ $desktop-item-gap: 20px,
60
+ $mobile-item-gap: 16px,
61
+ $spacing-above-search-field: true,
62
+ $query-input-width: 800px,
63
+ $gap-to-recs-factor: 3
64
+ ) {
65
+ .listing-page {
66
+ .query_input {
67
+ width: min(100%, $query-input-width);
68
+ align-self: center;
69
+
70
+ @if $spacing-above-search-field {
71
+ margin-top: calc(#{$desktop-item-gap} * 2);
72
+ }
73
+ margin-bottom: $desktop-item-gap;
74
+ @include mobile_sizes() {
75
+ margin-bottom: $mobile-item-gap;
76
+ @if $spacing-above-search-field {
77
+ margin-top: calc(#{$mobile-item-gap});
78
+ }
79
+ }
80
+ ~ .category-suggestions .category-suggestion {
81
+ &:last-child {
82
+ margin-right: auto;
83
+ }
84
+ &:first-child {
85
+ margin-left: auto;
86
+ }
87
+ }
88
+ }
89
+ .category-suggestions {
90
+ margin-bottom: $desktop-item-gap;
91
+ @include mobile_sizes() {
92
+ margin-bottom: $mobile-item-gap;
93
+ }
94
+ }
95
+ .query_input {
96
+ // if there are no category suggestions we should have 2x the gap between where they should be and what's there, only for desktop tho
97
+ & + .filter-results-for-one-row,
98
+ & + .results-for {
99
+ @media (min-width: 652px) {
100
+ margin-top: $desktop-item-gap;
101
+ }
102
+ }
103
+ }
104
+ .search-recs {
105
+ // whole gap here so that we don't have to make the margin bottom of search-results conditional
106
+ margin-top: calc(#{$desktop-item-gap} * #{$gap-to-recs-factor});
107
+ // in between these there's the border, a visual line separating the results and recs
108
+ padding-top: calc(#{$desktop-item-gap} * #{$gap-to-recs-factor});
109
+ @include mobile_sizes() {
110
+ margin-top: calc(#{$mobile-item-gap} * #{$gap-to-recs-factor});
111
+ padding-top: calc(#{$mobile-item-gap} * #{$gap-to-recs-factor});
112
+ }
113
+ }
114
+ .PLP-results.nothing + .search-recs {
115
+ // if no results, bring us closer
116
+ margin-top: calc(#{$desktop-item-gap} * 1.5);
117
+ padding-top: calc(#{$desktop-item-gap} * 1.5);
118
+ @include mobile_sizes() {
119
+ margin-top: calc(#{$mobile-item-gap} * 1.5);
120
+ padding-top: calc(#{$mobile-item-gap} * 1.5);
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ @mixin CategoryPage($spacing-to-filters: 12px, $desktop-item-gap: 20px, $mobile-item-gap: 16px) {
127
+ .listing-page {
128
+ .quicklinks,
129
+ .crumbs {
130
+ margin-bottom: $desktop-item-gap;
131
+ @include mobile_sizes() {
132
+ margin-bottom: $mobile-item-gap;
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ @mixin mobile_sizes() {
139
+ @media (max-width: 651px) {
140
+ @content;
141
+ }
142
+ }
@@ -0,0 +1,24 @@
1
+ @use "../../variables";
2
+
3
+ @mixin ScrollStatus(
4
+ $scroll-status-background: rgba(100, 100, 100, 0.9),
5
+ $border-radius: calc(variables.$border-radius * 5)
6
+ ) {
7
+ .scroll-status {
8
+ pointer-events: none;
9
+ position: sticky;
10
+ bottom: 10vh;
11
+ white-space: nowrap;
12
+ display: flex;
13
+ justify-content: center;
14
+ z-index: calc(#{variables.$base-z-index} + 4);
15
+ align-items: center;
16
+ opacity: 0;
17
+ .text {
18
+ background: $scroll-status-background;
19
+ color: white;
20
+ padding: 10px 20px;
21
+ border-radius: $border-radius;
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,74 @@
1
+ @use "../../variables";
2
+ @use "../../helpers/utils";
3
+ @use "../../helpers/supports-hover";
4
+ @use "./Buttons";
5
+
6
+ @mixin SelectedFilters(
7
+ $border-radius: variables.$border-radius,
8
+ $title-color: variables.$brand-black,
9
+ $filter-title-transform: uppercase,
10
+ $margin-on-desktop: 0px,
11
+ $set-border-on-crumbs: true
12
+ ) {
13
+ .listing-page .selected-filters {
14
+ .inner {
15
+ // this is in here because it's an ExpandingContainer and the animation gets borked otherwise
16
+ margin-top: 10px;
17
+ margin-bottom: 10px;
18
+ display: flex;
19
+ align-items: center;
20
+ .title {
21
+ margin-right: 10px;
22
+ }
23
+ @media (min-width: 652px) {
24
+ margin-top: $margin-on-desktop;
25
+ margin-bottom: $margin-on-desktop;
26
+ }
27
+
28
+ .title {
29
+ @media (max-width: 600px) {
30
+ display: none;
31
+ }
32
+ font-size: 1.1em;
33
+ text-transform: $filter-title-transform;
34
+ color: $title-color;
35
+ }
36
+
37
+ .depict_slider {
38
+ overflow: hidden;
39
+ width: unset;
40
+
41
+ .clear-filter {
42
+ @if $set-border-on-crumbs {
43
+ border: 1px solid Buttons.$primary-button-background;
44
+ }
45
+ svg {
46
+ width: 12.64px;
47
+ height: 12.64px;
48
+ }
49
+ }
50
+ .clear-all-filters {
51
+ @if $set-border-on-crumbs {
52
+ border: Buttons.$secondary-button-border;
53
+ }
54
+ }
55
+
56
+ .clear-filter,
57
+ .clear-all-filters {
58
+ flex: 0 0 auto;
59
+ box-sizing: border-box;
60
+ white-space: nowrap;
61
+ padding: 5px 10px;
62
+ display: flex;
63
+ @include utils.flex-gap(5px, "row nowrap");
64
+ align-items: center;
65
+ border-radius: $border-radius;
66
+ font-size: 1em;
67
+ line-height: 1;
68
+ cursor: pointer;
69
+ }
70
+ }
71
+ @content;
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,99 @@
1
+ // @use "../../../rendering/slider_button_positioning";
2
+ @use "../../helpers/utils";
3
+ @use "../../variables";
4
+ @use "../../helpers/supports-hover";
5
+
6
+ @mixin button_positioning {
7
+ .d_navbutton {
8
+ position: absolute;
9
+ z-index: 2;
10
+ top: 50%;
11
+ transform: translateY(-50%);
12
+ -webkit-transform: translateY(-50%);
13
+ touch-action: manipulation;
14
+ transition-duration: 0.2s;
15
+ padding-right: 1px;
16
+ cursor: pointer;
17
+ &.hidden {
18
+ cursor: default;
19
+ opacity: 0;
20
+ animation-name: depict_slider_button_unclickable;
21
+ animation-duration: 5s;
22
+ animation-fill-mode: forwards;
23
+ }
24
+ &.left {
25
+ transform: translateY(-50%) rotate(180deg);
26
+ left: -1px; // fix chrome rendering half a px of not the button
27
+ }
28
+ &.right {
29
+ right: -1px;
30
+ }
31
+ img {
32
+ width: 100%;
33
+ height: 100%;
34
+ }
35
+ @content;
36
+ }
37
+ @keyframes depict_slider_button_unclickable {
38
+ 0% {
39
+ pointer-events: all;
40
+ }
41
+ 100% {
42
+ pointer-events: none;
43
+ visibility: hidden; // make not keyboard focusable with tab
44
+ }
45
+ }
46
+ }
47
+
48
+ @mixin SlidableItems($fade-to: variables.$brand-lighter-grey, $fade-from: rgba(238, 238, 240, 0)) {
49
+ .depict_slider {
50
+ width: 100%;
51
+ position: relative;
52
+ .sliding {
53
+ height: 100%;
54
+ @include utils.flex-gap(10px, "row nowrap");
55
+ align-items: center;
56
+ display: flex;
57
+ flex-direction: row;
58
+ flex-wrap: nowrap;
59
+ overflow-x: scroll;
60
+ /* Internet Explorer 10+; next 3 properties stolen from: https://stackoverflow.com/a/38994837*/
61
+ -ms-overflow-style: none;
62
+ /* Firefox */
63
+ scrollbar-width: none;
64
+ // Chrome and Safari
65
+ &::-webkit-scrollbar {
66
+ display: none;
67
+ }
68
+ }
69
+ // TODO: break out button button positioning related lib code into a package and import that here instead of duplicating the code
70
+ // @include slider_button_positioning.button_positioning {
71
+ @include button_positioning {
72
+ height: calc(100% + 2px);
73
+ padding-top: 0;
74
+ padding-left: 0;
75
+ padding-bottom: 0;
76
+ width: 26px;
77
+ background: linear-gradient(270deg, $fade-to 50%, $fade-from 105%);
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: flex-end;
81
+ border: none;
82
+
83
+ @include supports-hover.supports-hover() {
84
+ &:hover {
85
+ svg {
86
+ transform: scale(1.2);
87
+ }
88
+ }
89
+ }
90
+ svg {
91
+ transition-duration: 150ms;
92
+ }
93
+
94
+ &:active {
95
+ opacity: 0.9;
96
+ }
97
+ }
98
+ }
99
+ }